@angular/build:unit-test (vitest): zoneless project fails to compile with "Top-level await is not available" when zone.js is a transitive dep

Đang mở
#33,324 3 bình luận 2 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
70/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
angular, typescript
Lĩnh vực
build-system, testing, tooling

Hướng nghiên cứu

Đọc @angular/build/src/builders/unit-test/runners/vitest/build-options.js, tập trung vào getZoneTestingStrategy() và module ảo angular:test-bed-init. Tái hiện lỗi bằng ng test trong một dự án zoneless, sau đó xác minh rằng strategy không phát ra mã khởi tạo zone và bundle unit-test biên dịch mà không gặp lỗi top-level-await.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

area: @angular/build gemini-triaged
Command

test

Is this a regression?
  • Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was

21.2.13

Description

Description

A zoneless Angular project (provideZonelessChangeDetection() in main.ts, no zone.js in the polyfills array) fails to compile its unit-test bundle with:
X [ERROR] Top-level await is not available in the configured target environment ("chrome145.0", "ios17.0", "safari17.0" + 2 overrides)

Root cause

In @angular/build/src/builders/unit-test/runners/vitest/build-options.js, getZoneTestingStrategy() decides what to emit into the virtual angular:test-bed-init module:

function getZoneTestingStrategy(buildOptions, projectSourceRoot) {
  if (buildOptions.polyfills?.includes('zone.js/testing')) return 'none';
  if (buildOptions.polyfills?.includes('zone.js'))         return 'static';
  try {
    projectRequire.resolve('zone.js');
    return 'dynamic';                       // ← falls through to here for zoneless projects
  } catch { return 'none'; }
}

For a zoneless app, polyfills correctly contains neither 'zone.js' nor 'zone.js/testing' — but zone.js is still resolvable on disk because it's an optional/peer dep of @angular/core (and several Angular test utilities like fakeAsync / tick still reference it). The strategy therefore resolves to 'dynamic', which emits this into the virtual module:

if (typeof Zone !== 'undefined') {
  // 'zone.js/testing' is used to initialize the ZoneJS testing environment.
  // It must be imported dynamically to avoid a static dependency on 'zone.js'.
  await import('zone.js/testing');
}

The runtime guard typeof Zone !== 'undefined' would correctly skip the import on a zoneless app, but esbuild evaluates the top-level await at compile time and rejects the syntax — regardless of whether the branch can actually run. The build fails before the guard ever executes.

Expected

A zoneless project should resolve the strategy to 'none' and emit no zone-init code. The unit-test bundle should compile cleanly.

Actual

Strategy resolves to 'dynamic' because zone.js is transitively installed. The virtual angular:test-bed-init module contains a top-level await, which esbuild rejects against the configured browser targets — even though those targets (Chrome 145, iOS 17, Safari 17) actually do support TLA. The compile-time rejection appears to be tied to the output format guarantees rather than the targets themselves, so tightening browserslist does not help.

Minimal Reproduction
  1. Generate a zoneless Angular 22 app (or upgrade an existing zoneless app).
  2. Confirm main.ts uses provideZonelessChangeDetection() and polyfills in angular.json does not include 'zone.js' or 'zone.js/testing'.
  3. Configure test to use @angular/build:unit-test with the vitest runner.
  4. Run ng test.
Exception or Error
Top-level await is not available
Your Environment
_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI       : 22.0.0
Angular           : 22.0.0
Node.js           : 24.16.0
Package Manager   : npm 11.13.0
Operating System  : win32 x64

┌────────────────────────────────────┬───────────────────┬───────────────────┐
│ Package                            │ Installed Version │ Requested Version │
├────────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular-devkit/build-angular      │ 22.0.0            │ 22.0.0            │
│ @angular/animations                │ 22.0.0            │ 22.0.0            │
│ @angular/build                     │ 22.0.0            │ 22.0.0            │
│ @angular/cdk                       │ 21.2.13           │ 21.2.13           │
│ @angular/cli                       │ 22.0.0            │ 22.0.0            │
│ @angular/common                    │ 22.0.0            │ 22.0.0            │
│ @angular/compiler                  │ 22.0.0            │ 22.0.0            │
│ @angular/compiler-cli              │ 22.0.0            │ 22.0.0            │
│ @angular/core                      │ 22.0.0            │ 22.0.0            │
│ @angular/forms                     │ 22.0.0            │ 22.0.0            │
│ @angular/google-maps               │ 21.2.13           │ 21.2.13           │
│ @angular/language-service          │ 22.0.0            │ 22.0.0            │
│ @angular/material                  │ 21.2.13           │ 21.2.13           │
│ @angular/material-date-fns-adapter │ 21.2.13           │ 21.2.13           │
│ @angular/platform-browser          │ 22.0.0            │ 22.0.0            │
│ @angular/platform-browser-dynamic  │ 22.0.0            │ 22.0.0            │
│ @angular/platform-server           │ 22.0.0            │ 22.0.0            │
│ @angular/router                    │ 22.0.0            │ 22.0.0            │
│ @angular/service-worker            │ 22.0.0            │ 22.0.0            │
│ @angular/ssr                       │ 22.0.0            │ 22.0.0            │
│ rxjs                               │ 7.8.2             │ 7.8.2             │
│ typescript                         │ 6.0.3             │ 6.0.3             │
│ vitest                             │ 4.1.7             │ 4.1.7             │
Anything else relevant?

No response

Ngôn ngữ chính
TypeScript
Star
27k
Fork
11.8k
Merge trung bình
16 giờ 21 phút
Pull request đã merge (30 ngày)
170

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của angular/angular-cli

Tất cả issue của angular/angular-cli

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.