从Angular 7的已编译库中延迟加载模块

时间:2019-04-12 08:59:04

标签: angular angular-cli lazy-loading jit

我正在尝试从库中延迟加载NgModule。我有一个ng应用,其中包含一些库(项目)。该库可在其他一些项目中重用。问题是我找不到解决方案,该解决方案既可以同时使用jit和aot,也可以使用已编译/未编译的库。

文件结构是这样的

app
-projects
--lib
---(lib files)
-src
--(app files)

AppModule具有路由,看起来像这样

const routes: Routes = [
    {
        path: 'eager',
        children: [
            {
                path: '',
                component: LibComponent // component imported from lib
            },
            {
                path: 'lazy',
                loadChildren: 'lib/src/lib/lazy/lazy.module#LazyModule' // module i want to load lazily
            }
        ]
    }
];

如果我这样使用它,则在尝试导航到jit中的惰性路由时会出现运行时错误(aot正常工作): ERROR Error: Uncaught (in promise): TypeError: undefined is not a function TypeError: undefined is not a function

此评论https://github.com/angular/angular-cli/issues/9488#issuecomment-370065452建议不要将LazyModule包含在任何桶文件中,但是如果我从库的public_api中排除它,则会出现构建错误:

ERROR in ./projects/lib/src/lib/lazy/lazy.module.ts
Module build failed (from ./node_modules/@ngtools/webpack/src/index.js):
Error: C:\projects\lazy_minimal\lazy-minimal\projects\lib\src\lib\lazy\lazy.module.ts is missing from the TypeSc
ript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
    at AngularCompilerPlugin.getCompiledFile (C:\projects\lazy_minimal\lazy-minimal\node_modules\@ngtools\webpac
k\src\angular_compiler_plugin.js:752:23)
    at plugin.done.then (C:\projects\lazy_minimal\lazy-minimal\node_modules\@ngtools\webpack\src\loader.js:41:31
)
    at process._tickCallback (internal/process/next_tick.js:68:7)

有什么方法可以使其同时适用于aot和jit吗?

1 个答案:

答案 0 :(得分:0)

Angular-CLI中存在一个开放的问题,涉及以延迟加载方式here将已编译的库加载到node_modules中,但它仍处于打开状态。

建议的最后一种解决方法是:

此线程是在不久前打开的。具有这样的注释使人们很难找到除最新注释之外的任何信息。但另一方面,我认为大多数人都不会接受所有评论。看到此主题的新用户大多会阅读第一条评论和最新评论,而在这两条评论之间会丢失一些内容。

因此,出于上述原因(大量评论,隐藏评论,难以举报和通知他人),我正在锁定此问题,以防止随着新评论的加入而丢失此评论。

感谢所有报告并帮助诊断问题并提供解决方法的人。

我们推荐的在有角度的工作空间或节点模块中延迟加载库的方法是使用代理/包装器模块。使用这种方法,延迟加载将同时在JIT和AOT模式下工作。还有其他一些只能在AOT模式下工作的解决方案,例如tsconfig import,但是为了获得更好的开发体验,我们不鼓励这样做。

在下面找到推荐方法的示例;

第一个lazy/lazy.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { LibModule, LazyComponent } from 'my-lib';

@NgModule({
  imports: [
    LibModule,
    RouterModule.forChild([
      { path: '', component: LazyComponent, pathMatch: 'full' }
    ])
  ]
})
export class LazyModule { }

然后app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
  ],
  imports: [
    RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full'},
      { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule'},
    ]),
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

1月10日与合作者的角度锁定和有限的对话