Reputation: 16416
I found a great tutorial that explains how to setup express.js with Angular CLI, but in this tutorial the angular app is compiled into a production dist folder: https://scotch.io/tutorials/mean-app-with-angular-2-and-the-angular-cli
How do I integrate express.js with Angular CLI, but I want the express.js to work with the development version of the Angular app and I want the nodemon to restart if I make changes to either the express OR angular app.
Have been spending over eight hours trying to get this working. Thanks!
I don't want to run 'ng build' every time I make a change to the Angular app (this takes too long) - I want instant reloading whenever I save a change to my angular app (as if I was running 'ng serve') or express app.
I found a tutorial where you hook up Angular 2 QuickStart with Express, it works but I'm looking to use Angular CLI.
I understand that the Angular CLI uses WebPack whereas the QuickStart uses System.js
Upvotes: 44
Views: 34253
Reputation: 5053
A proxy.conf.json
file in the src directory with the code -
{
"/api/*": {
"target": "http://localhost:3000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
And editing package.json
by adding these 3 entries to it - (replace back.js with your express file which is in the root directory of the Angular project)
"scripts": {
"client": "ng serve",
"server": "nodemon back.js",
"start": "npm-run-all -p client server"
}
Now running npm start
would start both Angular and Express at the same time in dev environment.
Upvotes: 0
Reputation: 16416
NEW ANSWER
My experience of 15 hours has taught me that trying to serve an Angular app with Express during development is NOT a good idea. The proper way is to run Angular and Express as two different apps on two different ports. Angular will be served on port 4200 and Express on port 3000 as usual. Then configure a proxy for API calls to Express app.
Add proxy.config.json to root of Angular project:
{
"/api/*":{
"target":"http://localhost:3000",
"secure":false,
"logLevel":"debug"
}
}
Open up a new terminal tab and run this command to start Express app:
nodemon [YOUR_EXPRESS_APP.js] --watch server
(YOUR_EXPRESS_APP.js is usually named server.js or app.js. server is a directory where you keep all your Express app files)
Open up a second terminal tab and run this command to start Angular app:
ng serve --proxy-config proxy.config.json
This will ensure that Angular app is rebuilt and browser reloaded when a change is made to any Angular app file. Similarly, Express server will restart when a change is made to any Express app files.
Your Angular app is here: http://localhost:4200/
Watch this video to see how to configure a proxy for your API calls with Angular CLI
NOTE:
this setup only applies for development environment. In production, you will want to run ng build
and place the Angular app inside a dist directory to be served up by Express. In production, there is only ONE app running - an Express app serving up your Angular app.
PREVIOUS ANSWER
Using input from @echonax I came up with this solution which is quite fast:
ng build -w & nodemon server.js --watch dist --watch server
This will rebuild the Angular app into the dist folder, and the node server will restart each time that happens. However, there is NOT automatic browser refresh with this setup :(
More on that here:
https://github.com/jprichardson/reload
Upvotes: 96
Reputation: 1263
"etayluz" solution is very good. But I want to add an additional option for NEW ANSWER to not opening two times terminal.
Firstly you have to install concurrently package (https://www.npmjs.com/package/concurrently);
npm install concurrently --save
Then you could add below codes into your package.json file.
"start": "concurrently \"npm run serve-api\" \"npm run serve\"",
"serve": "ng serve --port 3333 --proxy-config proxy.config.json", // You could add --port for changing port
"serve-api": "nodemon [YOUR_EXPRESS_APP.js] --watch server",
npm start
is enough for running your project.
Upvotes: 16
Reputation: 199
I've spent a decent amount of time figuring out how to do this in my own development environments. The best I've come up with is a two fold implementation that combines a lot of echonax's, squirrelsareduck's, and Max's solution, but taking advantage of built in Angular CLI strategies to watch frontend/Angular changes, and using nodemon to watch the backend/Express changes. The short of it is you end up running two processes (ng build and nodemon) to get your development environment up and running, but it automatically rebuilds and runs everything under one Express web server.
The first process you will need to run will be to build the Angular dist folder, and watch any changes made to the Angular frontend. Luckily for us, Angular CLI can do this natively (Tested on Angular CLI >= 1.5) with the following command:
ng build --watch
You'll need to leave this running in the background, but this will watch for any changes made in the Angular code, and rebuild the bundles on the fly.
The second process involves using nodemon to run your Express server, and may take a little bit more setup and planning depending on how extensive your backend/Express setup is. Just make sure Express is pointing to your index file in the dist folder. The big advantage here is that you can add all of this into a Gulpfile with gulp-nodemon to do even more sequential tasks after running nodemon to watch the backend/Express such as linting your backend, running tests parallel to your builds, minifying your backend, or whatever else you can think of to use Gulp for. Use npm or Yarn to add and install nodemon to your project's dependencies, and then run the following to start your Express server:
nodemon app.js
Replace app.js with whatever file you're using to build your Express backend, and it should now rebuild anytime there are changes made to your backend.
Run two separate processes in the background to start your development environment. First run:
ng build --watch
Second, add nodemon to your project dependencies, and run the following command in the background where app.js is replaced with whatever your Express file is called:
nodemon app.js
Since you asked how to automatically reload the browser, your best bet will be to take advantage of a browser plugin called LiveReload. Since we're already going to be using nodemon to watch our backend, you might seriously consider using Gulp if you're not already to run both nodemon and LiveReload as two tasks. Your best bet for implementing LiveReload into Gulp is to use the gulp-refresh plugin as this is an updated version of the gulp-livereload plugin. You'll end up with a Gulpfile resembling this:
const defaultAssets = require('./config/assets/default'),
gulp = require('gulp'),
gulpLoadPlugins = require('gulp-load-plugins'),
runSequence = require('run-sequence'),
plugins = gulpLoadPlugins(),
semver = require('semver');
// I store the locations of my backend js files in a config file, so
// that I can call them later on. ie; defaultAssets
gulp.task('nodemon', function () {
// Node.js v7 and newer use different debug argument
const debugArgument = semver.satisfies(process.versions.node, '>=7.0.0') ? '--inspect' : '--debug';
return plugins.nodemon({
script: 'app.js',
nodeArgs: [debugArgument],
ext: 'js,html',
verbose: true,
watch: defaultAssets.server.allJS
});
});
// Watch Files For Changes
gulp.task('watch', function () {
// Start LiveReload
plugins.refresh.listen();
// Watch backend for changes
gulp.watch(defaultAssets.server.allJS).on('change', plugins.refresh.changed);
// Watch frontend dist folder for changes
gulp.watch('./dist').on('change', plugins.refresh.changed);
});
gulp.task('default', function (done) {
runSequence(['nodemon', 'watch'], done);
});
Now you just run the gulp command in place of nodemon app.js to start your Express server.
Upvotes: 2
Reputation: 71
May be you can add a dependency called 'concurrently', or (npm-run-all, parallelshell).
npm i concurrently --save-dev
then edit the package.json like this: `
"scripts": {
"dev": "concurrently \"ng build -w\" \"cross-env NODE_ENV=development node .\" "
}
` this may be work.
References:
concurrently example: https://stackoverflow.com/a/30950298/7421101,
npm-run-all example: https://stackoverflow.com/a/38213212/7421101,
parallelshell example: https://stackoverflow.com/a/42373547/7421101.
Upvotes: 0
Reputation: 884
I was wondering this also. The Udemy course on the MEAN stack by Max Schwarzmüller has a sample code in there for integrating Express and Angular. In that sample code's package.json file, use uses the scripts.build property to give webpack a command which watches the angular files and updates accordingly. I don't want to copy his code here but that's the general idea. The rest will require some discovery work.
In the readme file, he suggests running npm run build which runs webpack, and then in a new terminal running npm start for the node server. So in theory, this runs two programs like you suggested in your version of the answer. But, it does a more "scripted"/pre-defined way of starting the Angular build process, instead of navigating to the Angular sub-directory and typing ng build --watch in there, and starting the Express app separately.
Upvotes: 1
Reputation: 40647
Using angular-cli, the ng build
or ng build --prod
command will give you bundled up files along with an index.html
. Make your app.js
(node/express) target this file.
Example:
app.use( express.static(__dirname + '/src' ) ); //<- it will automatically search for index.html under src folder.
Upvotes: 6