There was previously the potential for two workers to complete quickly at the same time which could result in one of the results not being propagated to the remainder of the system. This situation has now been corrected by removing the worker execution at a later point in the process.
(cherry picked from commit 802b1b0378c1816dbfd8f4320b5d69e82f0c7aa6)
With this change we unify most of the webpack configuration into the common configuration. A number of lengthy functions and code portions have been moved into a seperate file to make the configuration easier to follow.
This change brings in a security fix causes was causes by an outdated dependency. See https://github.com/GoogleChromeLabs/critters/pull/82 for more information.
Also, remote stylesheets are excluded from processing, were previously this caused build failures.
Closes#20794
Temporary JavaScript application files that have been queued for i18n processing are now removed immediately after reading their content. This reduces the on-disk size of temporary files as well as reduces the needed disk access during the final asset copy phase of the i18n inlining process. Additional debug logging has also been added to the i18n inlining process which can be enabled via the `NG_DEBUG=1` environment variable.
Currently, using 2 Angular applications from the same workspace on the same page causes a conflict because both of the webpack runtime chunks naming are the same.
With this change we configure the runtime chunk name to be inferred from the project name. This also results in reducing unnecessary file reads which Webpack needs to do to infer the name from the workspace package.json.
For more information about this option see: https://webpack.js.org/configuration/output/#outputuniquenameCloses#21957
With this change we disable critical css inline by default. The main motivations are the following issues #20760 and #20864.
BREAKING CHANGE:
Inlining of critical CSS is no longer enable by default. Users already on Angular CLI version 12 and have not opted-out from using this feature are encouraged to opt-in using the browser builder `inlineCritical` option.
The motivation behind this change is that the package used to parse the CSS has a number of defects which can lead to unactionable error messages when updating to Angular 13 from versions priors to 12. Such errors can be seen in the following issue #20760.
```json
"configurations": {
"production": {
"optimization": {
"styles": {
"inlineCritical": true,
}
},
...
}
```
Persistent disk build cache is now enabled by default. A number of options have been added to allow fine tuning of the cache.
The options can be configuration in `cli.cache` section in the `angular.json` as shown below.
- `enabled`: Configure whether disk caching is enabled. Defaults to `true`
- `environment`: Configure in which environment disk cache is enabled. Valid values `ci`, `local` or `all`. Defaults to: `local`
- `path`: cache base path. Defaults to `.angular/cache`
DEPRECATED: `NG_BUILD_CACHE` environment variable option will be removed in the next major version. Configure `cli.cache` in the workspace configuration instead.
BREAKING CHANGE: `NG_PERSISTENT_BUILD_CACHE` environment variable option no longer have effect. Configure `cli.cache` in the workspace configuration instead.
```json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"cache": {
"enabled": true,
"path": ".custom-cache-path",
"environment": "all"
}
}
...
}
```
This is a follow-up to fb210e5b747ce0351dd9ee7d482770b9cfa71133 which
added support for the ESM-variant of the `@angular/localize` package,
and also prepared for the `tools/` secondary entry-point we will expose
as of v13.
Unfortunately this change currently does not pass-through the ESM-loaded
plugin creators as the option (which is passed to the Babel plugin) is
incorrect. This was hidden due to a type cast. This commit fixes the
issue and also ensures TS would complain in the future if the option
names differ.
Previously, the search for a locale's data when using i18n was performed by a series of file system accesses that searched through the `@angular/common` package. The search is now conducted via Node.js module resolution which has several advantages. The internal structure of the package is no longer assumed and allows the `@angular/common` package to change its internal implementation without affecting the locale data search. File extensions of the locale data files are also not hard-coded as only the name of the locale data is needed to perform a search. There are also less direct file system access calls and the search can leverage whatever internal caching Node.js performs during module resolution.
With the Angular CLI currently being a CommonJS package, this change uses a dynamic import to load `@angular/localize` which may be ESM. CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript will currently, unconditionally downlevel dynamic import into a require call. require calls cannot load ESM code and will result in a runtime error. To workaround this, a Function constructor is used to prevent TypeScript from changing the dynamic import. Once TypeScript provides support for keeping the dynamic import this workaround can be dropped and replaced with a standard dynamic import.
Absolute import paths, especially on Windows, must be `file://` URLs when using ESM. Otherwise, Windows drive letters (e.g., `C:`) would be interpreted as a protocol instead of a drive letter when performing the import.
With the Angular CLI currently being a CommonJS package, this change uses a dynamic import to load `@angular/service-worker/config` which may be ESM. CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript will currently, unconditionally downlevel dynamic import into a require call. require calls cannot load ESM code and will result in a runtime error. To workaround this, a Function constructor is used to prevent TypeScript from changing the dynamic import. Once TypeScript provides support for keeping the dynamic import this workaround can be dropped and replaced with a standard dynamic import.
This is a followup PR for #21771 that addresses partial compilation linker usage.
With the Angular CLI currently being a CommonJS package, this change uses a dynamic import to load `@angular/compiler-cli/linker[/babel]` which may be ESM. CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript will currently, unconditionally downlevel dynamic import into a require call. require calls cannot load ESM code and will result in a runtime error. To workaround this, a Function constructor is used to prevent TypeScript from changing the dynamic import. Once TypeScript provides support for keeping the dynamic import this workaround can be dropped and replaced with a standard dynamic import.
This uses a dynamic import to load `@angular/compiler-cli` which may be ESM. CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript will currently, unconditionally downlevel dynamic import into a require call. require calls cannot load ESM code and will result in a runtime error. To workaround this, a Function constructor is used to prevent TypeScript from changing the dynamic import. Once TypeScript provides support for keeping the dynamic import this workaround can be dropped and replaced with a standard dynamic import.
Partial Webpack configuration generators are used to create the various aspects of the final Webpack configuration for build, testing, and serving. They previously could only be synchronous but may need to perform asynchronous actions to setup the Webpack configuration in the future. This is particularly relevant as the CLI transitions from CommonJS to ESM wherein synchronous require calls need to be replaced with asynchronous dynamic imports. For dynamic imports to be successfully used the configuration generators need to support asynchronous operations.
The `@angular/compiler-cli` is used as a peer dependency and has the potential to not be present. As a result static imports should only be used for types and value imports should be dynamic so that they can be guarded in the event of package absence. There are still several instances of static imports for values but these will be corrected in follow-ups.
The `no-useless-escape` eslint rule has now been enabled which removes unneeded characters and complexity from string literals and regular expressions. All files that were in violation of this rule have also been corrected.
An application's TypeScript configuration was previously being loaded multiple times in several different aspects of the build setup process. These aspects need to access specific compiler options relevant to that particular area of the setup. However, loading the configuration can be expensive due to the process also calculating the root files for the TypeScript compilation which can result in a large amount of file access. To improve the setup performance, the number of times the TypeScript configuration will be loaded has now been reduced with further reductions possible with additional refactorings.
All Angular builders are now located within one subdirectory of the `src` directory. This organization provides better discovery of the builders and will allow builder specific code to be stored in a single area.
In the Angular version check, the rxjs version was acquired by resolving and reading the rxjs package's package.json file. However, the rxjs version checks were removed in a previous major.
The Webpack configuration setup previously walked up the directory structure to find all `node_modules` directories and then pass this list to Webpack's `resolverLoader.modules` option. This was previously done to ensure that hoisted packages were properly resolved. However, all loader paths are now fully resolved prior to being added to the Webpack configuration. Since loader paths will now be absolute, Webpack no longer needs to resolve them which makes the resolve settings no longer necessary.
Webpack 5 supports setting a module's alias to `false` to signify that a module should be ignored. This option removes the need for the `empty.js` file as an alias option value.
The workaround code was gated on the presence of Node.js 10 but the CLI no longer supports Node.js 10 and will execute with an error if attempted. As a result, the workaround code would never be executed.
BREAKING CHANGE:
With this change we removed several deprecated builder options
- `extractCss` has been removed from the browser builder. CSS is now always extracted.
- `servePathDefaultWarning` and `hmrWarning` have been removed from the dev-server builder. These options had no effect.
BREAKING CHANGE:
The automatic inclusion of Angular-required ES2015 polyfills to support ES5 browsers has been removed. Previously when targetting ES5 within the application's TypeScript configuration or listing an ES5 requiring browser in the browserslist file, Angular-required polyfills were included in the built application. However, with Angular no longer supporting IE11, there are now no browsers officially supported by Angular that would require these polyfills. As a result, the automatic inclusion of these ES2015 polyfills has been removed. Any polyfills manually added to an application's code are not affected by this change.
BREAKING CHANGE:
Differential loading support has been removed. With Angular no longer supporting IE11, there are now no browsers officially supported by Angular that require ES5 code. As a result, differential loading's functionality for creating and conditionally loading ES5 and ES2015+ variants of an application is no longer required.
The logger API writes logs in an async fasion which previously caused messages not to be printed in the terminal when `process.exit` was invoked.
Closes#21322
The `@ampproject/remapping` package is now used for source map processing instead of Webpack for differential loading and i18n processing. This dependency is already used within the recently added JavaScript optimizer refactoring and reduces the amount of code that needs to be loaded into each worker to support differential loading sourcemaps.
With this change we add support to inline external Adobe fonts into the index html, we also add a `preconnect` hint which helps improve page load speed.
Closes#21186
Webpack is a large dependency with a large dependency graph. By only loading Webpack when needed in the differential loading and i18n processors, initial startup time can be improved and memory usage can be reduced.
The worker pool for differential loading and i18n processing is now managed by the `piscina` dependency. This dependency is already used within the recently added JavaScript optimizer refactoring and reduces both the number of direct dependencies and amount of code to setup the worker pools.
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
```
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.
Since #20518, the generation of the ServiceWorker configuration has been
broken on Windows. The reason is the use of `path.posix.*` methods on
non-POSIX paths, resulting in broken paths. I.e. we ended up with
something like the following:
```js
path.posix.relative('C:\\foo', 'C:\\foo\\bar/baz');
// Expected result: `bar/baz`
// Actual result: `../C:\\foo\\bar/baz`
```
This caused the config generator to fail to find any files and thus fail
to populate the config with cacheable assets.
This commit fixes this by using platform-specific `path.*` methods for
path manipulation and manually normalizing the path separators before
returning the results.
Fixes#20894