From b2061e9d4776efe15d6eda6c01469020c5513174 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:54:42 -0400 Subject: [PATCH] perf(@angular/build): default chunk optimization to use Rolldown Now that Rolldown is stable, swap the default chunk optimizer from Rollup to Rolldown to utilize native compilation benefits and optimize heap memory usage. Rollup remains an optional peer dependency of @angular/build, allowing users to opt back into Rollup by setting the environment variable `NG_BUILD_CHUNKS_ROLLDOWN=false` if it is also installed in the project. --- packages/angular/build/package.json | 8 +++- .../builders/application/chunk-optimizer.ts | 11 ++++- .../build/src/utils/environment-options.ts | 2 +- pnpm-lock.yaml | 48 +++++++++---------- tests/e2e/tests/build/chunk-optimizer-env.ts | 14 +++--- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 1690da4c60c7..9ea09ddf6a8a 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -36,7 +36,7 @@ "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.4", "piscina": "5.2.0", - "rollup": "4.62.0", + "rolldown": "1.1.1", "sass": "1.101.0", "semver": "7.8.4", "source-map-support": "0.5.21", @@ -55,7 +55,7 @@ "less": "4.6.6", "ng-packagr": "22.1.0-next.2", "postcss": "8.5.15", - "rolldown": "1.1.1", + "rollup": "4.62.0", "rxjs": "7.8.2", "vitest": "4.1.9" }, @@ -73,6 +73,7 @@ "less": "^4.2.0", "ng-packagr": "0.0.0-NG-PACKAGR-PEER-DEP", "postcss": "^8.4.0", + "rollup": "^4.0.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", "tslib": "^2.3.0", "typescript": ">=6.0 <6.1", @@ -112,6 +113,9 @@ "postcss": { "optional": true }, + "rollup": { + "optional": true + }, "tailwindcss": { "optional": true }, diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 1586b48155ea..61ec816d46ba 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -19,7 +19,7 @@ import type { Message, Metafile } from 'esbuild'; import assert from 'node:assert'; -import { type Plugin, rollup } from 'rollup'; +import type { Plugin } from 'rollup'; import { BundleContextResult } from '../../tools/esbuild/bundler-context'; import { type BuildOutputFile, @@ -306,6 +306,15 @@ export async function optimizeChunks( }); optimizedOutput = result.output; } else { + let rollup; + try { + rollup = (await import('rollup')).rollup; + } catch { + throw new Error( + `Rollup is required when 'NG_BUILD_CHUNKS_ROLLDOWN' is set to false. ` + + `Please install 'rollup' manually (e.g. 'npm install rollup --save-dev') to use this fallback.`, + ); + } bundle = await rollup({ input: mainFile, plugins: plugins as Plugin[], diff --git a/packages/angular/build/src/utils/environment-options.ts b/packages/angular/build/src/utils/environment-options.ts index b6a486f8f528..1177563c04b5 100644 --- a/packages/angular/build/src/utils/environment-options.ts +++ b/packages/angular/build/src/utils/environment-options.ts @@ -106,7 +106,7 @@ export const allowMinify = debugOptimize.minify; * Allows using Rolldown for chunk optimization instead of Rollup. * This is useful for debugging and testing scenarios. */ -export const useRolldownChunks = parseTristate(process.env['NG_BUILD_CHUNKS_ROLLDOWN']) ?? false; +export const useRolldownChunks = parseTristate(process.env['NG_BUILD_CHUNKS_ROLLDOWN']) ?? true; /** * Some environments, like CircleCI which use Docker report a number of CPUs by the host and not the count of available. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f308063f470a..72ea10fe6333 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -382,9 +382,9 @@ importers: piscina: specifier: 5.2.0 version: 5.2.0 - rollup: - specifier: 4.62.0 - version: 4.62.0 + rolldown: + specifier: 1.1.1 + version: 1.1.1 sass: specifier: 1.101.0 version: 1.101.0 @@ -425,9 +425,9 @@ importers: postcss: specifier: 8.5.15 version: 8.5.15 - rolldown: - specifier: 1.1.1 - version: 1.1.1 + rollup: + specifier: 4.62.0 + version: 4.62.0 rxjs: specifier: 7.8.2 version: 7.8.2 @@ -8945,7 +8945,7 @@ snapshots: '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 @@ -8984,7 +8984,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.29.7 '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -9011,14 +9011,14 @@ snapshots: '@babel/helper-member-expression-to-functions@7.29.7': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.29.7': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -9028,7 +9028,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9043,7 +9043,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-wrap-function': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9052,13 +9052,13 @@ snapshots: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.29.7': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -9076,7 +9076,7 @@ snapshots: '@babel/helper-wrap-function@7.29.7': dependencies: '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -9094,7 +9094,7 @@ snapshots: dependencies: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9129,7 +9129,7 @@ snapshots: dependencies: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9163,7 +9163,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9210,7 +9210,7 @@ snapshots: '@babel/helper-globals': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9224,7 +9224,7 @@ snapshots: dependencies: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9281,7 +9281,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9327,7 +9327,7 @@ snapshots: '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9367,7 +9367,7 @@ snapshots: '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.29.7) - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -9590,7 +9590,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/types': 7.29.7 - '@babel/traverse@7.29.7': + '@babel/traverse@7.29.7(supports-color@10.2.2)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 diff --git a/tests/e2e/tests/build/chunk-optimizer-env.ts b/tests/e2e/tests/build/chunk-optimizer-env.ts index 5453b2e042d2..e5221811664e 100644 --- a/tests/e2e/tests/build/chunk-optimizer-env.ts +++ b/tests/e2e/tests/build/chunk-optimizer-env.ts @@ -86,20 +86,20 @@ export default async function () { `Expected build with threshold 4 and 3 chunks to NOT be optimized. Thresh 4: ${jsFiles3Thresh4.length}, Unoptimized: ${jsFiles3Unopt.length}`, ); - // Case 4: Opt into Rolldown - await installPackage('rolldown@1.0.0-rc.12'); + // Case 4: Opt back into Rollup (requires manual install since it's an optional peer dependency) + await installPackage('rollup@4.62.0'); try { await execWithEnv('ng', ['build', '--output-hashing=none'], { ...process.env, - NG_BUILD_CHUNKS_ROLLDOWN: '1', + NG_BUILD_CHUNKS_ROLLDOWN: 'false', NG_BUILD_OPTIMIZE_CHUNKS: 'true', }); - const filesRolldown = await readdir('dist/test-project/browser'); - const jsFilesRolldown = filesRolldown.filter((f) => f.endsWith('.js')); + const filesRollup = await readdir('dist/test-project/browser'); + const jsFilesRollup = filesRollup.filter((f) => f.endsWith('.js')); - assert.ok(jsFilesRolldown.length > 0, 'Expected Rolldown build to produce output files.'); + assert.ok(jsFilesRollup.length > 0, 'Expected Rollup build to produce output files.'); } finally { // Clean up - await uninstallPackage('rolldown'); + await uninstallPackage('rollup'); } }