Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular AOT Build: Internal error: unknown identifier undefined

My current Angular 2 project started before Angular supported the AOT feature. Now, I’m trying to get it to work. I'm receiving the following error and I've no clue what this means and where I can start to debug the issue:

ERROR in Error: Internal error: unknown identifier undefined
at Object.importExpr$$1 [as importExpr] (...\node_modules\@angular\compiler\bundles\compiler.umd.js:24211:23)
at tokenExpr (...\node_modules\@angular\compiler\bundles\compiler.umd.js:18577:39)
at providerDef (...\node_modules\@angular\compiler\bundles\compiler.umd.js:18480:20)
at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:18697:77
at Array.map (<anonymous>)
at NgModuleCompiler.compile (...\node_modules\@angular\compiler\bundles\compiler.umd.js:18697:44)
at AotCompiler._compileModule (...\node_modules\@angular\compiler\bundles\compiler.umd.js:24144:32)
at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:24056:66
at Array.forEach (<anonymous>)
at AotCompiler._compileImplFile (...\node_modules\@angular\compiler\bundles\compiler.umd.js:24056:19)
at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:23969:87
at Array.map (<anonymous>)
at AotCompiler.emitAllImpls (...\node_modules\@angular\compiler\bundles\compiler.umd.js:23969:52)
at CodeGenerator.emit (...\node_modules\@angular\compiler-cli\src\codegen.js:42:46)
at ...\node_modules\@angular\compiler-cli\src\codegen.js:33:61
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)

Dependencies

"@angular/animations": "^4.4.4",
"@angular/common": "^4.4.4",
"@angular/compiler": "^4.4.4",
"@angular/core": "^4.4.4",
"@angular/forms": "^4.4.4",
"@angular/platform-browser": "^4.4.4",
"@angular/platform-browser-dynamic": "^4.4.4",
"@angular/router": "^4.4.4",
"@ngx-translate/core": "^8.0.0",
"@ngx-translate/http-loader": "^2.0.0",
"core-js": "^2.5.1",
"font-awesome": "^4.7.0",
"primeng": "^4.2.1",
"quill": "^1.3.2",
"rxjs": "^5.4.3",
"zone.js": "^0.8.18"

Has anyone an idea why this error occurs?

like image 537
im4ever Avatar asked Oct 04 '17 13:10

im4ever


4 Answers

This part of the application caused the problem:

export function windowFactory(): any {
    return window;
}

providers: [{
    provide: Window,
    useFactory: windowFactory
}],

Github: This fails with AoT compiler in Angular CLI, because Window (the browser window) is an interface

like image 182
im4ever Avatar answered Nov 01 '22 18:11

im4ever


I faced this problem twice and search for it twice. I just put my answer here for myself in future :)

In my case, this problem occurs when I create 2 projects:

  • my-lib (which contains common components that can be built as a library and publish to npmjs)
  • my-app (main application)

This is what I did:

  1. In my-lib, there is one class:
@Injectable()
export class MyFirstService implement IMyFirstService {
}
  1. In my-app, I declare one module which consume the service above:
@NgModule({
    providers: [
        {
            provide: MY_FIRST_SERVICE_INJECTION_TOKEN,
            useClass: MyFirstService
        }
    ]
})
export class MyLittleModule {
}
  1. When I ran ng build --prod, the exception occurs.

This is how I fix:

  • Remove the Injectable() annotation from MyFirstService class. The exception has gone.

Finally, I just want to say to my future me:

  • Hey myself, if you read this, that means this is nth times you forgot about this painful issue. :v
like image 22
Redplane Avatar answered Oct 26 '22 12:10

Redplane


I faced the same error in my Angular 6 project.

when you run "ng build --prod", read the warning messages carefully. In which file it throws warning message (for eg:dataservice.ts).

then go to that (dataService.ts) file and remove the @Injectable.

@Injectable({
providedIn: 'root'
})

Then try to build again. It works for me.

like image 14
Karthikeyan Vellingiri Avatar answered Nov 01 '22 18:11

Karthikeyan Vellingiri


Had the same error when trying to provide Date for injection instead of an injection token.

So I did:

providers: [
    { provide: Date, useValue: new Date() }
  ]

and changed it to

providers: [
    { provide: NOW, useValue: new Date() },
  ],

where NOW is defined in the service that depends on it like this

export const NOW = new InjectionToken<Date>('now');

All documented on the Angular site.

like image 3
Sylvain Girard Avatar answered Nov 01 '22 17:11

Sylvain Girard