2017-03-01 6 views
11

Angular-cli tree-shaking exclude component from removalの質問は非常によく似ていると思うが、何も手に入れられないようだ。Angular2(CLI)ツリーを振ると動的に作成されたNgModuleが削除される

本質的に私は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; 
    } 
} 
エラーメッセージの「E」が createComponentModule WHIから関数 e()ある

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 
}() 

にtranspiledされ

chは、あなたが見ることができるように、@NgModuleの内容が含まれていても空です。

新しいNgModuleを動的に作成しても、Angular CLIのプロダクションモードを使用するにはどうすればよいですか?

バージョン:
Angular2:2.4.8
角度CLI:1.0.0-beta.32.3
活字体:2.1.6

答えて

0

私は同じエラーメッセージを持っています。私が見つけた回避策は、ランタイムモジュールにデコレータを使用することではありません。

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

さて、私はエラーがなぜ発生するのか完全に理解していませんでした。エラーメッセージは、基本的にモジュールeにメタデータがないことを示しています。 Angularのモジュールのメタデータは、通常、デコレータとして宣言されます。

ES7のデコレータは、カレー機能に相当します。それは...

@NgModule({}) 
class A {} 

は個人的に私は、カレーの道がはるかに優れていると思います

NgModule({})(class A {}) 

に等しい

更新22試合意味: 公式レポからの回答https://github.com/angular/angular-cli/issues/5359#issuecomment-287500703 です単にAOTを使用しないでください。 コードを作成してくださいng build --prod --no-aot 私の場合、すべてが解決されます。

+0

正しく動作しないのではないでしょうか。コードはコンパイルされていますが、現在は新しい問題があります。 Angularは、新しい 'NgModule'でカスタムインポートされたモジュールを見つけることができません。したがって、上記のFormsModuleの例では、 'ReactiveFormsModule'と' BrowserModule'が見つかりますが、 'PipesModule'は見つかりません。エラーは 'CompileMetadataResolver.getNgModuleMetadata'にあります。 – Sebastian

+0

実際に私は同じ問題を抱えています。 JITコンパイルではデコレータをコンパイルしていないようです。だけでなく、 'RuntimeComponentModule'。コンパイルされた 'main.js'を読み込んだ場合、' PipesModule'のメタデータは含まれません。私はこの時間を続けます。角モジュールがうまくいけば教えてくれるThx。 –

+0

これはすぐにjit + aotを実行しています。 v4で –

0

残念ながら、現時点ではこれは不可能です(私は答えを最新に保つようにしています)、Angular 2.xでもAngular 4 betaでもないようです。
動的コンポーネント定義には、以前実行されたAOTコンパイラで実行時に解決できないファイル参照(テンプレート、スタイルシート)が含まれているという問題があります。
また、コンポーネントまたはモジュールにファイル参照が含まれていない場合、現在のAngularコードではコンポーネントの本当の動的作成ができません。実行時に作成されているメタデータは検出されません。

  1. 静的コンポーネントを定義し、AOTコンパイラがコンパイル時AOTで見つけることができることNgModuleに含める:問題をまとめる

    は、動的コンポーネントの作成の3つのレベルがあります。そのようなコンポーネントはいつでも問題なくインスタンス化できます。 (ComponentFactoryResolverなどを参照)

  2. コンポーネントの本体を静的に定義する(コードなど)が、動的テンプレートやスタイルを持つことができます(つまり、テンプレートは必要に応じてコード内に作成されます)。これは実行時にコンパイルされるNgModuleも必要とします。これは現在、AOTコンパイラを使用していない場合にのみ可能で、私がここに投稿した問題を表しています。
  3. コードやテンプレートを含め、完全なコンポーネントを動的に定義します。これはここに意図されているものではなく、さらに遠くに行くかもしれません。しかし、おそらく誰かがこの問題を抱えています。

私の意見では、2番の問題を解決することができます。 AngularチームはAOTなので、AOTコンパイル時に静的に知られているものだけをコンパイルすることができますが、私は同意しません。
私はAOTがそのようなコンポーネントの「スタブ」をコンパイルし、必要に応じて動的テンプレートやスタイルシートでインスタンス化する可能性を考えることができます。 @Component注釈に新しいプロパティを使用する必要があるか、@DynamicComponentのような完全に新しい注釈を使用する必要があるかもしれませんが、それは実現可能なようです。 @NgModule宣言に同じ変更が必要かどうかはわかりませんが、私はそれが正しいと思います。

+0

を使用しています。 jit + aot at once :) –

+0

うん、あなたのスレッドをgithubで見た!これでCLIで動作させる必要があります。 – Sebastian

+0

ciao Sebastian! –

関連する問題