396 Commits

Author SHA1 Message Date
Alan Agius
7a50df5c04 fix(@angular-devkit/build-angular): update ESM loader to work with Node.js 18.19.0
In Node.js 18.19 ESM loaders works the same way as Node.js 20.9+

Closes #26648
2023-12-12 18:10:36 +01:00
Charles Lyding
6a44989f54 fix(@angular-devkit/build-angular): retain symlinks to output platform directories on builds
The `deleteOutputPath` option will now empty specific build artifact directories instead of
removing them completely. This allows for symlinking or mounting the directories via Docker.
This is similar to the current behavior of emptying the root output path to allow similar
actions. All previous files will still be removed when the `deleteOutputPath` option is enabled.
This is useful in situations were the browser output files may be symlinked onto another
location on disk that is setup as a development server, or a Docker configuration mounts the browser
and server output to different locations on the host machine.
2023-12-11 10:29:46 +01:00
Alan Agius
f6e67df1c4 feat(@angular-devkit/build-angular): inline Google and Adobe fonts located in stylesheets
`@import url()` to Google and Adobe fonts that are located in global and component CSS will now be inlined when using the esbuild based builders.

Input
```css
@import url(https://fonts.googleapis.com/css?family=Roboto:300,400,500);
```

Output
```css
/* latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
```

Closes #23054
2023-12-09 08:17:43 +01:00
Alan Agius
bf5fbddd45 fix(@angular-devkit/build-angular): inlining of fonts results in jagged fonts for Windows users
We now replace the user agent string used to perform font inlining with a Windows one. This is because Google fonts will including hinting in fonts for Windows. Hinting is a technique used with Windows files to improve appearance however results in 20-50% larger file sizes, however this will make the fonts display correctly on all platforms.

More information about this can be found in:
- https://fonts.google.com/knowledge/glossary/hinting
- https://glyphsapp.com/learn/hinting-manual-truetype-hinting
- http://google3/java/com/google/fonts/css/OpenSansWebFontsCssBuilder.java?l=22

Closes #22248
2023-12-09 07:57:26 +01:00
Charles Lyding
5b8e2d5e57 fix(@angular-devkit/build-angular): ensure port 0 uses random port with Vite development server
Vite appears to consider a port value of `0` as a falsy value and use the default Vite port of
`5173` when zero is used as a value for the development server port option. To workaround this
issue, the port checker code now explicitly handles the zero value case and determines a random
port as would be done automatically by the Webpack-based development server.
2023-12-08 09:57:22 -05:00
Charles Lyding
10588c2fc3 refactor(@angular-devkit/build-angular): update Node.js module register load hook for new types 2023-12-06 11:26:12 -05:00
Charles Lyding
dcc60c6ce4 fix(@angular-devkit/build-angular): correctly align error/warning messages when spinner is active
When using the `application` builder with progress enabled (the default), the spinner text will
now automatically contain a trailing newline. This ensures that any diagnostic messages are not
awkwardly printed on the same line as the spinner.
2023-12-01 16:40:45 +01:00
Alan Agius
4bcee31675 fix(@angular-devkit/build-angular): improve file watching on Windows when using certain IDEs
This commit, fixes a file watching issue where file changes events are not triggered when using IDEs like Visual Studio (not VS Code).

The main changes to solve the issue are;

## Replace `watcher.on('all')` with `watcher.on('raw')`

Using `watcher.on('all')` does not capture some of events fired when using Visual studio and this does not happen all the time, but only after a file has been changed 3 or more times.

```
watcher.on('raw')
Change 1
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

Change 2
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

Change 3
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

watcher.on('all')
Change 1
change | 'C:\\..\\src\\app\\app.component.css'

Change 2
unlink | 'C:\\..\\src\\app\\app.component.css'

Change 3
... (Nothing)
```

## Handle `rename` events
Some IDEs will fire a rename event instead of unlink/changed when a file is modified}

Closes #26437

(cherry picked from commit 1725b91e357f613f7fb7547d13d6499973ee3849)
2023-12-01 08:50:03 +01:00
Doug Parker
72760d44e0 Revert "fix(@angular-devkit/build-angular): improve file watching on Windows when using certain IDEs"
This reverts commit bbbe13d6782ba9d1b80473a98ea95bc301c48597.

Switching to `raw` event changes the event names such that some events are getting dropped and breaking watch mode rebuilds on Mac.
2023-11-29 15:29:56 -08:00
Alan Agius
e0b274b8ff feat(@angular-devkit/build-angular): add option to retain CSS special comments in global styles
Prior to this change special CSS comments `/*! comment */` were being removed during minification when using the application builder. This caused tools that ran post build that rely on such comments such as purgeCSS and critters not to function properly.

We now provide a `removeSpecialComments` option to enable retention of these comments in global CSS files.

Usage example:
```json
{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "configurations": {
            "production": {
              "optimization": {
                "styles": {
                  "removeSpecialComments": false
                }
              }
            }
          }
        }
      }
    }
  }
}
```

Closes: #26432
2023-11-29 17:32:29 +01:00
Alan Agius
555164b407 refactor(@angular-devkit/build-angular): remove piscina minThreads workaround
This is no longer needed since 4.2.0
2023-11-24 21:54:12 +01:00
Alan Agius
36d9f19201 refactor(@angular-devkit/build-angular): remove no longer applicable comment
This comment is no longer correct.
2023-11-23 17:41:38 +01:00
Alan Agius
1725b91e35 fix(@angular-devkit/build-angular): improve file watching on Windows when using certain IDEs
This commit, fixes a file watching issue where file changes events are not triggered when using IDEs like Visual Studio (not VS Code).

The main changes to solve the issue are;

## Replace `watcher.on('all')` with `watcher.on('raw')`

Using `watcher.on('all')` does not capture some of events fired when using Visual studio and this does not happen all the time, but only after a file has been changed 3 or more times.

```
watcher.on('raw')
Change 1
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

Change 2
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

Change 3
rename | 'C:/../src/app/app.component.css'
rename | 'C:/../src/app/app.component.css'
change | 'C:/../src/app/app.component.css'

watcher.on('all')
Change 1
change | 'C:\\..\\src\\app\\app.component.css'

Change 2
unlink | 'C:\\..\\src\\app\\app.component.css'

Change 3
... (Nothing)
```

## Handle `rename` events
Some IDEs will fire a rename event instead of unlink/changed when a file is modified}

Closes #26437
2023-11-23 15:46:22 +01:00
Charles Lyding
96b5b10120 fix(@angular-devkit/build-angular): default to watching project root on Windows with application builder
When using the `application` or `browser-esbuild` builder in watch mode on Windows, the project root
will now be watched by default. This provides a workaround for users of Visual Studio which uses a
file save mechanism that causes the watch mode to not correctly trigger. By watching the entire
project root, this problem is avoided. However, this may result in additional rebuilds due to changes
of unrelated files in the project root.
This behavior can be disabled using the environment variable `NG_BUILD_WATCH_ROOT=0`. On non-Windows
platforms, disabled is the default.

Addresses #26437
2023-11-21 16:25:19 -05:00
Alan Agius
2b5409b4a5 refactor(@angular-devkit/build-angular): update deleteOutputDir to use FS promise APIs
As per commit title.
2023-11-13 08:29:10 +01:00
Alan Agius
6cf9342110 fix(@angular-devkit/build-angular): prerender default view when no routes are defined
Prior to the commit, when no routes were defined the default view was not prerendering.

Closes #26317
2023-11-13 08:27:43 +01:00
Charles Lyding
8e4802dd25 fix(@angular-devkit/build-angular): empty output directory instead of removing
When the `deleteOutputPath` option is enabled (default is enabled), the configured
`outputPath` for the project was previously removed directly. This was problematic
for cases such as when the path was mounted via a Docker setup. To alleviate these
issues, the contents of the output path will now be removed instead. This maintains
the existing output path directory itself but ensures an empty location to place the
new build output.
2023-11-09 10:43:30 +01:00
Charles Lyding
36867680c9 Revert "fix(@angular-devkit/build-angular): disable parallel TS/NG compilation inside WebContainers"
This reverts commit 421c175ec94e737081ff7328caddb29de8575acc.
2023-11-08 15:04:20 +01:00
Charles Lyding
421c175ec9 fix(@angular-devkit/build-angular): disable parallel TS/NG compilation inside WebContainers
When using the `application` or `browser-esbuild` builders, a parallel TS/NG compilation will
be used by default via a Node.js Worker. However, when used inside a Web Container, the
build will fail to initialize the compilation instance due to what appears to be a defect
within Web containers involving the transfer/serialization of a MessageChannel's MessagePort
objects. To avoid this problem, the parallel compilation is disabled by default when the
build system detects it is being executed from within a Web Container. A parallel compilation
can still be forced by using the `NG_BUILD_PARALLEL_TS=1` environment variable.
2023-11-06 17:51:37 +01:00
Charles Lyding
f06a760344 fix(@angular-devkit/build-angular): avoid in-memory prerendering ESM loader errors
The in-memory ESM loader hooks have been adjusted to avoid potential errors when
resolving and loading the bundled server code during prerendering. These errors
could result in hard to diagnose build failures. E2E testing via the deprecated
protractor builder, would silently exit, for instance. To ensure on disk files
including node modules are resolved from the workspace root, a virtual file root
is used for all in memory files. This path does not actually exist but is used to
overlay the in memory files with the actual filesystem for resolution purposes.
A custom URL schema (such as `memory://`) cannot be used for the resolve output
because the in-memory files may use `import.meta.url` in ways that assume a file
URL. `createRequire` from the Node.js `module` builtin is one example of this usage.
2023-11-05 13:30:53 +01:00
Alan Agius
e453695009 refactor(@angular-devkit/build-angular): remove redundant async from render-worker
The `async` keyword is not needed here.
2023-11-03 14:50:55 +01:00
Charles Lyding
6d8d948ad0 refactor(@angular-devkit/build-angular): cache compiled load ESM file helper
The dynamically compiled ESM import helper is now cached to prevent the need
to recompile the helper function everytime a load ESM helper call is made.
This helper is currently used to workaround dynamic import limitations with
the TypeScript compilation output. Once the build process is updated, it will
no longer be required.
2023-11-03 10:36:27 +01:00
Charles Lyding
271d561cf4 refactor(@angular-devkit/build-angular): reduce complexity of bundle budget threshold regex
The extra whitespace matching can be removed via a trim call prior to matching and casing
can be handled by the `i` flag.
2023-11-01 19:04:15 +01:00
Charles Lyding
974acb7fe1 fix(@angular-devkit/build-angular): ensure all SSR chunks are resolved correctly with dev server
The `server-utils` SSR generated chunk was not previously included in the ESM in memory loader for
prerendering which resulted in the ESM resolver incorrectly attempting to resolve non-relative
dependencies. This would lead to resolution errors when using the development server with caching
enabled. In this scenario, the Angular dependencies would be marked external and the server utilities
output chunk would contain non-relative imports and fail to prerender.
2023-11-01 14:48:47 +01:00
Alan Agius
dbb63299d2
fix(@angular-devkit/build-angular): Windows Node.js 20 prerendering failure (#26186)
* fix(@angular-devkit/build-angular): Windows Node.js 20 prerendering failure

On Node.js 20 prerendering failed on Windows with `An unhandled exception occurred: No handler function exported` error. This appears to be caused by transforming Piscina CJS bundles using the `JavaScriptTransformer`. interestingly, this does not effect other OS like Linux and Mac.

* fixup! fix(@angular-devkit/build-angular): Windows Node.js 20 prerendering failure

Co-authored-by: Charles <19598772+clydin@users.noreply.github.com>

---------

Co-authored-by: Charles <19598772+clydin@users.noreply.github.com>
2023-10-31 15:32:43 +01:00
Charles Lyding
06b8fe65df fix(@angular-devkit/build-angular): only watch used files with application builder
When using the application builder in watch mode (including `ng serve`), the file watching
will now only watch files used or relevant to the used files. Previously, all files within
the project root were watched. This previous behavior could result in unneeded rebuilds when
unrelated files were changed. An environment variable named `NG_BUILD_WATCH_ROOT` is also
now available to enable the previous behavior in cases where it is still preferred as well
as for testing and debugging purposes.
2023-10-31 12:10:07 +01:00
Alan Agius
68b6a5701f perf(@angular-devkit/build-angular): patch fetch to load assets from memory
This commit refactors the assets SSG asset loading from memory to use a patched version of `fetch` instead of spawning a separate server.
2023-10-30 10:05:07 +01:00
Alan Agius
a0f8fac4b3 refactor: update inquirer to version 9.0.6
Update the mentioned package.
2023-10-26 16:11:36 +02:00
Alan Agius
5b3541040b fix(@angular-devkit/build-angular): handle HTTP requests to assets during prerendering
This commit fixes an issue were during prerendering (SSG) http requests to assets causes prerendering to fail.

Closes #25720
2023-10-25 12:45:11 +02:00
Charles Lyding
6029c7580e refactor(@angular-devkit/build-angular): workaround for piscina worker destroy recreation
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.
2023-10-20 11:38:09 -07:00
Alan Agius
886cb3167a fix(@angular-devkit/build-angular): resolve and load sourcemaps when using vite dev server with prerendering and ssr
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.
2023-10-20 15:12:12 +02:00
Alan Agius
665b036ca2 fix(@angular-devkit/build-angular): address a path concatenation on Windows
This should solve the Windows failures
2023-10-18 13:58:04 -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
Alan Agius
2dc6566ad0 fix(@angular-devkit/build-angular): generate a file containing a list of prerendered routes
With this change when SSG is enabled a `prerendered-routes.json` file is emitted that contains all the prerendered routes.

This is useful for Cloud providers and other server engines to have server rules to serve these files as static.
2023-10-18 16:36:04 +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
Alan Agius
0f45e21189 fix(@angular-devkit/build-angular): resolve and load sourcemaps during prerendering to provide better stacktraces
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
2023-10-16 08:37:29 +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
3f679f165b 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
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
Alan Agius
c48982dc1d feat(@angular-devkit/build-angular): add buildTarget option to dev-server and extract-i18n builders
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`.
2023-10-10 19:43:11 +02:00
Alan Agius
8d0b707a79
refactor(@angular-devkit/build-angular): update ESM in memory file loader to work with Node.js 20 (#25988)
This commit refactors the ESM Node.js in memory loader to work with Node.js 20+
2023-10-09 19:41:59 +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
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
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
Alan Agius
1837fee197 refactor(@angular-devkit/build-angular): use whenStable private API in route extractor
This commit refactors the route extractor to use the newly `whenStable` API.
2023-09-28 17:31:51 +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
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
Alan Agius
48963fc17f fix(@angular-devkit/build-angular): several windows fixes to application builder prerendering
This commit fixes several Windows issues in the prerendering pipeline. Primarily due to path normalization and other Windows only constraints.
2023-09-14 17:25:30 +02:00
Alan Agius
e41e2015bf fix(@angular-devkit/build-angular): avoid spawning workers when there are no routes to prerender
This commit fixes an issue were previously we spawned piscina with `maxThreads` set to `0` which causes it to exit with a non zero error code when there are no routes to prerender.

Now, in the application builder we exit at n earlier stage if there are no routes to prerender.
2023-09-13 17:40:50 +02:00