The javascript optimization pipeline is now a two-phase process. `esbuild` is used in the first phase to remove the majority of the unused code and shorten identifiers in each output bundle script. `esbuild` can accomplish this in a fraction of the time that `terser` previously required. However, `esbuild` does not yet implement all of the optimizations that `terser` performs. As a result, `terser` is used as a second phase to further optimize and reduce the size of the output bundle scripts. Since `terser` is operating on a smaller input size, the time required for `terser` to complete is significantly reduced. To further improve performance when source maps are enabled, the source map merging is now performed within the optimization workers. A maximum of four (4) optimization workers are currently used and this value can be adjusted via the `NG_BUILD_MAX_WORKERS` environment variable.
This change allows the linker sourcemap behavior to be controlled by the Webpack sourcemap configuration. For example, if a vendor file is being processed and vendor sourcemaps are disabled, the linker will now skip its internal sourcemap loading and processing steps.
The `esModuleInterop` option is recommended to be enable by TypeScript and corrects several assumptions TypeScript would otherwise make when importing CommonJS files.
This option change helps ensure compatibility as packages move towards ESM.
Reference: https://www.typescriptlang.org/tsconfig#esModuleInterop
With this change we enable Webpack's filesystem cache, this important because `terser-webpack-plugin`, `css-minimizer-webpack-plugin` and `copy-webpack-plugin` all use Webpacks' caching API to avoid additional processing during the 2nd cold build.
This changes causes `node_modules` to be treated as immutable. Webpack will avoid hashing and timestamping them, assume the version is unique and will use it as a snapshot.
To opt-in using the experimental persistent build cache use the`NG_PERSISTENT_BUILD_CACHE` environment variable.
```
NG_PERSISTENT_BUILD_CACHE=1 ng serve
```
When not set, and browserslist returns no reesults due to the file being empty or commented. Webpack will generate invalid code because it doesn't know which enviorment we want to target.
```diff
- (self["webpackChunktest_app"] = self["webpackChunktest_app"] || []).push([["vendor"],{
/***/ 8583:
```
Closes#21111
With the support of TypeScript 4.3 within the Angular framework, the CLI now supports using TypeScript 4.3 as well. TypeScript 4.2 also continues to be supported for existing projects.
The `adjust-typescript-enums` plugin now includes an optional loose mode. This mode generates less code for an adjusted enum but differs from the canonical TypeScript enum structure emitted by the TypeScript compiler. This mode is only enabled for packages validated to operate correctly with this structure and is currently limited to first-party Angular packages. The adjusted structure is a variation of the previous build optimizer pass structure but better reflects the runtime behavior of the TypeScript emit structure.
The new babel-based build optimizer passes are now enabled when targetting ES2015 and higher. ES5 targets will currently continue to use the previous build optimizer. ES5 support will require additional refactoring of the downlevelling process as the new build optimizer passes are designed for ES2015 code.
The build optimizer passes that are still relevant for Ivy are now implemented as babel plugins. Using babel has several advantages. The `babel-loader` is already present within the build pipeline and many packages will already need to be processed by it. The `babel-loader` also provides the necessary infrastructure to setup babel and link it to the Webpack build system. This removes the need for the infrastructure code within the build optimizer loader and reduces the build optimizer to only a set of transformation plugins for babel to consume. The babel plugin architecture also allows for less code to represent similar transformations and provides a variety of helper utilities which further reduces the amount code needed.
The passes are now implemented to be safer when transforming code. Enum values which contain potential side effects are also no longer altered. Enums are wrapped in less destructive manner which reduces the likelihood of incorrectly emitting the transformed enum. Class static fields which contain potential side effects are no longer wrapped in pure annotated IIFEs. Known safe Angular static fields are also wrapped and Angular static fields which are not required in production code are also dropped.
The conversion of the passes not only reduces the amount of code to maintain but also provides a noticeable performance improvement. Initial tests of a production build of AIO resulted in a ~10% total build time reduction.
Closes#12160
With the recent changes in https://github.com/angular/angular-cli/pull/20960 we moved the spinner to be started outside of the progress callback, this causes a side-effect that after `succeed` is called the spinner will stop reporting progress unless it is started again.
Sass Worker instances and resource requests are now cleaned up when the Webpack compiler is shutdown. This removes the need to unreference the workers upon creation.
Fixes#20985
Webpack will only provide emitted assets in the returned Stats each rebuild unless the `cachedAssets` option is enabled. This is currently needed for the bundle budget calculations.
Fixes#21038
Until we depend on `webpackStats` in the browser builder we should only included the required stats.
The below are the needed stats;
```
all: false,
colors: true,
hash: true,
timings: true,
chunks: true,
builtAt: true,
warnings: true,
errors: true,
assets: true,
ids: true,
entrypoints: true,
```
Since sass 1.33.0, an importer can determine whether it’s being called from an `@import` rule by checking `this.fromImport`. This API, is now being used by `sass-loader` version 12.