@@ -28,7 +28,7 @@ export function createBrowserCodeBundleOptions(
2828 target : string [ ] ,
2929 sourceFileCache ?: SourceFileCache ,
3030) : BuildOptions {
31- const { workspaceRoot , entryPoints, outputNames, jit } = options ;
31+ const { entryPoints, outputNames } = options ;
3232
3333 const { pluginOptions, styleOptions } = createCompilerPluginOptions (
3434 options ,
@@ -63,6 +63,50 @@ export function createBrowserCodeBundleOptions(
6363 buildOptions . packages = 'external' ;
6464 }
6565
66+ if ( options . plugins ) {
67+ buildOptions . plugins ?. push ( ...options . plugins ) ;
68+ }
69+
70+ return buildOptions ;
71+ }
72+
73+ export function createBrowserPolyfillBundleOptions (
74+ options : NormalizedApplicationBuildOptions ,
75+ target : string [ ] ,
76+ sourceFileCache ?: SourceFileCache ,
77+ ) : BuildOptions | undefined {
78+ const { workspaceRoot, outputNames, jit } = options ;
79+
80+ const { pluginOptions, styleOptions } = createCompilerPluginOptions (
81+ options ,
82+ target ,
83+ sourceFileCache ,
84+ ) ;
85+
86+ const buildOptions : BuildOptions = {
87+ ...getEsBuildCommonOptions ( options ) ,
88+ platform : 'browser' ,
89+ // Note: `es2015` is needed for RxJS v6. If not specified, `module` would
90+ // match and the ES5 distribution would be bundled and ends up breaking at
91+ // runtime with the RxJS testing library.
92+ // More details: https://github.com/angular/angular-cli/issues/25405.
93+ mainFields : [ 'es2020' , 'es2015' , 'browser' , 'module' , 'main' ] ,
94+ entryNames : outputNames . bundles ,
95+ target,
96+ splitting : false ,
97+ supported : getFeatureSupport ( target ) ,
98+ plugins : [
99+ createSourcemapIgnorelistPlugin ( ) ,
100+ createCompilerPlugin (
101+ // JS/TS options
102+ { ...pluginOptions , noopTypeScriptCompilation : true } ,
103+ // Component stylesheet options are unused for polyfills but required by the plugin
104+ styleOptions ,
105+ ) ,
106+ ] ,
107+ } ;
108+ buildOptions . plugins ??= [ ] ;
109+
66110 const polyfills = options . polyfills ? [ ...options . polyfills ] : [ ] ;
67111
68112 // Angular JIT mode requires the runtime compiler
@@ -103,71 +147,68 @@ export function createBrowserCodeBundleOptions(
103147 buildOptions . plugins ?. push ( createAngularLocaleDataPlugin ( ) ) ;
104148 }
105149
106- // Add polyfill entry point if polyfills are present
107- if ( polyfills . length ) {
108- const namespace = 'angular:polyfills' ;
109- buildOptions . entryPoints = {
110- ...buildOptions . entryPoints ,
111- 'polyfills' : namespace ,
112- } ;
150+ if ( polyfills . length === 0 ) {
151+ return ;
152+ }
113153
114- buildOptions . plugins ?. unshift (
115- createVirtualModulePlugin ( {
116- namespace,
117- loadContent : async ( _ , build ) => {
118- let hasLocalizePolyfill = false ;
119- const polyfillPaths = await Promise . all (
120- polyfills . map ( async ( path ) => {
121- hasLocalizePolyfill ||= path . startsWith ( '@angular/localize' ) ;
122-
123- if ( path . startsWith ( 'zone.js' ) || ! extname ( path ) ) {
124- return path ;
125- }
126-
127- const potentialPathRelative = './' + path ;
128- const result = await build . resolve ( potentialPathRelative , {
129- kind : 'import-statement' ,
130- resolveDir : workspaceRoot ,
131- } ) ;
132-
133- return result . path ? potentialPathRelative : path ;
134- } ) ,
135- ) ;
154+ // Add polyfill entry point if polyfills are present
155+ const namespace = 'angular:polyfills' ;
156+ buildOptions . entryPoints = {
157+ 'polyfills' : namespace ,
158+ } ;
136159
137- if ( ! options . i18nOptions . shouldInline && ! hasLocalizePolyfill ) {
138- // Cannot use `build.resolve` here since it does not allow overriding the external options
139- // and the actual presence of the `@angular/localize` package needs to be checked here.
140- const workspaceRequire = createRequire ( workspaceRoot + '/' ) ;
141- try {
142- workspaceRequire . resolve ( '@angular/localize' ) ;
143- // The resolve call above will throw if not found
144- polyfillPaths . push ( '@angular/localize/init' ) ;
145- } catch { }
146- }
147-
148- // Generate module contents with an import statement per defined polyfill
149- let contents = polyfillPaths
150- . map ( ( file ) => `import '${ file . replace ( / \\ / g, '/' ) } ';` )
151- . join ( '\n' ) ;
160+ buildOptions . plugins ?. unshift (
161+ createVirtualModulePlugin ( {
162+ namespace,
163+ loadContent : async ( _ , build ) => {
164+ let hasLocalizePolyfill = false ;
165+ const polyfillPaths = await Promise . all (
166+ polyfills . map ( async ( path ) => {
167+ hasLocalizePolyfill ||= path . startsWith ( '@angular/localize' ) ;
168+
169+ if ( path . startsWith ( 'zone.js' ) || ! extname ( path ) ) {
170+ return path ;
171+ }
172+
173+ const potentialPathRelative = './' + path ;
174+ const result = await build . resolve ( potentialPathRelative , {
175+ kind : 'import-statement' ,
176+ resolveDir : workspaceRoot ,
177+ } ) ;
178+
179+ return result . path ? potentialPathRelative : path ;
180+ } ) ,
181+ ) ;
182+
183+ if ( ! options . i18nOptions . shouldInline && ! hasLocalizePolyfill ) {
184+ // Cannot use `build.resolve` here since it does not allow overriding the external options
185+ // and the actual presence of the `@angular/localize` package needs to be checked here.
186+ const workspaceRequire = createRequire ( workspaceRoot + '/' ) ;
187+ try {
188+ workspaceRequire . resolve ( '@angular/localize' ) ;
189+ // The resolve call above will throw if not found
190+ polyfillPaths . push ( '@angular/localize/init' ) ;
191+ } catch { }
192+ }
152193
153- // If not inlining translations and source locale is defined, inject the locale specifier
154- if ( ! options . i18nOptions . shouldInline && options . i18nOptions . hasDefinedSourceLocale ) {
155- contents += `(globalThis.$localize ??= {}).locale = " ${ options . i18nOptions . sourceLocale } ";\n` ;
156- }
194+ // Generate module contents with an import statement per defined polyfill
195+ let contents = polyfillPaths
196+ . map ( ( file ) => `import ' ${ file . replace ( / \\ / g , '/' ) } ';` )
197+ . join ( '\n' ) ;
157198
158- return {
159- contents,
160- loader : 'js' ,
161- resolveDir : workspaceRoot ,
162- } ;
163- } ,
164- } ) ,
165- ) ;
166- }
199+ // If not inlining translations and source locale is defined, inject the locale specifier
200+ if ( ! options . i18nOptions . shouldInline && options . i18nOptions . hasDefinedSourceLocale ) {
201+ contents += `(globalThis.$localize ??= {}).locale = "${ options . i18nOptions . sourceLocale } ";\n` ;
202+ }
167203
168- if ( options . plugins ) {
169- buildOptions . plugins ?. push ( ...options . plugins ) ;
170- }
204+ return {
205+ contents,
206+ loader : 'js' ,
207+ resolveDir : workspaceRoot ,
208+ } ;
209+ } ,
210+ } ) ,
211+ ) ;
171212
172213 return buildOptions ;
173214}
0 commit comments