From d084c3f1591e55d4d7d28c01e7c93660fb55e51d Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 27 Sep 2023 18:15:53 +0200 Subject: [PATCH] feat(@angular-devkit/build-angular): support namedChunks option in application builder This adds the support of `namedChunks` for the new `application` builder. It generates output like the following: ``` Initial Chunk Files | Names | Raw Size | Estimated Transfer Size chunk-ACXUMF56.js | - | 94.14 kB | 28.25 kB main-3WP5KDHR.js | main | 71.95 kB | 18.31 kB polyfills-4UVFGIFL.js | polyfills | 32.85 kB | 10.68 kB chunk-2XJVAMHT.js | - | 449 bytes | 449 bytes styles-5INURTSO.css | styles | 0 bytes | 0 bytes | Initial Total | 199.38 kB | 57.68 kB Lazy Chunk Files | Names | Raw Size | Estimated Transfer Size about.component-2PJOS5PM.js | - | 401 bytes | 401 bytes home.component-25UHFOEY.js | - | 398 bytes | 398 bytes ``` This is really handy to get a glimpse at what a chunk is referring to and be able to analyze it (especially in applications with dozens of chunks). --- .../src/builders/application/options.ts | 2 + .../src/builders/application/schema.json | 5 ++ .../tests/options/named-chunks_spec.ts | 70 +++++++++++++++++++ .../builder-status-warnings.ts | 2 - .../tools/esbuild/application-code-bundle.ts | 2 +- 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/builders/application/tests/options/named-chunks_spec.ts diff --git a/packages/angular_devkit/build_angular/src/builders/application/options.ts b/packages/angular_devkit/build_angular/src/builders/application/options.ts index 0a8664ed5ee1..8d998a4b144f 100644 --- a/packages/angular_devkit/build_angular/src/builders/application/options.ts +++ b/packages/angular_devkit/build_angular/src/builders/application/options.ts @@ -237,6 +237,7 @@ export async function normalizeOptions( progress = true, externalPackages, deleteOutputPath, + namedChunks, } = options; // Return all the normalized options @@ -284,6 +285,7 @@ export async function normalizeOptions( indexHtmlOptions, tailwindConfiguration, i18nOptions, + namedChunks, }; } diff --git a/packages/angular_devkit/build_angular/src/builders/application/schema.json b/packages/angular_devkit/build_angular/src/builders/application/schema.json index d5f646d7de32..316db65e4f62 100644 --- a/packages/angular_devkit/build_angular/src/builders/application/schema.json +++ b/packages/angular_devkit/build_angular/src/builders/application/schema.json @@ -325,6 +325,11 @@ "description": "Extract all licenses in a separate file.", "default": true }, + "namedChunks": { + "type": "boolean", + "description": "Use file name for lazy loaded chunks.", + "default": false + }, "subresourceIntegrity": { "type": "boolean", "description": "Enables the use of subresource integrity validation.", diff --git a/packages/angular_devkit/build_angular/src/builders/application/tests/options/named-chunks_spec.ts b/packages/angular_devkit/build_angular/src/builders/application/tests/options/named-chunks_spec.ts new file mode 100644 index 000000000000..1aae98ccce9c --- /dev/null +++ b/packages/angular_devkit/build_angular/src/builders/application/tests/options/named-chunks_spec.ts @@ -0,0 +1,70 @@ +/** + * @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.io/license + */ + +import { buildApplication } from '../../index'; +import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; + +const MAIN_OUTPUT = 'dist/main.js'; +const NAMED_LAZY_OUTPUT = 'dist/lazy-module-7QZXF7K7.js'; +const UNNAMED_LAZY_OUTPUT = 'dist/chunk-OW5RYMPM.js'; + +describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { + describe('Option: "namedChunks"', () => { + beforeEach(async () => { + // Setup a lazy loaded chunk + await harness.writeFiles({ + 'src/lazy-module.ts': 'export const value = 42;', + 'src/main.ts': `import('./lazy-module');`, + }); + }); + + it('generates named files in output when true', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + namedChunks: true, + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness.expectFile(MAIN_OUTPUT).toExist(); + harness.expectFile(NAMED_LAZY_OUTPUT).toExist(); + harness.expectFile(UNNAMED_LAZY_OUTPUT).toNotExist(); + }); + + it('does not generate named files in output when false', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + namedChunks: false, + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness.expectFile(MAIN_OUTPUT).toExist(); + harness.expectFile(NAMED_LAZY_OUTPUT).toNotExist(); + harness.expectFile(UNNAMED_LAZY_OUTPUT).toExist(); + }); + + it('does not generates named files in output when not present', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness.expectFile(MAIN_OUTPUT).toExist(); + harness.expectFile(NAMED_LAZY_OUTPUT).toNotExist(); + harness.expectFile(UNNAMED_LAZY_OUTPUT).toExist(); + }); + }); +}); diff --git a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/builder-status-warnings.ts b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/builder-status-warnings.ts index b4b5f9d2ad62..3151c2bfbf81 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/builder-status-warnings.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/builder-status-warnings.ts @@ -19,7 +19,6 @@ const UNSUPPORTED_OPTIONS: Array = [ // 'commonChunk', // * Unused by builder and will be removed in a future release - 'namedChunks', 'vendorChunk', 'resourcesOutputPath', @@ -43,7 +42,6 @@ export function logBuilderStatusWarnings(options: BrowserBuilderOptions, context } if ( - unsupportedOption === 'namedChunks' || unsupportedOption === 'vendorChunk' || unsupportedOption === 'resourcesOutputPath' || unsupportedOption === 'deployUrl' diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts index f59cc498b983..dd9f3fe4c97b 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts @@ -315,7 +315,7 @@ function getEsBuildCommonOptions(options: NormalizedApplicationBuildOptions): Bu outExtension: outExtension ? { '.js': `.${outExtension}` } : undefined, sourcemap: sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true), splitting: true, - chunkNames: 'chunk-[hash]', + chunkNames: options.namedChunks ? '[name]-[hash]' : 'chunk-[hash]', tsconfig, external: externalDependencies, write: false,