When using the application builder with Tailwind directives not in a directly referenced
Sass stylesheet, the Tailwind process was previously skipped. To avoid this problem, the
Tailwind keyword checks are now performed on the result of any stylesheet language processing
which will contain all the used stylesheet content.
When using the application builder with a Web Worker in watch mode, A change to the
Web Worker code will now invalidate the referencing source file to ensure that all changes
are captured and the new output file for the Web Worker is correctly injected into the
referencing output file. Previously, the Web Worker output file may have changed but the
reference may not have been updated causing an old instance of the Web worker code to be
used in watch mode.
Component style bundling when using the application builder will now only generate incremental contexts
when in watch mode. During non-watch build, this incremental context information is not needed and
unnecessarily increases memory usage during a build.
With this commit when running a build with sourcemaps enabled we enable Node.js Sourcemap support for stack traces.
See: https://nodejs.org/dist/latest/docs/api/cli.html#--enable-source-maps for more information about this feature.
Before
```
ERROR ReferenceError: window is not defined
at new _AppComponent (file:///chunk-HFZN2HE2.mjs:41631:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (file:///chunk-HFZN2HE2.mjs:41635:12)
at getNodeInjectable (file:///chunk-HFZN2HE2.mjs:6104:38)
at createRootComponent (file:///chunk-HFZN2HE2.mjs:10446:31)
at ComponentFactory.create (file:///chunk-HFZN2HE2.mjs:10348:19)
at _ApplicationRef.bootstrap (file:///chunk-HFZN2HE2.mjs:13247:40)
at file:///chunk-HFZN2HE2.mjs:12938:20
at _ZoneDelegate.invoke (file:///chunk-HFZN2HE2.mjs:320:158)
at Object.onInvoke (file:///chunk-HFZN2HE2.mjs:8562:25)
at _ZoneDelegate.invoke (file:///chunk-HFZN2HE2.mjs:320:46)
```
Now
```
ERROR ReferenceError: window is not defined
at constructor (/usr/xxxx/src/app/app.component.ts:16:17)
at NodeInjectorFactory.AppComponent_Factory (/usr/xxxx/src/app/app.component.ts:17:3)
at getNodeInjectable (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:4166:38)
at createRootComponent (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:14064:31)
at ComponentFactory.create (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:13931:19)
at _ApplicationRef.bootstrap (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:30650:40)
at <anonymous> (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:30163:20)
at _ZoneDelegate.invoke (/usr/xxxx/node_modules/zone.js/fesm2015/zone-node.js:344:158)
at Object.onInvoke (/usr/xxxx/node_modules/@angular/core/fesm2022/core.mjs:10964:25)
at _ZoneDelegate.invoke (/usr/xxxx/node_modules/zone.js/fesm2015/zone-node.js:344:46)
```
Closes#26013
When using the application builder to create server builds for SSR and/or prerendering with localization
enabled, the locale data for each enabled locale is now properly included in the server output files.
While browser builds contain this data in the polyfills output file, the server builds do not contain a
polyfill output file, as a result, the locale data is added to the main server code instead. This is also
the case for other polyfill-like code including zone.js.
Any provided or required polyfills (the later mainly related to i18n) will now be bundled in a separate
concurrent bundling action. This has several benefits including allowing different bundling options
for the polyfills and minimizing rebundling of polyfills (which rarely change) in watch/serve mode.
Along with this change, the polyfill bundling options have been adjusted to not externalize packages
when in development server mode. This allows the zone.js globals to be more easily used as well as
minimizing the need for Vite to process a typically unchanging output file.
When using localization with the application builder for a large amount of locales, the number
of files that may need to be written to disk can become large. This may be problematic on certain
operating systems depending on the open file process limits. To avoid approaching the limit, the
number of concurrent writes is now limited to 64.
Within the application builder's template stylesheet processing, internal identifiers are used to track
the incremental bundling status of each inline stylesheet. This identifier now consists of the stylesheet
language, data, and containing file. This ensures that a tracking entry is maintained for each inline
stylesheet and allows for the full cleanup and any incremental bundling resources at the end of the build.
When a Less stylesheet is detected to require the deprecated `javascriptEnabled` Less option, the option
is enabled for the stylesheet and a warning is issued to inform the user of the behavior change. The
Less `javascriptEnabled` option has been deprecated and disabled by default since Less v3 (https://github.com/less/less.js/releases/tag/v3.0.0).
When enabled, the `javascriptEnabled` option allows JavaScript within Less stylesheets to be executed at build time.
Less option reference: https://lesscss.org/usage/#less-options
This provides similar behavior to the default Webpack-based build system. However, the Webpack-based build system
currently unconditionally enables the option.
Similar to the existing Webpack-based `browser` builder, the new `application` builder is also exported
from the `@angular-devkit/build-angular` package for use programmatically. As is the case for the existing
builder JavaScript exports from the package, the new export (`buildApplication`) is also considered experimental
and does not provide the support nor semver guarantees that the builders have when used via `angular.json` configuration.
The usage of the `plugins` parameter of the `buildApplication` allows adding esbuild compatible plugins to the end
of the plugin list for the main application code bundling. However, usage of the parameter may result in unexpected application
output and/or build failures. Stable and supported methods for build process extension are being evaluated for a future release.
Protractor is no longer deprecated, it's already end-of-life. I didn't commit to a specific version because plans always fluctuate, but it is eligible to be removed in any future Angular major version.
This is to better match the nature of the application builder where the target can be both browser and server.
DEPRECATED: The `browserTarget` in the dev-server and extract-i18n builders have been deprecated in favor of `buildTarget`.
The `browser-esbuild` builder now provides support for using the `deployUrl` option when building
applications. This option is still considered deprecated which is the same status as with the
Webpack-based `browser` application builder. This option is only available with the `browser-esbuild`
builder and not other esbuild-based builders. The `browser-esbuild` builder is primarily intended
to be used as a compatibility builder with the `browser` builder that requires only minimal changes
to use.
When using the esbuild-based builders (`application`/`browser-esbuild`), the localize polyfill and the locale specifier
for the configured source locale will now be injected into the application when available and the application is not
configured to inline translations (`localize` option disabled or otherwise not used). This is useful for when developing
a localized application with the development server or when the application is not translated but has a customized source
locale.
When normalizing the proxy configuration for the Vite-based development server, the `pathRewrite` logic
will now be skipped if the proxy entry is not an object and therefore invalid. This situation can occur
if the proxy configuration JSON contains invalid properties.
Closes#25978
This commit improves the logic to block and share a TypeScript results across multiple esbuild instances (browser and server builds) which fixes an issue that previously during rebuilds in some cases did not block the build correctly.
Prior to this change, async/await in external packages were not being correctly downlevelled when using vite dev-server with cache enabled.
Closes#25985
With the output path directory structure updates in place, the localize support for SSR has
now been enabled. This allows for the `application` builder to produce both browser and server
output that is localized based on the i18n configuration for the project.
When using the esbuild-based builders (`esbuild-browser`/`application`) in watch mode (including `ng serve`),
component stylesheets will now be incrementally rebuilt when needed. This avoids a full build of each
affected component's styles during an application rebuild. Both JIT and AOT mode are supported as well
as both inline and external styles.
The `anyComponentStyle` budget type is now supported when using bundle budgets in the esbuild-
based builders (`browser-esbuild`/`application`). The configuration and behavior are intended
to match that of the Webpack-based builder (`browser`). With this addition, the bundle budget
feature is now at feature parity with the Webpack-based builder.
The implementation of this budget type requires less code than the Webpack implementation due
to the component stylesheet information being present in the application's output metadata. This
removes the need for a custom budget plugin to extract the stylesheet size information during the build.
The bundle budget functionality (`budgets` option) is not available when using the esbuild-based
builders (`browser-esbuild`/`application`). The existing option format from the Webpack-based builder can
continue to be used. All budget types except `anyComponentStyle` are implemented. Any usage of the
`anyComponentStyle` type will be ignored when calculating budget failures. This type will be implemented
in a future change.
The previous Web Worker bundling code for the esbuild-based builders assumed that the first
output file was the JavaScript code for the worker. While this is typically the case, when
sourcemaps are enabled it may not be. To ensure the code file is used as the replacement path
for the Worker constructor, the output files are now searched for the code file.
This commit updates the application builder to output files in a standardized manner. The builder will output a `browser` directory for all the files that can be accessible by the browser, and a `server` directory that contains the SSR application. Both of these directories are created as children in the configured `outputPath`. Stats and license files will be outputted directly in the configured `outputPath`.
Example of output:
```
3rdpartylicenses.txt
├── browser
│ ├── chunk-2XJVAMHT.js
│ ├── favicon.ico
│ ├── index.html
│ ├── main-6JLMM7WW.js
│ ├── polyfills-4UVFGIFL.js
│ └── styles-5INURTSO.css
└── server
├── chunk-4ZCEIHD4.mjs
├── chunk-PMR7BAU4.mjs
├── chunk-TSP6W7K5.mjs
├── index.server.html
├── main.server.mjs
└── server.mjs
```
This commit removed the hard coded Node.js version in application builder server config and instead passes the Angular CLI supported Node.js versions that are currently stamped using Bazel.
Prior to this change when `baseUrl` was set to non-root or not set polyfills were not correctly resolved. Internally Esbuild uses the `baseUrl` to resolve non relative imports.
Closes: #25341
This adds the support of `namedChunks` for the new `application` builder.
It generates output like the following:
```
Initial Chunk Files | Names | Raw Size | Estimated Transfer Size
chunk-ACXUMF56.js | - | 94.14 kB | 28.25 kB
main-3WP5KDHR.js | main | 71.95 kB | 18.31 kB
polyfills-4UVFGIFL.js | polyfills | 32.85 kB | 10.68 kB
chunk-2XJVAMHT.js | - | 449 bytes | 449 bytes
styles-5INURTSO.css | styles | 0 bytes | 0 bytes
| Initial Total | 199.38 kB | 57.68 kB
Lazy Chunk Files | Names | Raw Size | Estimated Transfer Size
about.component-2PJOS5PM.js | - | 401 bytes | 401 bytes
home.component-25UHFOEY.js | - | 398 bytes | 398 bytes
```
This is really handy to get a glimpse at what a chunk is referring to and be able to analyze it (especially in applications with dozens of chunks).
When using the esbuild-based application build system through the `application` builder, the `localize`
option will now allow inlining project defined localizations when using the app shell, prerendering,
and service worker features. Previously a warning was issued and these features were disabled when the
`localize` option was enabled.
To prevent stale Angular template diagnostics from persisting in watch mode (including `ng serve`), the template
diagnostic cache will now be invalidated based on the set of changed external template files. This ensures that
the Angular AOT compiler will analyze the template again during the rebuild and clear any fixed errors.
To better capture file changes after the initial build for the esbuild-based builders in a programmatic usage,
the file watching initialization has been moved to before the first build results are yielded. This allows tests
that execute code to change files with improved accuracy of the watch mode triggering. The application builder
now also supports aborting the watch mode programmatically. This allows tests to gracefully stop the watch mode
and more fully cleanup the test at completion.
This commit clean ups the compiled components state when the build is being executed in watch mode. This is required as otherwise during development `Component ID generation collision detected` are displayed on the server.
Closes: #25924
This commit disables logging `Angular is running in development mode.` when using SSR with vite dev-server. This to avoid polluting the server console with `Angular is running in development mode.` logs for each page load and reload.
Example:
```
ng s
Initial Chunk Files | Names | Raw Size
main.js | main | 34.31 kB |
polyfills.js | polyfills | 95 bytes |
styles.css | styles | 95 bytes |
| Initial Total | 34.49 kB
Application bundle generation complete. [5.205 seconds]
➜ Local: http://localhost:4200/
Watch mode enabled. Watching for file changes...
Angular is running in development mode.
Angular is running in development mode.
Angular is running in development mode.
Angular is running in development mode.
Angular is running in development mode.
Angular is running in development mode.
```