angular-cli: AOT broken when using loadChildren and a function : Replace modules import by modules factories ?
When I try to build my app with AOT since I’m using loadChildren
with a function it breaks (not at compilation but when running the app in the browser, complaining that r.create is not a function).
According to https://github.com/angular/angular/pull/13909 it seems that instead of having
we should rather import the factory (which is not available when coding, only when building) :
SamVerschueren asked if it could be replaced at build time (and opened an issue https://github.com/angular/angular/issues/14005 for that).
mhevery explained why it can’t be handled at build time by angular https://github.com/angular/angular/pull/13909#issuecomment-274650555.
I’m wondering if this can be done by angular-cli ? Or as soon as we use loadChildren
with a function (don’t want AOT or AOT is broken due to some other bugs for example) we have to manually do that ?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 17
- Comments: 32 (6 by maintainers)
Commits related to this issue
- fix(frontend): temporary use lazy loaded routes with aot (fixes #1) see: https://github.com/angular/angular-cli/issues/4192 — committed to kucharzyk/spring-kotlin-angular4 by kucharzyk 7 years ago
- Revert "improvement: do not lazy load the features module" This reverts commit caa0752d1db21ab6b13a45ca086aef2f23e0038d. Indeed, it's there are some problems with AOT and loadchildren. See this issu... — committed to maxime1992/angular-ngrx-starter by maxime1992 7 years ago
- fixed AOT-error with not lazy loaded modules Details: https://github.com/angular/angular-cli/issues/4192#issuecomment-274775116 — committed to geovistory/toolbox by joschne 6 years ago
I have been involved in attempts to get something like this working. The core team guys suggest it’s a tough nut to crack. It’s something I imagine the compiler-cli should be doing, changing the output of the compilation, it is compilation (translation) when you think about it.
For now, the workaround is to change the
loadChildren
assignment to astring
(lazy loading), but keep the function around to make the module get included in the same bundle instead of a separate one. Keeping theexport
ed function not just the import makes sure it doesn’t get tree shaked / minified.Like:
Check the
app-routing.module.ts
in my routing test project for a working example:https://github.com/meligy/routing-angular-cli
Specifically:
https://github.com/Meligy/routing-angular-cli/blob/deep-lazy-loading/src/app/app-routing.module.ts#L18
Function with loadChildren is still not working with AOT as of 9/6/2018, CLI version 6.1.1 - have to switch to lazy loaded path to enable AOT and bypass error of ‘Runtime compiler is not loaded’.
@steve3d it’s not an answer
i’m using ngtools/webpack and eagerly loaded modules
loadChildren: () => Module
won’t compile with AOT
i can import module.ngfactory only for AOT and so on, but it’s a mess and should be done by plugin
@robounohito , use
@angular/cli
it will save your life.Sorry what’s the solution?
@SamVerschueren
I think what @SamVerschueren mentioned is fully justified the need of loadChildren, and of course it should be AOT-compatible. An eager loaded routed feature module must be imported by another module so that the compiler learns about its components. In this way, feature-specified routes should define up to root path.
However, the feature module routing shouldn’t have knowledge from the ‘upper-stream’, which can
Please kindly reopen this issue.
I don’t think we’ll be able to correctly analyze in a static way what such a function would return.
Angular 7.2 still actual, no way to use AOT with
loadChildren = () => ModuleName
why the issue was closed? workaround from @Meligy is not working now. does anyone know how to use function with loadChildren and AOT (official way)?
To add to this conversation, a problem that I’m currently working on directly ties into this thread, and I can’t find a solution that works with AOT.
I have an application that fetches a configuration JSON from the backend at runtime, and uses that configuration to determine how to sort feature modules into a route hierarchy. I have a demo app here: https://github.com/colinjlacy/angular-dynamic-module-loading.
The problem is that I’m running analysis on module routes to add
loadChildren
properties where necessary, in order to create module interconnectivity. It works pretty well in dev mode, but once I pull AOT in, it fails when I call my analysis method, rewiring my routes according to the configuration: https://github.com/colinjlacy/angular-dynamic-module-loading/blob/master/src/app/genres/genre-routes.const.ts#L23.@filipesilva’s comment above is a bit disheartening:
So I want to follow up to be completely clear. Is there any way to run analysis functions on route declarations before sending them to
forRoot
without breaking AOT?EDIT: I’m following this guy as a reference: https://github.com/rangle/angular-2-aot-sandbox#func-in-routes-top and I’m not sure what the difference is. Even with exported functions defined in the same file it won’t work.
Error: Runtime compiler is not loaded
I still see, this is broken when you run the app with aot enabled {path: ‘helper’, loadChildren: () => HelperModule }
@filipesilva any idea if this would be supported anytime sooner ?
I’m wondering WHY do guys develop/add new features while having such an
important things
broken.@borislemke Because this way your feature module doesn’t need to know what path is being used to access it.
For example, suppose you have a
ContactModule
. You could define the routing like thisThis way your contact module itself defines that the URL is
/contact
. If you take this approach, you will define your routes like thisAnd in your app routing, you then load the contact module as child
This way, you contact module itself defines the routes where the contact and contact details are accessible, but your app itself defines what part comes in front of that. You contact module doesn’t need to know whether it is
/contact
or/mycontacts
.@C0ZEN lazy loading with loadChildren and functions is working for me in 8:
ref - https://blog.angularindepth.com/automatically-upgrade-lazy-loaded-angular-modules-for-ivy-e760872e6084
@steve3d AOT works well with lazy loading. The problem is when you want to load a module like that :
I’m attempting to use AOT with my app, which is quite large and lazy loads many modules.
I’m following the official AOT cookbook by using
ngc
androllup
. As was discussed in #11075, rollup does not even support lazy loading, so I’m looking for another way to compile my app.The issue is that
ngc
by itself does not actually build any of my lazy loaded modules because (I’m assuming) they are not directly imported with an import statement but instead specified as aloadChildren
string.At runtime, Angular correctly requests the Factory for the module instead of the Module itself, but the module doesn’t exist so the routing fails.
Is this the expected behavior of
ngc
? Is there no official way to compile the factories lazy loaded modules?Any news on this ? I’ve angular-cli 1.7.1 and have still the problem that I can’t run AOT builds when using loadChildren with factory method.
I can switch to lazy loading by path but the my startup performance will decrease. Would be very cool if you can fix this.
Thanks for the help @chriszrc. I used the syntax you recommended to me. I hope they will fix it to allow all syntaxes because this is causing so much struggle for nothing important…
but this doesn’t loadChildren: () => {reutrn import(‘./lazy/lazy.module’).then(m => m.LazyModule)}
@noamichael AOT and lazy loading should work just fine with the build system coming builtin with the CLI.
This issue is about non-lazy-loading, and as I mentioned in previous comment, a workaround is to trick AoT to think that it’s lazy-loading the module (because again, lazy-loading does work), while also having a dummy use of the module so that it still gets included in the main bundle.