angular-cli: AOT build produces applications unable to lazy load modules

angular-cli: 1.0.0-beta.16
node: 6.0.0
os: linux x64

reproduction repo can be found here

The log given by the failure.

main.cfeed71….bundle.js:547 EXCEPTION: Uncaught (in promise): Error: Cannot find module 
'app/lazy/lazy.module.ngfactory'.

It seems that aot option can not build project that lazily loads modules. I would hope that one could use the patterns in the official documentation – which I believe I’m doing – and use the -- aot option to compile your app easily. I would appreciate any clarification as to whether this is an issue with the CLI or with the compiler. Thanks.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 16
  • Comments: 54 (9 by maintainers)

Commits related to this issue

Most upvoted comments

@achimha all I can say is that we’re working as fast as possible to get it fixed. It’s our top priority atm really.

Could the maintainers provide us with some feedback regarding the AOT/lazy issues please? It’d be very helpful to know what we should expect.

@MrCroft and @naveedahmed1, the key change was the

    "baseUrl": "",

inside the tsconfig.json. The packages updates + this line solve the LazyModule is not an NgModule error at build.

With b17 I still don’t get the lazy route modules compiled by ng build --prod --aot. There isn’t even an ngfactory file, just a main bundle. For some reason the loadChildren does not trigger the compilation.

I have a file app/src/lazy/lazy.routes.ts:

export const lazyRoutes: Routes = [
    {
        path: 'signup',
        loadChildren: 'app/lazy/signup/signup.module#SignupModule'
    }
];

This route definition is part of the main route definition in app/app-routing.module.ts:

const routes: Routes = [
    {
        path: '',
        component: FrontpageComponent
    },
    {
        path: 'login',
        component: LoginComponent
    },
    ...lazyRoutes,
    {
        path: '**',
        component: NotFoundComponent
    },
];

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

I tried changing the loadChildren paths to be relative but then the JIT version throws as well, it has to start with app/.

I get the error HomeModule is not an NgModule when using ng build --prod --aot on beta.17. Using just ng build --prod works fine.

home.module.ts

const HomeRoutes: Routes = [
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(HomeRoutes)
  ],
  declarations: [HomeComponent]
})
export class HomeModule { }

app.module.ts

export const Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', loadChildren: 'app/home/home.module#HomeModule' },
  { path: 'about', loadChildren: 'app/about/about.module#AboutModule' }
];

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(Routes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

In Angular v5, what I’ve found is you can’t terminate the file name with .ts.

So if your RoutingModule is AuthRoutingModule in ./auth/auth-routing.module.ts, your loadChildren would be './auth/auth-routing.module#AuthRoutingModule.

I can confirm that I’ve just upgraded to angular-cli 1.0.0-beta.21 and lazy loading is working with AOT ❤️ ! Big shout out for the team 😃 !!

A big shout out to @hansl and @filipesilva for making this work in angular-cli 1.0.0-beta.20-4. I have our app lazy load with AOT now. You guys rock! I appreciate all the effort that goes into fixing the tooling so that angular devs can focus on building applications, not build infrastructure 👍

I have created a new project using angular-cli beta.19-3 and just added a lazy route to reproduce the problem: https://github.com/sgybas/angular-cli-2452

ng serve works fine, ng serve --aot does not. The browser console shows Error: Cannot find module './lazy/lazy.module.ngfactory'.

ng build --prod works fine, two bundles are created. ng build --prod --aot creates the main bundle but the second chunk is not created.

Is there anything I can do to help resolve the issue?

Any update on this?

Any updates on this issue?

We have a large app that was originally written against beta-17. I recently moved it over to the Angular2 release and hooked up the ng compiler to take advantage of AoT compilation, but as of now I haven’t found a way to leverage both AoT and lazy loading. As mentioned above, it will compile fine but when navigating to the lazy route it throws an error that ‘lazy.module.ngfactory’ could not be found

AoT is a killer feature and made a noticeable difference in our boot time, but at this point our --prod build still send down ~2.2mb all at once and we would love to cut that down by lazy loading some of our lesser-used routes

i have faced same issue but i solved it by doing following 2 things:

i have added ./ as prefix of html and css in every component file.

i am also using lazy loaded modules, so was exporting module class as default i removed default from export default class AdminModule and i have added

{ path: 'dashboard', loadChildren: 'app/admin/dashboard/dashboard.module#DashboardModule' },

and its working for me.

@naveedahmed1 I’ve tried your suggestion on 2 apps: a bigger app, with multiple lazy loaded modules… and in the repo I gave the link to as an example ( https://github.com/MrCroft/lazy ) First case (the bigger app): After having created routing modules, ng build --aot doesn’t throw errors anymore during the build process. But when browsing through the app, as soon as I try to access a link that needs to load a lazy module, I get this thrown in my browser’s console: EXCEPTION: Uncaught (in promise): Error: Cannot find module ‘app/user/user.module.ngfactory’. Error: Cannot find module ‘app/user/user.module.ngfactory’.

Second case (the repo I gave the link to): Very strange, I’m still getting the same error on build: LazyModule is not an NgModule… I’ve checked and double-checked, I can’t find anything missing.

I just upgraded the project I tested with beta.17 to beta.18. As mentioned above, I am encountering the same failure modes:

  • project build and serve are fine without --aot (regardless of dev or prod)
  • project compiles without errors with --aot. However, the chunks for the lazy modules are not emitted in js. There is, oddly enough, again a partial 0.map without any corresponding js file.

This error is also present in the demo app - webpack builds the project ok, but as soon as you click the lazy link, this error is thrown:

Uncaught (in promise): Error: Cannot find module './lazy.module.ngfactory'.

#2112 seems aot process does not polished. I issue No module factory available for dependency type: ContextElementDependency for lazyRoutes dependencies

When updating to from Angular 4 to Angular 5 i kept getting

ERROR in Error: Could not resolve module [module path] relative to [routing module path]

for lazy loaded modules. Removing the .ts suffix as @wbhob suggested works.

I am also getting the same error of:

Error: No module factory available for dependency type: ContextElementDependency

and also using lazy loaded modules… any ideas?

angular-cli: 1.0.0-beta.26
node: 6.9.4
os: win32 x64
@angular/common: 2.4.5
@angular/compiler: 2.4.5
@angular/core: 2.4.5
@angular/forms: 2.4.5
@angular/http: 2.4.5
@angular/language-service: 2.4.5
@angular/platform-browser: 2.4.5
@angular/platform-browser-dynamic: 2.4.5
@angular/router: 3.2.1
@angular/compiler-cli: 2.4.5

Regards,

Checkout the Ultimate Angular 2 Boorstrap App: @ http://ng2.javascriptninja.io Source@ https://github.com/born2net/ng2Boilerplate

@naveedahmed1 My bad… I didn’t think there was any difference between previous version and the latest (except only under the hood, but didn’t think there would be any in the actual files generated initially). I did an ng init now, overwrote all the files and then put back from history whatever needed to have my old app back. The simple one (the repo) worked right away! For the larger app - I also had to delete the entire node_modules folder, not just angular and angular-cli (like I did with the small test app). But it works now! Both work. Thank you!

I can confirm Lazyloading with AoT (ng build --aot --prod) is working properly in latest release of Angular-Cli

Those having issues could try creating routing module and add to imports of AppModule.


import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

@NgModule({
    imports: [
        RouterModule.forRoot([
            { path: '', loadChildren: 'app/home/home.module#HomeModule' },
            { path: 'lazyLoadedFeature', loadChildren: 'app/lazyLoadedFeature/lazy-loaded-feature.module#LazyLoadedFeatureModule' },
        ]
        )
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

In Lazy loaded module define its routing as a separate module and import in the child module.

import { FeatureListComponent } from './feature-list.component';
import { FeatureDetailsComponent } from './feature-details.component';

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: '', component: FeatureListComponent,
                children: [
                    { path: 'details/:id', component: FeatureDetailsComponent },
                ]
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})
export class LazyLoadedFeatureRoutingModule { }

I have this same issue as well. I dont have a repo to show yet but I get the same error as above. I ran ng build --prod --aot. Also one thing to note my outDir is set to dist/build instead of the default path.

angular-cli: 1.0.0-beta.16
node: 6.4.0
os: win32 x64
main.166efb8….bundle.js:1494 Unhandled Promise rejection: Cannot find module 'app/account/account.module.ngfactory'. ; Zone: angular ; Task: Promise.then ; Value: Error: Cannot find module 'app/account/account.module.ngfactory'.(…) Error: Cannot find module 'app/account/account.module.ngfactory'.