Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Oxc linker rejects parenthesized resolveMetadata return in deferred class metadata

Đã đóng Phù hợp với người mới
#34,129 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

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

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
76/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, tooling

Hướng nghiên cứu

Chạy bản tái hiện tối thiểu bằng npm run build và so sánh với npm run build:babel. Bắt đầu từ OxcAstHost.parseReturnValue() và PartialClassMetadataAsyncLinkerVersion1.linkPartialDeclaration, sử dụng fixture/index.mjs để so sánh arrow body ngắn gọn được đặt trong dấu ngoặc với dạng block-body đang hoạt động. Được xem là hoàn tất khi cả hai dạng callback tương đương đều được liên kết thành công bằng Oxc linker mặc định.

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

build

Description

With @angular/build@22.2.0-rc.0, the default Oxc linker fails to process a partial ɵɵngDeclareClassMetadataAsync declaration whose resolveMetadata callback returns a parenthesized object literal. The same input builds successfully with NG_BUILD_BABEL_LINKER=1.

The fixture below is hand-reduced from Angular 22.1.7 output for a library component containing @defer; it removes the original application's dependencies and UI. It exercises the real ng build pipeline, not a mock linker.

Is this a regression?

The original library artifact passes our stable Angular 20/21/22 CI matrix and fails the 22.2.0-rc.0 canary. I have not bisected the first affected version using this reduced reproduction.

Minimal Reproduction

Create an empty directory with the following files, then run:

npm install
npm run build
# Fails: Unsupported syntax, expected an object literal.

npm run build:babel
# Succeeds: same input, Babel linker.

The build cache is disabled in this reproduction.

Complete minimal project files

package.json

{
  "name": "angular-oxc-deferred-metadata-repro",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "ng build",
    "build:babel": "NG_BUILD_BABEL_LINKER=1 ng build"
  },
  "dependencies": {
    "@angular/core": "22.2.0-rc.0",
    "@angular/common": "22.2.0-rc.0",
    "@angular/compiler": "22.2.0-rc.0",
    "@angular/platform-browser": "22.2.0-rc.0",
    "rxjs": "7.8.2",
    "tslib": "2.8.1",
    "deferred-metadata-fixture": "file:./fixture"
  },
  "devDependencies": {
    "@angular/build": "22.2.0-rc.0",
    "@angular/cli": "22.2.0-rc.0",
    "@angular/compiler-cli": "22.2.0-rc.0",
    "typescript": "6.0.3"
  }
}

angular.json

{
  "version": 1,
  "cli": {
    "cache": {
      "enabled": false
    },
    "analytics": false
  },
  "projects": {
    "repro": {
      "projectType": "application",
      "root": "",
      "architect": {
        "build": {
          "builder": "@angular/build:application",
          "options": {
            "browser": "src/main.ts",
            "tsConfig": "tsconfig.json",
            "index": "src/index.html",
            "outputPath": "dist",
            "optimization": false
          }
        }
      }
    }
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "preserve",
    "moduleResolution": "bundler",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "strict": true,
    "lib": [
      "ES2022",
      "DOM"
    ]
  },
  "files": [
    "src/main.ts"
  ]
}

src/main.ts

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { DeferredFixture } from 'deferred-metadata-fixture';

@Component({ selector: 'app-root', template: 'Linker reproduction' })
class App {
  constructor() { console.log(DeferredFixture); }
}

bootstrapApplication(App).catch(console.error);

src/index.html

<!doctype html><html><head><title>Reproduction</title><base href="/"></head><body><app-root></app-root></body></html>

fixture/package.json

{
  "name": "deferred-metadata-fixture",
  "version": "1.0.0",
  "type": "module",
  "main": "index.mjs",
  "types": "index.d.ts"
}

fixture/index.mjs

import * as i0 from '@angular/core';

export class DeferredFixture {}

// Reduced from Angular 22.1.7 output for a component containing @defer.
// The parenthesized object returned by resolveMetadata triggers the failure.
i0.ɵɵngDeclareClassMetadataAsync({
  minVersion: '18.0.0',
  version: '22.1.7',
  ngImport: i0,
  type: DeferredFixture,
  resolveDeferredDeps: () => [],
  resolveMetadata: () => ({
    decorators: [],
    ctorParameters: null,
    propDecorators: null,
  }),
});

fixture/index.d.ts

export declare class DeferredFixture {}

Additional control: in fixture/index.mjs, replace resolveMetadata: () => ({ ... }) with the equivalent resolveMetadata: () => { return { ... }; }. Running npm run build then succeeds with the default Oxc linker. This was verified locally, in addition to the Babel comparison.

Expected: both equivalent callback forms link successfully with the default builder.

Actual: only the parenthesized expression form fails.

Exception or Error
Unsupported syntax, expected an object literal. [plugin angular-compiler]

at OxcAstHost.parseObjectLiteral (.../oxc-ast-host.js:95:19)
at _AstObject.parse
at _AstValue.getObject
at PartialClassMetadataAsyncLinkerVersion1.linkPartialDeclaration
at FileLinker.linkPartialDeclaration
at OxcLinker.linkCallExpression
Your Environment
Angular CLI: 22.2.0-rc.0
Angular: 22.2.0-rc.0
@angular/build: 22.2.0-rc.0
@angular/compiler-cli: 22.2.0-rc.0
TypeScript: 6.0.3
Node.js: 26.5.0
npm: 11.17.0
OS: darwin arm64

The original failure also occurs on Ubuntu CI with Node 24.17.0.

Anything else relevant?

The parser represents the concise arrow body as ParenthesizedExpression(ObjectExpression). OxcAstHost.parseReturnValue() returns the body unchanged; the subsequent object-literal check only accepts ObjectExpression. Unwrapping the parenthesized return expression before interpreting the metadata appears to be the required fix.

Related PR #33769 addresses parentheses when emitting JavaScript, whereas this failure occurs when reading the callback's return value.

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

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.