brandonroberts / angular-router-loader

A Webpack loader that enables string-based module loading with the Angular Router

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[docs] clarification on loadChildren path

GiuseppePiscopo opened this issue · comments

Hi there

sorry to bother again, it must be our project setup different from example. Main readme page, at lazy loading section, says:

[...] use loadChildren with a relative path to your lazy loaded angular module.

Could you please elaborate more on "relative" to what? Should the lazy loaded module path be expressed as relative to the routing file where the route itself is defined? Or relative to the module file where the route will be "imported" with RouterModule.forXxx()?

To better express, say one has a structure like:

|-- compiled\
   |-- src\
      |-- app\
      |-- lazy\

|-- src\
   |-- app\
      |-- config\
         |-- app.routing.ts
      |-- app.module.ts

   |-- lazy\
      |-- lazy.module.ts

|-- package.json

then what version should app.routing.ts include?

// A: relative to routing file
export const routes: Routes = [
  { path: 'lazy', loadChildren: '../../lazy/lazy.module#LazyModule' }
];

// B: relative to module file
export const routes: Routes = [
  { path: 'lazy', loadChildren: '../lazy/lazy.module#LazyModule' }
];

Again, more than willing to submit a PR with a doc change if needed. Thanks!

The reason I'm asking, of course, is that I'm using a separate routing file placed 1 level below the app.module.ts file. From the compiled output, I can see the generated app.module.ngFactory.ts eventually includes the route definitions and shows something like:

  get _ROUTES_88():any[] {
    if ((this.__ROUTES_88 == null)) { (this.__ROUTES_88 = [
        [{
          path: 'login',
          component: import83.LoginComponent,
          canActivate: [import62.LoginGuard]
        }
      ],
      [
        {  // ***** THIS IS THE IMPORTANT ONE *****
          path: '',
          loadChildren: '../../lazy/lazy.module#LazyModule',
          canLoad: [import66.AuthGuard]
        }
        ,
        {
          path: '**',
          component: import84.NotFoundComponent
        }

      ]

    ]
    ); }
    return this.__ROUTES_88;
  }

so basically the route definition has moved 1 level upward, but now that relative path is not good anymore. And of course build fails with (codegen is our compiled equivalent):

 ERROR in ../codegen/src/app/app.module.ngfactory.ts
 Module not found: Error: Can't resolve '..\..\lazy\lazy.module.ngfactory'

When I make the routing file a sibling of module file (and update the relative path accordingly as loadChildren: '../lazy/lazy.module#LazyModule') build goes fine.


When I keep routing file 1 level below and just update the relative path as loadChildren: '../lazy/lazy.module#LazyModule', build fails with "strange" relative paths, not present in original source files:

ERROR in ./app/config/app.routing.ts
Module not found: Error: Can't resolve '.\..\..\..\codegen\src\app\lazy\lazy.module.ngfactory' in 'X:\MyProjRoot\src\app\config'
resolve '.\..\..\..\codegen\src\app\lazy\lazy.module.ngfactory' in 'X:\MyProjRoot\src\app\config'
  using description file: X:\MyProjRoot\package.json (relative path: ./src/app/config)
    Field 'browser' doesn't contain a valid alias configuration

Yes, the convention is based on the routing file being a sibling file to the module file where the routing module is imported. AOT remaps the imports, so the original path to the file may be different. I need to document this, but you can also use absolute paths if you set an alias to the root of your project and use absolute paths to your lazy loaded modules.

Thanks for clarifying! There's a PR underway on the convention. What about the absolute path scenario? Could you provide an example, I mean: is it absolute like (on Windows):

X:/full/path/to/my/project/root/lazy/module#ModuleClass

or more "relaxed" like "/ equals project root", so basically:

/lazy/module#ModuleClass

? Second case would be optimal I'd say, and there would not be such a strong pressure to define an alias, I think.

The absolute path scenario depends on what your alias is. If you have a an alias named app pointing to the root of your app, then your lazy loaded path looks like app/path/to/lazy.module#LazyModule

Thanks for clarifying. Would the alias hold a full path, like e.g. X:/full/path/to/my/project/root/ on Windows?

Ok, thanks again.