在角度应用程序中动态包含另一个webpack包

Mor*_*ger 10 bundle require webpack angular

我正在研究与webpack捆绑在一起的Angular2应用程序.一切正常.然而,这个捆绑的应用程序将独立运行并在运行时,在引导应用程序之前,我需要将其他NgModule指定到我在我的应用程序中捆绑的其中一个模块中.基本上认为它是index.html中包含的两个bundle,并且当bootstraped时,bundle 1进入bundle2.只捆绑2引导应用程序.所以我做了一些实验,我想与你分享,以便对此有所了解(我可能会采取一种相当肮脏且完全错误的方法,所以如果是这样的话,请更正.我不介意脏,如果它是它可以工作的唯一方式.)唯一的要求是在翻译期间不应该做任何事情.要求是我可以在我的index.html上包含一个或多个包,并且可以将它们连接到实际应用程序中,而无需事先了解彼此.

我之所以这样做是因为我在一个平台上工作,其他开发人员可以通过安装扩展来挂钩代码.这意味着我提供了初始捆绑包,它在传输时间上不知道其他捆绑包.这在AngularJS中很容易,但是转移到Angular2以后,这已经不那么容易了.

我设法通过以下方法延迟引导应用程序:

在main.ts中:

window["platformBrowserDynamicRef"] = platformBrowserDynamic();
window["appModule"] = AppModule;
Run Code Online (Sandbox Code Playgroud)

这工作正常,当我手动调用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
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

将模块放在隐式数组中工作正常,但只要我从其他包中添加模块,我就会收到以下错误:

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>]
Run Code Online (Sandbox Code Playgroud)

我也试过AoT编译ExtensionsModule,它也不起作用.我还尝试使用JitCompiler在运行时动态编译组件,看看我是否可以通过这种方式将它们引入应用程序.但是同样的错误.

在应用程序的提升期间或在翻译期间是否装饰了组件?偷看我的隐式数组中的模块,我可以看到它们被装饰,但我的不是.那个webpack是否插入了装饰器方法的调用代码?我假设装饰器信息在转换过程中丢失了,所以也许我需要以某种方式临时存储它以便我可以在别处抓住它.(注意,作为第一个元素的extensionsmodule不包含装饰器数组)

应该在我的模块中导入的模块

我想我正在寻找如何从这里向前推进的指针.也许NgModule注释函数将是一个很好的起点.虽然无法找到它.

编辑

更深入地研究这个问题我尝试了使用路由器的延迟加载方法,首先我收到此错误,尝试使用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}        
      }
    ];
Run Code Online (Sandbox Code Playgroud)

解决了以下错误:"找不到名为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}        
      }
    ];
Run Code Online (Sandbox Code Playgroud)

解决:

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>]
Run Code Online (Sandbox Code Playgroud)

编辑 我认为可能错误是因为我的annontations从未被调用.不确定是否是这种情况.我希望在它上面运行ES5并将组件推送到我的隐式列表中,如下所示.在尝试将组件推送到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);
Run Code Online (Sandbox Code Playgroud)

这是Angular 4.0.0中的一个错误,还是根本不可能创建一个插件机制?

最好的问候莫滕

小智 1

我能找到的实现这一目标的唯一方法是删除 webpack,因为这似乎在构建时需要所有信息,并使用 SystemJS,它在运行时可以加载它不知道的模块