Charger de nouveaux modules dynamiquement au moment de l'exécution Angulaire de la CLI & Angulaire 5
Actuellement je travaille sur un projet qui est hébergé sur un des clients du serveur. Pour les nouveaux "modules" il n'y a pas l'intention de recompiler l'ensemble de l'application. Cela dit, le client veut mise à 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.
Code je l'ai déjà essayé et à mettre en œuvre, mais pas de travail en 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 de la plongée.
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
OriginalL'auteur Lars Meijdam | 2018-05-03
Vous devez vous connecter pour publier un commentaire.
J'ai été confrontée au même problème. Autant je comprends que jusqu'à maintenant:
Webpack met toutes les ressources dans un bundle et remplace toutes les
System.import
avec__webpack_require__
. Par conséquent, si vous souhaitez charger un module dynamiquement lors de l'exécution à l'aide de SystemJsNgModuleLoader, le chargeur de recherche pour le module dans le bundle. Si le module n'existe pas dans le bundle, vous obtiendrez une erreur. Webpack ne va pas demander au serveur pour ce module. C'est un problème pour nous, car nous voulons charger un module que nous ne savons pas à construire/moment de la compilation.Nous avons besoin d'un chargeur qui vous permettra de charger un module pour nous au moment de l'exécution (paresseux et dynamique). Dans mon exemple, je suis en utilisant SystemJS et Angulaire 6 /CLI.
app.composante.ts
mon-dynamique.composante.ts
autres.composante.ts
Comme vous pouvez le voir, nous pouvons dire SystemJS ce que les modules existent déjà dans notre bundle. Donc, nous n'avons pas besoin de les charger à nouveau (
SystemJS.set
). Tous les autres modules que nous importons dans notremy-dynamic-component
(dans cet exempleother
) sera demandée à partir du serveur au moment de l'exécution.La composante dynamique dans votre exemple, où est-il situé? Avez-vous créer une bibliothèque (ng g lib <nom>) tout d'abord et de l'utilisation de l'UMD module reçu de la construction de cette bibliothèque ? Ou avez-vous transpile vous-même avant de servir/la construction de l'ensemble de l'application? Sinon vous avez un plunkr ou?
Ma configuration est un peu plus complexe. Donc je ne suis pas sûr. Dès que vous exécutez
SystemJS.import('my-dynamic.component.js').then()
, vous pourrez voir où votre navigateur est à la recherche pour elle. Il devrait être dans le dossier racine de votre application ou de votre côtéAppComponent
. Je suis à l'aide de Visual Studio Visual Studio est transpiling monmy-dynamic.component.ts
. Vous pouvez utiliser tsc mon-dynamique.composante.ts Si je l'ai trouver un peu de temps, je vais créer une plunkr. Mais jusqu'alors, je vais mettre à jour ma réponse ici.Je viens de créer un github: github.com/mrmscmike/ngx-dynamic-module-loader C'est juste un projet et nous avons besoin de l'améliorer. Peut-être que nous pouvons rassembler nos expériences. Toute aide est la bienvenue.
Je pense que je sais quel est le problème avec "Pas de NgModule métadonnées trouvé pour 'undefined'". Si vous regardez votre
*.umd.js
et de le comparer à l'exemplemy.module.js
, vous pouvez voir que mon.module effectue les opérations suivantesexports["default"] = MyModule;
. L'angle de 6 lib neexports.MyModule = MyModule;
. Si vouscompileModuleAndAllComponentsAsync(module['PluginModule'])
il fonctionne. Aucune idée de comment obtenir.default
de travailOriginalL'auteur Michael
J'ai utilisé le https://github.com/kirjs/angular-dynamic-module-loading solution Angulaire 6 bibliothèque du soutien à la création d'une application que j'ai partagé sur Github. En raison de la politique de l'entreprise, il doit être pris en mode hors connexion. Dès que des discussions sont en cours à propos de l'exemple de projet source, je vais le partager sur Github!
Mise à JOUR: repo peut être trouvé ; https://github.com/lmeijdam/angular-umd-dynamic-example
assets
. Comment sur la liaison à un tapuscrit module? doivent d'abord être convertis à la js copiés manuellement.la solution que nous avons à notre projet cherché, c'est plus basé sur les modules compilés (JS), les charger dynamiquement à partir d'un serveur (qui est toujours discutable). donc il ne charge "fini" modules qui ont été placés dans un dossier spécifique, pas la machine si
OriginalL'auteur Lars Meijdam
Je crois que cela est possible à l'aide de SystemJS pour charger un UMD bundle si vous créez et exécutez votre application principale à l'aide de webpack. J'ai utilisé une solution qui utilise la ng-packagr de construire un UMD ensemble de la dynamique plugin/addon module. Cette github montre la procédure décrite:
https://github.com/nmarra/dynamic-module-loading
OriginalL'auteur N.M.
Faire angulaire 6 bibliothèque et cumulatif de faire le tour. Je viens de le tester et je peux partager autonome angulaire AOT module avec l'application principale sans reconstruction dernier.
angularCompilerOptions.skipTemplateCodegen
pour faux et après la construction de la bibliothèque, vous obtiendrez module d'usine.rollup dist/plugin/esm2015/lib/plugin.module.ngfactory.js --file src/assets/plugin.module.umd.js --format umd --name plugin
Ici https://github.com/iwnow/angular-plugin-example vous pouvez trouver comment développer plugin dans un bâtiment isolé et AOT
Un problème avec cette configuration, c'est que, lorsque le plugin projet importations Angulaire Module qui a l'entrée des composants répertoriés, généré plugin UMD va se retrouver avec des usines de tous les composants énumérés à l'entrée des composants.
OriginalL'auteur Vitaliy Vostroknutov
Oui, vous pouvez le lazy load modules à l'aide en se référant à eux comme à des modules dans le routeur. Voici un exemple https://github.com/start-angular/SB-Admin-BS4-Angular-6
vous n'avez donc fid une solution? Je suis de créer du html/ts formes angulaires dinamically et je voulais importer dans une application en cours d'exécution. Je voudrais aussi que ce genre de choses pour ne pas être précompilés, juste la plaine ts+html. Aucune info?
OriginalL'auteur Jaya Krishna
J'ai testé Angulaire 6, ci-dessous la solution fonctionne pour le chargement dynamique d'un module à partir d'un package externe ou un module interne.
1. Si vous voulez charger dynamiquement un module à partir d'un projet de bibliothèque ou d'un package:
J'ai un projet de bibliothèque "admin" (ou vous pouvez utiliser un paquet) et un projet d'application "app".
Dans mon "admin" de la bibliothèque de projet, j'ai AdminModule et AdminRoutingModule.
Dans mon "app" projet:
un. Faire des changements dans le tsconfig.app.json:
b. En application de routage.le module.ts:
2. si vous souhaitez charger un module à partir d'un même projet.
Il y a 4 options différentes:
un. En application de routage.le module.ts:
C'est très bien. J'ai été à la recherche d'une solution similaire avec votre cas. Mais la différence est que, je voudrais avoir un fichier de configuration de la liste de tous les modules, puis les charger ensuite dans l'application de manière dynamique. Malheureusement, mon approche (cas 1) ci-dessus a encore quelques questions. c'est à dire Dans le but d'utiliser
await import(...)
, je ne peux pas utiliser une variable, ce qui signifie que je n'arrive pas à atteindre l'objectif de charger dynamiquement les paquets. Mais le cas 2 fonctionne très bien. Je suis encore en train de faire de la recherche avec webpack pour voir si il y a un autre indice.Avez-vous vérifier mon projet github qui est noté à la fin de la question ?:) Cela pourrait être d'une aide!;) github.com/lmeijdam/angular-umd-dynamic-example
Je vous remercie beaucoup. Il fonctionne bien. Chargement à partir d'une URL est une très bonne solution. 🙂
OriginalL'auteur Robin Ding
Pas De Travail
de travail
OriginalL'auteur Sushil Sultan Sunuwar