I just updated my Angular samples to version 4 of Angular. Since version 2 the Angular team has made a few tweaks to the Angular distribution format. In this post I will point out a few of the differences.
In version 2 the published Angular distribution consisted of all the original ESM source files. All the original modules (source files) were downloaded with the npm package. This resulted in a large number of source files in the package.
Version 4 of Angular has moved away from publishing the individual source files. Instead we now get a consolidated ESM bundle. You can think of this as a “rolled up” version of the individual modules. All the individual Angular source files have been combined into a single bundle per Angular module (core, http, router, etc).
This means the package contains fewer files since the individual files are replaced by a single ESM bundle per angular module.
Does this hinder Tree Shaking?
No, since the bundle is still published as ESM JavaScript there is no negative impact on Tree Shaking.
To be clear: By “ESM” I am referring to JavaScript with ES2015 import and export statements. It is not important to utilize any other features from ES2015 like classes.
The ES2015 import/export statements is what makes your code statically analyzable by Tree Shakers like Rollup. It doesn't matter that all the import/export statements appear in the same file. I discuss this point in one of my earlier articles.
Rollup shakes at the statement level. Rollup can still infer usage by following the trail of import/export statements, even if they all appear in the same physical file.
UMD vs ESM
Like before, Angular ships with an UMD bundle per Angular module. Why do we need two different types of bundles?
The answer is that UMD bundles and ESM bundles serve different purposes.
The point of UMD is to serve as a universal bundle that supports most common module formats (CommonJS, AMD, global state). In the case of Angular the UMDs are also pure ES5 which makes them runnable in all browsers. The typical use case of UMDs in Angular is unit testing or JiT builds during development. UMDs are flexible, but they are not Tree Shakable. This is where the ESM bundles come into play.
By contrast ESM bundles are not directly runnable in browsers that don't support ES2015 modules. The point of ESM is to publish code in a format optimized for Tree Shaking. You should view ESMs as a format meant to improve application bundling. It's not a suitable runtime format.
But given that ESM bundles contain ES2015 import/export statements, how can we run them in non-ES2015 browser?
This is where bundlers help us out.
Remember that the code in the ESM bundles is pure ES5 expect for the import/export statements. When a bundler like Rollup starts to bundle you application, it will follow the trail of import and export statements. In the end Rollup will create a bundle consisting of only explicitly imported code.
During this process the import/export statements will be removed. Only the actual ES5 code will be included in the final bundle.