Skip to content

feat(@angular/build): support runtime Zone.js detection in Vitest unit test runner#32492

Open
clydin wants to merge 1 commit intoangular:mainfrom
clydin:vitest/dynamic-zonejs-inclusion
Open

feat(@angular/build): support runtime Zone.js detection in Vitest unit test runner#32492
clydin wants to merge 1 commit intoangular:mainfrom
clydin:vitest/dynamic-zonejs-inclusion

Conversation

@clydin
Copy link
Member

@clydin clydin commented Feb 13, 2026

This commit improves how the Vitest unit test runner handles Zone.js and its testing polyfills. Previously, the inclusion of provideZoneChangeDetection and zone.js/testing was determined solely by a build-time check for zone.js in the polyfills array.

Now, the runner supports three strategies for zone.js/testing inclusion:

  • none: If zone.js is not installed in the project.
  • static: If zone.js is explicitly included in the polyfills build option.
  • dynamic: If zone.js is installed but not explicitly in polyfills. This uses a runtime check and dynamic import to load testing support if Zone is present.

Additionally, TestBed initialization now dynamically provides ZoneChangeDetection based on the runtime presence of Zone.js, better supporting zoneless applications and implicit Zone.js loading scenarios.

@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: @angular/build labels Feb 13, 2026
@clydin clydin force-pushed the vitest/dynamic-zonejs-inclusion branch from c83fb87 to 7e654f5 Compare February 14, 2026 03:13
…t test runner

This commit improves how the Vitest unit test runner handles Zone.js and its testing polyfills.
Previously, the inclusion of provideZoneChangeDetection and zone.js/testing was determined solely by a build-time check for zone.js in the polyfills array.

Now, the runner supports three strategies for zone.js/testing inclusion:
- none: If zone.js is not installed in the project.
- static: If zone.js is explicitly included in the polyfills build option.
- dynamic: If zone.js is installed but not explicitly in polyfills. This uses a runtime check and dynamic import to load testing support if Zone is present.

Additionally, TestBed initialization now dynamically provides ZoneChangeDetection based on the runtime presence of Zone.js, better supporting zoneless applications and implicit Zone.js loading scenarios.
@clydin clydin force-pushed the vitest/dynamic-zonejs-inclusion branch from 7e654f5 to 53cc74d Compare February 18, 2026 19:25
@clydin clydin marked this pull request as ready for review February 27, 2026 00:43
@clydin clydin added target: major This PR is targeted for the next major release action: review The PR is still awaiting reviews from at least one requested reviewer labels Feb 27, 2026
@clydin clydin requested a review from alan-agius4 February 27, 2026 00:43
Comment on lines +165 to +181
let zoneTestingStrategy: 'none' | 'static' | 'dynamic' = 'none';
let isZoneJsInstalled = false;
try {
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
projectRequire.resolve('zone.js');
isZoneJsInstalled = true;
} catch {}

if (isZoneJsInstalled) {
if (buildOptions.polyfills?.includes('zone.js/testing')) {
zoneTestingStrategy = 'none';
} else if (buildOptions.polyfills?.includes('zone.js')) {
zoneTestingStrategy = 'static';
} else {
zoneTestingStrategy = 'dynamic';
}
}
Copy link
Collaborator

@alan-agius4 alan-agius4 Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case zone.js is listed in the polyfills, it seems redundant to check if it's installed.

Suggested change
let zoneTestingStrategy: 'none' | 'static' | 'dynamic' = 'none';
let isZoneJsInstalled = false;
try {
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
projectRequire.resolve('zone.js');
isZoneJsInstalled = true;
} catch {}
if (isZoneJsInstalled) {
if (buildOptions.polyfills?.includes('zone.js/testing')) {
zoneTestingStrategy = 'none';
} else if (buildOptions.polyfills?.includes('zone.js')) {
zoneTestingStrategy = 'static';
} else {
zoneTestingStrategy = 'dynamic';
}
}
// Inject the zone.js testing polyfill if Zone.js is installed.
let zoneTestingStrategy: 'none' | 'static' | 'dynamic';
if (buildOptions.polyfills?.includes('zone.js/testing')) {
zoneTestingStrategy = 'none';
} else if (buildOptions.polyfills?.includes('zone.js')) {
zoneTestingStrategy = 'static';
} else {
try {
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
projectRequire.resolve('zone.js');
zoneTestingStrategy = 'dynamic';
} catch {
zoneTestingStrategy = 'none';
}
}

let zoneTestingStrategy: 'none' | 'static' | 'dynamic' = 'none';
let isZoneJsInstalled = false;
try {
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this by intention to use the projectSourceRoot instead of the workspaceRoot?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/build detected: feature PR contains a feature commit target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants