如何手动延迟加载模块?

问题描述 投票:45回答:2

我尝试使用SystemJsNgModuleLoader在没有路由器的情况下加载模块,但无法使其正常工作:

SystemJsNgModuleLoader

无论我为URL使用什么字符串,我都会得到this.loader.load(url).then(console.info); (粗鲁/相对url /路径...尝试了许多选项)。我查看了路由器的源代码,但没有找到其他内容,除了此Cannot find module xxx。我什至不确定我应该使用这个...


[这个问题是在昨天SystemJsNgModuleLoader会议上提出的-Miško和Matias回答:

MiškoHevery:只需获取模块的所有权,就可以从那里获得组件工厂的所有权,并且可以在应用程序中所需的任何位置动态加载组件工厂。这正是路由器内部所做的。因此,您也可以这样做。

MatiasNiemelä唯一需要特别注意的是,在[Ng] Module上有一个称为ng-europe 2016的东西,它标识可以延迟加载的组件-这是该组件集的入口。因此,当您有延迟加载的模块时,请将stuff放入entryComponents

...但是如果没有关于该主题的示例和差劲的文档,这并不是那么困难(;

任何人都知道如何在不使用entryComponents的情况下手动加载模块吗?如何获取模块和应该放入Route.loadChildren东西到底是什么(我读了entryComponents,但如果没有实际加载模块就无法尝试)?

angular
2个回答
51
投票

任何人都知道如何手动加载模块,而无需使用Route.loadChildren?

您可以使用FAQ获取模块的工厂:

SystemJsNgModuleLoader

对于Angular 8,请参见this.loader.load('./src/lazy.module#TestModule').then((factory: NgModuleFactory<any>) => { console.log(factory); });

这是它的外观:

lazy.module.ts

Lazy load module in angular 8

app.ts

@Component({
  selector: 'test',
  template: `I'm lazy module`,
})
export class Test {}

@NgModule({
  imports: [CommonModule],
  declarations: [Test],
  entryComponents: [Test]
})
export class LazyModule {
  static entry = Test;
}
import {
  Component, NgModule, ViewContainerRef,
  SystemJsNgModuleLoader, NgModuleFactory,
  Injector} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `<h2>Test lazy loading module</h2>`,
})
export class AppComponent {
  constructor(
    private loader: SystemJsNgModuleLoader, 
    private inj: Injector, 
    private vcRef: ViewContainerRef) {}

  ngOnInit() {
     this.loader.load('./src/lazy.module#LazyModule')
       .then((moduleFactory: NgModuleFactory<any>) => {
         const moduleRef = moduleFactory.create(this.inj);
         const entryComponent = (<any>moduleFactory.moduleType).entry;
         const compFactory = 
               moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
         this.vcRef.createComponent(compFactory);
      });
  }
} 

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ AppComponent ],
  providers: [SystemJsNgModuleLoader],
  bootstrap: [ AppComponent ]
})
export class AppModule {} 

this.loader.load('./src/test.module#TestModule').then((factory: NgModuleFactory<any>) => { console.log(factory); });

AOTprecompile模块有两个选项:

1)Angular CLI lazyModules选项(自Angular 6起)

使用angular / cli内置功能:

Plunker Example

请参阅

  • @ RomainLT { "projects": { "app": { "architect": { "build": { "options": { "lazyModules": [ <====== add here all your lazy modules "src/path-to.module" ] } } } } } }
  • answer文章以获取更多详细信息

2)使用来自RouterModule的provideRoutes>

app.module.ts

The Need for Speed: Lazy Load Non-Routable Modules in Angular

app.component.ts

providers: [
  SystemJsNgModuleLoader,
  provideRoutes([
     { loadChildren: 'app/lazy/lazy.module#LazyModule' }
  ])
],

export class AppComponent implements OnInit { title = 'Angular cli Example SystemJsNgModuleLoader.load'; @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef; constructor(private loader: SystemJsNgModuleLoader, private inj: Injector) {} ngOnInit() { this.loader.load('app/lazy/lazy.module#LazyModule').then((moduleFactory: NgModuleFactory<any>) => { const entryComponent = (<any>moduleFactory.moduleType).entry; const moduleRef = moduleFactory.create(this.inj); const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent); this.container.createComponent(compFactory); }); } }


使用webpack和AOT的延迟加载

使用ngc进行编译

使用以下工厂的初始化编译器

Github repo angular-cli-lazy

export function createJitCompiler () { return new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler(); }


10
投票

[[Angular 6]

© www.soinside.com 2019 - 2024. All rights reserved.