Setting up Angular Universal App for development

For development, run npm run start which triggers ng serve. The current setup has hot module reloading so it will watch for your changes and update your dev view. I used the same instructions and got it working here

In short, for development, run npm run start and look at http://localhost:4200.

For production, run npm run build:ssr and npm run serve:ssrand look at http://localhost:4000

As contributors have pointed out, it might not be the most efficient and fastest way to develop, but nevertheless I did not want to accept workarounds. Besides, hosting front and back on separate servers brings up CORS issues, and I never planned my app to run on separate hosts, I wanted it all on the same host together with API methods.

The problem with --dev build was this:

when building with the following command:

ng build --app 1 --output-hashing=false (note that there is no --prod flag)

AppServerModuleNgFactory turned out missing in the ./dist-server/main.bundle

I imagine that this relates to the ahead of time(--aot) compilation which is the default behavior if you are building for --prod. So the instructions from included instructions to configure express server for production build only. And since there is no need for server to be able to dynamically render html templates the working --dev build command would be:

ng build --app 1 --output-hashing=false --aot

and this gets rid of the TypeError: Cannot read property 'moduleType' of undefined

Now to watch this whole mess:

run these in separate command windows:

  1. ng build --watch
  2. ng build --app 1 --output-hashing=false --aot --watch
  3. webpack --config webpack.server.config.js --progress --colors --watch

And for the server to restart on change, you have to install nodemon package and run it like this:

  1. nodemon --inspect dist/server (--inspect if you wish to debug server with chrome)

Some other important stuff:

Angular/CLI has a command to generate necessary scaffolding for a universal app:

ng generate universal

and it generates a fixed version of main.ts that avoids client angular bootstrap issue: document.addEventListener('DOMContentLoaded', () => { platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.log(err)); });

a problem that I stumbled upon once I implemented TransferState