Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

target es2015 throw on circular dependency: Uncaught ReferenceError component is not defined #14247

Closed
elvisbegovic opened this issue Apr 23, 2019 · 6 comments

Comments

@elvisbegovic
Copy link
Contributor

🐞 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

@filipesilva
Copy link
Contributor

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.

@filipesilva
Copy link
Contributor

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.

@filipesilva
Copy link
Contributor

I've made a simple reproduction and bug report on Webpack: webpack/webpack#9060

This issue is now blocked on a fix there.

@filipesilva
Copy link
Contributor

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 angular/angular#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 angular/angular#30106, because it's not a CLI issue but a forwardRef design/usage issue.

@nhhockeyplayer
Copy link

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

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants