Angular-cli: Nested lazy loading no longer works, bundles not being generated - beta 24

Created on 21 Dec 2016  路  22Comments  路  Source: angular/angular-cli

Please provide us with the following information:

OS?

Windows 10

Versions.

angular-cli: 1.0.0-beta.24
node: 7.2.1
os: win32 x64
@angular/common: 2.3.1
@angular/compiler: 2.3.1
@angular/core: 2.3.1
@angular/forms: 2.3.1
@angular/http: 2.3.1
@angular/platform-browser: 2.3.1
@angular/platform-browser-dynamic: 2.3.1
@angular/router: 3.3.1
@angular/compiler-cli: 2.3.1

(Tried angular 2.4 too)

Repro steps.

App was created with cli (beta 5). Lazy loading was working with beta.22-1. No longer works after upgrading to beta 24.
Have many nested levels of lazy loaded routes. App routing module lazy loads a module, which lazy loads another, in some cases 4 levels deep.
one => two => three => four
Bundles are no longer being created for 4th level lazy loaded routes. (I get about 10 bundles in my app compared to about 25 when its working)
Workaround - If I cut and paste the routes exactly as they are (I did change the paths to fake paths so they wont ever be matched) from the third level routing module into the second level one, the bundles are created, and the app works. The routes are then matched properly from the third level, so its strictly a bundling issue. Whatever analysis is being done to figure out what lazy loaded bundles need to be built isn't following the trail far enough. (I thought I saw an issue related to a recent change in how the cli determines what bundles need to be built a week or two ago, but couldn't find it now. That was before the problem manifested itself though, so unless it was against the unreleased version it wasn't a problem for me until now)

The log given by the failure.

I see very few bundles produced by ng serve and the when attempting to route I get:

EXCEPTION: Uncaught (in promise): Error: Cannot find module 'FULL_PATH/MY_MODULE.module'.
Error: Cannot find module 'FULL_PATH/MY_MODULE.module'.
at webpackAsyncContext (http://localhost:4200/main.bundle.js:628:25) [angular]
at SystemJsNgModuleLoader.loadAndCompile (http://localhost:4200/vendor.bundle.js:86862:40) [angular]
at SystemJsNgModuleLoader.load (http://localhost:4200/vendor.bundle.js:86850:60) [angular]
at RouterConfigLoader.loadModuleFactory (http://localhost:4200/vendor.bundle.js:25223:128) [angular]
at RouterConfigLoader.load (http://localhost:4200/vendor.bundle.js:25210:81) [angular]
at MergeMapSubscriber.project (http://localhost:4200/vendor.bundle.js:91107:111) [angular]
at MergeMapSubscriber._tryNext (http://localhost:4200/vendor.bundle.js:17084:27) [angular]
at MergeMapSubscriber._next (http://localhost:4200/vendor.bundle.js:17074:18) [angular]
at MergeMapSubscriber.Subscriber.next (http://localhost:4200/vendor.bundle.js:5016:18) [angular]
at ScalarObservable._subscribe (http://localhost:4200/vendor.bundle.js:74230:24) [angular]
at ScalarObservable.Observable.subscribe (http://localhost:4200/vendor.bundle.js:748:27) [angular]
at MergeMapOperator.call (http://localhost:4200/vendor.bundle.js:17049:23) [angular]
at Observable.subscribe (http://localhost:4200/vendor.bundle.js:745:22) [angular]
at MergeMapOperator.call (http://localhost:4200/vendor.bundle.js:17049:23) [angular]

Mention any other details that might be useful.


Thanks! We'll be in touch soon.

1 (urgent) bufix

Most helpful comment

i found a solution
maybe this will help someone:
when i was searching on the internet for a tutorial for lazy loading they making sure to use the word "default" on the exported module
well this actually makes you to import the module in the route like this :
{ path: 'project', loadChildren:'app/components/project/project.module' },
WITHOUT #ProjectModule at the end or the module path

when i have a nested lazy loaded modules this giving me an error can't find the submodule
to fix this error i have to load all the modules with the #Modulename at the end of the module path:
{ path: 'create', loadChildren: 'app/components/project/create-project/create-project.module#CreateProjectModule' },
and remove all the default word on the modules

this works for me with angular cli BUT when i build the project with ng build and try to run the project the error back again
please if someone know how to fix this ?

Edit :
refresh the application with ctrl f5 works fine
it seems the js file was cached in the browser

All 22 comments

Can corroborate this, though I am on:
angular-cli: 1.0.0-beta.22-1
node: 6.9.2
os: win32 x64

I tried jumping up to beta 24, that didn't fix it. I tried uninstalling angular-cli globally, clearing the cache, and reinstalling, that didn't do it, and lastly I made a new project to see if building would work there. It did. I moved the created package.json from there to my project (which does have a fairly nested structure as the above comment stated) to ensure the packages I'm using are correct, and I still had the same issue

If you are using the default key word in your lazy modules, try to remove it on every lazy loaded modules and append #yourLazyModuleName to the url.
I got a similar issue

I've also been experiencing the same with @ngtools/[email protected]. Even putting angular2-router-loader looks like not to work any longer.

@diicar Thanks but I'm already doing it that way

I had a look at the source today and it seems the the function that crawl the lazy loaded modules does not dive into submodules. This code has been added after the @ngtools/webpack version 1.0.0. It might be a on liner to fix but I don't know the code base so this is not obvious.

I also encountered the same problem, how should be resolved?

+10086 .. why old version can suuccess lazyload , but new version incorrect(Can't find loadChildren Module) .. new version change lazyload express ? not resolve path ??

@Meligy since you're looking at a solution, also see https://github.com/angular/angular-cli/issues/3593, particularly @jmpmscorp's comment that seems to have a temporary solution.

When will this be released? Our entire app is completely broken because of this.

A temporary fix based on the pr:
at ROW54:
node_modules\@angular\compiler-cli\src\ngtools_impl.js

replace:

lazyRoutes.forEach(function (lazyRoute) {
        var route = lazyRoute.routeDef.toString();
        _assertRoute(routes, lazyRoute);
        routes[route] = lazyRoute;
        var lazyModuleSymbol = reflector.findDeclaration(lazyRoute.absoluteFilePath, lazyRoute.routeDef.className || 'default');
        var subRoutes = _extractLazyRoutesFromStaticModule(lazyModuleSymbol, reflector, host, ROUTES);
        // Populate the map using the routes we just found.
        subRoutes.forEach(function (subRoute) {
            _assertRoute(routes, subRoute);
            routes[subRoute.routeDef.toString()] = subRoute;
        });
    });
    return routes;

with:

const allLazyRoutes = lazyRoutes.reduce(
        function includeLazyRouteAndSubRoutes(allRoutes, lazyRoute) {
            const route = lazyRoute.routeDef.toString();
            _assertRoute(allRoutes, lazyRoute);
            allRoutes[route] = lazyRoute;
            if (!lazyRoute.routeDef.className) {
                return allRoutes;
            }

            const lazyModuleSymbol = reflector.findDeclaration(
                lazyRoute.absoluteFilePath, lazyRoute.routeDef.className || 'default');

            const subRoutes =
                _extractLazyRoutesFromStaticModule(lazyModuleSymbol, reflector, host, ROUTES);

            return subRoutes.reduce(includeLazyRouteAndSubRoutes, allRoutes);
        },
        {});

    return allLazyRoutes;

I have the same problem with webpack beta 24 ! And the solution of @Cronkan doesn't fix the issue !

Can this issue be listed in the breaking changes section of the change log? I'm guessing that some people won't upgrade until this is fixed in CLI or until they have time to make their app aot ready.

@zecide I've tried "his" solution and I can confirm that it works. It's the official PR solution as well. Have you restarted your server after changing the file?

i managed to make it work without the fix, cause it doesn't work for me !
Here is what i done :

1 - make the routing code in the module ( not a file )
2 - make the module file in the parent directory of the component
3 - delete the 'default' in the export like this

export DEFAULT class HomeModule { }

became

export class HomeModule { }

for some reason when the module file is not in the same folder that the component it works,
i know it sounds weird but i tested it, you can see that it works with beta 24 here :
https://github.com/mauricedb/lazy-routes

i don't know what is happening !!!

@Cronkan 's solution is not working for me either. I am still getting a "Could not resolve" module error in the terminal and the dev console says that it cannot find my second-level nested module now, which was working fine previously.

UPDATE: I now got it working, there was a problem with my local code. I can confirm that the PR fix works.

I am seeing the same issue, after upgrade to cli beta 24 and angular 2.4.1, nested lazy loading is broken as it cannot find the module. But I can confirm that the workaround proposed by @Cronkan is working for me with no changes to my code.

A couple things:

  • Default exports are problematic at the moment, please avoid them until you see something about enabling them in release notes or something
  • Anyone able to try the generated @nagular/compiler package / folder from this PR https://github.com/angular/angular/pull/13678 ? It should fix the issue

FYI: I upgraded this project to Angular CLI 25.5 and chunking IS working with AOT and lazy loaded routes - https://github.com/rodneyjoyce/lazy-routes

The issue arise with two levels of lazy loaded component so I think your demo does not prove it works. I saw a fix in Angular 4, not sure it has been back ported.

Ah, I see - if I get time will try and replicate that scenario

i found a solution
maybe this will help someone:
when i was searching on the internet for a tutorial for lazy loading they making sure to use the word "default" on the exported module
well this actually makes you to import the module in the route like this :
{ path: 'project', loadChildren:'app/components/project/project.module' },
WITHOUT #ProjectModule at the end or the module path

when i have a nested lazy loaded modules this giving me an error can't find the submodule
to fix this error i have to load all the modules with the #Modulename at the end of the module path:
{ path: 'create', loadChildren: 'app/components/project/create-project/create-project.module#CreateProjectModule' },
and remove all the default word on the modules

this works for me with angular cli BUT when i build the project with ng build and try to run the project the error back again
please if someone know how to fix this ?

Edit :
refresh the application with ctrl f5 works fine
it seems the js file was cached in the browser

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._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

IngvarKofoed picture IngvarKofoed  路  3Comments

daBishMan picture daBishMan  路  3Comments

MateenKadwaikar picture MateenKadwaikar  路  3Comments

gotschmarcel picture gotschmarcel  路  3Comments

purushottamjha picture purushottamjha  路  3Comments