How to package a lazy loaded module following the Angular Package Format specification?

714 views Asked by At

I am packaging my angular module using ngc and rollup following the Angular Package Format 4.0 specification.

I'm able to lazy load it using the angular cli using a wrapper module.

import { LibraryModule } from 'my-library';
import { NgModule } from '@angular/core';
@NgModule({
    imports: [LibraryModule],
    exports: [LibraryModule]
})
export class WrapperModule { }

...

RouterModule.forRoot([
  {
    path: 'todolist',
    loadChildren: './wrapper.module#WrapperModule'
  }],

The library module also contains sub routes. If I define one of those sub routes as:

{
  path: 'foo',
  loadChildren: '../foo/foo.module#FooModule'
}

I get a cli compiler error:

ERROR in Error: Could not resolve module ../foo/foo.module relative to C:/Workspace/test-app/node_modules/my-library/my-library.d.ts
    at StaticSymbolResolver.getSymbolByModule (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:31826:30)
    at StaticReflector.resolveExternalReference (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:30292:62)
    at parseLazyRoute (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:28577:55)
    at listLazyRoutes (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:28539:36)
    at visitLazyRoute (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:29937:47)
    at visitLazyRoute (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:29941:17)
    at AotCompiler.listLazyRoutes (C:\Workspace\test-app\node_modules\@angular\compiler\bundles\compiler.umd.js:29905:20)
    at AngularCompilerProgram.listLazyRoutes (C:\Workspace\test-app\node_modules\@angular\compiler-cli\src\transformers\program.js:157:30)
    at Function.NgTools_InternalApi_NG_2.listLazyRoutes (C:\Workspace\test-app\node_modules\@angular\compiler-cli\src\ngtools_api.js:44:36)
    at AngularCompilerPlugin._getLazyRoutesFromNgtools (C:\Workspace\test-app\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:246:66)
    at Promise.resolve.then.then (C:\Workspace\test-app\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:542:50)
    at process._tickCallback (internal/process/next_tick.js:109:7)

I've tried exporting the lazy loaded module in index.js, I've also included it in the tsconfig.json files array.

Any other clues?

2

There are 2 answers

2
R. Richards On

Your route with lazy loading path needs to start from the app root, like so:

{
  path: 'foo',
  loadChildren: 'app/foo/foo.module#FooModule'
}

Your actual full path may be different from this, but starting from the app folder in a CLI application is important. Relative paths will not work. Based on information in the error you are getting, the CLI (ng serve) is not able to resolve a relative path.

0
Michael Kang On

If you're using webpack or @angular/cli, you can use ng-router-loader to ensure that lazy-loaded modules are bundled correctly.

npm install ng-router-loader --save-dev;

webpack.config.js

{
    test: /\.ts$/,
    use: [
        {
            loader: 'ng-router-loader',
            options: {

            }
        },
        {
            loader: '@ngtools/webpack', 
            options: {
                tsConfigPath: './tsconfig.json'
            }
        }
    ]
},