To prevent `JSON.parse` errors triggered by Byte Order Marks (BOMs) in package.json files, the `readJson` tree method is now utilized for more reliable BOM handling.
Closes#27052
The `load` event for each stylesheet may not always be triggered by Google Chrome's handling. Refer to: https://crbug.com/1521256
This results in the media attribute persistently being set to print, leading to distorted styles in the UI. To address this issue, we substitute the onload logic by replacing `link.addEventListener('load', ...` with `document.documentElement.addEventListener('load', ...` and filtering for link tags.
Closes#26932
This is a new `@angular-devkit/build-angular:web-test-runner` builder which invokes Web Test Runner to execute unit tests in a real browser.
The implementation calls `application` builder under the hood with some option overrides build the application to a temporary directory and then runs Web Test Runner on the output. This set up is still minimal, but sufficient to run and pass tests in the generated `ng new` application.
The `schema.json` file is directly copied from the `karma` builder, since this is intended to serve as a migration target for users coming from Karma. Most of the options don't actually work yet, which is logged when they are used.
The most interesting part of this change is configuring Jasmine to execute in Web Test Runner. This is done through the `testRunnerHtml` option which allows us to control the HTML page tests are executed on. We use `test_page.html` which very carefully controls the loading process. I opted to make a single `<script type="module">` which dynamic imports all the relevant pieces so the ordering can be directly controlled more easily. This is better than trying to manage multiple `<script>` tags and pass data between them. Ideally everything would be bundled into a single entry point, however this is not feasible due to the way that ordering requirements do not align with typical `import` structure. Jasmine must come before polyfills which must come before the runner which invokes user code. In an ideal world, this ordering relationship would be represented in `import` statements, but this is not practically feasible because Angular CLI doesn't own all the files (`./polyfills.js` is user-defined) and Jasmine's loading must be split into two places so Zone.js can properly patch it.
`jasmine_runner.js` serves the purpose of executing Jasmine tests and reporting their results to Web Test Runner. I tried to write `jasmine_runner.js` in TypeScript and compile it with a `ts_library`. Unfortunately I don't think this is feasible because it needs to import `@web/test-runner-core` at runtime. This dependency has some code generated at runtime in Web Test Runner, meaning we cannot bundle this dependency and must mark it as external and dynamic `import()` the package at runtime. This works fine in native ESM, but compiling with TypeScript outputs CommonJS code by default (and I don't believe our `@build_bazel_rules_nodejs` setup can easily change that), so any `import('@web/test-runner-core')` becomes `require('@web/test-runner-core')` which fails because that package is ESM-only. The `loadEsmModule` trick does work here either because Web Test Runner is applying Node module resolution at serve time, meaning it looks for `import('@web/test-runner-core')` and rewrites it to something like `import('/node_modules/@web/test-runner-core')`. In short, there is no easy syntax which circumvents the TypeScript compiler while also being statically analyzable to Web Test Runner.
The index HTML augmentation within the PWA schematic now uses the Node.js
promise-based pipeline helper to reduce the complexity of the code when
using the parse5 streaming rewriter. This removes a noticeable amount of
code as well as removing the need to manually wrap the result in a Promise.
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.
When updating to v17, the `@nguniversal/builders` is now ignored when checking peer
dependency ranges. The `@nguniversal/builders` is no longer used and will be removed
in a migration during the update process.
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
```
This commit adds an option to the `CommonEngine` to enable performance profiling. When enabled, timings of a number of steps will be outputted in the server console.
Example:
```
********** Performance results **********
Retrieve SSG Page: 0.3ms
Render Page: 25.4ms
Inline Critical CSS: 2.3ms
*****************************************
```
To enable profiling set `enablePeformanceProfiler: true` in the `CommonEngine` options.
```ts
const commonEngine = new CommonEngine({
enablePeformanceProfiler: true
});
```
This commit enabled users to opt-in adding SSR and SSG to their application during the `ng new` experience. This can be done either by using the `--ssr` option or answer `Yes` when prompted.
This commit configures both `ssr` and `prerender` both both development and production configurations. This is needed to improve DX and allow for a better debugging.
This removes that code that was used to set `initialNavigation: enabledBlocking` as this is no longer needed to reduce flickering. This is because `initialNavigation: enabledBlocking` is not needed when enabling hydration via `provideClientHydration` which is done in the internal server schematic.
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.
This commit updates the `ng generate application` to use the esbuild `application` builder. This also updates the schematics to support both `browser` and `application` builders.
BREAKING CHANGE: `rootModuleClassName`, `rootModuleFileName` and `main` options have been removed from the public `pwa` and `app-shell` schematics.