In this commit, we've optimized the build performance for applications containing a large number of components when using the esbuild-based builder. This optimization entails replacing the spread operator with `Object.assign` when appending to the result metadata in the Angular compiler plugin to avoid creating multiple copies of the object.
See: https://bugs.chromium.org/p/v8/issues/detail?id=11536
**Previous Performance**:
- Initial compilation: 37 seconds
- First incremental build: 20 seconds
- Second incremental build: 16 seconds
**Updated Performance**:
- Initial compilation: 24 seconds
- First incremental build: 6 seconds
- Second incremental build: 2 seconds
Closes#27280
Currently, errors occurring in ESM loader hooks while using `--import` are not correctly displayed, as they cannot be transferred from the worker to the main thread. Although the error is an instance of Error, it contains non-transferable properties and cannot be transmitted from a worker when --import is used. Consequently, when read outside of the worker, the error object displays as `[Object object]`. To address this issue, we reconstruct the error message.
See: https://github.com/angular/angular-cli/issues/27251
Multiple cases where builder options were being cast to the `JsonObject` type
have been removed. These casts are no longer needed and unnecessarily added
complexity to the code.
Logging types are now based on the BuilderContext's type instead of the
`@angular-devkit/core` type. This reduces the need to directly depend
on this package while also allowing the builder logging type to diverge
if needed. The two usages of the BaseException type which is a small
wrapper around Error have also been removed.
The `i18n` project field is used to configure i18n behavior for a project.
The validation code has been reorganized to use two helper functions to
centralize the type validation and exception throwing. This reduces the complexity
of the analysis code as well as removing the need to rely on `@angular-devkit/core`.
Previously, a race condition could occur due to the spinner, resulting in the deletion of the last printed log when warnings or errors were present. With this update, we ensure that logs are printed after the spinner has stopped.
Fixes#27233
This commit removes the legacy Sass implementation previously used with Webpack.
BREAKING CHANGE: The support for the legacy Sass build pipeline, previously accessible via `NG_BUILD_LEGACY_SASS` when utilizing webpack-based builders, has been removed.
Only the injected index HTML file references and component stylesheets require
the modification of relative URLs with a public path when specified. Other
usages are already resolved relative to their containing file location with
the `application` builder.
The usage of several Webpack-centric option helper functions has now been
removed from the `application` builder. This allows for more efficient
processing of incoming options but also removes additional imports across
builder code.
`optimizeDeps.disabled` has been deprecated in favor of `optimizeDeps.noDiscovery` to `true` and `optimizeDeps.include` to `undefined`
```
(!) Experimental ssr.optimizeDeps.disabled and deps pre-bundling during build were removed in Vite 5.1.
To disable the deps optimizer, set ssr.optimizeDeps.noDiscovery to true and ssr.optimizeDeps.include as undefined or empty.
Please remove ssr.optimizeDeps.disabled from your config.
```
When purging stale build cache entries, the `readdir` call will fail if
the cache base path does not exist. This allows for a single check and
the removal of the previous separate `existSync` call. Additionally,
a repeat join call has also been removed during the stale directory check.
The Node.js `node:util` builtin contains a helper (`stripVTControlCharacters`) that
can be used to remove ANSI color characters from a string. Usage removes the need
for a custom helper within the package.
The Node.js async `pipeline` helper function reduces the amount of infrastructure code
needed to pipe HTML content through the parse5 transform stream.
The globally available TextDecoder class will automatically handle the presence of a BOM in
text files when decoding. This allows the removal of the utility function present in the
package to do the same.
To support future package building as ESM, the direct usage of require has now been
removed from the Angular compatibility check code used by various builders.
Additionally, the limited use of `@angular-devkit/core` has also been removed from
the check code as it was only used to adjust string values for error messages which
can be done directly instead.
The logic to detect media output files was previously predicated on the presence of a media subdirectory
being defined. Prior to the ability to customize output path subcomponents there was a guaranteed media
subdirectory. However, now that customization is possible, there is the potential for media files to
not have a distinct subdirectory in the output. To facilitate output media detection in this scenario
a file extension based method is now employed. This avoids a dependence on output directory structure.
The latest version of the worker pool package used by the build system (`Piscina`) now
has an option to disable performance timing information. Since the build system does
not currently use that information, disabling it avoids the extra overhead of histogram
creation and usage. This information collection could potentially be enabled conditionally
in the future if needed.
Unlike the non-ESM Node.js resolution for JS files, CSS does not have the concept
of implicit file extensions. To avoid incorrectly resolving a file as CSS,
stylesheet bundling no longer attempts to resolve implicit extensions. Preprocessors,
such as Sass, contain logic internally that handles any specific resolution cases
for their respective preprocessor and such behavior is unaffected.
The sourcemap for the Vite client code was previously not being loaded along with the
actual code. This could lead to browser 404 console messages when debugging applications.
Updates the `fileReplacement` pattern to allow `.mts` and `.cts` files.
This enables support for TypeScript files with explicit ESM support.
Closes#27124
In certain cases, the plugin option may be a string value, as shown in the example below:
```json
{
"plugins": {
"tailwindcss/nesting": "postcss-nesting"
}
}
```
In certain cases, the plugin option may be a string value, as shown in the example below:
```json
{
"plugins": {
"tailwindcss/nesting": "postcss-nesting"
}
}
```
See: https://tailwindcss.com/docs/using-with-preprocessors#nesting
The `copy-webpack-plugin@12` package has a dependency on the `globby@14` package. The recently released
`globby@14.0.1` uses the `merge-streams@2.1.0` package which requires a minimum Node.js version higher
than the officially supported 18.13 for the Angular CLI. Due to both `globby` and `merge-streams` being
transitive dependencies in end-user projects, the Angular CLI cannot directly control the package versions.
However, `copy-webpack-plugin@11` uses `globby@13` which is not affected by the Node.js version problem.
To workaround the Node.js compatibility problem, `copy-webpack-plugin` has been downgraded to version 11.0.0
which is the latest version in the 11 major for the package. The `copy-webpack-plugin` is only used with the
Webpack-based builders when in watch mode. From a review of the commit history between 11.0.0 and 12.0.2 (latest
at the time of this commit), it appears the only notable changes are several performance improvements and the
major version update of `globby`.
To avoid the Vite-based development server's prebundling system from attempting to
prebundle import statements containing absolute URLs, the set of external specifiers
will now be pre-filtered before being passed onto Vite. Currently, the check for
an absolute URL is any specifier starting with `http://`, `https://`, or '//'.