gpt4 book ai didi

angular - 在 Angular 应用程序中动态包含另一个 webpack 包

转载 作者:太空狗 更新时间:2023-10-29 17:07:58 25 4
gpt4 key购买 nike

我正在开发一个与 webpack bundle 在一起的 Angular2 应用程序。一切正常。然而,这个 bundle 的应用程序将在运行时独立交付,在引导应用程序之前,我需要将其他 NgModules 指定到我 bundle 在我的应用程序中的模块之一。基本上可以将其视为包含在 index.html 中的两个包,当引导时,包 1 进入包 2。只有 bundle 2 引导应用程序。所以我做了一些实验,想与大家分享,以阐明这一点(我可能采取了一种相当肮脏且完全错误的方法,所以如果是这样,请纠正。如果它是肮脏的,我不介意是它可以工作的唯一方法。)。唯一的要求是在转译过程中什么都不应该做。要求是我可以在我的 index.html 中包含一个或多个包,并且它们可以在彼此事先不了解的情况下连接到实际的应用程序中。

我首先这样做的原因是因为我在一个平台上工作,其他开发人员可以通过安装扩展来挂接代码。这意味着我交付了初始包,它对其他包的转译时间一无所知。这在 AngularJS 中很容易,但移动到 Angular2 及更高版本时,就不再那么容易了。

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

在 main.ts 中:

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

这工作正常,当我手动调用 bootstrap 时,应用程序启动正常。我创建了另一个 bundle ,它可以作为另一个应用程序独立运行。

当我尝试通过像上面那样在隐式数组中导入组件来将它们 bundle 在一起,并引导应用程序时,我收到一个错误,我不知道该怎么做。

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 不包含装饰器数组)

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

解决了以下错误:“找不到名为 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 并将组件推送到我的隐式列表,如下所示。尝试将组件推送到 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 中的一个错误还是根本不可能创建一个插件机制?

最好的问候莫腾

最佳答案

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

关于angular - 在 Angular 应用程序中动态包含另一个 webpack 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43203490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com