Динамически включить другой пакет webpack внутри приложения angular

Я работаю над приложением Angular2, которое поставляется вместе с webpack. Все работает отлично. Однако это связанное приложение будет отправлено независимо и во время выполнения, прежде чем загружать приложение, мне нужно указать другие NgModules в один из модулей, которые я установил в своем приложении. В основном думайте об этом как о двух пучках, включенных в index.html, и когда bootstraped, bundle 1 переходит в bundle2. Загрузите только 2 загрузочных приложения. Поэтому я сделал несколько экспериментов, которые я хотел бы поделиться с вами, чтобы пролить свет на это (я мог бы принять довольно грязный и совершенно неправильный подход, поэтому, пожалуйста, исправьте, если так. Я не против грязного, если это это единственный способ, которым это может работать.). Только требование состоит в том, что во время транспиляции ничего не нужно делать. Требование состоит в том, что я могу включить один или несколько пакетов в свой index.html, и они могут быть подключены к реальному приложению без каких-либо предварительных знаний друг о друге.

Причина, по которой я это делаю, в первую очередь заключается в том, что я работаю на платформе, где другие разработчики могут подключаться к коду, устанавливая расширения. Это означает, что я доставляю исходный пакет, который не знает других пакетов о времени пересылки что-то еще. Это было легко в AngularJS, но переход на Angular2 и далее, это уже не так просто.

Мне удалось отложить загрузку приложения с помощью следующего подхода:

В main.ts:

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

Это отлично работает, и когда я вызываю bootstrap вручную, приложение запускается просто отлично. Я создал еще один пакет, который независимо работает отлично как другое приложение.

Когда я пытаюсь связать их вместе, импортируя компоненты в неявный массив, как указано выше, и я загружаю приложение, я получаю сообщение об ошибке, которое я не знаю, что делать.

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
        };
    }
}

Наличие модулей в неявном массиве отлично работает, но как только я добавляю модуль из другого моего пакета, я получаю следующую ошибку:

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>]

Я также попытался скомпилировать ExtosModule с AoT, который тоже не работает. Я также попробовал динамически компилировать компоненты во время выполнения с помощью JitCompiler, чтобы узнать, могу ли я их подключить к этому приложению. Тем не менее, ту же ошибку.

Являются ли компоненты украшенными во время развертывания приложения или во время транспиляции? Подглядывая модули в моем неявном массиве, я вижу, что они украшены, но мой нет. Этот веб-пакет вставляет код вызова метода декоратора? Я предполагаю, что информация о декораторе теряется во время транспиляции, поэтому, возможно, мне нужно временно сохранить его так или иначе, чтобы я мог схватить его в другом месте. (обратите внимание, что extensionsmodule в качестве первого элемента не содержит массив декоратора)

модули, которые должны быть импортированы в моем модуле

Я предполагаю, что Im ищет указатели на то, как двигаться дальше отсюда. Может быть, функция аннотации NgModule станет хорошим местом для начала. Не удалось найти нигде.

ИЗМЕНИТЬ

вникая в проблему, я пробовал ленивый подход к загрузке с использованием Router, где сначала я получаю эту ошибку, пытаясь загрузить ее с помощью js файла (вкладка в сети показывает, что он никогда не выдает запрос на файл ):

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}        
      }
    ];

Разрешает следующую ошибку: "Не удалось найти модуль с именем ExtensionsModule.js"

Во-вторых, я попытался использовать функцию loadChildren следующим образом:

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}        
      }
    ];

Решает в:

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>]

ИЗМЕНИТЬ Я думал, что, возможно, ошибка была в том, что мои аннотации никогда не назывались. Не уверен, что так. Я решил пойти на ES5 и направить компонент в мой неявный список, как показано ниже. Такая же ошибка возникает, когда вы пытаетесь подтолкнуть компонент к части объявлений part.module.ts.

    var HelloWorldComponent = function () {

};

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

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

Итак, это ошибка в Angular 4.0.0 или вообще не возможно создать механизм плагина?

С уважением Morten

Ответ 1

Единственный способ добиться этого, я мог бы найти, это отбросить веб-пакет, поскольку, похоже, он хочет получить всю информацию во время сборки и использовать SystemJS, который во время выполнения может загружать модули, которые он не знает о