There might be cases were currently, the render application promise does not resolve because the application never becomes stable in most cases this is due to errors, this causes the worker to never exit and the build to keep running until it's manually terminated.
With this change, we add a maximum rendering timeout of 30seconds for each page.
The newly introduced incremental bundler result caching is now used for both global styles
(`styles` option) and global scripts (`scripts` option). This allows the bundling steps
to be skipped in watch mode when no related files for either have been modified. This
can be especially beneficial for applications with large global stylesheets.
`ng serve` might fail with: `Cannot read properties of undefined (reading 'explicit')` because `result.externalMetadata` is optional.
This commit guards the access and should fix the issue related to the fix 9768c184e0
When using the Vite-based development server combined with the `externalDependencies` option, Vite
will no longer attempt to resolve the explicitly marked externals.
This is still not ideal since it vite will still transform the import specifier to `/@id/${source}`
but is currently closer to a raw external than a resolved file path. Further investigation with
a possible feature request for Vite may be needed to achieve the desired outcome of an unresolved
and untransformed external import specifier.
The builder system (architect) currently attempts to treat all results as JSON and
attempts to validate the object with a JSON schema validator. This can lead to slow
build completion (even after the actual build is fully complete) or crashes if the
size and/or quantity of output files is large. Architect only requires a `success`
property so that is all that will be passed here if the infrastructure settings have
not been explicitly set to avoid writes. Writing is only disabled when used directly
by the dev server which bypasses the architect behavior.
When using the Vite-based development server, the application build step already contains the
list of known packages that would need to be prebundled. This information can be passed to Vite
directly to avoid Vite needing to perform discovery on every output file that will be requested.
This also avoids the Vite server behavior where Vite forces a reload of the page when it discovers
a new dependency. This behavior can result in lost state during lazy loading of a route.
To avoid incorrectly invalidating the stylesheet bundler within the application builder
on Windows, the paths of changed files are now first normalized. This ensures that any
changed files properly cause affected component stylesheets to be reprocessed.
The built packages that will be published on npm previously contained inlined
sourcemaps for every JavaScript file. This caused a significant increase in the
overall package size of over two times larger. This has a negative effect on
developer experience especially the new project experience due to the increase
time to download and setup a new project. The sourcemaps are also rarely used
as debugging the CLI code itself is typically done with development builds.
The generated code is also very close to the original source due to it being
emitted as ES2022 code and with the eventual switch to ESM output this will
become even closer.
As an example of the size difference, the `@angular/cli` compressed package size
was reduced from ~352Kb to ~115Kb with this change.
The idle timeout for threads in the JavaScript transformer worker pool for the esbuild-based builders
(`application`/`browser-esbuild`) is now set at 1 second. This prevents the default of immediate shutdown
of an idle worker from occurring. The immediate shutdown causes additional worker threads to be created
due to the variable time between bundler requests for node module JavaScript files. The shutdown and
subsequent recreation of the threads during the build causes unneeded extra processing that can now be
avoided.
With the full set of dependencies and watch files tracked within the bundler context object for
component stylesheets, the entire bundler output can be cached in memory and reused when none of
the relevant files have changed since the last rebuild. This is particularly useful for scenarios
when a large tree of components are considered affected and must be recompiled by the AOT compiler.
The Angular compiler's partial compilation mode is only intended for use when building libraries.
If attempting to use the mode while building an application, the application would fail. A warning
is now issued if partial mode is configured for the application and the mode is switched to full
compilation mode to prevent the build from failing due to the option value.
The stylesheet url() resource plugin will now correctly issue warnings for the usage of Webpack
specific prefixes such as the tilde when used in an imported Sass file. Previously, these URLs
would be rebased by the Sass processing step which would cause the tilde prefix to no longer
be a prefix. This would then no longer be considered a warning due to the tilde no longer being
the first character of the URL value. Additionally, a warning is also now issued for the previously
unsupported but available caret prefix. Removing the caret prefix and adding the path to the
`externalDependencies` build option should provide equivalent behavior.
The build time is now shown when bundling fails. Previously only the errors were shown. This
provides additional information that the build did indeed fail and how long it took to fail.
The recent version of the Sass compiler (`dart-sass@1.68.0`) now provides
additional information within an importer that allows more accurate resolution of node
modules packages without several existing workarounds. Previously, the Sass files needed
to be pre-processed to extract all `@import` and `@use` paths so that information regarding
the containing Sass file could be used to fully resolve the paths. The Sass compiler now
provides this information directly.
When using the esbuild-based builders (`application`/`browser-esbuild`), the Angular compiler plugin
is now only added to the polyfills bundler configuration if TypeScript files are found in the `polyfills`
build option. This is not the case for a default project. The Angular compiler plugin is used to provide
type-checking diagnostics for any TypeScript files present within the build. However, if there are no
TypeScript files to process, there is no need to use it for the polyfills processing.
When using the esbuild-based builders (`application`/`browser-esbuild`) in watch mode including `ng serve`,
component stylesheets that used Sass and imported other stylesheets were previously no properly tracked.
As a result, changes to the imported stylesheets would not invalidate the component and the rebuild would
not contain the updated styles. The files used by the Sass (and Less) stylesheet processing are now correctly
tracked in these cases.
This commit updates the behaviour of `ng update --migrate-only` to remove the need for `--migrate-only` option to be specified. `--migrate-only` will be set internally.
Before
```
ng update @angular/cli --migrate-only --name=migration-name
```
Now
```
ng update @angular/cli --name=migration-name
```
To improve initialization type for the application builder, loading of the typescript package as been removed from the
main thread. The parallel TS/NG compilation will instead load typescript during its worker thread startup. The typescript
package is currently large and can take several hundred milliseconds to load.
When destroying a `piscina` package worker pool, the minimum workers must be set to 0 first
to prevent the recreation of the minimum number of workers. These workers would then be
cleaned up once the worker pool goes out of scope but the recreation and initialization of
each worker is unneeded processing that should be avoided.
The development server used with the esbuild-based builders (`application`/`browser-esbuild`) will
now use the recently introduced hash values provided by esbuild in its output files. This removes
the need for each file to be hashed and analyzed on each rebuild during the development server
update analysis.
This commit adds caching to the polyfills virtual modules to avoid module resolutions on rebuilds which can take up to 3 seconds in some cases. Whilst these are done async, these can still slow down the build slightly due to IO limits.
This commit improves the printed error messages when using Vite with SSR and/or SSG by doing a couple of things.
- Enabling resolving and loading of sourcemap in Node.js by using `process.setSourceMapsEnabled`. See https://nodejs.org/api/process.html#processsetsourcemapsenabledval
- Amends Vite's `ssrTransform` method to remap the sourcemaps and inlines them.
- Enables `__zone_symbol__DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION` Zone.js flag to output cleaner stacktraces.
To enable, the above mentioned zone.js flag we had to create a server polyfill bundle as otherwise in some cases, zone.js would have been split and loaded before the flag.
**Before**
```
ERROR ReferenceError: window is not defined
at new _AppComponent (/main.server.mjs:36:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (/main.server.mjs:42:12)
at getNodeInjectable (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:4277:44)
at createRootComponent (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14399:35)
at ComponentFactory.create (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14263:25)
at ApplicationRef.bootstrap (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:31122:42)
at file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:30644:32
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:368:26)
at Object.onInvoke (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11202:33)
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:367:52)
ERROR Error: Uncaught (in promise): ReferenceError: window is not defined
ReferenceError: window is not defined
at new _AppComponent (/main.server.mjs:36:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (/main.server.mjs:42:12)
at getNodeInjectable (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:4277:44)
at createRootComponent (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14399:35)
at ComponentFactory.create (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14263:25)
at ApplicationRef.bootstrap (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:31122:42)
at file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:30644:32
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:368:26)
at Object.onInvoke (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11202:33)
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:367:52)
at resolvePromise (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:1124:31)
at /usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:1195:17
at _ZoneDelegate.invokeTask (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:402:31)
at AsyncStackTaggingZoneSpec.onInvokeTask (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:10879:28)
at _ZoneDelegate.invokeTask (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:401:60)
at Object.onInvokeTask (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11189:33)
at _ZoneDelegate.invokeTask (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:401:60)
at Zone.runTask (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:173:47)
at drainMicroTaskQueue (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:581:35) {
rejection: ReferenceError: window is not defined
at new _AppComponent (/main.server.mjs:36:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (/main.server.mjs:42:12)
at getNodeInjectable (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:4277:44)
at createRootComponent (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14399:35)
at ComponentFactory.create (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14263:25)
at ApplicationRef.bootstrap (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:31122:42)
at file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:30644:32
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:368:26)
at Object.onInvoke (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11202:33)
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:367:52),
promise: ZoneAwarePromise [Promise] {
__zone_symbol__state: 0,
__zone_symbol__value: ReferenceError: window is not defined
at new _AppComponent (/main.server.mjs:36:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (/main.server.mjs:42:12)
at getNodeInjectable (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:4277:44)
at createRootComponent (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14399:35)
at ComponentFactory.create (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14263:25)
at ApplicationRef.bootstrap (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:31122:42)
at file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:30644:32
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:368:26)
at Object.onInvoke (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11202:33)
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:367:52)
},
zone: <ref *1> Zone {
_parent: Zone {
_parent: [Zone],
_name: 'asyncStackTagging for Angular',
_properties: {},
_zoneDelegate: [_ZoneDelegate]
},
_name: 'angular',
_properties: { isAngularZone: true },
_zoneDelegate: <ref *2> _ZoneDelegate {
_taskCounts: [Object],
zone: [Circular *1],
_parentDelegate: [_ZoneDelegate],
_forkZS: null,
_forkDlgt: null,
_forkCurrZone: null,
_interceptZS: null,
_interceptDlgt: null,
_interceptCurrZone: null,
_invokeZS: [Object],
_invokeDlgt: [_ZoneDelegate],
_invokeCurrZone: [Circular *1],
_handleErrorZS: [Object],
_handleErrorDlgt: [_ZoneDelegate],
_handleErrorCurrZone: [Circular *1],
_scheduleTaskZS: [Object],
_scheduleTaskDlgt: [_ZoneDelegate],
8:23:50 AM [vite] Internal server error: window is not defined
at new _AppComponent (/main.server.mjs:36:19)
at NodeInjectorFactory.AppComponent_Factory [as factory] (/main.server.mjs:42:12)
at getNodeInjectable (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:4277:44)
at createRootComponent (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14399:35)
at ComponentFactory.create (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:14263:25)
at ApplicationRef.bootstrap (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:31122:42)
at file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:30644:32
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:368:26)
at Object.onInvoke (file:///usr/local/xxx/cli-reproduction/test-ssr-/node_modules/@angular/core/fesm2022/core.mjs:11202:33)
at _ZoneDelegate.invoke (/usr/local/xxx/cli-reproduction/test-ssr-/node_modules/zone.js/fesm2015/zone-node.js:367:52)
```
**After**
```
ERROR ReferenceError: window is not defined
at console (/src/app/app.component.ts:17:3)
at NodeInjectorFactory.AppComponent_Factory (/src/app/app.component.ts:12:26)
at getNodeInjectable (/usr/local/xxx/git/packages/core/src/render3/di.ts:659:38)
at createRootComponent (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:464:31)
at ComponentFactory.create (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:288:19)
at ApplicationRef.bootstrap (/usr/local/xxx/git/packages/core/src/application_ref.ts:1017:38)
at <anonymous> (/usr/local/xxx/git/packages/core/src/application_ref.ts:287:20)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
at Object.onInvoke (/usr/local/xxx/git/packages/core/src/zone/ng_zone.ts:443:29)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
ERROR ReferenceError: window is not defined
at console (/src/app/app.component.ts:17:3)
at NodeInjectorFactory.AppComponent_Factory (/src/app/app.component.ts:12:26)
at getNodeInjectable (/usr/local/xxx/git/packages/core/src/render3/di.ts:659:38)
at createRootComponent (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:464:31)
at ComponentFactory.create (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:288:19)
at ApplicationRef.bootstrap (/usr/local/xxx/git/packages/core/src/application_ref.ts:1017:38)
at <anonymous> (/usr/local/xxx/git/packages/core/src/application_ref.ts:287:20)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
at Object.onInvoke (/usr/local/xxx/git/packages/core/src/zone/ng_zone.ts:443:29)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
8:13:37 AM [vite] Internal server error: window is not defined
at console (/src/app/app.component.ts:17:3)
at NodeInjectorFactory.AppComponent_Factory (/src/app/app.component.ts:12:26)
at getNodeInjectable (/usr/local/xxx/git/packages/core/src/render3/di.ts:659:38)
at createRootComponent (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:464:31)
at ComponentFactory.create (/usr/local/xxx/git/packages/core/src/render3/component_ref.ts:288:19)
at ApplicationRef.bootstrap (/usr/local/xxx/git/packages/core/src/application_ref.ts:1017:38)
at <anonymous> (/usr/local/xxx/git/packages/core/src/application_ref.ts:287:20)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
at Object.onInvoke (/usr/local/xxx/git/packages/core/src/zone/ng_zone.ts:443:29)
at _ZoneDelegate.invoke (/node_modules/zone.js/fesm2015/zone-node.js:370:40)
```
**Note:** in the above case the error is printed 3x, this will be addressed in the future.