When using the application builder, a `loader` import attribute is now available
for use with import statements and expressions. The presence of the import
attribute takes precedence over all other loading behavior including JS/TS and
any `loader` build option values. This allows per file control over loading
behavior. For general loading for all files of an otherwise unsupported file
type, the `loader` build option is recommended.
For the import attribute, the following loader values are supported:
* `text` - inlines the content as a string
* `binary` - inlines the content as a Uint8Array
* `file` - emits the file and provides the runtime location of the file
Unfortunately, at this time, TypeScript does not support type definitions
that are based on import attribute values. The use of `@ts-expect-error`
or the use of individual type definition files (assuming the file is only
imported with the same loader attribute) is currently required.
Additionally, the TypeScript `module` option must be set to `esnext` to
allow TypeScript to successfully build the application code.
As an example, an SVG file can be imported as text via:
```
// @ts-expect-error TypeScript cannot provide types based on attributes yet
import contents from './some-file.svg' with { loader: 'text' };
```
When using the development server and a file that is referenced from a Node.js
package with a loader attribute, the package must be excluded from prebundling
via the development server `prebundle` option. This does not apply to relative
file references.
When the sourceMaps are enabled they are generating some files that are computed by the budget stats. Now the method `generateBudgetStats` skip when the file is undefined.
The `ansi-color` and `ora` dependencies have been replaced with `listr2`.
This package provides both color and spinner capabilities and further
reduces the dependency count. This also aligns the dependencies with
the `@angular/cli` package with already uses `listr2`. The spinner also
now will not overwrite console output that happens to be written while
the spinner is active. Instead, the output will be written after the
spinner task is complete.
The schematics encapsulation process now uses a similar wrapping setup to
Node.js itself. This removes some custom code and also provides a more
comprehensive global object which should provide improved compatibility
for third-party packages used within schematics.
When using a WASM file on Node.js via SSR/SSG/etc. the path for the `readFile`
call will now be based on the location of the script using the WASM file
instead of the current working directory.
This change also adds a general Node.js WASM E2E test via prerendering.
The Node.js types (`@types/node`) now contains the information for the `Response`
class and the global `fetch` function. The `Response` object is also globally
accessible in all versions of Node.js supported by the Angular CLI. This removes
the need to depend directly on the `undici` package.
The `undici` package is still used for unit-testing and remains as a development
dependency.
The `extract-i18n` command will now use a default project target and builder
name if the target entry is not explicitly defined. This allows the removal
of additional configuration from an `angular.json` file. If the target is
already present than it will take priority over any default builder behavior.
Infrastructure is also now present to allow other architect commands to
have similar functionality in the future.
The isolated modules transpilation option that was recently introduced is
currently disabled when source maps are enabled. TypeScript has two mutually
exclusive options that can be used to check for source map usage. Both of
these options (`sourceMap` and `inlineSourceMap`) are now checked to determine
if the direct transpilation optimization can be used.
Application builds will now support the direct import of WASM files.
The behavior follows the WebAssembly/ES module integration proposal. The usage
of this feature requires the ability to use native async/await and top-level
await. Due to this requirement, applications must be zoneless to use this new
feature. Applications that use Zone.js are currently incompatible and an error
will be generated if the feature is used in a Zone.js application. Manual
setup of a WASM file is, however, possible in a Zone.js application if WASM
usage is required. Further details for manual setup can be found here:
https://developer.mozilla.org/en-US/docs/WebAssembly/Loading_and_running
The following is a brief example of using a WASM file in the new feature
with the integration proposal behavior:
```
import { multiply } from './example.wasm';
console.log(multiply(4, 5));
```
NOTE: TypeScript will not automatically understand the types for WASM files.
Type definition files will need to be created for each WASM file to allow
for an error-free build. These type definition files are specific to each
individual WASM file and will either need to be manually created or provided
by library authors.
The feature relies on an active proposal which may change as it progresses
through the standardization process. This may result in behavioral differences
between versions.
Proposal Details: https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
For more information regarding zoneless applications, you can visit https://angular.dev/guide/experimental/zoneless
The babel-based JavaScript transformer currently requires a syntax plugin
to support import attributes. Import attributes are otherwise supported in
application code. However, in production builds the JavaScript transformations
such as the build optimizer passes would fail on code that contain any import
attributes. The inclusion of the babel syntax plugin removes this problem.
Once babel provides built-in support for this syntax feature, the plugin
can be removed.
With the potential future introduction of features such as WASM/ES module integration
and the experimental chunk optimizer, the need to restrict top-level await
usage is no longer needed and a blocker for new features. As such, top-level
await will now be available if an application has been configured to be
zoneless.
Zoneless Angular is currently experimental and more details can be found here:
https://angular.dev/guide/experimental/zoneless
This commit reduces the maximum number of workers to the available CPUs minus 1. This adjustment ensures that some resources are left for the main thread, preventing it from being starved of CPU cycles.
Prior to this commit, accessing a static asset directory without a trailing slash resulted in a 404 error. With this change, we now redirect to the path with a trailing slash, aligning with the behavior of express static.
Closes#27949
An experimental chunk optimizer is now available for initial usage.
To enable the optimization, script optimization must be enabled as well as
an environment variable `NG_BUILD_OPTIMIZE_CHUNKS=1`. This build step uses
`rollup` internally to process the build files directly in memory. The main
bundling performs all resolution, bundling, and tree-shaking of the application.
The chunk optimizer step then only needs to access the in-memory built files and does not
need to perform any disk access or module resolution. This allows the step to be
performed fairly quickly but it does add time to the overall production build.
The `NG_BUILD_DEBUG_PERF=1` environment variable can be used to view how long the step
takes within a build via the `OPTIMIZE_CHUNKS` entry. In the future, this optimization
step may be automatically enabled based on initial file entry count and size.
There are several current known issues:
1) Bundle budgets for named lazy chunks may not work as expected.
2) The console output may not show names (files will be present) for lazy chunk files.
3) The stats file (`--stats-json` option) will not exactly reflect the final written application files. This is similar to the current behavior of the `browser` builder with Webpack's stat file.
As stated in https://github.com/angular/angular-cli/issues/11744,
`ng update` command removed the newline at the end of the package.json file.
This commit makes `ng update` to preserve newline, if it was present before running the command.
Fixes#11744
The bundle budget calculators and the console build stats output are now
calculated directly from the build output file information instead of the
esbuild metafile where possible. This provides a more generic method of
accessing the information and can more accurately account for post-processing
steps that may alter the output files. The metafile is still used for
component style budgets and lazy chunk name information.
The `BuildOutputFile` type's helper functions have been adjusted to cache
commonly accessed property values to avoid potentially expensive repeat
processing. This includes encoding/decoding UTF-8 content and calculating
hash values for the output file content. A size property has also been
added to allow consumers to more directly determine the byte size of the
output file. The size property is currently unused but will be leveraged
in forthcoming updates to bundle budgets and console info logging.
Several smaller code changes to improve type information and remove now
unneeded code structures based on improvements to both Node.js, TypeScript,
and underlying dependencies.
With standard decorator support now available for use, the memoize decorator
has been updated to be a standard decorator instead of a TypeScript experimental
decorator. This change also removes the only usage of decorators within the
Angular CLI code itself. This change does not affect application code.
Due to bazel rules_nodejs caching, several additional `JSON.parse` usages were not
caught in the first set of fixes. These have now been addressed. Also,
the `must-use-promises` rule has been patched to match the behavior of the
`@typescript-eslint/no-floating-promises` for consistency.
The bazel option `suppressTsconfigOverrideWarnings` was also removed from the
`tsconfig` as it is a no-op and was previously used for now removed feature.
Test files are currently excluded from the `JSON.parse` rule to avoid large
changes to test code.
To remove the tsetse rule exclusions, several usages of `JSON.parse` that
did not have type casting where adjusted to add types. This removed the
need for the manual configuration within the tsconfig.
Replacing the paths to ESM in Vite can cause prebundling to fail in some cases, resulting in errors similar to the following:
```
12:55:12 PM [vite] Error when evaluating SSR module /chunk-CHB4JJIP.mjs:
|- TypeError: Cannot read properties of undefined (reading 'Subject')
at eval (//src/app/shared/snackbar/snackbar.service.ts:2:25)
at async instantiateModule (file:////node_modules/vite/dist/node/chunks/dep-BcXSligG.js:53408:5)
12:55:12 PM [vite] Error when evaluating SSR module /chunk-GQZ5BKXC.mjs:
|- TypeError: Cannot read properties of undefined (reading 'Subject')
at eval (//src/app/shared/snackbar/snackbar.service.ts:2:25)
at async instantiateModule (file:////node_modules/vite/dist/node/chunks/dep-BcXSligG.js:53408:5)
```
Closes: #27907
The TypeScript `isolatedModules` option is now enabled for all TypeScript
code within the repository. As a result, all packages will now be built
with the option enabled. This does not affect projects created with the CLI
and is only related to the building of the actual Angular CLI code.
The `isolatedModules` option ensures that code can be emitted without the
TypeScript typechecker and allows tools other than TypeScript to potentially
be used. Code was updated to correct all errors after the option was enabled.
Additionally, some early code fixes were done to add function and accessor
return types to prepare for future `isolatedDeclarations` usage. More changes
would be needed to consider turning on `isolatedDeclarations`, however.
If the persistent cache store for the JavaScript transformations fails
to initialize, a warning will now be shown to better explain the outcome
and to allow the build to continue. The build will still complete without
the cache but may be slower to finish.
The bundler context class now has a static helper method to support merging
bundler results outside of a specific bundle action. This will be used in the
future to support more complex bundling hierarchies.
The Angular compiler code that is not specific to esbuild has been moved
into a separate `tools` subdirectory. This allows for potential reuse internal
reuse outside of the Angular esbuild plugin.
The `isTTY` and `supportColor` helpers can now accept a stream to check
instead of assuming stdout. This is useful if stderr needs to be checked,
for instance. Also, color checking now uses Node.js `hasColors` where
possible which has been available since Node.js v10.
Add `createCompilerPlugin` function to the private export of the package.
Note that these are not considered part of the public API and
are intended for use only with the `@angular-devkit/build-angular` package.
The ora package has been removed now that the progress indicator for the
update command is now based on the `listr2` package that is also used
by the `ng add` command.
The `listr2` dependency that was recently introduced to improve the console
UI for the `ng add` command is now used for the package installation step
of the `ng update` command process.