92 Commits

Author SHA1 Message Date
Charles Lyding
9e91463b2d build: add diagnose return type annotation for windows bazel builds
Due to the Windows Bazel directory structure, TypeScript can not safely
infer the return type of the `diagnose` function in the parallel worker
module. The return type should ideally be explicit regardless and so
a return type is now provided for the function.
2023-10-18 11:25:49 -04:00
Charles Lyding
a5962ac62f refactor(@angular-devkit/build-angular): add initial support for parallel TS/NG compilation
By default Angular compilations will now use a Node.js Worker thread to load and execute the
TypeScript and Angular compilers when using esbuild-based builders (`application`/`browser-esbuild`).
This allows for longer synchronous actions such as semantic and template diagnostics to be calculated
in parallel to the other aspects of the application bundling process. The worker thread also has
a separate memory pool which significantly reduces the need for adjusting the main Node.js CLI process
memory settings with large application code sizes. This can be disabled via the `NG_BUILD_PARALLEL_TS`
environment variable currently to support performance benchmarking. However, this is an unsupported
environment variable option and may be removed in a future version.
2023-10-18 16:36:39 +02:00
Charles Lyding
08c1229ff8 fix(@angular-devkit/build-angular): avoid dev server update analysis when build fails with vite
When using an esbuild-based builder (`application` or `browser-esbuild`) with the development server,
a build that fails due to an TypeScript, Angular, or bundling error will now skip all output file result
processing. This avoids unnecessary work since an update of the client code will not take place. This
also allows for an error overlay to be displayed showing the first error available. The full list of
errors will still be shown in the console used to execute the `ng serve` command. Fixing the error will
automatically clear the error overlay but if there were multiple errors the next unfixed error will be
shown instead.
2023-10-18 16:35:40 +02:00
Alan Agius
57fef7b8d3 perf(@angular-devkit/build-angular): reduce CLI loading times by removing critters from critical path
Critters has a number of large deps like postcss which slow down the Angular CLI loading times.
2023-10-18 16:34:44 +02:00
Charles Lyding
06dacb015e fix(@angular-devkit/build-angular): ensure recalculation of component diagnostics when template changes
Previously, the application builder relied on TypeScript to detect affected component files via changes
to the internal template type check code. However, not all AOT compiler generated template errors will cause
the template type check code to be changed. Block syntax errors are one example. To ensure that component
diagnostics are recalculated when required, the component file will now always be considered affected when
a used template file is changed.
2023-10-18 16:34:20 +02:00
Charles Lyding
a03b83c549 fix(@angular-devkit/build-angular): process nested tailwind usage in application builder
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.
2023-10-18 16:34:04 +02:00
Charles Lyding
1ed3a16bd4 fix(@angular-devkit/build-angular): fully track Web Worker file changes in watch mode
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.
2023-10-17 08:36:54 -07:00
Charles Lyding
8d1d3531d0 fix(@angular-devkit/build-angular): use incremental component style bundling only 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.
2023-10-17 08:36:33 -07:00
Charles Lyding
a136f2ec58 fix(@angular-devkit/build-angular): ensure i18n locale data is included in SSR application builds
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.
2023-10-16 08:36:44 +02:00
Charles Lyding
6ec14323a3 refactor(@angular-devkit/build-angular): bundle polyfills independent of main code in application builder
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.
2023-10-13 10:45:59 +02:00
Alan Agius
9ad99c1c70 fix(@angular-devkit/build-angular): do not print Angular is running in development mode. in the server console when running prerender in dev mode
Prior to this change `Angular is running in development mode` was printed multiple times when running prerendering in devmode.
2023-10-13 07:26:46 +02:00
Alan Agius
b2678bb792 fix(@angular-devkit/build-angular): several fixes to assets and files writes in browser-esbuild builder
This commit ports https://github.com/angular/angular-cli/pull/26016 to the esbuilder and also fixes an issue where assets were being outputted in the wrong directory.

Closes #26021
2023-10-12 15:57:44 +02:00
Charles Lyding
0da87bf1c9 fix(@angular-devkit/build-angular): limit concurrent output file writes with application builder
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.
2023-10-12 07:43:08 +02:00
Alan Agius
6d481c8d88 refactor(@angular-devkit/build-angular): move common steps in a shared function
With this change common steps that are executed when running an i18n build and not are moved into a shared file.
2023-10-12 07:30:16 +02:00
Charles Lyding
ac7caa4264 fix(@angular-devkit/build-angular): ensure unique internal identifiers for inline stylesheet bundling
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.
2023-10-11 21:16:22 +02:00
Charles Lyding
c12f98f948 fix(@angular-devkit/build-angular): conditionally enable deprecated Less stylesheet JavaScript support
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.
2023-10-11 19:53:39 +02:00
Charles Lyding
c74e618429 refactor(@angular-devkit/build-angular): export application builder for experimental programmatic usage
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.
2023-10-11 19:52:26 +02:00
Charles Lyding
771e036d5c feat(@angular-devkit/build-angular): support deploy URL option for browser-esbuild builder
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.
2023-10-10 16:28:43 +02:00
Charles Lyding
3ad028bb44 fix(@angular-devkit/build-angular): ensure localize polyfill and locale specifier are injected when not inlining
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.
2023-10-09 19:40:14 +02:00
Alan Agius
8981d8c355 fix(@angular-devkit/build-angular): improve sharing of TypeScript compilation state between various esbuild instances during rebuilds
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.
2023-10-09 16:40:36 +02:00
Charles Lyding
223a82f5f0 perf(@angular-devkit/build-angular): use incremental bundling for component styles in esbuild builders
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.
2023-10-09 10:29:55 +02:00
Charles Lyding
9e425308a0 feat(@angular-devkit/build-angular): support component style budgets in esbuild builders
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.
2023-10-09 10:17:35 +02:00
Charles Lyding
1fb0350eb7 feat(@angular-devkit/build-angular): add initial support for bundle budgets to esbuild builders
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.
2023-10-06 14:49:38 -04:00
Alan Agius
1541cfd6b8 refactor(@angular-devkit/build-angular): move SourceFileCache into dedicated file
This is to reduce the code in `compiler-plugin.ts`
2023-10-06 19:51:27 +02:00
Charles Lyding
1f73bcc49a fix(@angular-devkit/build-angular): ensure Web Worker code file is replaced in esbuild builders
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.
2023-10-05 15:35:34 -04:00
Alan Agius
49f07a84d6 feat(@angular-devkit/build-angular): standardize application builder output structure
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
```
2023-10-05 13:30:52 -04:00
Alan Agius
f29b744d4e refactor(@angular-devkit/build-angular): remove hardcoded Node.js version in application builder
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.
2023-10-05 17:28:48 +02:00
Alan Agius
667f43af6d fix(@angular-devkit/build-angular): correctly resolve polyfills when baseUrl URL is not set to root
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
2023-10-05 10:00:05 -04:00
cexbrayat
5898f72a97 feat(@angular-devkit/build-angular): support namedChunks option in application builder
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).
2023-10-04 11:21:54 -04:00
Charles Lyding
fd62a9315d feat(@angular-devkit/build-angular): support i18n with service worker and app-shell with esbuild builders
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.
2023-10-04 09:53:45 -04:00
Charles Lyding
83020fc329 fix(@angular-devkit/build-angular): clear diagnostic cache when external templates change with esbuild builders
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.
2023-10-04 09:50:06 -04:00
Alan Agius
2d2e79921a fix(@angular-devkit/build-angular): clean up internal Angular state during rendering SSR
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
2023-09-29 18:47:39 +02:00
Charles Lyding
c3a87a60e0 feat(@angular-devkit/build-angular): support basic web worker bundling with esbuild builders
When using the esbuild-based builders (`application`/`browser`), Web Workers that use the supported
syntax will now be bundled. The bundling process currently uses an additional synchronous internal
esbuild execution. The execution must be synchronous due to the usage within a TypeScript transformer.
TypeScript's compilation process is fully synchronous. The bundling itself currently does not provide
all the features of the Webpack-based builder. The following limitations are present in the current
implementation but will be addressed in upcoming changes:
* Worker code is not type-checked
* Nested workers are not supported
2023-09-22 16:47:55 +02:00
Charles Lyding
c5f3ec71f5 feat(@angular-devkit/build-angular): support i18n inlining with esbuild-based builder
When using the esbuild-based application build system through either the `application`
or `browser-esbuild` builder, the `localize` option will now allow inlining project
defined localizations. The process to configure and enable the i18n system is the same
as with the Webpack-based `browser` builder. The implementation uses a similar approach
to the `browser` builder in which the application is built once and then post-processed
for each active locale. In addition to inlining translations, the locale identifier is
injected and the locale specific data is added to the applications. Currently, this
implementation adds all the locale specific data to each application during the initial
building. While this may cause a small increase in the polyfills bundle (locale data is
very small in size), it has a benefit of faster builds and a significantly less complicated
build process. Additional size optimizations to the data itself are also being
considered to even further reduce impact. Also, with the eventual shift towards the standard
`Intl` web APIs, the need for the locale data will become obsolete in addition to the build
time code necessary to add it to the application.
While build capabilities are functional, there are several areas which have not yet been
fully implemented but will be in future changes. These include console progress information,
efficient watch support, and app-shell/service worker support.
2023-09-22 10:48:17 +02:00
Charles Lyding
ccdd268d7e refactor(@angular-devkit/build-angular): avoid double emit of TypeScript files in AOT with esbuild
Some TypeScript files may previously have been emitted twice during builds when using the Angular compiler
esbuild plugin used within the esbuild-based browser application builder. It did not cause any build problems.
However, it may have caused builds to take longer than expected. This was caused by an incorrect comparison of the
transformed source file and the original source file found within the TypeScript program. Comparisons during
emit now compare only original source files which avoids the issue with the emitted files checks.
2023-09-21 11:02:20 +02:00
Charles Lyding
8bce80b91b feat(@angular-devkit/build-angular): initial support for application Web Worker discovery with esbuild
When using the esbuild-based builders (application/browser-esbuild), Web Workers following the previously
supported syntax as used in the Webpack-based builder will now be discovered. The worker entry points are not
yet bundled or otherwise processed. Currently, a warning will be issued to notify that the worker will not
be present in the built output.
Additional upcoming changes will add the processing and bundling support for the workers.

Web Worker syntax example: `new Worker(new URL('./my-worker-file', import.meta.url), { type: 'module' });`
2023-09-21 11:02:20 +02:00
cexbrayat
4e89c3cae4 fix(@angular-devkit/build-angular): use a dash in bundle names
This updates the esbuild based builder to use a dash in bundles and media instead of a dot to be consistent with the chunks files `chunk-xxx.js`.
2023-09-21 10:58:48 +02:00
Alan Agius
f9fdd0907c refactor(@angular-devkit/build-angular): use ɵloadChildren helper from router package
This commit updates the routes extractor to use the newly exported private `ɵloadChildren` method from the router to executes a `route.loadChildren` callback and return an array of child routes.

See: https://github.com/angular/angular/pull/51818
2023-09-21 07:02:17 +02:00
cexbrayat
fe64193b78 refactor(@angular-devkit/build-angular): typo in ignore list plugin function 2023-09-20 19:48:55 +02:00
Alan Agius
8f9a0d70cd feat(@angular-devkit/build-angular): support standalone apps route discovery during prerendering
This fixes an issue were routes could not be discovered automatically in a standalone application.

This is a total overhaul of the route extraction process as instead of using `guess-parser` NPM package, we now use the Angular Router. This enables a number of exciting possibilities for the future which were not possible before.

# How it works?
The application is bootstrapped and through DI injection we get the injector and router config instance and recursively build the routes tree.
2023-09-18 22:26:06 +02:00
Charles Lyding
b07ba1a90c refactor(@angular-devkit/build-angular): remove usage of terser constants in esbuild
The terser build time constant import from the `@angular/compiler-cli` package is no
longer used in the esbuild-based builder. The constants present are already defined
and conditionally added within the build configuration itself. This not only provides
more flexibility but also removes the need to import the package early in the process.
The import is also an expensive import due to it needing TypeScript and being ESM that
needs to be dynamically imported via a function helper to work around current ESM/TypeScript/CommonJS
limitations.
2023-09-14 21:59:56 +02:00
Alan Agius
c8909406a5 fix(@angular-devkit/build-angular): correctly re-point RXJS to ESM on Windows
Previously, the path matching and replacement did not consider non posix file systems like windows.
2023-09-14 10:53:38 +02:00
Alan Agius
7632bafe72 refactor(@angular-devkit/build-angular): remove deep import of zone.js/node
This is no longer needed as `zone.js` now has proper package exports.
2023-09-13 16:23:22 +02:00
Kristiyan Kostadinov
2f299fc7b5 fix(@angular-devkit/build-angular): account for styles specified as string literals and styleUrl
An upcoming change in Angular will allow `style` specified as strings, in addition to a new `styleUrl` property. These changes update the JIT resource transform to support the change.
2023-09-13 09:33:50 +02:00
Charles Lyding
b4a12a9264 refactor(@angular-devkit/build-angular): update babel package usage and types based on current versions
Newer versions of the babel packages allow for removing some types packages as well as some helper
packages. The `@babel/template` package export used within the CLI is accessible from the `@babel/core`
package which allows removal of `@babel/template` as a direct dependency. Also, the `@babel/plugin-proposal-async-generator-functions`
package has been transitioned to `@babel/plugin-transform-async-generator-functions` due to async generators
being merged into the ECMAScript standard. Minor code cleanup based on the type cleanup was also performed
in the build optimizer babel passes.
2023-09-11 20:15:15 +02:00
Kristiyan Kostadinov
188a00f3e4 fix(@angular-devkit/build-angular): elide setClassMetadataAsync calls
Updates the logic that elides `setClassMetadata` calls to also elide `setClassMetadataAsync`. The latter will be emitted when the component uses the new `defer` block syntax.
2023-09-05 10:03:04 -07:00
Kristiyan Kostadinov
6b08efa6ff fix(@angular-devkit/build-angular): account for arrow function IIFE
Updates the logic for removing Angular metadata and pure top-level functions to account for arrow-function-based IIFEs. Currently Angular doesn't generate arrow functions, but it's being explored in https://github.com/angular/angular/pull/51637.
2023-09-05 10:03:04 -07:00
Charles Lyding
c7d12910a9 refactor(@angular-devkit/build-angular): remove unneeded esbuild external packages workaround
Version 0.19 of esbuild added the ability to consider tsconfig path mappings when using the
external packages build option. This addition allows the Angular build system to remove a
resolve plugin that previously was used to workaround this limitation. Removal of the plugin
may also provide improved rebuild performance when used with the development server as many
of the JavaScript resolution attempts will no longer need to be handled by the now removed
plugin.
2023-08-14 10:57:41 +02:00
Alan Agius
f3229c44ad fix(@angular-devkit/build-angular): update vite to be able to serve app-shell and SSG pages
This commits, update the application builder and vite dev-server to be able to serve the app-shell and prerendered pages.
2023-08-14 10:57:13 +02:00
Charles Lyding
8b74a50e7b fix(@angular-devkit/build-angular): encode Sass package resolve directories in importer URLs
When using the new developer preview application build system, Sass import/use usage that specifies
a package is adjusted to contain the resolve directory to workaround Sass import plugin limitations.
This resolve directory is now encoded to prevent the new specifier from looking like a URL with a
scheme to the Sass compiler. This can occur on Windows when a drive letter is present (`C:\`).
2023-08-11 11:07:33 -07:00