我正在使用与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作为第一个元素并不包含装饰器数组)
我想我正在寻找如何从这里向前推进的指针。也许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
答案 0 :(得分:1)
实现这一点的唯一方法我可以找到删除webpack,因为它似乎想要在构建时获取所有信息,并使用SystemJS,它在运行时可以加载它不知道的模块