angular: Router: AoT compilation fails when using a function with loadChildren
I’m submitting a … (check one with “x”)
[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
In order to enable lazy loading with Webpack 1, a custom NgModuleFactoryLoader
must be implemented to lazy load routes with loadChildren
. I’ve implemented an example loader here.
The custom load
function is being used here: https://github.com/brandonroberts/router-cli-aot/blob/master/src/app/app.routing.ts#L12-L25
When running ngc
over the provided repo, an error occurs:
Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 23:24 in the original .ts file), resolving symbol crisisCenterRoutes in /router-cli-aot/src/app/app.routing.ts, resolving symbol appRoutes in /router-cli-aot/src/app/app.routing.ts, resolving symbol routing in /router-cli-aot/src/app/app.routing.ts, resolving symbol AppModule in /router-cli-aot/src/app/app.module.ts, resolving symbol AppModule in /router-cli-aot/src/app/app.module.ts
I can comment out the loadChildren
line and ngc
completes successfully. If I uncomment the line after running ngc
and bundle with webpack, the app works as desired with lazy loading.
While https://github.com/angular/angular/pull/10705 adds support for using a callback function with loadChildren
such as loadChildren: () => System.import('lazy.module#LazyModule')
, this will cause AoT compilation to fail also with the same error.
Expected/desired behavior
Providing a callback function to loadChildren
does not cause AoT compilation to fail when used
with vanilla webpack or some other bundling tool.
Reproduction of the problem If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
What is the expected behavior?
What is the motivation / use case for changing the behavior?
Webpack 1/2 use a callback function to provide lazy loading through returning a promise.
Please tell us about your environment:
- Angular version: 2.0.0-rc.5
- Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
- Language: [all | TypeScript X.X | ES6/7 | ES5]
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 16
- Comments: 33 (10 by maintainers)
Links to this issue
Commits related to this issue
- fix(FlexLayoutModule): fix AOT compile issue with exported lambdas @see discussion on angular/angular#10789 Fixes #38. — committed to angular/flex-layout by ThomasBurleson 8 years ago
Calling functions or calling
new
is not supported in metadata when using AoT. This includes things like all the examples of above.The work-around is to introduce an exported function to call such as changing the first example to,
@Richard87’s example can be transformed into:
@lpenet’s example can be transformed into:
The reason for this limitation is that the AoT compiler needs to generate the code that calls the factory and there is no way to import a lambda from a module, you can only import an exported symbol.
@samiheikki you cannot call functions in metadata. your code should be statically analizable
@arandehkharghani The statement was intended to imply that there is a large set of code that works in both without modification. It was not intended to imply that all code the works with JIT will work with AoT without modification. Once you have code that works in AoT you can use that same code in JIT without modification; the inverse is not true.
Please start another issue as this is the same error arrived at in a different scenario.
It is confusing to have an issue whose title and initial description is about using the router with AoT turn into an issue discussing using the
UpgradeAdapter
with AoT. If this gets resolved, which issue was resolved?re chuckjaz’s suggestion I can say that the solution shouldn’t be updating the source code to get it to work with AOT, because this defeats the statement made by Angular team in link One of the benefits of the introduction of NgModules is that your code does not have to change based on whether you’re running in AoT or just in time (JiT) mode
do this: npm install typescript@next --save typescript@next===typescript 2.1.0 and then change your gulp file to this: let tsProject = ts.createProject(‘tsconfig.json’, { typescript: require(‘typescript’)}); and then update/create your tsconfig.json: { “compilerOptions”: { “target”: “es5”, “module”: “es2015”, “moduleResolution”: “node”, “sourceMap”: true, “emitDecoratorMetadata”: true, “experimentalDecorators”: true, “removeComments”: false, “noImplicitAny”: true, “suppressImplicitAnyIndexErrors”: true }, “files”: [ “app/app.module.ts”, “app/main.ts”, “./typings/index.d.ts” ], “angularCompilerOptions”: { “genDir”: “aot”, “skipMetadataEmit”: false } } and try running your ngc -p “path to the tsconfig”
The information recorded in annotations is translated into code by the AoT compiler and any references made in the annotations must be to simple exported symbols so having inline lambda or call is not supported because there is no way to extract the code in a way we can generate it correctly in another context.
The error you received is trying to communicate that you ran into one of the unsupported scenario. The key part of the error is
Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 12:28 in the original .ts file)
.Consider changing your code to something like:
Hi guys, I’m not sure if it’s related, but it’s I get the same error message:
It complains about my AuthConfig factory in my AppModule:
(Running on Win10 Angular2.0.0@RC5)
Hi,
I’m very new to Angular 2 development and I have been working through the Angular 2 Tour of Heroes tutorial replacing the angular2-in-memory-web-api with the Angular 2 MockBackend working in Visual Studio Code.
Once completed I found that running “ng serve” in the VS Code terminal resulted in the error noted above, i.e. “Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function…” webpack: failed to compile.
After reviewing your comments above I realised the problem was a lambda function used in the useFactory metadata for MocBackend. I was able to export the function and the error disappeared.
The odd thing was that when the problem first appeared, before I fixed it by exporting the function, I noticed something odd that I don’t understand. Once I ran “ng serve” in the VS code terminal and it failed, if I then opened and saved any .ts file, it kicked off an automatic build which then ran without error. Each successive automatic build after that ran without error. I understand that the typescript file watcher probably kicked off the build but why would those automatic builds succeed and a manual “ng serve” fail?
Cheers,
Rob C.
@chuckjaz export a function then reference this function name is ok in providers, routes, and decarations but not ok in @Component metadata, Do you have any good solution? thanks
My code as follow: … import { CustomAnimationsService } from ‘…/shared/services/custom-animations.service’; … export function customAnimations() { let animations = new CustomAnimationsService(); return animations.getAnimations(); } @Component({ selector: ‘app-test’, templateUrl: ‘./test.component.html’, styleUrls: [‘./test.component.css’], animations: customAnimations() }) export class TestComponent implements OnInit { … }
@sosnet you need the latest version of the
angular-in-memory-web-api
(the name has changed) that supports AoT.https://github.com/angular/in-memory-web-api
@chuckjaz I’ve created a bare bone project that reproduces the problem @marcalj and mysef are having.
All this project contains are, 1 ng2 component, 1 ng1 (ngUpgraded) component, and 1 module. Nothing more.
npm run tsc (works) npm run ngc (does not work)
ngc throws the error that @marcalj posted above
Attached sample project: ng2bad-build.zip
The problem is as @marcalj indicated, including the return value from upgradeNg1Component in the module declarations prevents ngc from compiling.
Also, should this bug be re-opened or we need to start a new bug?
Ok, cannot use
export const ng1Component = upgradeAdapter.upgradeNg1Component('ng1Component');
with ngc…Any suggestions? Thanks!
@chuckjaz What about using
forwardRef
?Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule …
Thanks!
EDITED: I have problems putting upgradeAdapter.upgradeNg1Component(‘…’) inside decorator.
Same issue for me. This «Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function» makes it impossible to configure a custom provider such as in the following snippet :
Or please indicate a workaround !
I have the same error in an ngUpgrade app with RC5. Not sure what is causing the error since the stack trace is not pointing to my code.