2017-04-04 6 views
10

Je travaille sur une application Angular2 qui est regroupée avec webpack. Tout fonctionne très bien. Cependant, cette application groupée sera expédiée de manière indépendante et à l'exécution, avant de démarrer l'application, j'ai besoin de spécifier d'autres NgModules dans l'un des modules que j'ai inclus dans mon application. Fondamentalement, pensez-y comme deux faisceaux inclus dans index.html, et quand bootstraped, bundle 1 va dans bundle2. Seulement bundle 2 bootstraps une application. J'ai donc fait quelques expériences que j'aimerais partager avec vous pour faire la lumière (je suis peut-être en train de prendre une approche plutôt sale et complètement fausse, alors s'il vous plait, corrigez si c'est le cas. est la seule façon dont cela peut fonctionner si.). La seule exigence est que rien ne doit être fait pendant la transpiration. L'exigence est que je peux inclure un ou plusieurs paquets sur mon index.html et ils peuvent être accrochés dans l'application réelle sans aucune connaissance préalable les uns des autres.inclure dynamiquement un autre paquet webpack dans une application angulaire

La raison pour laquelle je fais ceci en premier lieu est parce que je travaille sur une plate-forme où d'autres développeurs peuvent accrocher le code en installant des extensions. Cela signifie que je livre le paquet initial, qui n'a aucune connaissance d'autres paquets sur le temps de transpile quoi-si-jamais. C'était facile dans AngularJS, mais en passant à Angular2 et au-delà, ce n'est plus si facile.

j'ai réussi à retarder bootstrapping l'application de l'approche suivante:

En main.ts:

window["platformBrowserDynamicRef"] = platformBrowserDynamic(); 
window["appModule"] = AppModule; 

Cela fonctionne bien et quand j'appelle bootstrap manuellement, l'application démarre très bien. J'ai créé un autre bundle qui fonctionne indépendamment comme une autre application.

Lorsque j'essaie de les regrouper en important les composants dans un tableau implicite comme ci-dessus, et que j'amorce l'application, j'obtiens une erreur que je ne sais pas quoi faire.

window["app"].modulesImport.push(CommonModule); 
window["app"].modulesImport.push(FormsModule); 
window["app"].modulesImport.push(BrowserModule); 
window["app"].modulesImport.push(NgGridModule); 
window["app"].modulesImport.push(ReactiveFormsModule); 
window["app"].modulesImport.push(BrowserAnimationsModule); 
window["app"].modulesImport.push(HttpModule); 

@NgModule({ 
    imports: window["app"].modulesImport, 
    declarations: [ 
     DYNAMIC_DIRECTIVES, 
     PropertyFilterPipe, 
     PropertyDataTypeFilterPipe, 
     LanguageFilterPipe,  
     PropertyNameBlackListPipe  
    ], 
    exports: [ 
     DYNAMIC_DIRECTIVES, 
     CommonModule, 
     FormsModule, 
     HttpModule 
    ] 
}) 
export class PartsModule { 

    static forRoot() 
    { 
     return { 
      ngModule: PartsModule, 
      providers: [ ], // not used here, but if singleton needed 
     }; 
    } 
} 

Avoir les modules dans un tableau implicite fonctionne très bien, mais dès que j'ajouter un module de mon autre paquet je reçois l'erreur suivante:

Uncaught Error: Unexpected value 'ExtensionsModule' imported by the module 'PartsModule'. Please add a @NgModule annotation. 
    at syntaxError (http://localhost:3002/dist/app.bundle.js:43864:34) [<root>] 
    at http://localhost:3002/dist/app.bundle.js:56319:44 [<root>] 
    at Array.forEach (native) [<root>] 
    at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>] 
    at CompileMetadataResolver.getNgModuleSummary (http://localhost:3002/dist/app.bundle.js:56244:52) [<root>] 
    at http://localhost:3002/dist/app.bundle.js:56317:72 [<root>] 
    at Array.forEach (native) [<root>] 
    at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>] 
    at CompileMetadataResolver.getNgModuleSummary (http://localhost:3002/dist/app.bundle.js:56244:52) [<root>] 
    at http://localhost:3002/dist/app.bundle.js:56317:72 [<root>] 
    at Array.forEach (native) [<root>] 
    at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>] 
    at JitCompiler._loadModules (http://localhost:3002/dist/app.bundle.js:67404:64) [<root>] 
    at JitCompiler._compileModuleAndComponents (http://localhost:3002/dist/app.bundle.js:67363:52) [<root>] 

J'ai aussi essayé de compiler ATdD le ExtensionsModule qui ne fonctionne pas non plus. J'ai également essayé de compiler dynamiquement les composants à l'exécution en utilisant JitCompiler pour voir si je pouvais les intégrer dans l'application de cette façon. Même erreur cependant.

Les composants sont-ils décorés pendant le boostrapping de l'application ou pendant la transpiration? Jetant un œil aux modules de mon tableau implicite, je peux voir qu'ils sont décorés, mais pas le mien. Est-ce que webpack insère le code appelant de la méthode décorator? Je suppose que l'information du décorateur est perdue pendant la transpiration, alors peut-être que j'ai besoin de le stocker temporairement de façon à ce que je puisse l'attraper ailleurs. (Notez que extensionsmodule comme premier élément ne contient pas le tableau décorateur)

modules that should be imported in my module

Je suppose que je cherche des pointeurs sur la façon de se déplacer vers l'avant de here.Maybe la fonction d'annotation NgModule serait un bon endroit commencer. Impossible de trouver ça ailleurs.

EDIT

creuser plus dans la question que j'ai essayé l'approche de chargement à l'aide du routeur, où le premier que je reçois cette erreur, en essayant de le charger avec un fichier js (onglet réseau montre que il délivre jamais la demande du fichier):

const appRoutes: Routes = [ 
     { 
     path: 'edit-entity/:type/:id/:culture', 
     component: EntityEditor, 
     resolve: { 
      entity: EntityResolver, 
      navigation: NavigationResolver 
     }, 
     data: { shouldDetach: true}, 
     loadChildren: "/dist/extensions.bundle.js#ExtensionsBundle", 

     }, 
     { 
     path: '', 
     component: Dashboard, 
     resolve: { 
      navigation: NavigationResolver 
     }, 
     data: { shouldDetach: true}   
     } 
    ]; 

Résout l'erreur suivante: « Impossible module de trouver avec le nom ExtensionsModule.js »

en second lieu j'ai essayé en utilisant une fonction loadChildren comme ceci:

const appRoutes: Routes = [ 
     { 
     path: 'edit-entity/:type/:id/:culture', 
     component: EntityEditor, 
     resolve: { 
      entity: EntityResolver, 
      navigation: NavigationResolver 
     }, 
     data: { shouldDetach: true}, 
     loadChildren:() => { 
      //"/dist/extensions.bundle.js#ExtensionsModule",    
      // return System.import('./dynamic.module').then((comp: any) => { 
      //  return comp.otherExport; 
      // }); 

      return window["lux"].modulesLazyImport[0]; 
     } 
     }, 
     { 
     path: '', 
     component: Dashboard, 
     resolve: { 
      navigation: NavigationResolver 
     }, 
     data: { shouldDetach: true}   
     } 
    ]; 

Résout dans:

app.bundle.js:1548 ERROR Error: Uncaught (in promise): Error: No NgModule metadata found for 'ExtensionsModule'. 
Error: No NgModule metadata found for 'ExtensionsModule'. 
    at NgModuleResolver.resolve (app.bundle.js:55709) [angular] 
    at CompileMetadataResolver.getNgModuleMetadata (app.bundle.js:56288) [angular] 
    at JitCompiler._loadModules (app.bundle.js:67404) [angular] 
    at JitCompiler._compileModuleAndComponents (app.bundle.js:67363) [angular] 
    at JitCompiler.compileModuleAsync (app.bundle.js:67325) [angular] 
    at ModuleBoundCompiler.compileModuleAsync (app.bundle.js:67693) [angular] 
    at MergeMapSubscriber.project (app.bundle.js:30608) [angular] 
    at MergeMapSubscriber._tryNext (app.bundle.js:69744) [angular] 
    at MergeMapSubscriber._next (app.bundle.js:69734) [angular] 
    at MergeMapSubscriber.Subscriber.next (app.bundle.js:14584) [angular] 
    at ScalarObservable._subscribe (app.bundle.js:69206) [angular] 
    at ScalarObservable.Observable.subscribe (app.bundle.js:118) [angular] 
    at MergeMapOperator.call (app.bundle.js:69709) [angular] 
    at Observable.subscribe (app.bundle.js:115) [angular] 
    at NgModuleResolver.resolve (app.bundle.js:55709) [angular] 
    at CompileMetadataResolver.getNgModuleMetadata (app.bundle.js:56288) [angular] 
    at JitCompiler._loadModules (app.bundle.js:67404) [angular] 
    at JitCompiler._compileModuleAndComponents (app.bundle.js:67363) [angular] 
    at JitCompiler.compileModuleAsync (app.bundle.js:67325) [angular] 
    at ModuleBoundCompiler.compileModuleAsync (app.bundle.js:67693) [angular] 
    at MergeMapSubscriber.project (app.bundle.js:30608) [angular] 
    at MergeMapSubscriber._tryNext (app.bundle.js:69744) [angular] 
    at MergeMapSubscriber._next (app.bundle.js:69734) [angular] 
    at MergeMapSubscriber.Subscriber.next (app.bundle.js:14584) [angular] 
    at ScalarObservable._subscribe (app.bundle.js:69206) [angular] 
    at ScalarObservable.Observable.subscribe (app.bundle.js:118) [angular] 
    at MergeMapOperator.call (app.bundle.js:69709) [angular] 
    at Observable.subscribe (app.bundle.js:115) [angular] 
    at resolvePromise (app.bundle.js:77503) [angular] 
    at resolvePromise (app.bundle.js:77488) [angular] 
    at :3000/dist/app.bundle.js:77537:17 [angular] 
    at Object.onInvokeTask (app.bundle.js:4599) [angular] 
    at ZoneDelegate.invokeTask (app.bundle.js:77289) [angular] 
    at Zone.runTask (app.bundle.js:77179) [<root> => angular] 
    at drainMicroTaskQueue (app.bundle.js:77433) [<root>] 
    at HTMLDivElement.ZoneTask.invoke (app.bundle.js:77364) [<root>] 

EDIT Je pensais que peut-être l'erreur était parce que mes annontations ne furent jamais appelés. Je ne sais pas si c'est le cas. Je ai déserté pour y aller ES5 et pousser un composant à ma liste implicite comme ci-dessous. La même erreur provient après tout lorsque vous essayez de pousser un composant vers la partie déclarations du fichier parts.module.ts.

var HelloWorldComponent = function() { 

}; 

HelloWorldComponent.annotations = [ 
    new ng.core.Component({ 
     selector: 'hello-world', 
     template: '<h1>Hello World!</h1>', 
    }) 
]; 

window["lux"].componentsLazyImport.push(HelloWorldComponent); 

est donc un bug de angulaire 4.0.0 ou est-il pas possible du tout de créer un mécanisme de plug-in?

Meilleures salutations Morten

+0

Je travaille sur le même mécanisme de plugin comme vous et j'ai les mêmes problèmes que vous. Après quatre jours, je n'ai trouvé aucune solution. Avez-vous trouvé quelque chose? – moohkooh

+0

Oui j'ai trouvé une réponse, juste répondu avec elle. –

+0

Copie possible de [composants de charge d'exécution ou modules dans un module en angulaire2] (https://stackoverflow.com/questions/43630165/runtime-load-components-or-modules-into-a-module-in-angular2) –

Répondre

1

La seule façon d'y parvenir, je pouvais trouver était de laisser tomber webpack, comme cela semble vouloir toutes les informations au moment de la construction, et l'utilisation SystemJS qui lors de l'exécution peut charger des modules, il ne sait pas environ