Longer Explanation
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.
tldr;
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
Bonus
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.