angular-cli: [Bug] cli needs to be reloaded when a lazy loaded module is added in routes (FIXED)
Versions
Angular CLI: 1.7.1
Node: 8.9.4
OS: win32 x64
Angular: 5.2.6
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
@angular/cli: 1.7.1
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.3.2
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.1
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
typescript: 2.5.3
webpack: 3.11.0
Repro steps
- Run
ng serve
to start the application bundle - Create a new lazy module
- Modify the routes in the main module to do lazy load of the new module
Observed behavior
The lazy module cannot be loaded.
Stack
null: ERROR
null: Error: Uncaught (in promise): TypeError: __webpack_require__.e is not a function
message: "Uncaught (in promise): TypeError: __webpack_require__.e is not a function
TypeError: __webpack_require__.e is not a function
at webpackAsyncContext (eval at ./src/$$_lazy_route_resource lazy recursive (http://localhost:4200/main.bundle.js:13:1), <anonymous>:11:29)
at SystemJsNgModuleLoader.loadAndCompile (webpack-internal:///./node_modules/@angular/core/esm5/core.js:6774:82)
at SystemJsNgModuleLoader.load (webpack-internal:///./node_modules/@angular/core/esm5/core.js:6758:60)
at RouterConfigLoader.loadModuleFactory (webpack-internal:///./node_modules/@angular/router/esm5/router.js:4626:122)
at RouterConfigLoader.load (webpack-internal:///./node_modules/@angular/router/esm5/router.js:4606:52)
at MergeMapSubscriber.eval [as project] (webpack-internal:///./node_modules/@angular/router/esm5/router.js:2098:115)
at MergeMapSubscriber._tryNext (webpack-internal:///./node_modules/rxjs/_esm5/operators/mergeMap.js:133:27)
at MergeMapSubscriber._next (webpack-internal:///./node_modules/rxjs/_esm5/operators/mergeMap.js:123:18)
at MergeMapSubscriber.Subscriber.next (webpack-internal:///./node_modules/rxjs/_esm5/Subscriber.js:97:18)
at ScalarObservable._subscribe (webpack-internal:///./node_modules/rxjs/_esm5/observable/ScalarObservable.js:53:24)"
promise: ZoneAwarePromise {__zone_symbol__state: 0, __zone_symbol__value: TypeError: __webpack_require__.e is not a function…}
rejection: TypeError: __webpack_require__.e is not a function
stack: "Error: Uncaught (in promise): TypeError: __webpack_require__.e is not a function
TypeError: __webpack_require__.e is not a function
at webpackAsyncContext (eval at ./src/$$_lazy_route_resource lazy recursive (http://localhost:4200/main.bundle.js:13:1), <anonymous>:11:29)
at SystemJsNgModuleLoader.loadAndCompile (webpack-internal:///./node_modules/@angular/core/esm5/core.js:6774:82)
at SystemJsNgModuleLoader.load (webpack-internal:///./node_modules/@angular/core/esm5/core.js:6758:60)
at RouterConfigLoader.loadModuleFactory (webpack-internal:///./node_modules/@angular/router/esm5/router.js:4626:122)
at RouterConfigLoader.load (webpack-internal:///./node_modules/@angular/router/esm5/router.js:4606:52)
at MergeMapSubscriber.eval [as project] (webpack-internal:///./node_modules/@angular/router/esm5/router.js:2098:115)
at MergeMapSubscriber._tryNext (webpack-internal:///./node_modules/rxjs/_esm5/operators/mergeMap.js:133:27)
at MergeMapSubscriber._next (webpack-internal:///./node_modules/rxjs/_esm5/operators/mergeMap.js:123:18)
at MergeMapSubscriber.Subscriber.next (webpack-internal:///./node_modules/rxjs/_esm5/Subscriber.js:97:18)
at ScalarObservable._subscribe (webpack-internal:///./node_modules/rxjs/_esm5/observable/ScalarObservable.js:53:24)
at resolvePromise (webpack-internal:///./node_modules/zone.js/dist/zone.js:809:31)
at resolvePromise (webpack-internal:///./node_modules/zone.js/dist/zone.js:775:17)
at eval (webpack-internal:///./node_modules/zone.js/dist/zone.js:858:17)
at ZoneDelegate.invokeTask (webpack-internal:///./node_modules/zone.js/dist/zone.js:421:31)
at Object.onInvokeTask (webpack-internal:///./node_modules/@angular/core/esm5/core.js:4956:33)
at ZoneDelegate.invokeTask (webpack-internal:///./node_modules/zone.js/dist/zone.js:420:36)
at Zone.runTask (webpack-internal:///./node_modules/zone.js/dist/zone.js:188:47)
at drainMicroTaskQueue (webpack-internal:///./node_modules/zone.js/dist/zone.js:595:35)
at <anonymous>"
task: ZoneTask {_zone: Zone, runCount: 0, _zoneDelegates: null, …}
zone: Zone {_properties: Object, _parent: Zone, _name: "angular", …}
__proto__: Object {constructor: , name: "Error", message: "", …}
Desired behavior
The module should load without errors.
Mention any other details that might be useful (optional)
The real problem here, is that the cli does not catch up the module after the path is changed.
Current workarounds:
- Just reloading the cli makes the lazy loaded module to work again.
I haven’t try every recommended workaround, but some of them are clearly not a option if you really want those modules to be lazy loaded. This is especially true for solutions like:
import { LazyModule } from 'lazy-module';
Anything that makes the module to be bundle with the app, is not an acceptable workaround.
If you are having issues with a lazy loaded module, that is NOT about changing the route o creating another lazy loaded module into the path when the CLI is serving, then you should look a proper issue, or create a new one.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 93
- Comments: 128
Links to this issue
Commits related to this issue
- resolved bug with webpack https://github.com/angular/angular-cli/issues/9825 — committed to applantic/lisboa-ui by dkarski 6 years ago
- Fix lazyLoad feature https://github.com/angular/angular-cli/issues/9825 — committed to var-bin/ng-events by var-bin 6 years ago
I recomended change
{ path: 'user-panel', loadChildren: './user-panel/user-panel.module#UserPanelModule', },
to
{ path: 'user-panel', loadChildren: () => UserPanelModule, },
+1
Confirming that restarting ‘ng serve’ fixes the issue.
@michaeljota
Eager Loaded Routing Modules: The modules must be defined in the NgModule.imports before your router module.
Lazy Loaded Routing Modules: Remove the Lazy loaded modules from NgModule.imports
Either way, just make sure that your RoutingModule is last in the list of NgModule.imports E.g.: imports: [ BrowserModule, FormsModule, HeroesModule, AppRoutingModule ],
I had the same problem then stumbled across this article: https://angular.io/guide/router#module-import-order-matters.
Also look at the example (links at the top of the article) it shows different techniques to import Modules. E.g.: HerosModule is loaded eagerly CrisisCenterModule is loaded lazily
To solve the problem:
I upgraded @angular/cli to version 6.0.1 (not 100% sure if this made any difference) I moved the order of my imports around. (Move the *RoutingModule to the bottom of the list of imports) I also removed the lazy-loaded modules from the NgModule.imports property list Using an absolute path value for ‘loadChildren’ still works for me: loadChildren: ‘app/dashboard/dashboard.module#DashboardModule’
Same issue as 9488, see @kcir3v4M 's answer:
loadChildren’s value must be stored in an export const. Solves issues in both JIT and AOT and preserves lazy loading capabilities:
import { Routes } from ‘@angular/router’;
@RafaelFronteira That worked for me what @sluglit suggested:
The second one solved the problem for me.
And leave the lazy loading as it was: loadChildren: ‘app/dashboard/dashboard.module#DashboardModule’
And don’t use AOT in dev build, it’s just a workaround, but not a solution.
+1; I fixed my issue with
ng serve --aot
Update: This also happen when the lazy module throws an error in the first build.
@EcoFreak if you are using Lazy Loading you should never import the lazy module in your application, neither in AppModule, nor AppRoutingModule. You should only reference it by a string that points to the module class of that Lazy Module.
@michaeljota Even when downgrading the version, the problem remained in my case. The problem in my case was the order of imports of the main module. The
AppRoutingModule
defines the main routes and loads the remaining withloadChildren
. TheEquipmentsModule
defined extra routes and it’s imported byAppRoutingModule
. Before:(AppRoutingModule
was imported beforeEquipmentsModule
)After:
(AppRoutingModule
was imported afterEquipmentsModule
)Hope it helps!
Using full path: loadChildren: ‘app/registration/registration.module#RegistrationModule’
and ng serve --aot resolves this issue temporarily for me.
Same Problem with Angular 5.2.8 and CLI v1.7.3 Resolved that Issue by downgrading the CLI to v1.6.8. Alternate Workaround is using
ng serve --aot
suggested by @stanleyeosakul@karol-depka, that’s not a solution, it’s just a work around. The only real solution is to reload the CLI.
You only can use the string version for AoT. So if you aren’t using AoT for anything, sure, you can do this. But, still, it is recommended to use the string version.
Czesc, @dkarski 😃.
Is this
loadChildren: () => UserPanelModule
gonna do proper lazy loading? If so, whey is theloadChildren: './user-panel/user-panel.module#UserPanelModule'
so widespread (any advantages?)Same problem here using Angular CLI 1.7.2.
I’m using ng serve --aot to fixes and now worked.
@NapkinHD +1
For me, that’s not working either (even after restarting the CLI). It’s just working if you use ng serve --aot, as said by @stanleyeosakul
For some reason, the string version stopped working for me even after reloading the CLI. This happened after I updated to @angular/cli@1.7.3 from v1.6.5…
After downgrading to v1.6.5, the strings are working fine again (still needs reloading)
@speti43
This worked for me. loadChildren loads the module dynamically. No need to import the module in your app.module.
Cheers
Hey @dkarski, can you explain this solution? This worked for me, but I really did not understand how it works.
“{ path: ‘user-panel’, loadChildren: () => UserPanelModule, },”
I’m sorry if that’s a silly question …
+1
Either 1.7.3 + ng serve --aot or 1.6.8 + ng serve as temp fixes worked. I had to downgrade to 5.2.7 due to the issue 5.2.8 has with oidc-client.
+1
updated to @angular/cli@1.7.3 and restart
ng serve
, it works.I had this same issue but was not importing the lazy module in my
app.module.ts
nor did any of the other of the aforementioned suggested solutions resolve the error.I was lazy loading a module that was using a custom angular component library. This library worked fine in ng5 but as soon as we upgraded to ng6, this error started occurring.
The fix was COMPLETELY unrelated to the error message, in fact, the error was terribly misleading and useless! We had to start stripping modules from our app ONE BY ONE to finally see what was causing the error to get some clue as to what the actual root cause was.
As it turns out in our custom library we were importing a few modules from an
index.js
(bucket) file which for whatever reason Angular compiler still can’t figure out.Sounds like my case is rare given that most people were able to resolve their issue with the solutions listed above but I wanted to comment in hopes that this could help someone else.
As of angular/cli 6.0.5 I face an issue where : Either I get a webpack.e is not a function Either I get ./xxx.module can not be found
@sluglit solution worked.
I was importing lazy loaded modules in my AppModule. Removing them made it OK 😃
Thanks buddy.
I was facing same issue. I am using latest version of Angular-CLI. I was facing issue because I forgot to add pathMatch: ‘full’ to my lazy loading module’s route.
Hello guys, managed to fix my problem. I was importing the ChildModule with the routes after the AppRoutingModule in AppModule. Just by swapping the order everything worked nicely.
Hope it helps 😉
@dkarski 's solution worked for me. Import your module
import { Awesome } from './awesome/awesome.module';
and doloadChildren: () => Awesome
Restarting CLI solved issue
I’m runing @angular/cli v 1.7.3 and @Dercetech’s solution didn’t work. Any solutions?
For me I was making import module for my leazy loded module so that was wrong. I delete all this declarations but I had webpack error for my own created library something like webpack error e._ is not function ( I don’t remember the exactly the error). So i make ng --eject and all think work perfectly, but you must do npm run build to create production js code.
same issue here, even with using
AoT
@dkarski does that work with AoT?
Possible duplicate of #9488.
+1 same issue, restarting fixes it for me too