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": [
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 3087fb56a773..68eafb61d96f 100644
--- a/packages/angular/build/src/builders/dev-server/vite-server.ts
+++ b/packages/angular/build/src/builders/dev-server/vite-server.ts
@@ -160,18 +160,15 @@ 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' +
- '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.',
);
}
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,
};
};
}
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;
}
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()
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,