Skip to content

webpack rc5 loadChildren -Error: Uncaught (in promise): TypeError: Cannot read property 'import' of undefined #1636

Closed

Description

@jjlgjkkl
  • when i click the link redirecting to the lazy load path, error occurs:

browser_adapter.js:84 Error: Uncaught (in promise): TypeError: Cannot read property 'import' of undefined
at resolvePromise (zone.js:538)
at zone.js:515
at ZoneDelegate.invoke (zone.js:323)
at Object.onInvoke (ng_zone_impl.js:53)
at ZoneDelegate.invoke (zone.js:322)
at Zone.run (zone.js:216)
at zone.js:571
at ZoneDelegate.invokeTask (zone.js:356)
at Object.onInvokeTask (ng_zone_impl.js:44)
at ZoneDelegate.invokeTask (zone.js:355)

  • my source code is:

export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module' }
];
which is from
https://angular.io/docs/ts/latest/guide/ngmodule.html

**everything is ok in systemjs**
  • my environment is:
    angular-cli: 1.0.0-beta.11-webpack.2

angular: 2.0.0-rc.5


Thanks!

Activity

  1. iurii-kyrylenko commented on Aug 11, 2016

    @iurii-kyrylenko

    I think you should use a custom module loader, not just a string.
    See closed issue: angular/angular#9938

  2. iurii-kyrylenko commented on Aug 11, 2016

    @iurii-kyrylenko

    Just updated my starter project for webpack.
    I used Brandon's approach to lazy load Task2:

    export const routes: Routes = [
        { path: '', redirectTo: 'task1', pathMatch: 'full' },
        { path: 'task1', component: Task1Component },
        {
            path: 'task2',
            loadChildren: load(() => new Promise(resolve => {
                (require as any).ensure([], (require: any) => {
                    resolve(require('./task-2/task2.module').Task2Module);
                })
            }))
        }
    ];
    

    Anyway, I would be grateful for any easier solution.
    CC: @brandonroberts

  3. jjlgjkkl commented on Aug 12, 2016

    @jjlgjkkl
    Author

    to @iurii-kyrylenko ,

  4. filipesilva commented on Aug 18, 2016

    @filipesilva
    Contributor

    @TheLarkInn can you add some context to the current resolution of this issue?

  5. added
    P1Impacts a large percentage of users; if a workaround exists it is partial or overly painful
    on Aug 18, 2016
  6. added a commit that references this issue on Aug 19, 2016
    3b226be
  7. Martin-Luft commented on Aug 23, 2016

    @Martin-Luft

    I need the loadChildren feature with webpack and can't wait until RC6 is released therefore I used the nightly builds but it does not work :(

    ReferenceError: System is not defined

    So I realized that I now need systemjs (in other words... 2 module loaders?)?

    Which steps are needed to make the Angular 2 webpack example (https://angular.io/docs/ts/latest/guide/webpack.html) work with loadChildren?

    Thank you so much!

  8. kylecordes commented on Aug 23, 2016

    @kylecordes

    I think the best way to describe the status of this is simply that the CLI team hasn't gotten to it yet. Most likely, if things go well, down the road a bit you will simply use ng new, ng generate route, etc., and it will all get wired up to "just work" the first time. I can't speak to the timeline of that, I'm not on the CLI team.

    I believe there are some lazy loading examples around the web right now, although I don't have a URL handy as I type this. As far as I know, these examples don't yet use CLI.

  9. reflog commented on Aug 23, 2016

    @reflog

    this is actually not closed... #1632 only adds the base for lazy loading, the actual loader seems to be missing... or atleast I didn't manage to find it in the commits :)

  10. brandonroberts commented on Aug 23, 2016

    @brandonroberts
    Contributor

    The built in loader assumes you have SystemJS available globally already. You need to add SystemJS to your head scripts, and be on the master builds of angular also for this to work. If you want to do it the "webpack" way right now you'll need a custom loader.

  11. reflog commented on Aug 23, 2016

    @reflog

    @brandonroberts thanks for the explaination, i couldn't gather that from the code. I guess I'll have to wait for the official 'webpack' wait to land.

  12. Martin-Luft commented on Aug 23, 2016

    @Martin-Luft

    When I do that (what a mess, 2 module loaders...), it tries to load the module file by using baseURL + string from the router (e.g. http://localhost:8080/app/configuration/configuration.module). This makes no sense to me (e.g. bundling your applicationn or without bundling you must configure the server to find the file at this location and you run into trouble with route URL naming conflicts). The official Angular 2 documentation says, it does not matter if you use SystemJS or Webpack... The official Angular 2 ngmodule documentation says you must use loadChildren when dealing with modules and routes (this only works with SystemJS therefore modules only work with SystemJS in RC5). I know that I can use synchronous routes in RC6 which work with Webpack (this works, I tested it with the nightly builds).

  13. brandonroberts commented on Aug 23, 2016

    @brandonroberts
    Contributor

    @Martin-Wegner if you're concerned with the implementation, wait until its officially supported and explained by the CLI. Once RC6 lands, using loadChildren with a function that returns a promise will be supported.

    I imagine that the CLI will replace the loadChildren string with the appropriate function returning a promise that resolves the lazy loaded module as if you did it the "webpack way" and will not being using the provided SystemJS loader.

  14. stefanaerts commented on Aug 29, 2016

    @stefanaerts

    @Martin-Wegner If you want to use the angular-cli current in npm with webpack(angular-cli@1.0.0-beta.11-webpack.2) and make this work right now you have to do the following steps:

    1. add the file async-ng-module-loader.ts to the root of your folder.
    2. add these 2 lines to app.module.ts:
      import {NgModule, NgModuleFactoryLoader} from '@angular/core';
      import {AsyncNgModuleLoader} from './async-ng-module-loader';
    3. at the provider to app.module.ts
      providers: [
      {provide: NgModuleFactoryLoader, useClass: AsyncNgModuleLoader}
      ],
    4. at this import to app.routing.ts
      import {load} from './async-ng-module-loader';
    5. at this path to the module to be lazy loaded,in this example heroes to the HeroModule
      {
      path: 'heroes',
      loadChildren: load(() => new Promise(resolve => {
      (require as any).ensure([], require => {
      resolve(require('./hero/hero.module').HeroModule);
      });
      }))
      }
    6. verify your HeroModule if its export with default or not.
      If it's with default (export default class HeroModule {}) then remove the default word or change the path in step 5 to
      {
      path: 'heroes',
      loadChildren: load(() => new Promise(resolve => {
      (require as any).ensure([], require => {
      resolve(require('./hero/hero.module').default);
      });
      }))
      }
  15. Martin-Luft commented on Aug 29, 2016

    @Martin-Luft

    @stefanaerts thank you :) I hope there will be a out of the box solution like the async routing described here: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#lazy-load

  16. stefanaerts commented on Aug 29, 2016

    @stefanaerts

    Well that document is based on a angular version that uses SystemJs module
    loader.
    So the docs are not up to date, or the angular CLI is ahead of the docs.
    The source code example with it in plunkr uses also a systemjs config file.
    But if you create a project with 'ng new' using the angular cli you get the
    main.ts platformBrowserDynamic().bootstrapModule(AppModule);

    So soon it will be all synchronised(the docs i mean) to handle asynchronous
    stuff.
    Nice ha all synchronised -> to handle asynchronous stuff (-)

    Kind Rg,
    Stefan.

    On Mon, Aug 29, 2016 at 4:27 PM, Martin-Wegner notifications@github.com
    wrote:

    @stefanaerts https://github.com/stefanaerts thank you :) I hope there
    will be a out of the box solution like the async routing described here:
    https://angular.io/docs/ts/latest/guide/ngmodule.html#!#lazy-load

    —
    You are receiving this because you were mentioned.
    Reply to this email directly, view it on GitHub
    #1636 (comment),
    or mute the thread
    https://github.com/notifications/unsubscribe-auth/ADg4935WwhcMefXrvh0sbdx3klFkB4Xuks5qkuxogaJpZM4JhzxM
    .

  17. mjolk commented on Aug 31, 2016

    @mjolk

    @Martin-Wegner I'm guessing if you add typings for System.import it will work? The PR referenced (https://github.com/angular/angular-cli/pull/1632) uses the webpack contextplugin so the existing System.imports should work for webpack as well? At least i think that's the idea.
    check this for typescript support: https://github.com/TypeStrong/ts-loader/issues/129
    I'm just theorizing after reading up on webpack contextplugin, i will test it when i have time :p
    edit: System.import only works with webpack 2.x as far as i know

  18. mjolk commented on Sep 5, 2016

    @mjolk

    i'm trying with angular-cli from master npm linked, i'm getting the System is not defined error and adding Systemjs typings does not help (there are typings for System in src/typings.d.ts apparently), investigating... i would really like to have the lazy loading working with webpack

  19. stephenwilson1984 commented on Sep 5, 2016

    @stephenwilson1984

    Getting the same error myself. Uncaught (in promise): ReferenceError: System is not defined. I'm using Angular2 RC6 with Angular-CLI 1.0.0-beta.11-webpack.2

    Is there any glimmer of hope here?

  20. brandonroberts commented on Sep 5, 2016

    @brandonroberts
    Contributor

    @stephenwilson1984 you can install System using npm install systemjs --save and add it to your scripts array in the angular-cli.json

    From there you can use loadChildren with a function that returns a System.import with the path to your lazy loaded module.

    I have an example repo here using the CLI and RC6: https://github.com/brandonroberts/router-cli-aot

  21. hansl commented on Sep 5, 2016

    @hansl
    Contributor

    To everyone here (before I lock this conversation):

    This feature is working

    You DO NOT need SystemJS in your code. You need RC6 (the latest router specifically) because webpack relies on SystemJS.import() calls which it wouldn't see if you didn't have the latest.

    Again, DO NOT install SystemJS. You're in a world of pain if you do while using webpack (it's possible to make it work but it's not worth it).

    What the #1632 PR did was to pass modules from lazy loading to webpack so webpack would split the bundles in chunks. Then webpack will read angular's code and see System.import() and update it to call the proper chunks.

    The new issue is due to angular/angular#11049 changing the way System is called making it impossible for webpack to detect. We're working on a fix.

    The Angular-CLI itself is working fine. The bug is in Angular's code. We might be able to fix in Angular-CLI by making a custom plugin.

  22. locked and limited conversation to collaborators on Sep 5, 2016
  23. added a commit that references this issue on Jul 14, 2026
    42e1b07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Impacts a large percentage of users; if a workaround exists it is partial or overly painfultype: bug/fix

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions