Actuellement, je travaille sur un projet qui est hébergé sur un des clients du serveur. Pour les nouveaux "modules" il n'y a aucune intention de recompiler l'ensemble de l'application. Cela dit, le client veut mettre à jour le routeur/paresseux modules chargés dans le runtime. J'ai essayé plusieurs choses mais je ne peux pas le faire fonctionner. Je me demandais si l'un de vous sait ce que je pourrais toujours essayer ou de ce que j'ai raté.
Une chose que j'ai remarqué, la plupart des ressources que j'ai essayé, à l'aide angulaire de la cli, sont regroupés en deux morceaux par webpack par défaut lors de la construction de l'application. Ce qui semble logique, car il rend l'utilisation de la webpack code de fractionnement. mais que faire si le module n'est pas encore connu au moment de la compilation (mais la compilation d'un module est stocké quelque part sur un serveur)? Le regroupement ne fonctionne pas car il ne trouve pas le module d'importation. Et à l'Aide de SystemJS vous permettra de charger jusqu'UMD modules où qu'ils se trouvent sur le système, mais sont également regroupés dans un autre morceau par webpack.
Quelques ressources que j'ai déjà essayé;
- dynamique-à distance-composant-chargeur
- module de chargement
- Le chargement des modules de serveur différent au moment de l'exécution
- Comment charger de la dynamique de composants externes dans Angulaire de l'application
- Mise en œuvre d'une architecture de plugin / plugin / système enfichable cadre Angulaire 2, 4, 5, 6
- Angulaire 5 - charger les modules (qui ne sont pas connus au moment de la compilation) de manière dynamique au moment de l'exécution
- https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e
- Plusieurs autres concernant ce sujet.
Certains code, je l'ai déjà essayé et à mettre en œuvre, mais ne fonctionne pas à ce moment;
L'extension de routeur avec la normale du module.fichier ts
this.router.config.push({
path: "external",
loadChildren: () =>
System.import("./module/external.module").then(
module => module["ExternalModule"],
() => {
throw { loadChunkError: true };
}
)
});
Normal SystemJS Importation de 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);
});
});
Importation de module externe, pas de travail avec webpack (autant que je sache)
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);
});
Utilisation 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);
});
Essayé le chargement d'un module avec le correctif cumulatif
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();
Exemple avec SystemJsNgModuleLoader ne fonctionne que lorsque le Module est déjà prévu comme "paresseux" voie de la RouterModule de l'application (ce qui en fait un morceau construit avec webpack)
J'ai trouvé beaucoup de discussion sur ce sujet sur StackOverflow ici et là et les solutions apportées semblent vraiment bon de charger les modules/composants dynamiquement si elle est connue d'avance. mais il n'est pas convenable pour notre cas d'utilisation du projet. S'il vous plaît laissez-moi savoir ce que je peux toujours essayer ou de plongée dans.
Merci!
EDIT: j'ai trouvé; https://github.com/kirjs/angular-dynamic-module-loading et de donner à ceci un essai.
Mise à JOUR: j'ai créé une archive avec un exemple de chargement des modules dynamiquement à l'aide de SystemJS (et en utilisant Angulaire 6); https://github.com/lmeijdam/angular-umd-dynamic-example