Laden Sie neue Module, die dynamisch während der Laufzeit mit Winkel-CLI & Winkel 5

Derzeit arbeite ich an einem Projekt, die gehostet wird auf einem Kunden server. Für die neuen "Module" gibt es nicht die Absicht, neu zu kompilieren die gesamte Anwendung. Das heißt, der client will update der router/lazy geladene Module in der runtime. Ich habe versucht, verschiedene Dinge aus, aber ich kann nicht ankommen es zu wirken. Ich Frage mich, ob einer von Euch weiß, was könnte ich noch versuchen oder was habe ich verpasst.

Eine Sache, die ich bemerkt, die meisten Ressourcen, die ich habe versucht, mit Winkel-cli, sind gebündelt in einzelne Brocken, die von webpack standardmäßig beim erstellen der Anwendung. Das scheint logisch, denn es macht Gebrauch von der webpack-code aufteilen. aber was ist, wenn das Modul noch nicht bekannt ist zur compile-Zeit (aber ein kompiliertes Modul ist irgendwo gespeichert auf einem server)? Die Bündelung funktioniert nicht, weil es nicht finden können, das Modul zu importieren. Und Mit SystemJS lädt UMD-Module, wenn auf dem system gefunden, aber auch gebündelt in einem separaten chunk webpack.

Einige Ressourcen, die ich schon ausprobiert;

Einigen code habe ich schon versucht und implementieren, aber nicht arbeiten in dieser Zeit;

Ausweitung der router mit dem normalen Modul.ts-Datei

     this.router.config.push({
    path: "external",
    loadChildren: () =>
      System.import("./module/external.module").then(
        module => module["ExternalModule"],
        () => {
          throw { loadChunkError: true };
        }
      )
  });

Normalen SystemJS Import von UMD-bundle

System.import("./external/bundles/external.umd.js").then(modules => {
  console.log(modules);
  this.compiler.compileModuleAndAllComponentsAsync(modules['External']).then(compiled => {
    const m = compiled.ngModuleFactory.create(this.injector);
    const factory = compiled.componentFactories[0];
    const cmp = factory.create(this.injector, [], null, m);

    });
});

Importieren von externen Modul funktioniert nicht mit webpack (afaik)

const url = 'https://gist.githubusercontent.com/dianadujing/a7bbbf191349182e1d459286dba0282f/raw/c23281f8c5fabb10ab9d144489316919e4233d11/app.module.ts';
const importer = (url:any) => Observable.fromPromise(System.import(url));
console.log('importer:', importer);
importer(url)
  .subscribe((modules) => {
    console.log('modules:', modules, modules['AppModule']);
    this.cfr = this.compiler.compileModuleAndAllComponentsSync(modules['AppModule']);
    console.log(this.cfr,',', this.cfr.componentFactories[0]);
    this.external.createComponent(this.cfr.componentFactories[0], 0);
});

Verwenden SystemJsNgModuleLoader

this.loader.load('app/lazy/lazy.module#LazyModule').then((moduleFactory: NgModuleFactory<any>) => {
  console.log(moduleFactory);
  const entryComponent = (<any>moduleFactory.moduleType).entry;
  const moduleRef = moduleFactory.create(this.injector);

  const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
});

Habe versucht, laden Sie ein Modul gemacht, mit rollup

this.http.get(`./myplugin/${metadataFileName}`)
  .map(res => res.json())
  .map((metadata: PluginMetadata) => {

    //create the element to load in the module and factories
    const script = document.createElement('script');
    script.src = `./myplugin/${factoryFileName}`;

    script.onload = () => {
      //rollup builds the bundle so it's attached to the window object when loaded in
      const moduleFactory: NgModuleFactory<any> = window[metadata.name][metadata.moduleName + factorySuffix];
      const moduleRef = moduleFactory.create(this.injector);

      //use the entry point token to grab the component type that we should be rendering
      const compType = moduleRef.injector.get(pluginEntryPointToken);
      const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(compType); 
//Works perfectly in debug, but when building for production it returns an error 'cannot find name Component of undefined' 
//Not getting it to work with the router module.
    }

    document.head.appendChild(script);

  }).subscribe();

Beispiel mit SystemJsNgModuleLoader funktioniert nur, wenn das Modul bereits zur Verfügung gestellt, die als 'faul' route in der RouterModule der app (die verwandelt es in ein Stück, wenn gebaut mit webpack)

Fand ich eine viel Diskussion über dieses Thema auf StackOverflow hier und da, und Lösungen scheinen wirklich gut der laden von Modulen/Komponenten dynamisch, wenn bekannt vor. aber keiner ist passend für unseren use-case des Projekts. Bitte lassen Sie mich wissen, was ich noch versuchen kann, oder Tauchen Sie ein in.

Dank!

EDIT: ich habe gefunden; https://github.com/kirjs/angular-dynamic-module-loading und geben dieses ein versuchen.

UPDATE: ich;ve erstellt ein repository mit einem Beispiel für das laden von Modulen, die dynamisch mit SystemJS (und mit Winkel-6); https://github.com/lmeijdam/angular-umd-dynamic-example

InformationsquelleAutor Lars Meijdam | 2018-05-03

Schreibe einen Kommentar