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

Lazy loading in Angular2 RC7 and angular-cli webpack #2112

Closed
stephenwilson1984 opened this issue Sep 14, 2016 · 40 comments
Closed

Lazy loading in Angular2 RC7 and angular-cli webpack #2112

stephenwilson1984 opened this issue Sep 14, 2016 · 40 comments
Labels
needs: more info Reporter must clarify the issue

Comments

@stephenwilson1984
Copy link

stephenwilson1984 commented Sep 14, 2016

Please provide us with the following information:

  1. OS? Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)
    Windows 7

  2. Versions. Please run ng --version. If there's nothing outputted, please run
    in a Terminal: node --version and paste the result here:
    angular-cli: 1.0.0-beta.11-webpack.9-4
    node: 6.5.0
    os: win32 x64

  3. Repro steps. Was this an app that wasn't created using the CLI? What change did you
    do on your code? etc.
    Created a boilerplate app using "ng new" then added a basic home module manually.

  4. The log given by the failure. Normally this include a stack trace and some
    more information.
    error_handler.js:45EXCEPTION: Uncaught (in promise): Error: Cannot find module '/app/home.module'.ErrorHandler.handleError @ error_handler.js:45next @ application_ref.js:273schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:64ZoneDelegate.handleError @ zone.js:196Zone.runGuarded @ zone.js:102_loop_1 @ zone.js:368drainMicroTaskQueue @ zone.js:375
    error_handler.js:50ORIGINAL STACKTRACE:ErrorHandler.handleError @ error_handler.js:50next @ application_ref.js:273schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:64ZoneDelegate.handleError @ zone.js:196Zone.runGuarded @ zone.js:102_loop_1 @ zone.js:368drainMicroTaskQueue @ zone.js:375
    error_handler.js:51Error: Uncaught (in promise): Error: Cannot find module '/app/home.module'.
    at resolvePromise (zone.js:418)
    at zone.js:395
    at ZoneDelegate.invoke (zone.js:192)
    at Object.onInvoke (ng_zone_impl.js:43)
    at ZoneDelegate.invoke (zone.js:191)
    at Zone.run (zone.js:85)
    at zone.js:451
    at ZoneDelegate.invokeTask (zone.js:225)
    at Object.onInvokeTask (ng_zone_impl.js:34)
    at ZoneDelegate.invokeTask (zone.js:224)ErrorHandler.handleError @ error_handler.js:51next @ application_ref.js:273schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub @ Subscriber.js:223SafeSubscriber.next @ Subscriber.js:172Subscriber._next @ Subscriber.js:125Subscriber.next @ Subscriber.js:89Subject.next @ Subject.js:55EventEmitter.emit @ async.js:74onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:64ZoneDelegate.handleError @ zone.js:196Zone.runGuarded @ zone.js:102_loop_1 @ zone.js:368drainMicroTaskQueue @ zone.js:375
    zone.js:344Unhandled Promise rejection: Cannot find module '/app/home.module'. ; Zone: angular ; Task: Promise.then ; Value: Error: Cannot find module '/app/home.module'.(…) Error: Cannot find module '/app/home.module'.
    at webpackEmptyContext (http://localhost:4200/main.bundle.js:41545:8)
    at SystemJsNgModuleLoader.loadAndCompile (http://localhost:4200/main.bundle.js:50064:40)
    at SystemJsNgModuleLoader.load (http://localhost:4200/main.bundle.js:50057:60)
    at RouterConfigLoader.loadModuleFactory (http://localhost:4200/main.bundle.js:16894:128)
    at RouterConfigLoader.load (http://localhost:4200/main.bundle.js:16886:81)
    at MergeMapSubscriber.project (http://localhost:4200/main.bundle.js:52671:111)
    at MergeMapSubscriber._tryNext (http://localhost:4200/main.bundle.js:25798:27)
    at MergeMapSubscriber._next (http://localhost:4200/main.bundle.js:25788:18)
    at MergeMapSubscriber.Subscriber.next (http://localhost:4200/main.bundle.js:5728:18)
    at ScalarObservable._subscribe (http://localhost:4200/main.bundle.js:40540:24)consoleError @ zone.js:344_loop_1 @ zone.js:371drainMicroTaskQueue @ zone.js:375
    zone.js:346Error: Uncaught (in promise): Error: Cannot find module '/app/home.module'.(…)

  5. Mention any other details that might be useful.
    Also a question raised on StackOverflow with more details: http://stackoverflow.com/q/39493782/616304


    Thanks! We'll be in touch soon.

@slubowsky
Copy link

Try killing and restarting ng serve. Worked for me, see #2033

@mjolk
Copy link

mjolk commented Sep 14, 2016

yep it works, gj!

@ritz078
Copy link
Contributor

ritz078 commented Sep 14, 2016

@slubowsky @mjolk is there any way i can change the name of generated chunks that you know ? my chunks are named 0.chunk.js, 1.chunk.js and so on.

@mjolk
Copy link

mjolk commented Sep 14, 2016

@ritz078
Copy link
Contributor

ritz078 commented Sep 15, 2016

that's definitely not a solution. will create a separate issue.

@stephenwilson1984
Copy link
Author

Nothing has worked for me. Killing and restarting ng serve has no effect. I've seen another post exactly the same as this on stack overflow so I'm not the only one getting this. One person has suggested the below:

"The mechanism you are using is still systemjs based. I couldn't make it work with webpack using the "path#class" syntax. So we require the module directly:

First we'll need the es6-promise-loader:

npm i --save-dev es6-promise-loader

Then define your route like this:

{path:"lazy", loadChildren: () => require('es6-promise!./path/to/module')('ClassName')}"

I'm not sure about this though. I would have thought the lazy loading that used to work with System JS should work the same in webpack with no extra config. Am I wrong?

@marklagendijk
Copy link

I just got it working. Restarting ng serve worked for me.
Make sure you are using the full path, so app/my-lazy-module/my-lazy-module.module#MyLazyModule instead of ./app/my-lazy-module/my-lazy-module.module#MyLazyModule. The relative syntax does not (yet?) work.

@mxii
Copy link
Contributor

mxii commented Sep 15, 2016

Isn't it possible to lazy load just a Component instead of a whole NgModule?

@andyrue
Copy link

andyrue commented Sep 15, 2016

With the latest beta.14 and Angular 2.0.0 Final I used app/home/home.module without specifying the module class to load with #HomeModule.

@chosroes
Copy link

chosroes commented Sep 15, 2016

Maybe it's better to follow the documentation style:
https://angular.io/docs/ts/latest/guide/router.html

const adminRoutes: Routes = [ { path: 'admin', loadChildren: 'app/admin/admin.module#AdminModule', } ];

@andyrue
Copy link

andyrue commented Sep 15, 2016

@chosroes That's how I was originally doing it but it could never find the module file. Removing the #HomeModule part got it working. Confusing!

@reflog
Copy link

reflog commented Sep 15, 2016

One thing that failed me at first: make sure that the class inside your module is NOT exported as 'default', otherwise it will not be picked up by systemJS loader!

@andyrue
Copy link

andyrue commented Sep 15, 2016

@reflog Thanks for pointing that out. After removing default from my exported class I was then able to use app/home/home.module#HomeModule method. Seems that's the documented way to do things now. But note that the other way appears to work as well if you export default and don't specify the module class in the path.

@chosroes
Copy link

chosroes commented Sep 15, 2016

@andyrue Yeah, default means that you have not to specify the module.

@PostImpatica
Copy link

PostImpatica commented Sep 19, 2016

Are you guys seeing it actually create additional bundles? Cuz although this appears to be working, in that I'm not getting any errors, it doesn't appear to be creating separate bundles. Therefore, nothing is really being lazy loaded when you look at the network tab.

UPDATE: Never mind, I had to remove the module from the main app.module.ts and now it loads as a seperate chunk. I was surprised this worked, lol.

@davidejones
Copy link

I'm having the same issue mostly because the children aren't relative to the the project. I have it in another package. Is there anyway to have loadChildren work like import somehow?

import { CoreModule } from '@blahblah/core-stuff';

@ritz078
Copy link
Contributor

ritz078 commented Sep 20, 2016

Lazy loading Worked for me
https://twitter.com/ritz078/status/777057390487146497
On Wed, 21 Sep 2016 at 2:34 AM, David Jones [email protected]
wrote:

I'm having the same issue mostly because the children aren't relative to
the the project. I have it in another package. Is there anyway to have
loadChildren work like import somehow?

import { CoreModule } from '@blahblah/core-stuff';


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#2112 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFI6657BTMirVDZy-5hL6zmpEid6Ep46ks5qsEp0gaJpZM4J88bW
.

@scrivy
Copy link

scrivy commented Sep 21, 2016

does anybody have a working plnkr example? I'm using angular-cli and can't figure it out

@tianyangj
Copy link

Lazy loading seems to be working for me.
screen shot 2016-09-21 at 12 08 02 am
I created a simple repo with two modules, one eager loaded and one lazy loaded, https://github.com/tianyangj/angular-cli.

@filipesilva
Copy link
Contributor

@stephenwilson1984 are you still having problems? If you show me repo with the latest CLI, I can try to debug.

@filipesilva filipesilva added the needs: more info Reporter must clarify the issue label Oct 3, 2016
@stephenwilson1984
Copy link
Author

Hi, Everything is fine now, we ditched angular-cli and stayed using SystemJs which works fine for now.

Thanks,
Stephen

@deebloo
Copy link
Contributor

deebloo commented Oct 3, 2016

@filipesilva would using the same module in the root app and a lazy loaded module cause this? For example. I have a core module. In the root app I call forRoot to configure a provider. Then when I import that same module in a lazy loaded module I do not get multiple bundles

@deebloo
Copy link
Contributor

deebloo commented Oct 3, 2016

@filipesilva I think the issue is that it is not obvious how the cli decides to create bundles since it seems it is not just defined by defining a module to be lazy loaded.

@Delagen
Copy link

Delagen commented Oct 4, 2016

Load children in webpack try to use SystemJS loader for resolve. But I don't want to use it.
Angular 2 template Loader works fine. Why AOT generation from ngtools/webpack produce it?
Direct use of NGC (ngc -p) produces valid ngfactory.

@Delagen
Copy link

Delagen commented Oct 4, 2016

@tianyangj
ng build --prod --aot

 10% building modules 6/7 modules 1 active ...\index.js!C:\1\new-ng-app\src\main.tsError: AboutModule is not an NgModule

    at NgcWebpackPlugin.getNgModuleMetadata (C:\1\new-ng-app\node_modules\@ngtools\webpack\src\plugin.js:121:19)
    at NgcWebpackPlugin._processNgModule (C:\1\new-ng-app\node_modules\@ngtools\webpack\src\plugin.js:109:42)
    at C:\1\new-ng-app\node_modules\@ngtools\webpack\src\plugin.js:114:34
    at Array.reduce (native)
    at NgcWebpackPlugin._processNgModule (C:\1\new-ng-app\node_modules\@ngtools\webpack\src\plugin.js:111:29)
    at C:\1\new-ng-app\node_modules\@ngtools\webpack\src\plugin.js:96:37
 10% building modules 7/7 modules 0 active

but ng build --prod works

@pleerock
Copy link

pleerock commented Oct 5, 2016

I have same issue here. using webpack without angular cli worked fine, but with cli it does not generate bundles

@onedotover
Copy link

I was having the same issue as @Delagen. I was defining routes in this format from https://angular.io/docs/ts/latest/guide/router.html.

const routes: Routes = [
  {path: "", component: HomeComponent},
  {path: "lazy", loadChildren: "app/lazy-test/lazy.module#LazyModule"}
];
export const AppRoutes = RouterModule.forRoot(routes);

ng build --aot >> LazyModule is not an NgModule

Updating to the module format used in the angular-cli blueprints works fixes this error

const routes: Routes = [
  {path: "", component: HomeComponent},
  {path: "lazy", loadChildren: "app/lazy-test/lazy.module#LazyModule"}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutesModule {}

Once you get past this issue you hit #2452 noted above.

@Delagen
Copy link

Delagen commented Oct 7, 2016

@onedotover No I issue different problem

@aaronleestic
Copy link

@filipesilva I encountered a lazy loading issue but it is unlike stephenwilson1984's. Instead of 'Cannot find module', the main bundle includes the lazily loaded module.

Per your request I have a repo that reproduces the issue, under this related issue:
#2496 (comment)

@pleerock
Copy link

pleerock commented Oct 7, 2016

same for me, everything is packed into single module, instead having multiple generated bundles.

@Delagen
Copy link

Delagen commented Oct 7, 2016

angular-cli beta 17 the same issue.
Even bundle broken due ngtools/webpack@latest resolved to 1.0.0 but needed 1.1.0 with only tagged as experimental. No testing at all. Sad (((

@filipesilva
Copy link
Contributor

For issues related to AOT and lazy loaded modules, please use #2452 instead of this issue.

We have a custom mechanism in the CLI to find and separately bundle lazy loaded routes that does not need SystemJS and instead uses Webpack2.

Regarding bundles not being generated. the cause is likely that you are importing that module elsewhere in the app, as mentioned in #2112 (comment).

As long as there is at least one ES6 import statement in your code that requires that file it will never be factored out into a lazy loaded module. That makes sense though... if you have an import then it can't be lazily loaded, there's a part of your app that needs it right then and now.

I'm closing this issue because the exact reported issue doesn't exist anymore, it was originally for an older version, the original poster isn't part of the discussion anymore, and the thread is branching out to related but different issues.

Please open new issues for problems you're still having with lazy loaded modules.

@danya0365
Copy link

danya0365 commented Oct 14, 2016

I'm using angular-cli "version": "1.0.0-beta.16"

with first time I have config for lazy load

loadChildren: 'app/my-account/my-account.module#MyAccountModule'

it's not worked.

I try to close web server then run ng-serve again it's worked again

web pack has been generate 0.chunk.js & 0.map file

screen shot 2016-10-14 at 2 13 27 pm

@kentoj
Copy link

kentoj commented Nov 6, 2016

I confirm that the restarting of ng serve fixed the problem for me. I saw the additional chunk being generated in the network tab. I had to make sure as others have said that there were no imports in app.module.ts or app-routing.module.ts to the module the app was supposed to lazy load. It would be nice to mention this in the docs since it is probably an easy beginner mistake, especially since the () => ModuleName syntax exists out there. I saw that on a blog post and on another issue on this repo. After much searching I came across this issue, which solved the issue entirely for me.

@thucnguyen77
Copy link

"restarting ng serve" worked for me too

@pleerock
Copy link

still not working for me... How does cli "automatically understand and find lazy routes"? Maybe I do something wrong that this automatic code cant find any matches in my project? I have AppRoutes file that contains such code:

export const APP_ROUTES: Routes = [
    {
        path: "posts",
        loadChildren: "../modules/content-modules/post/PostModule#PostModule"
    },
];

@da45
Copy link

da45 commented Dec 27, 2016

make sure that you included 'Routes' in the lazy module as described below:
import { Routes, RouterModule } from '@angular/router';

@dustintheweb
Copy link

Felt this bug for the first time today. No issues locally (dev or production / Mac OS), but got hit with it after I pushed to my production server (Heroku / Ubuntu).
Here's how I fixed it: http://stackoverflow.com/a/41780310/923454

@guilhermelucio
Copy link

I just put the route in the app.module.ts file, if I add a new file called route.module.ts and try to import within the app.module.ts file, the app will crash, so if you just leave the code inline, it should work.

import { Routes, RouterModule } from '@angular/router';
...

const routes: Routes = [
  { path: '',  loadChildren: './home/home.module#HomeModule' },
  { path: 'contacts', component: ContactsComponent }
];

const routerModule = RouterModule.forRoot(routes);

@NgModule({
  declarations: [
    AppComponent,
    ContactsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    routerModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

References:
https://github.com/mauricedb/lazy-routes.git

@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 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs: more info Reporter must clarify the issue
Projects
None yet
Development

No branches or pull requests