懒加载在Angular 6中无法正常工作

7

当尝试导航到'http://localhost:4200/dashboard'的懒加载路由时,我遇到了这个错误,使用的是Angular和Angular-CLI 6.0.0。

错误:未捕获(在promise中):错误:找不到模块"app/dashboard/dashboard.module"。错误:找不到模块"app/dashboard/dashboard.module"。 在$_lazy_route_resource lazy namespace object:5处

const routes: Routes = [
    {
        path: 'login',
        loadChildren: 'app/login/login.module#LoginModule',

    },
    {
        path: '',
        component: MasterComponent,
        children: [
            {
                path: 'dashboard',
                loadChildren: 'app/dashboard/dashboard.module#DashboardModule'
            }
        ],
    },
    {
        path: '**',
        redirectTo: 'login
    }
];


@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
    providers: []
})
export class AppRoutingModule {
}

1
应该是'./dashboard/dashboard.module#DashboardModule',对吗? - Fateh Mohamed
谢谢,它可以工作了。 https://github.com/angular/angular/commit/f44a2c730a84cd86695d1851395ad28423704bd0 (@samalexander 3天前提交) - Chanuka Asanka
发表为答案,我会点赞 ;) - A T
好知道,祝你好运 - Fateh Mohamed
9个回答

12

以前的版本使用'app/path/to/module#Module'来支持loadChildren路径,但现在不再起作用了,改为使用相对路径'./path/to/module#Module'

例如angular/aio/content/examples/lazy-loading-ngmodules 的示例在Angular 6发布后发生了更改

https://github.com/angular/angular/commit/f44a2c730a84cd86695d1851395ad28423704bd0

Angular社区已经对我提出的问题做出了回应,请查看下面的答复。

https://github.com/angular/angular-cli/issues/10673#issuecomment-391786453

根据Angular社区的回复,他们将更新文档。

使用方式需要更改为

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: 'app/customers/customers.module#CustomersModule'
  },
  {
    path: 'orders',
    loadChildren: 'app/orders/orders.module#OrdersModule'
  },
  {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: './customers/customers.module#CustomersModule'
  },
  {
    path: 'orders',
    loadChildren: './orders/orders.module#OrdersModule'
  },
  {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];

另一个提示:

模块导入顺序很重要 https://angular.io/guide/router#module-import-order-matters


2
另一个解决方案:https://angular.io/guide/router#module-import-order-matters
  • 导入顺序发生了变化。(将 *RoutingModule 移动到导入列表底部)
  • 同时从 NgModule.imports 属性列表中删除了惰性加载的模块。
- Chanuka Asanka
社区已经在另一个问题中讨论了有关文档更改的内容。https://github.com/angular/angular-cli/issues/10673#issuecomment-391817263 - Chanuka Asanka
1
那个“另一个提示”救了我!谢谢。 - Ardeshir Izadi
1
指出“顺序很重要”做得好!在我找到这个之前,我已经骂了好几个小时了。 - seankonig

5

我有同样的问题,但是在Angular 6中,每个使用“懒加载”的模块似乎都必须从根模块(app.module.ts)的imports声明中移除。至少对于我来说这种方法有效。


1
正是我的问题。如果你想一想,为什么要将那个懒加载模块导入到根目录呢?这完全违背了懒加载整个代码块的初衷。 - mccainz

4

使用 Angular 7

这对我有效

loadChildren = 'src/app/layout/waay/lazy.module.ts#LazyModule';

同时在

angular.json

...
"lazyModules": [
            "src/app/layout/waay/lazy.module.ts",
]

也许这能帮助某些人调试懒加载路径 ->

(在即将发布的 Angular 版本中,这可能会有所改变)

在谷歌浏览器中

  • 打开开发者工具 F12

  • 按下 ctrl+O (字母 O)

  • (一个搜索提示框将会打开)

  • 在键盘上,输入 "lazyroute"

  • (它应该列出 $_lazy_route_resource lazy namespace object)

  • 按下 Enter

现在,它应该向您显示 Angular/webpack 用于查找懒加载路由的映射内容

$_lazy_route_resource 懒加载命名空间对象(文件开头)

var map = {
    "src/app/layout/waay/lazy.module.ts": [
        "./src/app/layout/waay/lazy.module.ts"
    ],
    "src/app/pages/even/more-lazy.module.ts": [
        "./src/app/pages/even/more-lazy.module.ts",
        "default~src-app-pages-even-more-lazy-module-ts~src-app-pages-some-page-module-ts~sr~2cb20cb3",
        "default~src-app-pages-even-more-lazy-module-ts~src-app-pages-counter-page-module~7852bff4",
        "common",
        "src-app-pages-even-more-lazy-module-ts"
    ],
    "src/app/pages/too/lazy-to-be-true.module.ts": [
        "./src/app/pages/too/lazy-to-be-true.module.ts",
        "default~src-app-pages-too-lazy-to-be-true-module-ts~src-app-pages-some-page-modu~c179459d",
        "default~src-app-pages-too-lazy-to-be-true-module-ts~src-app-pages-home-home-page-module-ts~src-app-~50ff7d88",
        "default~src-app-pages-too-lazy-to-be-true-module-ts~src-app-pages-home-home-page-module-ts",
        "common",
        "src-app-pages-too-lazy-to-be-true-module-ts"
    ],
    ...
};

地图显示了给定模块路径的模块路径要加载的模块之间的关系。通过查看这张地图,可能会帮助您找出为什么有些路径无法解析。
您也可以在以下行中设置断点,通过调试器逐步执行它并清楚地了解在查找中它可能失败的位置。 $_lazy_route_resource lazy namespace object (文件向下)
function webpackAsyncContext(req) {
    var ids = map[req];           // <-- put a breakpoint there, lookup in the map happens here
    if(!ids) {
        return Promise.resolve().then(function() {
            var e = new Error("Cannot find module '" + req + "'");
            e.code = 'MODULE_NOT_FOUND';
            throw e;
        });
    }
    ...
}

希望这可以帮助到某些人,对我来说起作用了


1
这是一个很棒的解释,非常感谢朋友。现在调试更容易了。 - Debadatta
1
谢谢Debadatta,真的很高兴能帮到你!:)) - lolcatzftw
这个地方应该用冒号而不是等于号吧? - MindRoasterMir

3

我来修改这个内容

loadChildren: './layouts/admin-layout/admin-layout.module#AdminLayoutModule',

To

loadChildren: () => AdminLayoutModule,

需要工作并且不要忘记导入模块文件。

希望这有所帮助!


1
没错,但那是急加载。 - Glenn Bullock
你部署在哪里了吗?我已经在Azure应用服务上部署了,而且它对我来说很有效。 - Naveen Motwani - AIS
它需要JIT编译资源,因为这是动态加载。它不能在启用AOT的生产构建中工作,但您可以在本地使用它。 - dprophecyguy
这个可以工作,但你必须导入该模块。谢谢。 - MindRoasterMir

2
有效地,有三种可能的解决方案

  • 使用相对路径loadChildren: './dashboard...
  • 绝对路径但从/src开始:loadChildren: 'src/app/dashboard...
  • tsconfig.json中设置BaseUrl: "./src"

您可以跟踪Angular存储库中的问题的进展。

(*) 编辑,值得庆幸的是,在最新版本中使用箭头函数进行懒加载已经改变了。


绝对路径但从/src开始:loadChildren: 'src/app/dashboard...应该从'app/exampleroute'开始。https://angular.io/guide/router#lazy-loading-route-configuration - Chanuka Asanka
是的,baseUrl已经更改为Angular项目的根目录,因为它将包含多个应用程序。他们开放了一个问题来更新文档并利用相对路径。 - Ricard Castelló Rocamora
对我有效的唯一方法就是更改tsconfig.json文件,将BaseUrl设置为“./src”。 - markelc

2

当我用component替换loadchildren时,它对我起作用了。


0

对我来说,它的工作方式是:

{path: 'Customer', loadChildren: () => import('../Customer/CustomerModule').then(mod => mod.CustoModule)},

这是一个用于路由的单独文件,我没有在app.routing中进行路由设置,所以如果你也像我一样,请在模块文件的imports中删除"AppRoutingModule"。只有这样才能正常工作。


0

幸运的是,最新版本中使用箭头函数进行惰性加载,这种情况得到了改善。


请提供高质量的答案,直到您能够编写评论。这种类似评论的答案是不够的。 - MoxxiManagarm

0

我在开始使用Angular Cli 9时遇到了同样的问题。为了解决这个问题,需要按照以下方式重新编写loadChildren

{path: 'admin', canLoad: [AuthGuard], loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)},

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接