Angular 2 is an amazing platform, and Angular-CLI is a fantastic way to start an Angular 2 project. Generating a project via Angular-CLI gives you a client-side code. This code needs to be served up from the server and a lot of people seem to question how exactly this should be done. I see this question pops up often so I decided to write a quick post about wiring the output that angular-CLI generates with NodeJS. In particular, this example shows how to wire things up with the ExpressJS server.
Below is a basic folder structure that we'll end up with:
The two folders -
let's start by generating the client side project:
Notice that we didn't create the directory Below is a basic folder structure that we'll end up with:
/pathTo/MyAwesomeProject
/client
/server
The two folders -
/client
, and /server
will have completely independent projects inside with their own package.json
files.Generate client-side code
> cd /pathTo/MyAwesomeProject
> ng new client
> cd client
> ng build
/client
manually. We just navigated in the /MyAwesomeProject
directory and Angular-CLI generated directory /client
for us. Then we navigated into the /client
directory and executed the Angular-CLI build
command. At this point, we have the dist
directory that contains client-side code ready to be served from the web server.Generate server-side code
/server
directory. Then execute commands below:> cd /pathTo/MyAwesomeProject/server
> npm init -f
> npm i --save express
npm init -f
will generate package.json
file for us. Then we'll install ExpressJS dependency.package.json specifies index.js file as an entry point for nodejs. So let's create index.js file and write basic ExpressJS server code in it:
var express = require('express');
var app = express();
var server = app.listen(3000, function() {
var port = server.address().port;
console.log('App is listening on port:' + port);
});
The code above creates the server, but it does not do anything yet. Now comes the interesting part. Let's wire it up to serve client-side resources.Wire up server with client
Add one more require statement to the top of our server-side code:
var path = require('path');
Then add the code below after declaring the app variable:var app = express();
var clientRoot = path.resolve(__dirname, '..', 'client', 'dist');
var indexPath = path.join(clientRoot, 'dist', 'index.html');
app.use(express.static(clientRoot));
app.get('/', function (req, res, next) {
res.sendFile(indexPath);
});
We are done! The code above tells ExpressJS that all files in the /client/dist/
directory should be allowed to be served if requested for. Further, we tell ExpressJs to serve the index.html page from the dist
directory if the root URL is hit. Now see if the code works:> node index.js
Navigate in your browser to
localhost:3000
and you should see "app works!".Bonus: utilize Angular-CLI's serve command for browser auto-refresh
Angular-CLI's
serve
command is very convenient with its browser synchronization feature. We'd like to utilize it during the development. However, running this command as-is will start Angular-CLI's own server, when we'd like to use server we created. This can easily be achieved by using --proxy-config
option.In the
/client
directory create file proxy.conf.json
with the following contents:{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
Now, if you run the command below while in the /client
directory, all requests starting with /api
will be routed to our real server, and the browser will automatically refresh on any client-side changes.> ng serve --proxy-config proxy.conf.json
Of course, before executing the command above you should make sure that your server is running.Also remember to observe changes in your browser on port 4200 (
localhost:4200
), not 3000. This is the default port on which Angular-CLI serves client side code.This command is a bit lengthy and it's easy to forget to append the proxy option every time you want to run it. This is a perfect use case for npm scripts. In the
/client/package.json
file modify the start
script to include the proxy option. Now, you can simply type npm start
and your client side code will be served with the correct configuration.Final comments
The code above is a simple proof of concept. There is a lot of room for improvement left. I usually write my server-side code in TypeScript, thus have a separate build process for it. Add hot module reloading to server-side code, and many more shenanigans that make development a pleasant process.
Hope you found this post useful.