ngBuilding your app with Angular CLI

Khachatur Tovmassian
SFL Newsroom
Published in
7 min readFeb 11, 2019

It’s known that one of the very big and important phases while handling the JavaScript boilerplate is the building process. And before going into that, we must first define for which environment we are building, whether it’s for development, production or something else specific. Based on that decision we need to make sure that our building is properly configured and it serves its purpose best. If we are building for the development environment, the build should make the development cycle as efficient as possible. For the production, we have completely different needs such as build load optimization. This kind of optimization can be done with code uglification(same as minification), bundling, tree shaking, etc. For all these situations that powerful command line interface for creating Angular applications — Angular CLI comes to make these complicated processes smooth and joyful. If you have ever interacted with Angular CLI you should know that every command there starts with those magical initials “ng” and you might already guess that it will be followed by “build.” The best way to dive deeper with a new command that you are going to explore is to add “--help” flag and see what options it provides. And building command is not an exception (Fig. 1).

Fig. 1. 1st step on exploring “ng build.”

ngBuild in the development environment

If we check our Angular project before the build, we can see that there is no “/dist” folder. After running “ng build” in the terminal (Fig. 2) and waiting for a few seconds (if your machine is not deprecated or you are building a huge application) you will see the newly created “/dist” folder (you can configure your build target directory in angular.json file’s build section).

Fig. 2. Building the application with default parameters (development environment).

Looking into that “/dist” directory, we will see the built files and among them “/dist/angular-app/index.html” where we can look into all our main built files attached. Let’s tackle them in more detail (Fig. 3).

Fig. 3. “index.html” file with attached built files for the development environment.

Looking through it we will see five main bundles that have been created during the build. Each of them is essential for our application to run properly. Reading the first line of /dist/angular-app/runtime.js file (Fig. 4) is enough to understand that Angular CLI uses Webpack under the hood to build the application.

Fig. 4. The first line of runtime.js — Webpack runtime file.

And here are more details about those five bundles built by the CLI:

  • runtime.js - Webpack runtime file
  • polyfills.js - Polyfill scripts for supporting the variety of the latest modern browsers
  • styles.js - Global style files bundled in one .js file, which is being generated faster than if styles would have been extracted into .css
  • vendor.js - Angular and other 3rd party vendor scripts bundled in one file
  • main.js - Application code bundled into one file

ngBuild in the production

When it comes to production, we have a different image. We just need to add the “--prod” flag if we are using Angular CLI, and with this single flag, all the configurations will change (Fig. 5).

Fig. 5. Building the application for production.

And again, looking into the generated “/dist/angular-app/index.html” file, we can obviously see the difference from the previous build (Fig. 6).

Fig. 6. “index.html” file with attached built files for the production environment.

As we see there is a slightly different image:

  • during the production build, the cache-busting technique is being applied. It adds hash codes to the bundle file names. When we modify something in the code and perform a new build, the cache-busting technique will generate a new hash code for the modified file. This on its turn, helps the users avoid downloading the existing, non-modified files while loading the page. Only, the modified files will be downloaded.
  • global styles are generated in .css file unlike previously generated .js file
  • vendor.js file is included in main.js making all optimizations such as code uglification and tree-shaking(getting rid of all code that is not being referenced) to be applied faster once and for both bundles in one file.

Besides the mentioned differences during the production build another powerful technique is being applied by Angular CLI called Ahead Of Time (AOT) compilation. When this option is turned on, all the compilation is being done on the server side instead of the browser-side. As the code is already compiled on the server-side, there is no need to send the compile.js file to the browser to perform the browser-side compilation.

Also for the development mode, additional source maps are being added to our build for helping with debugging, while on production we don’t have these maps. Here are the key differences between default development and production builds (Fig. 7).

Fig. 7. Development build vs. Production build

ngAnalyzing the build with the Webpack Bundle Analyzer

There is another tool that we can use to better analyze the building process and see the differences. It’s called webpack-bundle-analyzer. With this tool, we can see the differences in our builds in a more visual way. Let’s install the tool, then ngBuild our app with “--stats-json” flag. After a successful build, we can find the newly-generated “/dist/angular-app/stats.json” file which contains all the data needed for the webpack-bundle-analyzer. You should use “npx” (I assume you already have it installed globally) to run the webpack-bundle-analyzer with the data from the previously-generated “stats.json” file. (Fig. 8).

Fig. 8. Installing the webpack-bundle-analyzer and running it with the default development build.

With the last command, we will see a newly-loaded tab in our browser which will visually show what has been built (Fig. 9).

Fig. 9. Development build analyzed by webpack-bundle-analyzer.

On the left side, we can see that our build is about 4MB which is too much for the small application on which we are experimenting build. We can notice the earlier mentioned compiler.js bundled in vendor.js file making its size more than 3MB and indicating that compilation is made on the browser side.

Let’s do another build with Ahead Of Time compilation. For this, we need to add the “--aot” flag after the “ng build” command. (Fig. 10).

Fig. 10. Building the app with Ahead Of Time compilation and running the webpack-bundle-analyzer.

Another newly-opened tab with the new visualization indicates that the previously built compiler.js is missing in vendor.js bundle file making it 1 MB smaller. This makes the whole build size be about 3MB. And all this optimization is done with the help of the Ahead Of Time compilation technique mentioned above (Fig. 11).

Fig. 11. App building with Ahead Of Time compilation analyzed by the webpack-bundle-analyzer.

Let’s take one more step and build our app again, now with the “--prod” flag and run the build analyzer (Fig. 12).

Fig. 12. Building the app for production and running the webpack-bundle-analyzer.

This time we’ve got even more optimized build with the size of only 391KB (Fig. 13). These all are done because of cache-busting, uglification, tree-shaking, ahead of time compilation. In comparison with the development build, we’ve got 10 times smaller built files. Of course, depending on the size and the scale of your application, the amounts will vary.

Fig. 13. Production building analyzed by the webpack-bundle-analyzer.

Here we explored the development, production and one custom build with ahead of time compilation, but Angular CLI provides a bunch of options that can help you to configure your build based on your specific needs. This is the list of some options that you can use to manually configure your ngBuilding process (Fig. 14).

Fig. 14. A list of some useful “ng build” options.

Final notes

To get more information about other ngBuild options, you can check the Angular documentation and if you are interested in exploring more powerful tools of Angular CLI then make sure to check this awesome online course at Pluralsight by John Papa.

About this author: Khachatur Tovmasyan is a JavaScript Jedi with a heart for web technologies, yoga and meditation.

Check out our open roles at https://sflpro.com/job/.

Let’s talk!

Read more:

--

--

Khachatur Tovmassian
SFL Newsroom

Lead Software Engineer @EPAM, JavaScript, Angular enthusiast who also enjoys doing yoga, meditation, traveling, techno music, and much more