77 */
88
99import { BuilderContext } from '@angular-devkit/architect' ;
10- import assert from 'node:assert' ;
1110import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache' ;
1211import {
1312 createBrowserCodeBundleOptions ,
@@ -19,7 +18,6 @@ import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execu
1918import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker' ;
2019import { createGlobalScriptsBundleOptions } from '../../tools/esbuild/global-scripts' ;
2120import { createGlobalStylesBundleOptions } from '../../tools/esbuild/global-styles' ;
22- import { generateIndexHtml } from '../../tools/esbuild/index-html-generator' ;
2321import { extractLicenses } from '../../tools/esbuild/license-extractor' ;
2422import {
2523 calculateEstimatedTransferSizes ,
@@ -30,10 +28,8 @@ import {
3028} from '../../tools/esbuild/utils' ;
3129import { checkBudgets } from '../../utils/bundle-calculator' ;
3230import { copyAssets } from '../../utils/copy-assets' ;
33- import { maxWorkers } from '../../utils/environment-options' ;
34- import { prerenderPages } from '../../utils/server-rendering/prerender' ;
35- import { augmentAppWithServiceWorkerEsbuild } from '../../utils/service-worker' ;
3631import { getSupportedBrowsers } from '../../utils/supported-browsers' ;
32+ import { executePostBundleSteps } from './execute-post-bundle' ;
3733import { inlineI18n , loadActiveTranslations } from './i18n' ;
3834import { NormalizedApplicationBuildOptions } from './options' ;
3935
@@ -48,25 +44,23 @@ export async function executeBuild(
4844 const {
4945 projectRoot,
5046 workspaceRoot,
51- serviceWorker ,
47+ i18nOptions ,
5248 optimizationOptions,
5349 serverEntryPoint,
5450 assets,
55- indexHtmlOptions,
5651 cacheOptions,
5752 prerenderOptions,
5853 appShellOptions,
5954 ssrOptions,
60- verbose,
6155 } = options ;
6256
6357 const browsers = getSupportedBrowsers ( projectRoot , context . logger ) ;
6458 const target = transformSupportedBrowsersToTargets ( browsers ) ;
6559
6660 // Load active translations if inlining
6761 // TODO: Integrate into watch mode and only load changed translations
68- if ( options . i18nOptions . shouldInline ) {
69- await loadActiveTranslations ( context , options . i18nOptions ) ;
62+ if ( i18nOptions . shouldInline ) {
63+ await loadActiveTranslations ( context , i18nOptions ) ;
7064 }
7165
7266 // Reuse rebuild state or create new bundle contexts for code and global stylesheets
@@ -152,68 +146,6 @@ export async function executeBuild(
152146 await logMessages ( context , { warnings : messages } ) ;
153147 }
154148
155- /**
156- * Index HTML content without CSS inlining to be used for server rendering (AppShell, SSG and SSR).
157- *
158- * NOTE: we don't perform critical CSS inlining as this will be done during server rendering.
159- */
160- let indexContentOutputNoCssInlining : string | undefined ;
161-
162- // Generate index HTML file
163- // If localization is enabled, index generation is handled in the inlining process.
164- // NOTE: Localization with SSR is not currently supported.
165- if ( indexHtmlOptions && ! options . i18nOptions . shouldInline ) {
166- const { content, contentWithoutCriticalCssInlined, errors, warnings } = await generateIndexHtml (
167- initialFiles ,
168- executionResult . outputFiles ,
169- {
170- ...options ,
171- optimizationOptions,
172- } ,
173- // Set lang attribute to the defined source locale if present
174- options . i18nOptions . hasDefinedSourceLocale ? options . i18nOptions . sourceLocale : undefined ,
175- ) ;
176-
177- indexContentOutputNoCssInlining = contentWithoutCriticalCssInlined ;
178- printWarningsAndErrorsToConsole ( context , warnings , errors ) ;
179-
180- executionResult . addOutputFile ( indexHtmlOptions . output , content , BuildOutputFileType . Browser ) ;
181-
182- if ( ssrOptions ) {
183- executionResult . addOutputFile (
184- 'index.server.html' ,
185- contentWithoutCriticalCssInlined ,
186- BuildOutputFileType . Server ,
187- ) ;
188- }
189- }
190-
191- // Pre-render (SSG) and App-shell
192- // If localization is enabled, prerendering is handled in the inlining process.
193- if ( ( prerenderOptions || appShellOptions ) && ! options . i18nOptions . shouldInline ) {
194- assert (
195- indexContentOutputNoCssInlining ,
196- 'The "index" option is required when using the "ssg" or "appShell" options.' ,
197- ) ;
198-
199- const { output, warnings, errors } = await prerenderPages (
200- workspaceRoot ,
201- appShellOptions ,
202- prerenderOptions ,
203- executionResult . outputFiles ,
204- indexContentOutputNoCssInlining ,
205- optimizationOptions . styles . inlineCritical ,
206- maxWorkers ,
207- verbose ,
208- ) ;
209-
210- printWarningsAndErrorsToConsole ( context , warnings , errors ) ;
211-
212- for ( const [ path , content ] of Object . entries ( output ) ) {
213- executionResult . addOutputFile ( path , content , BuildOutputFileType . Browser ) ;
214- }
215- }
216-
217149 // Copy assets
218150 if ( assets ) {
219151 // The webpack copy assets helper is used with no base paths defined. This prevents the helper
@@ -230,30 +162,6 @@ export async function executeBuild(
230162 ) ;
231163 }
232164
233- // Augment the application with service worker support
234- // If localization is enabled, service worker is handled in the inlining process.
235- if ( serviceWorker && ! options . i18nOptions . shouldInline ) {
236- try {
237- const serviceWorkerResult = await augmentAppWithServiceWorkerEsbuild (
238- workspaceRoot ,
239- serviceWorker ,
240- options . baseHref || '/' ,
241- executionResult . outputFiles ,
242- executionResult . assetFiles ,
243- ) ;
244- executionResult . addOutputFile (
245- 'ngsw.json' ,
246- serviceWorkerResult . manifest ,
247- BuildOutputFileType . Browser ,
248- ) ;
249- executionResult . addAssets ( serviceWorkerResult . assetFiles ) ;
250- } catch ( error ) {
251- context . logger . error ( error instanceof Error ? error . message : `${ error } ` ) ;
252-
253- return executionResult ;
254- }
255- }
256-
257165 // Analyze files for bundle budget failures if present
258166 let budgetFailures ;
259167 if ( options . budgets ) {
@@ -274,17 +182,30 @@ export async function executeBuild(
274182 estimatedTransferSizes = await calculateEstimatedTransferSizes ( executionResult . outputFiles ) ;
275183 }
276184
277- logBuildStats ( context , metafile , initialFiles , budgetFailures , estimatedTransferSizes ) ;
278-
279- const buildTime = Number ( process . hrtime . bigint ( ) - startTime ) / 10 ** 9 ;
280- context . logger . info ( `Application bundle generation complete. [${ buildTime . toFixed ( 3 ) } seconds]` ) ;
281-
282185 // Perform i18n translation inlining if enabled
283- if ( options . i18nOptions . shouldInline ) {
186+ if ( i18nOptions . shouldInline ) {
284187 const { errors, warnings } = await inlineI18n ( options , executionResult , initialFiles ) ;
285188 printWarningsAndErrorsToConsole ( context , warnings , errors ) ;
189+ } else {
190+ const { errors, warnings, additionalAssets, additionalOutputFiles } =
191+ await executePostBundleSteps (
192+ options ,
193+ executionResult . outputFiles ,
194+ executionResult . assetFiles ,
195+ initialFiles ,
196+ // Set lang attribute to the defined source locale if present
197+ i18nOptions . hasDefinedSourceLocale ? i18nOptions . sourceLocale : undefined ,
198+ ) ;
199+
200+ executionResult . outputFiles . push ( ...additionalOutputFiles ) ;
201+ executionResult . assetFiles . push ( ...additionalAssets ) ;
202+ printWarningsAndErrorsToConsole ( context , warnings , errors ) ;
286203 }
287204
205+ logBuildStats ( context , metafile , initialFiles , budgetFailures , estimatedTransferSizes ) ;
206+
207+ const buildTime = Number ( process . hrtime . bigint ( ) - startTime ) / 10 ** 9 ;
208+ context . logger . info ( `Application bundle generation complete. [${ buildTime . toFixed ( 3 ) } seconds]` ) ;
288209 // Write metafile if stats option is enabled
289210 if ( options . stats ) {
290211 executionResult . addOutputFile (
0 commit comments