简体   繁体   中英

Angular lazy load module that only contains services?

I'm looking for a way to lazy load a module that doesn't contains any components but services only. The background: in my app is an Excel export service using exceljs library. This library is extremely large and I'm trying to prevent that the library will become part of vendor.js or main.js . It is "included" via import * as Excel from 'exceljs/dist/exceljs.min.js' in a service.

Now I have several components in separate modules that make use of the "Excel export" service (no component). I would prefer a method that the service is only loaded if the user is "clicking the export button" but not before.

How this can be done?

Here would be an approach:

excel.module.ts

@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ],
  providers: [ExcelService]
})
export class ExcelModule {
  static loaded = false;
}

app.component.ts

export class AppComponent {
  constructor (
    private compiler: Compiler,
    private injector: Injector
  ) { }
  
  load () {
    import('./excel/excel.module')
      .then(m => m.ExcelModule)
      .then(m => {
        console.dir(m.loaded)
        
        return m;
      })
      .then(m => this.compiler.compileModuleAsync(m).then(r => (m.loaded = true,r)))
      .then(factory => {
        const module = factory.create(this.injector);
        
        console.dir(module.injector.get(ExcelService))
      })
  }
}

The first time is loaded, m.loaded will be false . On subsequent times, it will be true . With this, we can be sure that we don't load the module multiple times.

Of course, a easier (and probably better) approach will be to have a dedicated service for loading modules eg ModuleLoaderService , where you'd have a Map object keeping track of loaded modules.

ng-run demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM