From efe3bda483b5776b2097ab68ea0b134d13d1a589 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:08:27 -0500 Subject: [PATCH] fix(@angular-devkit/build-angular): ensure external dependencies are used by Web Worker bundling When processing a Web Worker reference in application code, the Web Worker entry point is bundled in a separate action. The external dependencies configuration was previously not passed on to this action which caused the Web Worker bundling to attempt to bundle any configured external dependencies. This could lead to build errors if the dependency does not exist within the project. --- .../options/external-dependencies_spec.ts | 35 +++++++++++++++++++ .../tools/esbuild/angular/compiler-plugin.ts | 15 ++++---- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/application/tests/options/external-dependencies_spec.ts b/packages/angular_devkit/build_angular/src/builders/application/tests/options/external-dependencies_spec.ts index 3f3d4e6740bd..13707e96ca3f 100644 --- a/packages/angular_devkit/build_angular/src/builders/application/tests/options/external-dependencies_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/application/tests/options/external-dependencies_spec.ts @@ -38,5 +38,40 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .expectFile('dist/browser/main.js') .content.not.toMatch(/from ['"]@angular\/common['"]/); }); + + it('should externalize the listed depedencies in Web Workers when option is set', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + externalDependencies: ['path'], + }); + + // The `path` Node.js builtin is used to cause a failure if not externalized + const workerCodeFile = ` + import path from "path"; + console.log(path); + `; + + // Create a worker file + await harness.writeFile('src/app/worker.ts', workerCodeFile); + + // Create app component that uses the directive + await harness.writeFile( + 'src/app/app.component.ts', + ` + import { Component } from '@angular/core' + @Component({ + selector: 'app-root', + template: '

Worker Test

', + }) + export class AppComponent { + worker = new Worker(new URL('./worker', import.meta.url), { type: 'module' }); + } + `, + ); + + const { result } = await harness.executeOnce(); + // If not externalized, build will fail with a Node.js platform builtin error + expect(result?.success).toBeTrue(); + }); }); }); diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts index 936cd3537b87..75cf2124d10a 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts @@ -528,22 +528,19 @@ function bundleWebWorker( ) { try { return build.esbuild.buildSync({ + ...build.initialOptions, platform: 'browser', write: false, bundle: true, metafile: true, format: 'esm', - mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'], - logLevel: 'silent', - sourcemap: pluginOptions.sourcemap, entryNames: 'worker-[hash]', entryPoints: [workerFile], - absWorkingDir: build.initialOptions.absWorkingDir, - outdir: build.initialOptions.outdir, - minifyIdentifiers: build.initialOptions.minifyIdentifiers, - minifySyntax: build.initialOptions.minifySyntax, - minifyWhitespace: build.initialOptions.minifyWhitespace, - target: build.initialOptions.target, + 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, }); } catch (error) { if (error && typeof error === 'object' && 'errors' in error && 'warnings' in error) {