diff --git a/packages/angular/build/src/builders/application/tests/behavior/rebuild-web-workers_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/rebuild-web-workers_spec.ts index 2fdad10f8d8d..886b8daa6b8d 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/rebuild-web-workers_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/rebuild-web-workers_spec.ts @@ -17,9 +17,10 @@ import { /** * A regular expression used to check if a built worker is correctly referenced in application code. + * Matches both hashed (worker-ABCD1234.js) and non-hashed (worker-worker.js) filenames. */ const REFERENCED_WORKER_REGEXP = - /new Worker\(new URL\("worker-[A-Z0-9]{8}\.js", import\.meta\.url\)/; + /new Worker\(new URL\("worker-.+\.js", import\.meta\.url\)/; describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { describe('Behavior: "Rebuilds when Web Worker files change"', () => { diff --git a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts index 135d5ff68165..15716c496714 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts @@ -11,9 +11,10 @@ import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setu /** * A regular expression used to check if a built worker is correctly referenced in application code. + * Matches both hashed (worker-ABCD1234.js) and non-hashed (worker-worker.js) filenames. */ const REFERENCED_WORKER_REGEXP = - /new Worker\(new URL\("worker-[A-Z0-9]{8}\.js", import\.meta\.url\)/; + /new Worker\(new URL\("worker-.+\.js", import\.meta\.url\)/; describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { describe('Behavior: "Bundles web worker files within application code"', () => { 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 1bcb8c40500a..f3e628dd22a2 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -286,8 +286,9 @@ export function createCompilerPlugin( ); // Return bundled worker file entry name to be used in the built output + // Match both hashed (worker-ABCD1234.js) and non-hashed (worker-.js) patterns const workerCodeFile = workerResult.outputFiles.find((file) => - /^worker-[A-Z0-9]{8}.[cm]?js$/.test(path.basename(file.path)), + /^worker-.+\.[cm]?js$/.test(path.basename(file.path)), ); assert(workerCodeFile, 'Web Worker bundled code file should always be present.'); const workerCodePath = path.relative( @@ -763,6 +764,13 @@ function bundleWebWorker( workerFile: string, ) { try { + // Use content hashing only when the parent build uses hashing in entry names. + // During dev server (ng serve), hashing is disabled and using it for workers + // causes the filename hash to change on every rebuild even when the worker + // content hasn't changed, breaking debugging sessions. + const parentEntryNames = build.initialOptions.entryNames ?? ''; + const useHashing = parentEntryNames.includes('[hash]'); + return build.esbuild.buildSync({ ...build.initialOptions, platform: 'browser', @@ -770,13 +778,18 @@ function bundleWebWorker( bundle: true, metafile: true, format: 'esm', - entryNames: 'worker-[hash]', + entryNames: useHashing ? 'worker-[hash]' : 'worker-[name]', entryPoints: [workerFile], sourcemap: pluginOptions.sourcemap, // Zone.js is not used in Web workers so no need to disable supported: undefined, // Plugins are not supported in sync esbuild calls plugins: undefined, + // Splitting is not needed for workers and can cause non-deterministic output + splitting: false, + // Footer may contain build-specific data (e.g., i18n hashes) that changes + // between rebuilds, causing unnecessary hash changes for workers + footer: undefined, }); } catch (error) { if (error && typeof error === 'object' && 'errors' in error && 'warnings' in error) {