Angular-cli: target es2015 throw on circular dependency: Uncaught ReferenceError component is not defined

Created on 23 Apr 2019  路  6Comments  路  Source: angular/angular-cli

馃悶 Bug report

at runtime

Is this a regression?

Yes, was working (target:es5) before targetting to es2015 by default

Description

A clear and concise description of the problem...

馃敩 Minimal Reproduction

ng serve with tsconfig.json targetting es2015 throw :
Uncaught ReferenceError: ParentComponent is not defined

  1. In ParentComponent I have @ViewChild(ChildComponent)

  2. On ChildComponent's constructor I have
    constructor( @Inject(forwardRef(() => ParentComponent)) private parent:ParentComponent)

    Target es5 everything is ok!

    N.B. If you remove circular dependencies types
    or in constructor (:ParentComponent) or in viewchild (:ChildComponent)
    it works!

  1. Download ap.zip
  2. npm i && ng s
  3. open localhost:4200

馃敟 Exception or Error


child.component.ts:9 Uncaught ReferenceError: ParentComponent is not defined
    at Module.ParentComponent (child.component.ts:9)
    at Module../src/app/child.component.ts (child.component.ts:10)
    at __webpack_require__ (bootstrap:78)
    at Module../src/app/parent.component.ts (child.component.ts:9)
    at __webpack_require__ (bootstrap:78)
    at Module../src/app/app.module.ts (app.component.ts:24)
    at __webpack_require__ (bootstrap:78)
    at Module../src/main.ts (main.ts:1)
    at __webpack_require__ (bootstrap:78)
    at Object.2 (main.ts:12)

馃實 Your Environment


Angular CLI: 8.0.0-beta.16
Node: 11.12.0
OS: win32 x64
Angular: 8.0.0-beta.13
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.0-beta.16
@angular-devkit/build-angular     0.800.0-beta.16
@angular-devkit/build-optimizer   0.800.0-beta.16
@angular-devkit/build-webpack     0.800.0-beta.16
@angular-devkit/core              8.0.0-beta.16
@angular-devkit/schematics        8.0.0-beta.16
@angular/cli                      8.0.0-beta.16
@ngtools/webpack                  8.0.0-beta.16
@schematics/angular               8.0.0-beta.16
@schematics/update                0.800.0-beta.16
rxjs                              6.4.0
typescript                        3.4.4
webpack                           4.30.0

cc @filipesilva

devkibuild-angular high broken bufix

Most helpful comment

This issue was not caused by a Webpack bug but rather a problem between forwardRef and constructor types when targetting ES2015. I have detailed the problem in https://github.com/angular/angular/issues/30106.

A temporary workaround is to remove the type in the constructor parameter for ChildComponent:

// Instead of 
export class ChildComponent {
  constructor(@Inject(forwardRef(() => ParentComponent)) private parent: ParentComponent) { }
}

// Use
export class ChildComponent {
  private parent: ParentComponent;
  constructor(@Inject(forwardRef(() => ParentComponent)) parent) { 
    this.parent = parent as ParentComponent;
  }
}

I'm closing the issue here because it really should be addressed in the framework repository instead via https://github.com/angular/angular/issues/30106, because it's not a CLI issue but a forwardRef design/usage issue.

All 6 comments

Still trying to figure out what's happening here. Looked at it a bit today and added a github repro at https://github.com/filipesilva/es2015-forwardref.

I see a different error though:

child.component.ts:78 Uncaught ReferenceError: Cannot access 'ParentComponent' before initialization
    at Module.ParentComponent (child.component.ts:78)
    at Module../src/app/child.component.ts (child.component.ts:10)
    at __webpack_require__ (bootstrap:78)
    at Module../src/app/parent.component.ts (child.component.ts:78)
    at __webpack_require__ (bootstrap:78)
    at Module../src/app/app.module.ts (app.component.ts:27)
    at __webpack_require__ (bootstrap:78)
    at Module../src/main.ts (main.ts:1)
    at __webpack_require__ (bootstrap:78)
    at Object.2 (main.ts:12)

I tried checking if the usage of Angular's es2015 bundles had anything to do with it. We automatically use those when "target": "es2015", is the tsconfig. But I saw the same error with es5 and es2015 bundles.

It seems to be related to the app code itself, and the result when transpiled to es5 vs es2015.

Still not sure of why though.

It's interesting to see what happens when ng serve --source-map=false is used though.

The error shows up as:

main.js:9644 Uncaught ReferenceError: Cannot access 'ParentComponent' before initialization
    at Module.ParentComponent (main.js:9644)
    at Module../src/app/child.component.ts (main.js:9576)
    at __webpack_require__ (runtime.js:79)
    at Module../src/app/parent.component.ts (main.js:9647)
    at __webpack_require__ (runtime.js:79)
    at Module../src/app/app.module.ts (main.js:9520)
    at __webpack_require__ (runtime.js:79)
    at Module../src/main.ts (main.js:9766)
    at __webpack_require__ (runtime.js:79)
    at Object.2 (main.js:9790)

Where (main.js:9644) is

/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParentComponent", function() { return ParentComponent; });

Which belongs to the rest of the parent component code:

/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParentComponent", function() { return ParentComponent; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.js");
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm2015/core.js");
/* harmony import */ var _child_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./child.component */ "./src/app/child.component.ts");



let ParentComponent = class ParentComponent {
    constructor() {
        this.child = null;
    }
};
tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
    Object(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ViewChild"])(_child_component__WEBPACK_IMPORTED_MODULE_2__["ChildComponent"]),
    tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"]("design:type", _child_component__WEBPACK_IMPORTED_MODULE_2__["ChildComponent"])
], ParentComponent.prototype, "child", void 0);
ParentComponent = tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
    Object(_angular_core__WEBPACK_IMPORTED_MODULE_1__["Component"])({
        selector: 'app-parent',
        template: `<app-child #thisworks></app-child>`
    })
], ParentComponent);

So this is interesting. It errors out because ParentComponent is declared as

let ParentComponent = class ParentComponent {

But there's an export at the top using the let before it's declared. That kinda looks like a bug in Webpack.

I've made a simple reproduction and bug report on Webpack: https://github.com/webpack/webpack/issues/9060

This issue is now blocked on a fix there.

This issue was not caused by a Webpack bug but rather a problem between forwardRef and constructor types when targetting ES2015. I have detailed the problem in https://github.com/angular/angular/issues/30106.

A temporary workaround is to remove the type in the constructor parameter for ChildComponent:

// Instead of 
export class ChildComponent {
  constructor(@Inject(forwardRef(() => ParentComponent)) private parent: ParentComponent) { }
}

// Use
export class ChildComponent {
  private parent: ParentComponent;
  constructor(@Inject(forwardRef(() => ParentComponent)) parent) { 
    this.parent = parent as ParentComponent;
  }
}

I'm closing the issue here because it really should be addressed in the framework repository instead via https://github.com/angular/angular/issues/30106, because it's not a CLI issue but a forwardRef design/usage issue.

I have an NgRX stateful lazy loaded component feature module referenced in the router
Im receiving same exception in browser trying to make it 100% module oriented and bootstrapped on demand and with NgRX

it was previously modeled with barrels which I removed I think the module construct should be sufficient no?

same exception
seeing this happen...

Angular CLI: 8.1.2
Node: 12.3.1
OS: win32 x64
Angular: 8.1.2
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package Version

@angular-devkit/architect 0.801.2
@angular-devkit/build-angular 0.801.2
@angular-devkit/build-optimizer 0.801.2
@angular-devkit/build-webpack 0.801.2
@angular-devkit/core 8.1.2
@angular-devkit/schematics 8.1.2
@angular/cdk 8.1.1
@angular/flex-layout 7.0.0-beta.19
@angular/http 7.2.15
@angular/material 8.1.1
@ngtools/webpack 8.1.2
@schematics/angular 8.1.2
@schematics/update 0.801.2
rxjs 6.5.2
typescript 3.4.5
webpack 4.35.2

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MateenKadwaikar picture MateenKadwaikar  路  3Comments

jmurphzyo picture jmurphzyo  路  3Comments

naveedahmed1 picture naveedahmed1  路  3Comments

daBishMan picture daBishMan  路  3Comments

rajjejosefsson picture rajjejosefsson  路  3Comments