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

时间:2017-04-04 09:37:32

标签: angular webpack bundle require

我正在使用与webpack捆绑在一起的Angular2应用程序。一切正常。然而,这个捆绑的应用程序将独立运行并在运行时,在引导应用程序之前,我需要将其他NgModule指定到我在我的应用程序中捆绑的其中一个模块中。基本上认为它是index.html中包含的两个bundle,并且当bootstraped时,bundle 1进入bundle2。只捆绑2引导应用程序。所以我做了一些我想与你分享的实验,以便对此有所了解(我可能会采取一种相当肮脏且完全错误的方法,所以如果是这样,请更正。我不会&#39如果这是它可以工作的唯一方式,那就小心脏了。)唯一的要求是在翻译期间不应该做任何事情。要求是我可以在我的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>]

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

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

modules that should be imported in my module

我想我正在寻找如何从这里向前推进的指针。也许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}        
      }
    ];

解决以下错误: &#34;找不到名为ExtensionsModule.js&#34;的模块。

其次我尝试使用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并将组件推送到我的隐式列表中,如下所示。在尝试将组件推送到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);

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

祝你好运 的Morten

1 个答案:

答案 0 :(得分:1)

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

相关问题