Skip to content

Production build errors with type-only imports inside curlys and emitDecoratorMetadata on #23667

Closed
@jdforsythe

Description

@jdforsythe

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Yes, the previous version in which this bug was not present was: ~~12.x.x~~ (we were using tslint before, so I'm not really sure)

Description

A clear and concise description of the problem...

🔬 Minimal Reproduction

  1. Run ng new test-app
  2. Apply the below patch, which just imports OnChanges and SimpleChanges as type-only imports and adds emitDecoratorMetadata: true to tsconfig.json
  3. Run npx ng build (succeeds on development build)
  4. Run npx ng build --configuration production:
./src/app/app.component.ts - Error: Module build failed (from ./node_modules/@angular-devkit/build-angular/src/babel/webpack-loader.js):
SyntaxError: /Users/********/dev/temp/test-type-modifier/src/app/app.component.ts: Unexpected token, expected "," (1:14)

> 1 | import { type SimpleChanges, } from '@angular/core';
    |               ^
  2 | import * as i0 from "@angular/core";
  3 | import * as i1 from "@angular/common";
  4 | import * as i2 from "@angular/router";

Patch for minimum reproduction:

diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 0e696fa..36f0caf 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,10 +1,18 @@
-import { Component } from '@angular/core';
+import {
+  Component,
+  type OnChanges,
+  type SimpleChanges,
+} from '@angular/core';
 
 @Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.scss']
 })
-export class AppComponent {
+export class AppComponent implements OnChanges {
   title = 'test-type-modifier';
+
+  ngOnChanges(changes: SimpleChanges): void {
+    console.log(changes);
+  }
 }
diff --git a/tsconfig.json b/tsconfig.json
index ff06eae..b5be6c7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -14,6 +14,7 @@
     "declaration": false,
     "downlevelIteration": true,
     "experimentalDecorators": true,
+    "emitDecoratorMetadata": true,
     "moduleResolution": "node",
     "importHelpers": true,
     "target": "es2020",

🔥 Exception or Error




./src/app/app.component.ts - Error: Module build failed (from ./node_modules/@angular-devkit/build-angular/src/babel/webpack-loader.js):
SyntaxError: /Users/******/dev/temp/test-type-modifier/src/app/app.component.ts: Unexpected token, expected "," (1:14)

> 1 | import { type SimpleChanges, } from '@angular/core';
    |               ^
  2 | import * as i0 from "@angular/core";
  3 | import * as i1 from "@angular/common";
  4 | import * as i2 from "@angular/router";

🌍 Your Environment




     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 14.1.0
Node: 16.15.0
Package Manager: npm 8.5.5 
OS: darwin arm64

Angular: 14.1.0
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1401.0
@angular-devkit/build-angular   14.1.0
@angular-devkit/core            14.1.0
@angular-devkit/schematics      14.1.0
@schematics/angular             14.1.0
rxjs                            7.5.6
typescript                      4.7.4

Anything else relevant?

The problem only exists with:

  1. A type-only import which uses the type keyword inside the curly braces
  2. emitDecoratorMetadata is true in tsconfig.json
  3. Certain type imports
  4. Production build

Details:

This problem happens when you use type-only imports (using the type keyword) using the syntax introduced in TypeScript 4.5 where you use the type keyword inside the curly braces:

import { type SimpleChanges } from '@angular/core';

and does not happen when you use the type keyword outside the curly braces:

import type { SimpleChanges } from '@angular/core';

We enable emitDecoratorMetadata in tsconfig.json due to eslint rules which require type information (otherwise it thinks DI classes in the constructor should be type-only imports, for example, but they can't be)

This problem only happens with certain imports, and only with @angular imports. Known failing types:

  • import { type SimpleChanges } from '@angular/core'
  • import { type Route } from '@angular/router'

Known types that don't cause the error:

  • import { type Routes, type CanLoad } from '@angular/router'
  • import { type OnInit, type OnChanges } from '@angular/core';
  • import { type HttpHeaders, type HttpParams } from '@angular/common/http'
  • any other npm module, e.g. import { type Observable } from 'rxjs' - this works fine
  • any local module, e.g. import { type MyInterface } from './interface' - this works fine

This problem only happens on production builds. Regular development builds and ng serve work without issue.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions