【问题标题】:angular-cli router lazy loadingangular-cli 路由器延迟加载
【发布时间】:2017-05-17 19:57:14
【问题描述】:

我正在尝试运行一个示例 Web 应用程序来了解使用 Angular 模块进行延迟加载的工作原理。我通过使用 angular 2.4.1 的 angular-cli 1.0.0-beta.24 生成了应用程序。我生成了核心应用程序,然后生成了 3 个组件。然后,我在应用程序级别添加了路由,并通过将组件导入应用程序模块来直接引用前两个组件。对于第三个组件,我只是使用Angular routing docs 中指定的 loadChildren 方法添加了路由。我的主应用路由配置如下:

const appRoutes: Routes  = [
    { path: 'comp1', component: Comp1Component},
    { path: 'comp2', component: Comp2Component},
    { path: 'comp3', loadChildren: 'app/comp3/comp3.module'}
];

export default RouterModule.forRoot(appRoutes);

我将第三个组件的代码转换为一个模块,并删除了从应用程序到第三个组件的所有导入。该模块的路由配置如下:

const routes: Routes = [
    {path: '', component:Comp3Component}
];

export default RouterModule.forChild(routes);

当我运行应用程序时,Comp1 和 Comp2 的路由工作正常,当我单击 Comp3 的链接(模块路由)时,我在控制台中记录了以下错误:

EXCEPTION: Uncaught (in promise): Error: Cannot find module ./comp3/comp3.module'.
Error: Cannot find module './comp3/comp3.module'.
    at webpackEmptyContext (http://localhost:4200/main.bundle.js:77:8) [angular]

似乎 webpack 没有处理延迟加载。我尝试了“loadChildren”调用的各种路径变体,包括:

loadChildren: 'app/comp3/comp3.module#Comp3Module'

行为没有变化(仍然出现上述错误)。 angular2 的新手,所以可能是我的代码中的某些内容,但我看到其他人也遇到了同样的错误。我的 google/stackoverflow foo 没有引导我找到解决方案。 我添加了我的sample app to my Github account here。

I saw this issue logged by another developer with the Angular team but they kicked it as a support issue to StackOverflow because the sample worked on plunkr. 我确信那里有一个线索,但我对 webpack 以及它在寻找应用程序的 plunkr 与 ng serve 运行之间的差异方面的了解还不够。

添加附加信息。该应用的 html 模板如下所示(also available on github repo):

 <h1>
    {{title}}
 </h1>
 <ul>
    <li><a class="nav-link" routerLink="/comp1" routerLinkActive="active">Component 1</a></li>
    <li><a class="nav-link" routerLink="/comp2" routerLinkActive="active">Component 2</a></li>
    <li><a class="nav-link" routerLink="/comp3" routerLinkActive="active">Component 3</a></li>
  </ul>
  <p></p>
  <router-outlet></router-outlet>

我将此应用程序的源代码树(从 src/app 向下)复制到 angular2 seed project,并在预期的一些较小的 tweeks 中运行良好,并在 angular-cli 设置的环境中继续失败。我对 TS 源所做的唯一更改是使用相对路径:

{ path: 'comp3', loadChildren: './comp3/comp3.module#Comp3Module'}

用于 loadChildren 调用。我更改了我的 Github 示例代码以反映此更新,但在 angular-cli 环境下仍然失败。

【问题讨论】:

    标签: angular angular2-routing angular-cli


    【解决方案1】:

    试着像这样改变你的路线 常量路线:路线= [

    {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
    }, 
    {    
            path: 'home',
        component: HomeComponent
    },
    
     {
        path: 'job-details/:id',
        component: JobDetailsComponent
    },
    

    ];

    【讨论】:

      【解决方案2】:

      使用 loadChildren 路由的另一种方式如下:

      在您的app.route.ts 中使用

      // have to be export modules to handle the lazy loading routing
      export function loadExampleModuleOne() {  return ExampleModuleOne } 
      export function loadExampleModuleTwo() { return ExampleModuleTwo }
      

      然后在你的路由之后你需要使用如下:

      const APP_ROUTE: Routes = [
        {
          path: '',
          redirectTo: 'example-one',
          pathMatch: 'full'
        },
        {
          path: 'example-one',
          loadChildren: loadExampleModuleOne
        },
        {
          path: 'example-two',
          loadChildren: loadExampleModuleTwo
        }
      ];
      
      export const AppRouting = RouterModule.forRoot(APP_ROUTE);
      

      然后在app.module.ts 中使用AppRouting 常量,例如:

      import {AppRouting} from './app.routing';
      
      
      @NgModule({
         import: [
           AppRouting
         ]
      })
      export class AppModule() {
      }
      

      【讨论】:

      • 对我来说,这个解决方法暂时解决了这个问题,但它真的是延迟加载模块吗?
      • 这不是真正的延迟加载,实际上 AngularCLI 不会生成模块文件
      【解决方案3】:

      更改您的 comp3.routes.ts:

      export default RouterModule.forChild(routes);
      

      收件人:

      export const comp3Routing = RouterModule.forChild(routes);
      

      在你的 comp3.module.ts 上替换:

      import comp3Routes from "./comp3.routes";
      

      收件人:

      import { comp3Routing } from "./comp3.routes";
      

      最后导入 comp3Routing,所以它应该是这样的:

      @NgModule({
          imports: [
              CommonModule,
              RouterModule,
              comp3Routing,
          ],
          declarations: [
              Comp3Component
          ],
          exports: [
              Comp3Component
          ],
      
          providers: [],
      })
      export class Comp3Module { }
      

      你对 comp3 的延迟加载应该可以工作。

      【讨论】:

      • 解决了。第三个组件加载并显示在 webpack 源代码中。非常感谢。
      • 出于兴趣,您是否使用这种方法获得了额外的块构建文件?我使用 Lazy Loaded 儿童路线,在为 prod 和 AOT 构建时,我只得到标准的 4 个捆绑包 - 它永远不会进一步分解它......我不知道这是否正常
      【解决方案4】:

      您是否尝试过为延迟加载的组件指定完整路径?

      以下是我们工作的示例(我们所有的惰性组件都位于 +lazy 文件夹中):

      { path: 'lazy', loadChildren: './omfpages/+lazy/lazy.module#LazyModule' }], canActivate: [AuthGuard] }
      

      我们使用带有 webpack 的 angular cli。

      另外 - 你的路由器链接到惰性页面是什么样的?

      我们的:

      routerLink: ['omfpages/lazy/page32']   
      

      请注意,“懒惰”标签是命中主路由器的标签。 App.router 然后查找惰性模块的路径,然后将“page32”部分传递给惰性路由器。

      下面是我们的惰性路由器:

      ...
      const routes: Routes = [
        { path: 'page30', component: Page30Component, data: { title: 'Fun     Page'} },
        { path: 'page31/:id', component: Page31Component, data: { title:     'Another Page'} },     // <-- this route requires a param to be passed.
        { path: 'page32', component: Page32Component, data: { title: 'Some Page'} }
      ];
      
      export const routing: ModuleWithProviders = RouterModule.forChild(routes);
      

      【讨论】:

      • 我已经为 loadChildren 调用尝试了几种路径变体。我的来源位于根目录下的 /src/app/comp3 。我尝试过:'./app/comp3/comp3.module'、'/app/comp3/comp3.module'、'./comp3/comp3.module',可能还有其他一些
      • 'omfpages/+lazy/lazy.module#lazyModule'字符串中的'+'有什么意义?
      • + 只是一个命名约定。您是否尝试过“comp3”而不是“懒惰路由器”中的路径?
      猜你喜欢
      • 2019-06-14
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      相关资源
      最近更新 更多