gpt4 book ai didi

Angular2 (CLI) tree shaking 移除动态创建的 NgModule

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

我假设问题在 Angular-cli tree-shaking exclude component from removal非常相似,但我似乎无法从中得到任何东西。

本质上,我有一个动态组件工厂,如 How can I use/create dynamic template to compile dynamic Component with Angular 2.0? 中所述.

当我使用最新的 Angular CLI 和非生产设置构建它时,它一切正常。但是,一旦我使用生产设置,当我尝试加载具有动态创建内容的页面时,我会立即在浏览器中得到以下错误跟踪:

EXCEPTION: No NgModule metadata found for 'e'.
ORIGINAL STACKTRACE:
main.dc05ae9….bundle.js:formatted:4731
Error: No NgModule metadata found for 'e'.
at f (vendor.c18e6df….bundle.js:formatted:76051)
at t.resolve (vendor.c18e6df….bundle.js:formatted:20624)
at t.getNgModuleMetadata (vendor.c18e6df….bundle.js:formatted:20169)
at t._loadModules (vendor.c18e6df….bundle.js:formatted:40474)
at t._compileModuleAndAllComponents (vendor.c18e6df….bundle.js:formatted:40462)
at t.compileModuleAndAllComponentsSync (vendor.c18e6df….bundle.js:formatted:40436)
at e.createComponentFactory (main.dc05ae9….bundle.js:formatted:4789)

这是我的组件工厂类:

@Injectable()
export class DynamicTypeBuilder {
constructor() {
}

private _cacheOfFactories: {[templateKey: string]: ComponentFactory<any>} = {};
private compiler: Compiler = new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler();

public createComponentFactory<COMPONENT_TYPE>(type: any, template: string, additionalModules: any[] = []): Observable<ComponentFactory<COMPONENT_TYPE>> {

let factory = this._cacheOfFactories[template];
if (factory) {
return Observable.of(factory);
}

// unknown template ... let's create a Type for it
let module = this.createComponentModule(type, additionalModules);

// compiles and adds the created factory to the cache
return Observable.of(this.compiler.compileModuleAndAllComponentsSync(module))
.map((moduleWithFactories: ModuleWithComponentFactories<COMPONENT_TYPE>) => {
factory = moduleWithFactories.componentFactories.find(value => value.componentType == type);
this._cacheOfFactories[template] = factory;
return factory;
});
}

protected createComponentModule(componentType: any, additionalModules: any[]): Type<any> {
@NgModule({
imports: [
FormsModule,
ReactiveFormsModule,
BrowserModule,
PipesModule,
...additionalModules
],
declarations: [
componentType
],
schemas:[CUSTOM_ELEMENTS_SCHEMA]
})
class RuntimeComponentModule {
}

return RuntimeComponentModule;
}
}

正在被转译为

var _ = function() {
function e() {
this._cacheOfFactories = {},
this.compiler = new i.a([{
useDebug: !1,
useJit: !0
}]).createCompiler()
}
return e.prototype.createComponentFactory = function(e, t, n) {
var i = this;
var _ = this._cacheOfFactories[t];
if (_)
r.Observable.of(_);
var a = this.createComponentModule(e, n);
return r.Observable.of(this.compiler.compileModuleAndAllComponentsSync(a)).map(function(n) {
return _ = n.componentFactories.find(function(t) {
return t.componentType == e
}),
i._cacheOfFactories[t] = _,
_
})
}
,
e.prototype.createComponentModule = function(e, t) {
var n = function() {
function e() {}
return e
}();
return n
}
,
e.ctorParameters = function() {
return []
}
,
e
}()

错误消息中的“e”是 createComponentModule 中的函数 e(),如您所见,它是空的,尽管它应该包含 >@NgModule 内容。

如何动态创建新的 NgModule 并仍然使用 Angular CLI 的生产模式?

版本:
Angular 2:2.4.8
Angular CLI:1.0.0-beta.32.3
typescript :2.1.6

最佳答案

不幸的是,无论是 Angular 2.x 还是 Angular 4 beta,目前看来这是不可能的(我会尽量使答案保持最新)。
问题在于动态组件定义包含文件引用(模板、样式表),这些文件引用(模板、样式表)无法在运行时使用之前运行的 AOT 编译器解决。
但如果组件或模块不包含文件引用,则当前的 Angular 代码不允许真正动态地创建组件。它只是找不到在运行时创建的元数据。

总结问题,动态组件创建有3个层次:

  1. 静态定义一个组件,并将其包含在 AOT 编译器可以在 AOT 编译时找到的 NgModule 中。这样的组件可以在任何时候毫无问题地被实例化。 (参见 ComponentFactoryResolver 等)
  2. 静态定义组件的主体(代码等),但允许具有动态模板和/或样式(即仅在需要时在代码中创建模板)。这也需要在运行时编译一个 NgModule。这目前只有在不使用 AOT 编译器时才有可能,并且代表我在此处发布的问题。
  3. 动态定义完整组件,包括代码和模板。这不是这里的意图,甚至可能走得更远。但可能有人也有这个问题。

在我看来,第二个问题是可以解决的。 Angular 团队说因为它是 AOT 它只能编译那些在 AOT 编译时静态已知的东西,但我不同意。
我可以想到 AOT 编译此类组件的“ stub ”的可能性,然后在需要时使用动态模板或样式表实例化该组件。可能需要为 @Component 注释使用新属性或像 @DynamicComponent 这样的全新注释,但这对我来说似乎是可行的。我不知道 @NgModule 声明是否需要相同的更改,但我认为他们会。

关于Angular2 (CLI) tree shaking 移除动态创建的 NgModule,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537138/

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