From a3504fd45602ec73ce1781e46e6c92b6042a51da Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 21 May 2025 13:17:05 +0000 Subject: [PATCH 1/7] fix(@angular/build): HMR requires AOT do not show HMR enabled when using JIT Currently, the HMR (Hot Module Replacement) functionality in `@angular/build` requires AOT compilation to be enabled. However, when using JIT compilation, a message indicating that HMR is enabled is incorrectly displayed. --- packages/angular/build/src/builders/dev-server/vite-server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/vite-server.ts b/packages/angular/build/src/builders/dev-server/vite-server.ts index 3087fb56a773..1e80d1e4eca8 100644 --- a/packages/angular/build/src/builders/dev-server/vite-server.ts +++ b/packages/angular/build/src/builders/dev-server/vite-server.ts @@ -160,12 +160,12 @@ export async function* serveWithVite( // Enable to support link-based component style hot reloading (`NG_HMR_CSTYLES=1` can be used to enable) browserOptions.externalRuntimeStyles = - serverOptions.liveReload && serverOptions.hmr && useComponentStyleHmr; + browserOptions.aot && serverOptions.liveReload && serverOptions.hmr && useComponentStyleHmr; // Enable to support component template hot replacement (`NG_HMR_TEMPLATE=0` can be used to disable selectively) // This will also replace file-based/inline styles as code if external runtime styles are not enabled. browserOptions.templateUpdates = - serverOptions.liveReload && serverOptions.hmr && useComponentTemplateHmr; + browserOptions.aot && serverOptions.liveReload && serverOptions.hmr && useComponentTemplateHmr; if (browserOptions.templateUpdates) { context.logger.warn( 'Component HMR has been enabled.\n' + From 5ce9f96a4efeb4efabe3c161ab596d049a1edd97 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 21 May 2025 14:41:51 -0400 Subject: [PATCH 2/7] fix(@angular/build): include full metadata for AOT unit-testing Include class metadata and JIT information in code built for development and/or test usage. All non-optimized builds will now contain this metadata (`optimization.scripts` is false). The Angular TestBed APIs require additional metadata for the Angular aspects of the application such as Components, Modules, Pipes, etc. TestBed may also leverage JIT capabilities during testing (e.g., overrideComponent). To support all these TestBed usage scenarios both the underlying `setClassMetadata` and `setNgModuleScope` class augmentation functions are now emitted when test metadata inclusion is enabled. (cherry picked from commit 578525e64ca4797b0a6dd3660d3f751aabb3c1bb) --- .../build/src/tools/esbuild/angular/compiler-plugin.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 6b5ff732f6b4..c20a9b86ffea 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -35,6 +35,13 @@ export interface CompilerPluginOptions { sourcemap: boolean | 'external'; tsconfig: string; jit?: boolean; + + /** + * Include class metadata and JIT information in built code. + * The Angular TestBed APIs require additional metadata for the Angular aspects of the application + * such as Components, Modules, Pipes, etc. + * TestBed may also leverage JIT capabilities during testing (e.g., overrideComponent). + */ includeTestMetadata?: boolean; advancedOptimizations?: boolean; @@ -89,7 +96,7 @@ export function createCompilerPlugin( sourcemap: !!pluginOptions.sourcemap, thirdPartySourcemaps: pluginOptions.thirdPartySourcemaps, advancedOptimizations: pluginOptions.advancedOptimizations, - jit: pluginOptions.jit, + jit: pluginOptions.jit || pluginOptions.includeTestMetadata, }, maxWorkers, cacheStore?.createCache('jstransformer'), @@ -717,6 +724,7 @@ function createCompilerOptionsTransformer( externalRuntimeStyles: pluginOptions.externalRuntimeStyles, _enableHmr: !!pluginOptions.templateUpdates, supportTestBed: !!pluginOptions.includeTestMetadata, + supportJitMode: !!pluginOptions.includeTestMetadata, }; }; } From 5c86b804418ef10c0c26e9cdb2e5651a71d31be1 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 21 May 2025 10:55:33 -0400 Subject: [PATCH 3/7] refactor(@angular/build): use new HMR documentation URL for console message The https://angular.dev/hmr URL is now used in the HMR enabled console message for the development server. The message text has also been shortened as the information is available at the aforementioned documentation location. --- .../builders/dev-server/tests/options/hmr_spec.ts | 12 ++++++------ .../build/src/builders/dev-server/vite-server.ts | 5 +---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/options/hmr_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/hmr_spec.ts index 4b9ba6a4c780..349876297e67 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/hmr_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/hmr_spec.ts @@ -18,7 +18,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT setupTarget(harness, {}); }); - it('shows message with opt out steps by default', async () => { + it('shows message with documentation by default', async () => { harness.useTarget('serve', { ...BASE_OPTIONS, }); @@ -33,12 +33,12 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT ); expect(logs).toContain( jasmine.objectContaining({ - message: jasmine.stringMatching('--no-hmr'), + message: jasmine.stringMatching('angular.dev/hmr'), }), ); }); - it('shows message with opt out steps when explicitly enabled', async () => { + it('shows message with documentation when explicitly enabled', async () => { harness.useTarget('serve', { ...BASE_OPTIONS, hmr: true, @@ -54,12 +54,12 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT ); expect(logs).toContain( jasmine.objectContaining({ - message: jasmine.stringMatching('--no-hmr'), + message: jasmine.stringMatching('angular.dev/hmr'), }), ); }); - it('does not show enabled message with opt out steps when explicitly disabled', async () => { + it('does not show enabled message with documentation when explicitly disabled', async () => { harness.useTarget('serve', { ...BASE_OPTIONS, hmr: false, @@ -75,7 +75,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT ); expect(logs).not.toContain( jasmine.objectContaining({ - message: jasmine.stringMatching('--no-hmr'), + message: jasmine.stringMatching('angular.dev/hmr'), }), ); }); diff --git a/packages/angular/build/src/builders/dev-server/vite-server.ts b/packages/angular/build/src/builders/dev-server/vite-server.ts index 1e80d1e4eca8..68eafb61d96f 100644 --- a/packages/angular/build/src/builders/dev-server/vite-server.ts +++ b/packages/angular/build/src/builders/dev-server/vite-server.ts @@ -168,10 +168,7 @@ export async function* serveWithVite( browserOptions.aot && serverOptions.liveReload && serverOptions.hmr && useComponentTemplateHmr; if (browserOptions.templateUpdates) { context.logger.warn( - 'Component HMR has been enabled.\n' + - 'If you encounter application reload issues, you can manually reload the page to bypass HMR and/or disable this feature with the' + - ' `--no-hmr` command line option.\n' + - 'Please consider reporting any issues you encounter here: https://github.com/angular/angular-cli/issues\n', + 'Component HMR has been enabled, see https://angular.dev/hmr for more info.', ); } From 33aee3753adb55a6f05a082ce2d3466bd3ecf28f Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 22 May 2025 08:12:36 +0000 Subject: [PATCH 4/7] refactor(@angular/build): update `ensureWorkerPool` to do an early exit The avoid unnecessary logic to be executed for every call to `transformFile`. (cherry picked from commit eed60d1300f6f28d011652efb4dbf4e947bb77fa) --- .../build/src/tools/esbuild/javascript-transformer.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index 8e2d8e31ab8f..b728a0f599e2 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -56,6 +56,10 @@ export class JavaScriptTransformer { } #ensureWorkerPool(): WorkerPool { + if (this.#workerPool) { + return this.#workerPool; + } + const workerPoolOptions: WorkerPoolOptions = { filename: require.resolve('./javascript-transformer-worker'), maxThreads: this.maxThreads, @@ -67,7 +71,7 @@ export class JavaScriptTransformer { workerPoolOptions.execArgv = filteredExecArgv; } - this.#workerPool ??= new WorkerPool(workerPoolOptions); + this.#workerPool = new WorkerPool(workerPoolOptions); return this.#workerPool; } From cf4e676bec4c10bf4a36f88e8c42829c13725c53 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 23 May 2025 07:22:34 +0000 Subject: [PATCH 5/7] build: correctly replace `BUILD_SCM_HASH-PLACEHOLDER` with `BUILD_SCM_ABBREV_HASH` Correctly replace `BUILD_SCM_HASH-PLACEHOLDER` with `BUILD_SCM_ABBREV_HASH` by enclosing it in `{}` for proper interpolation. Example of the issue: https://github.com/angular/angular-build-builds/blob/cac2e58892c99256d3a1f0abeb274f116edd5a26/package.json#L26 (cherry picked from commit c4efd7421d1d7d0bc7d3ec483252610cdd059f73) --- tools/substitutions.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/substitutions.bzl b/tools/substitutions.bzl index 098b511b1d6e..b2e3877138cd 100644 --- a/tools/substitutions.bzl +++ b/tools/substitutions.bzl @@ -5,7 +5,7 @@ _stamp_substitutions = { "0.0.0-PLACEHOLDER": "{{STABLE_PROJECT_VERSION}}", "0.0.0-EXPERIMENTAL-PLACEHOLDER": "{{STABLE_PROJECT_EXPERIMENTAL_VERSION}}", # --- - "BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}", + "BUILD_SCM_HASH-PLACEHOLDER": "{{BUILD_SCM_ABBREV_HASH}}", "0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE, "0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM, "0.0.0-ENGINES-YARN": RELEASE_ENGINES_YARN, From 3ffd43a1464688aadf9da61ac09acdba6bbf2e4d Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 26 May 2025 09:44:24 +0000 Subject: [PATCH 6/7] build: preserve `peerDependenciesMeta` in snapshots Addresses an issue where publishing snapshot builds would replace the value with the package SHAs in `peerDependenciesMeta`. See: https://github.com/angular/angular-build-builds/blob/d4d0f1ca0932bd4fe2df4cc2da10d132789dcd8f/package.json#L89 (cherry picked from commit 697d7e64cc06b9acf586c568d01d40948018a513) --- tools/snapshot_repo_filter.bzl | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tools/snapshot_repo_filter.bzl b/tools/snapshot_repo_filter.bzl index 00e26b44dd9d..a648e8e300a7 100644 --- a/tools/snapshot_repo_filter.bzl +++ b/tools/snapshot_repo_filter.bzl @@ -6,14 +6,23 @@ load("//:constants.bzl", "SNAPSHOT_REPOS") def _generate_snapshot_repo_filter(): - filter = "" - for (i, pkg_name) in enumerate(SNAPSHOT_REPOS.keys()): - filter += "{sep}(..|objects|select(has(\"{pkg_name}\")))[\"{pkg_name}\"] |= \"github:{snapshot_repo}#BUILD_SCM_HASH-PLACEHOLDER\"\n".format( - sep = "| " if i > 0 else "", - pkg_name = pkg_name, - snapshot_repo = SNAPSHOT_REPOS[pkg_name], + individual_pkg_filters = [] + for pkg_name, snapshot_repo in SNAPSHOT_REPOS.items(): + individual_pkg_filters.append( + """ + . as $root + | [paths(..)] + | [(.[] | select( + contains(["{pkg_name}"]) and + contains(["peerDependenciesMeta"]) != true))] as $paths + | $paths | reduce $paths[] as $path ($root; setpath($path; "github:{snapshot_repo}#BUILD_SCM_HASH-PLACEHOLDER")) | . + """.format( + pkg_name = pkg_name, + snapshot_repo = snapshot_repo, + ), ) - return filter + + return " | ".join(individual_pkg_filters) # jq filter that replaces package.json dependencies with snapshot repos SNAPSHOT_REPO_JQ_FILTER = _generate_snapshot_repo_filter() From d1103797d59ea7ccf23e99861d1f7ebb503224e8 Mon Sep 17 00:00:00 2001 From: Jan Martin Date: Wed, 28 May 2025 06:32:50 -0700 Subject: [PATCH 7/7] release: cut the v19.2.14 release --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e52da31caa9a..3a371c02cc12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ + + +# 19.2.14 (2025-05-28) + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | +| [a3504fd45](https://github.com/angular/angular-cli/commit/a3504fd45602ec73ce1781e46e6c92b6042a51da) | fix | HMR requires AOT do not show HMR enabled when using JIT | +| [5ce9f96a4](https://github.com/angular/angular-cli/commit/5ce9f96a4efeb4efabe3c161ab596d049a1edd97) | fix | include full metadata for AOT unit-testing | + + + # 19.2.13 (2025-05-21) diff --git a/package.json b/package.json index 9e9b2386b607..4df432cf26da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "19.2.13", + "version": "19.2.14", "private": true, "description": "Software Development Kit for Angular", "keywords": [