diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index 3e37271ca1e6..0b58423a418b 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -66,28 +66,23 @@ export class ParallelCompilation extends AngularCompilation { ); this.#webWorkerChannel?.port1.close(); - this.#webWorkerChannel = undefined; - let webWorkerSignal: Int32Array | undefined; - if (buildType !== 'library') { - // The web worker processing is a synchronous operation and uses shared memory combined with - // the Atomics API to block execution here until a response is received. - const webWorkerChannel = new MessageChannel(); - this.#webWorkerChannel = webWorkerChannel; - const signal = new Int32Array(new SharedArrayBuffer(4)); - webWorkerSignal = signal; - webWorkerChannel.port1.on('message', ({ workerFile, containingFile }) => { - try { - const workerCodeFile = hostOptions.processWebWorker(workerFile, containingFile); - webWorkerChannel.port1.postMessage({ workerCodeFile }); - } catch (error) { - webWorkerChannel.port1.postMessage({ error }); - } finally { - Atomics.store(signal, 0, 1); - Atomics.notify(signal, 0); - } - }); - } + // The web worker processing is a synchronous operation and uses shared memory combined with + // the Atomics API to block execution here until a response is received. + const webWorkerChannel = new MessageChannel(); + this.#webWorkerChannel = webWorkerChannel; + const webWorkerSignal = new Int32Array(new SharedArrayBuffer(4)); + webWorkerChannel.port1.on('message', ({ workerFile, containingFile }) => { + try { + const workerCodeFile = hostOptions.processWebWorker(workerFile, containingFile); + webWorkerChannel.port1.postMessage({ workerCodeFile }); + } catch (error) { + webWorkerChannel.port1.postMessage({ error }); + } finally { + Atomics.store(webWorkerSignal, 0, 1); + Atomics.notify(webWorkerSignal, 0); + } + }); let success = false; try { @@ -100,14 +95,12 @@ export class ParallelCompilation extends AngularCompilation { browserOnlyBuild: this.browserOnlyBuild, compilerOptionOverrides, stylesheetPort: stylesheetChannel.port2, - webWorkerPort: this.#webWorkerChannel?.port2, + webWorkerPort: webWorkerChannel.port2, webWorkerSignal, }, { name: 'initialize', - transferList: this.#webWorkerChannel - ? [stylesheetChannel.port2, this.#webWorkerChannel.port2] - : [stylesheetChannel.port2], + transferList: [stylesheetChannel.port2, webWorkerChannel.port2], }, ); success = true; diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation_spec.ts deleted file mode 100644 index 7157251e1ab9..000000000000 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation_spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { MessageChannel } from 'node:worker_threads'; -import { AotCompilation } from './aot-compilation'; -import { initialize } from './parallel-worker'; - -describe('parallel-worker', () => { - it('uses incrementing numeric request IDs for transformStylesheet and handles omitted webWorkerPort in library builds', async () => { - const receivedRequestIds: unknown[] = []; - let workerResult: string | undefined; - - spyOn(AotCompilation.prototype, 'initialize').and.callFake(async (_tsconfig, hostOptions) => { - const [style1, style2] = await Promise.all([ - hostOptions.transformStylesheet('body {}', '/src/a.ts', '/src/a.css', 0, 'CompA'), - hostOptions.transformStylesheet('div {}', '/src/b.ts', '/src/b.css', 1, 'CompB'), - ]); - expect(style1).toBe('transformed:body {}'); - expect(style2).toBe('transformed:div {}'); - - workerResult = hostOptions.processWebWorker('./my.worker', '/src/a.ts'); - - return { - compilerOptions: {}, - referencedFiles: ['/src/a.ts'], - }; - }); - - const stylesheetChannel = new MessageChannel(); - stylesheetChannel.port1.on('message', ({ requestId, data }) => { - receivedRequestIds.push(requestId); - stylesheetChannel.port1.postMessage({ - requestId, - value: `transformed:${data}`, - }); - }); - - try { - const result = await initialize({ - jit: false, - browserOnlyBuild: false, - tsconfig: '/src/tsconfig.lib.json', - buildType: 'library', - stylesheetPort: stylesheetChannel.port2, - }); - - expect(receivedRequestIds).toEqual([1, 2]); - expect(workerResult).toBe('./my.worker'); - expect(result.referencedFiles).toEqual(['/src/a.ts']); - } finally { - stylesheetChannel.port1.close(); - } - }); -}); diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index 56cbdd612d68..5bf293da727d 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -8,6 +8,7 @@ import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; +import { randomUUID } from 'node:crypto'; import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; import { initializeHash } from '../../../utils/hash'; import { getAndClearCumulativeDurations } from '../../../utils/profiling'; @@ -27,8 +28,8 @@ export interface InitRequest { fileReplacements?: Record; compilerOptionOverrides?: CompilerOptionOverrides; stylesheetPort: MessagePort; - webWorkerPort?: MessagePort; - webWorkerSignal?: Int32Array; + webWorkerPort: MessagePort; + webWorkerSignal: Int32Array; } let compilation: AngularCompilation | undefined; @@ -50,9 +51,8 @@ export async function initialize(request: InitRequest): Promise void, (reason: Error) => void] >(); request.stylesheetPort.on('message', ({ requestId, value, error }) => { @@ -80,7 +80,7 @@ export async function initialize(request: InitRequest): Promise((resolve, reject) => stylesheetRequests.set(requestId, [resolve, reject]), ); @@ -97,10 +97,6 @@ export async function initialize(request: InitRequest): Promise