66 * found in the LICENSE file at https://angular.dev/license
77 */
88
9- import type { BuildOptions , PartialMessage } from 'esbuild' ;
9+ import type { BuildOptions , PartialMessage , Plugin } from 'esbuild' ;
1010import assert from 'node:assert' ;
1111import { createHash } from 'node:crypto' ;
1212import { extname , relative } from 'node:path' ;
@@ -45,6 +45,7 @@ export function createBrowserCodeBundleOptions(
4545) : BundlerOptionsFactory {
4646 return ( loadCache ) => {
4747 const { entryPoints, outputNames, polyfills } = options ;
48+ const zoneless = isZonelessApp ( polyfills ) ;
4849
4950 const pluginOptions = createCompilerPluginOptions (
5051 options ,
@@ -53,8 +54,6 @@ export function createBrowserCodeBundleOptions(
5354 templateUpdates ,
5455 ) ;
5556
56- const zoneless = isZonelessApp ( polyfills ) ;
57-
5857 const buildOptions : BuildOptions = {
5958 ...getEsBuildCommonOptions ( options ) ,
6059 platform : 'browser' ,
@@ -67,27 +66,25 @@ export function createBrowserCodeBundleOptions(
6766 entryPoints,
6867 target,
6968 supported : getFeatureSupport ( target , zoneless ) ,
70- plugins : [
71- createLoaderImportAttributePlugin ( ) ,
72- createWasmPlugin ( { allowAsync : zoneless , cache : loadCache } ) ,
73- createSourcemapIgnorelistPlugin ( ) ,
74- createAngularLocalizeInitWarningPlugin ( ) ,
75- createCompilerPlugin (
76- // JS/TS options
77- pluginOptions ,
78- angularCompilation ,
79- // Component stylesheet bundler
80- stylesheetBundler ,
81- ) ,
82- ] ,
8369 } ;
8470
71+ buildOptions . plugins ??= [ ] ;
72+ buildOptions . plugins . push (
73+ createWasmPlugin ( { allowAsync : zoneless , cache : loadCache } ) ,
74+ createAngularLocalizeInitWarningPlugin ( ) ,
75+ createCompilerPlugin (
76+ // JS/TS options
77+ pluginOptions ,
78+ angularCompilation ,
79+ // Component stylesheet bundler
80+ stylesheetBundler ,
81+ ) ,
82+ ) ;
83+
8584 if ( options . plugins ) {
86- buildOptions . plugins ? .push ( ...options . plugins ) ;
85+ buildOptions . plugins . push ( ...options . plugins ) ;
8786 }
8887
89- appendOptionsForExternalPackages ( options , buildOptions ) ;
90-
9188 return buildOptions ;
9289 } ;
9390}
@@ -275,22 +272,21 @@ export function createServerMainCodeBundleOptions(
275272 } ,
276273 entryPoints,
277274 supported : getFeatureSupport ( target , zoneless ) ,
278- plugins : [
279- createWasmPlugin ( { allowAsync : zoneless , cache : loadResultCache } ) ,
280- createSourcemapIgnorelistPlugin ( ) ,
281- createAngularLocalizeInitWarningPlugin ( ) ,
282- createCompilerPlugin (
283- // JS/TS options
284- pluginOptions ,
285- // Browser compilation handles the actual Angular code compilation
286- new NoopCompilation ( ) ,
287- // Component stylesheet bundler
288- stylesheetBundler ,
289- ) ,
290- ] ,
291275 } ;
292276
293277 buildOptions . plugins ??= [ ] ;
278+ buildOptions . plugins . push (
279+ createWasmPlugin ( { allowAsync : zoneless , cache : loadResultCache } ) ,
280+ createAngularLocalizeInitWarningPlugin ( ) ,
281+ createCompilerPlugin (
282+ // JS/TS options
283+ pluginOptions ,
284+ // Browser compilation handles the actual Angular code compilation
285+ new NoopCompilation ( ) ,
286+ // Component stylesheet bundler
287+ stylesheetBundler ,
288+ ) ,
289+ ) ;
294290
295291 if ( ! externalPackages ) {
296292 buildOptions . plugins . push ( createRxjsEsmResolutionPlugin ( ) ) ;
@@ -369,8 +365,6 @@ export function createServerMainCodeBundleOptions(
369365 buildOptions . plugins . push ( ...options . plugins ) ;
370366 }
371367
372- appendOptionsForExternalPackages ( options , buildOptions ) ;
373-
374368 return buildOptions ;
375369 } ;
376370}
@@ -418,21 +412,20 @@ export function createSsrEntryCodeBundleOptions(
418412 'server' : ssrEntryNamespace ,
419413 } ,
420414 supported : getFeatureSupport ( target , true ) ,
421- plugins : [
422- createSourcemapIgnorelistPlugin ( ) ,
423- createAngularLocalizeInitWarningPlugin ( ) ,
424- createCompilerPlugin (
425- // JS/TS options
426- pluginOptions ,
427- // Browser compilation handles the actual Angular code compilation
428- new NoopCompilation ( ) ,
429- // Component stylesheet bundler
430- stylesheetBundler ,
431- ) ,
432- ] ,
433415 } ;
434416
435417 buildOptions . plugins ??= [ ] ;
418+ buildOptions . plugins . push (
419+ createAngularLocalizeInitWarningPlugin ( ) ,
420+ createCompilerPlugin (
421+ // JS/TS options
422+ pluginOptions ,
423+ // Browser compilation handles the actual Angular code compilation
424+ new NoopCompilation ( ) ,
425+ // Component stylesheet bundler
426+ stylesheetBundler ,
427+ ) ,
428+ ) ;
436429
437430 if ( ! externalPackages ) {
438431 buildOptions . plugins . push ( createRxjsEsmResolutionPlugin ( ) ) ;
@@ -506,21 +499,19 @@ export function createSsrEntryCodeBundleOptions(
506499 buildOptions . plugins . push ( ...options . plugins ) ;
507500 }
508501
509- appendOptionsForExternalPackages ( options , buildOptions ) ;
510-
511502 return buildOptions ;
512503 } ;
513504}
514505
515506function getEsBuildServerCommonOptions ( options : NormalizedApplicationBuildOptions ) : BuildOptions {
516507 const isNodePlatform = options . ssrOptions ?. platform !== ExperimentalPlatform . Neutral ;
517508
518- const commonOptons = getEsBuildCommonOptions ( options ) ;
519- commonOptons . define ??= { } ;
520- commonOptons . define [ 'ngServerMode' ] = 'true' ;
509+ const commonOptions = getEsBuildCommonOptions ( options ) ;
510+ commonOptions . define ??= { } ;
511+ commonOptions . define [ 'ngServerMode' ] = 'true' ;
521512
522513 return {
523- ...commonOptons ,
514+ ...commonOptions ,
524515 platform : isNodePlatform ? 'node' : 'neutral' ,
525516 outExtension : { '.js' : '.mjs' } ,
526517 // Note: `es2015` is needed for RxJS v6. If not specified, `module` would
@@ -585,15 +576,41 @@ function getEsBuildCommonOptions(options: NormalizedApplicationBuildOptions): Bu
585576 conditions . push ( ...customConditions ) ;
586577 } else {
587578 // Include default conditions
588- conditions . push ( 'module' ) ;
589- conditions . push ( optimizationOptions . scripts ? 'production' : 'development' ) ;
579+ conditions . push ( 'module' , optimizationOptions . scripts ? 'production' : 'development' ) ;
580+ }
581+
582+ const plugins : Plugin [ ] = [
583+ createLoaderImportAttributePlugin ( ) ,
584+ createSourcemapIgnorelistPlugin ( ) ,
585+ ] ;
586+
587+ let packages : BuildOptions [ 'packages' ] = 'bundle' ;
588+ if ( options . externalPackages ) {
589+ // Package files affected by a customized loader should not be implicitly marked as external
590+ if (
591+ options . loaderExtensions ||
592+ options . plugins ||
593+ typeof options . externalPackages === 'object'
594+ ) {
595+ // Plugin must be added after custom plugins to ensure any added loader options are considered
596+ plugins . push (
597+ createExternalPackagesPlugin (
598+ options . externalPackages !== true ? options . externalPackages : undefined ,
599+ ) ,
600+ ) ;
601+
602+ packages = 'bundle' ;
603+ } else {
604+ // Safe to use the packages external option directly
605+ packages = 'external' ;
606+ }
590607 }
591608
592609 return {
593610 absWorkingDir : workspaceRoot ,
594611 format : 'esm' ,
595612 bundle : true ,
596- packages : 'bundle' ,
613+ packages,
597614 assetNames : outputNames . media ,
598615 conditions,
599616 resolveExtensions : [ '.ts' , '.tsx' , '.mjs' , '.js' , '.cjs' ] ,
@@ -626,6 +643,7 @@ function getEsBuildCommonOptions(options: NormalizedApplicationBuildOptions): Bu
626643 } ,
627644 loader : loaderExtensions ,
628645 footer,
646+ plugins,
629647 } ;
630648}
631649
@@ -636,11 +654,10 @@ function getEsBuildCommonPolyfillsOptions(
636654 loadResultCache : LoadResultCache | undefined ,
637655) : BuildOptions | undefined {
638656 const { jit, workspaceRoot, i18nOptions } = options ;
639- const buildOptions : BuildOptions = {
640- ...getEsBuildCommonOptions ( options ) ,
641- splitting : false ,
642- plugins : [ createSourcemapIgnorelistPlugin ( ) ] ,
643- } ;
657+
658+ const buildOptions = getEsBuildCommonOptions ( options ) ;
659+ buildOptions . splitting = false ;
660+ buildOptions . plugins ??= [ ] ;
644661
645662 let polyfills = options . polyfills ? [ ...options . polyfills ] : [ ] ;
646663
@@ -668,14 +685,14 @@ function getEsBuildCommonPolyfillsOptions(
668685 needLocaleDataPlugin = true ;
669686 }
670687 if ( needLocaleDataPlugin ) {
671- buildOptions . plugins ? .push ( createAngularLocaleDataPlugin ( ) ) ;
688+ buildOptions . plugins . push ( createAngularLocaleDataPlugin ( ) ) ;
672689 }
673690
674691 if ( polyfills . length === 0 ) {
675692 return ;
676693 }
677694
678- buildOptions . plugins ? .push (
695+ buildOptions . plugins . push (
679696 createVirtualModulePlugin ( {
680697 namespace,
681698 cache : loadResultCache ,
@@ -736,29 +753,3 @@ function entryFileToWorkspaceRelative(workspaceRoot: string, entryFile: string):
736753 . replace ( / \\ / g, '/' )
737754 ) ;
738755}
739-
740- function appendOptionsForExternalPackages (
741- options : NormalizedApplicationBuildOptions ,
742- buildOptions : BuildOptions ,
743- ) : void {
744- if ( ! options . externalPackages ) {
745- return ;
746- }
747-
748- buildOptions . plugins ??= [ ] ;
749-
750- // Package files affected by a customized loader should not be implicitly marked as external
751- if ( options . loaderExtensions || options . plugins || typeof options . externalPackages === 'object' ) {
752- // Plugin must be added after custom plugins to ensure any added loader options are considered
753- buildOptions . plugins . push (
754- createExternalPackagesPlugin (
755- options . externalPackages !== true ? options . externalPackages : undefined ,
756- ) ,
757- ) ;
758-
759- buildOptions . packages = undefined ;
760- } else {
761- // Safe to use the packages external option directly
762- buildOptions . packages = 'external' ;
763- }
764- }
0 commit comments