diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 4d72606640f7..5898c95401ee 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -312,6 +312,7 @@ export async function optimizeChunks( }); const result = await bundle.generate({ + compact: true, sourcemap, chunkFileNames: (chunkInfo) => `${chunkInfo.name.replace(/-[a-zA-Z0-9]{8}$/, '')}-[hash].js`, diff --git a/tests/e2e.bzl b/tests/e2e.bzl index 2c80375c580f..95f4d7a8c435 100644 --- a/tests/e2e.bzl +++ b/tests/e2e.bzl @@ -59,6 +59,7 @@ WEBPACK_IGNORE_TESTS = [ "tests/build/chunk-optimizer-lazy.js", "tests/build/chunk-optimizer-heuristic.js", "tests/build/chunk-optimizer-env.js", + "tests/build/chunk-optimizer-animations.js", ] def _to_glob(patterns): diff --git a/tests/e2e/tests/build/chunk-optimizer-animations.ts b/tests/e2e/tests/build/chunk-optimizer-animations.ts new file mode 100644 index 000000000000..158c0a2ec474 --- /dev/null +++ b/tests/e2e/tests/build/chunk-optimizer-animations.ts @@ -0,0 +1,74 @@ +import assert from 'node:assert/strict'; +import { readdir } from 'node:fs/promises'; +import { readFile, writeFile } from '../../utils/fs'; +import { installPackage } from '../../utils/packages'; +import { execWithEnv } from '../../utils/process'; + +export default async function () { + // Read @angular/core version from test project's package.json + const projectJson = JSON.parse(await readFile('package.json')); + const ngCoreVersion = + projectJson.dependencies?.['@angular/core'] ?? + projectJson.devDependencies?.['@angular/core'] ?? + 'latest'; + + // Install @angular/animations package with matching version + await installPackage(`@angular/animations@${ngCoreVersion}`); + + // Configure app.config.ts with provideAnimationsAsync + const originalConfig = await readFile('src/app/app.config.ts'); + await writeFile( + 'src/app/app.config.ts', + ` + import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; + ${originalConfig.replace(/providers:\s*\[/, 'providers: [provideAnimationsAsync(),')} + `, + ); + + const updatedConfig = await readFile('src/app/app.config.ts'); + assert.ok( + updatedConfig.includes('provideAnimationsAsync()'), + 'Expected src/app/app.config.ts to include provideAnimationsAsync().', + ); + + // Build with chunk optimization + await execWithEnv('ng', ['build', '--output-hashing=none'], { + ...process.env, + NG_BUILD_OPTIMIZE_CHUNKS: '1', + }); + const optimizedFiles = await readdir('dist/test-project/browser'); + const optimizedJsFiles = optimizedFiles.filter((f) => f.endsWith('.js')); + + // Read the optimized main.js file + const mainCode = await readFile('dist/test-project/browser/main.js'); + + // Check that optimized chunks still contain more than 1 javascript file + assert.ok( + optimizedJsFiles.length > 1, + `Expected more than one chunk, but found ${optimizedJsFiles.length}.`, + ); + + // Check that one of the lazy loaded chunks contains the animations package code + let foundAnimationsChunk = false; + for (const file of optimizedJsFiles) { + if (file === 'main.js') { + continue; + } + const code = await readFile(`dist/test-project/browser/${file}`); + if (code.includes('AnimationEngine')) { + foundAnimationsChunk = true; + break; + } + } + + assert.ok( + foundAnimationsChunk, + 'Expected to find AnimationEngine in one of the optimized lazy chunks.', + ); + + // The animations engine should not be bundled in main.js + assert.ok( + !mainCode.includes('AnimationEngine'), + 'Expected main.js not to contain AnimationEngine from @angular/animations/browser.', + ); +}