9

I have an app that lazy loads its feature components. Everything is fine and dandy as long as I don't AOT compile (which after days of struggling I got working).

My initial page load is super quick now. However, when I click any of my nav links which are supposed to lazy load that feature, I get a 404 and rightly so. There is a request being made to myfeature.module.ngfactory.js but this file does not exist. I have followed the cookbook on the dev site but it does not go into details on how to get lazy loads working. I see that my AOT compile creates a myfeature.module.ngfactory.ts but does not create a myfeature.module.ngfactory.js file. How do I go about creating this file? My tsconfig-aot.json file looks like this:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "es2015",
      "dom"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "sourceMap": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es5"
  },
  "files": [
    "app/shared/shared.module.ts",
    "app/app.module.ts",
    "app/myfeature/myfeature.module.ts",
    "main.ts"
  ],
  "angularCompilerOptions": {
    "skipMetadataEmit": true
  },
  "exclude": [
    "node_modules/*",
    "**/*-aot.ts"
  ]
}

I feel like I am missing something. Looks like the bootstrap process is the one that creates app.module.ngfactory.js but there is nothing triggering the creation of myfeature.module.ngfactory.js.

4
  • 1
    Were you able to get this to work with @Minko Gechev's suggestion? If so, can you share. Commented Dec 22, 2016 at 20:13
  • 2
    @Minko's solution is good but that was not my problem. Turned out that Rollup does not work with lazy loaded routes. In my case, I had to forego the lazy loading in favor of a fast startup (bundled). So I removed the lazy routes and used Rollup to build 1 large bundle. Commented Dec 23, 2016 at 16:07
  • 1
    That is what I found as well, but I wanted to see if maybe you had any other solution. Thanks for responding! Commented Dec 23, 2016 at 18:25
  • Any updates on this? I had to forego lazy-loading as well : / Commented Mar 17, 2017 at 10:37

1 Answer 1

7

Routing behavior

With configuration:

const rootRoutingConfig = RouterModule.forRoot([{
  path: 'home',
  loadChildren: './home.module#HomeModule'
}]);

By default, when the user navigates to /home, application using JiT will have the following behavior:

With SystemJS download APP_BASE_HREF/home.module.js and after that use the HomeModule export.

In contrast, when you're using AoT, the default behavior of the router will be:

With SystemJS download APP_BASE_HREF/home.module.ngfactory.js and use the HomeModule export.

What is *.ngfactory

home.module.ngfactory.js is an artifact which is produced by the Angular's compiler. During compilation the compiler will produce *.ngfactory.(js|ts) files for all your components and modules. For further information about the compiler take a look at this link.

How to solve your problem?

What you need to do is to either:

  1. Configure the module loader that the router uses to load the bundles from the location where you've saved them.
  2. Provide a custom callback for loading the module bundles.
  3. Produce the application bundles and store them in the location which is going to be used by the module loader by default.

With the second approach I prototyped an example for angular-seed. Take a look at the lazy branch. You can build the application for production using AoT and lazy-loading by running: npm run build.prod.exp. Note that the example is not complete. It only applies basic bundling without any sophisticated strategy which takes care of proper dependency resolution.

Sign up to request clarification or add additional context in comments.

1 Comment

Hey, so build.prod.exp doesnt use SystemJS, it uses a custom callback to load AOT files that have been bundled with SystemJS Builder.buildStatic() Right? Can you help me find the custom callback in the source?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.