Solvedangular 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 angular/angular#13909 it seems that instead of having

image

we should rather import the factory (which is not available when coding, only when building) :

image

SamVerschueren asked if it could be replaced at build time (and opened an issue angular/angular#14005 for that).

mhevery explained why it can't be handled at build time by angular angular/angular#13909 (comment).

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 ?

33 Answers

✔️Accepted Answer

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 a string (lazy loading), but keep the function around to make the module get included in the same bundle instead of a separate one. Keeping the exported function not just the import makes sure it doesn't get tree shaked / minified.

Like:

import { ProfileModule } from './profile/profile.module';

// Do not delete. Used to ensure ProfileModule is loaded in the same bundle.
// Referencing the function directly in `loadChildren` breaks AoT compiler.
export function loadProfileModule() {
    return ProfileModule;
}

export const routes: Routes = [
    // ... other routes ...
    { path: 'profile', loadChildren: './profile/profile.module#ProfileModule' }
];

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

Other Answers:

@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

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

Sorry what's the solution?

@SamVerschueren

Because this way your feature module doesn't need to know what path is being used to access it.

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

  1. prevent the name collusion problem (feature modules could have used the same pathname)
  2. also based on the 1 that it therefore achieves the truly modularized structure with fully separated concerned among modules.

Please kindly reopen this issue.

More Issues: