From 78622df003352bc62d3d74dfb75ae67f8304580c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:52:30 -0500 Subject: [PATCH] fix(@angular/build): enhance Vitest dependency externalization and pre-bundling This commit refactors the dependency handling for the Vitest runner to improve flexibility and correctness, especially for browser-based tests. The previously hardcoded list of external Angular packages has been removed. Instead, a new `externalPackages: true` option is passed to the application builder, allowing for more dynamic and configurable externalization of packages. This prevents packages from `node_modules` from being bundled into the test entry points. Note: For cases where a dependency should not be pre-bundled, the `optimizeDeps.exclude` option can be used within a custom runner configuration file. --- .../unit-test/runners/vitest/build-options.ts | 27 +++++-------------- .../unit-test/runners/vitest/executor.ts | 2 +- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 72152bd8c624..05aba1d9c261 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -14,21 +14,6 @@ import { NormalizedUnitTestBuilderOptions, injectTestingPolyfills } from '../../ import { findTests, getTestEntrypoints } from '../../test-discovery'; import { RunnerOptions } from '../api'; -/** - * A list of Angular related packages that should be marked as external. - * This allows Vite to pre-bundle them, improving performance. - */ -const ANGULAR_PACKAGES_TO_EXTERNALIZE = [ - '@angular/core', - '@angular/common', - '@angular/platform-browser', - '@angular/compiler', - '@angular/router', - '@angular/forms', - '@angular/animations', - 'rxjs', -]; - function createTestBedInitVirtualFile( providersFile: string | undefined, projectSourceRoot: string, @@ -110,11 +95,10 @@ export async function getVitestBuildOptions( }); entryPoints.set('init-testbed', 'angular:test-bed-init'); - const externalDependencies = new Set(['vitest']); - ANGULAR_PACKAGES_TO_EXTERNALIZE.forEach((dep) => externalDependencies.add(dep)); - + // The 'vitest' package is always external for testing purposes + const externalDependencies = ['vitest']; if (baseBuildOptions.externalDependencies) { - baseBuildOptions.externalDependencies.forEach((dep) => externalDependencies.add(dep)); + externalDependencies.push(...baseBuildOptions.externalDependencies); } const buildOptions: Partial = { @@ -135,7 +119,10 @@ export async function getVitestBuildOptions( outputHashing: adjustOutputHashing(baseBuildOptions.outputHashing), optimization: false, entryPoints, - externalDependencies: [...externalDependencies], + // Enable support for vitest browser prebundling. Excludes can be controlled with a runnerConfig + // and the `optimizeDeps.exclude` option. + externalPackages: true, + externalDependencies, }; buildOptions.polyfills = injectTestingPolyfills(buildOptions.polyfills); diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index 21cdd05c9359..8d09550b671a 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -231,7 +231,7 @@ export class VitestExecutor implements TestExecutor { coverage, projectName, projectSourceRoot: this.options.projectSourceRoot, - optimizeDepsInclude: this.externalMetadata.explicitBrowser, + optimizeDepsInclude: this.externalMetadata.implicitBrowser, reporters, setupFiles: testSetupFiles, projectPlugins,