2017-09-15 1 views
0

typescript 2.4 [import()][1]機能はモジュールを動的にロードするのに役立ちます。私はこの機能を試してみてうまく動作します。私は、typescriptで書かれ、インポートされたモジュールが同じフォルダにあるときは常にモジュールとコンポーネントを動的にロードできます。モジュールまたはプラグインの外部へのインポート方法角型CLIプロダクション生成スクリプトのtypescript 2.4のimport()機能を使用して動的にインポートする

プロダクションモードでビルドしようとすると問題が発生します。私はAngular-CLIを使用しており、プロダクションモードでプロジェクトをビルドすると、javascriptバンドルが生成されました。今私はモジュールをロードするのが混乱しています。

異なるプラグインを動的に追加できるプラグインベースの機能を開発しています。したがって、これらのプラグインはメインアプリから分離され、import()メソッドを使用して動的に追加できます。最初はtypescriptでプラグインを開発し、そのプラグインはimport()メソッドを使って完全にロードされています。しかし、プロダクションモードでは、import()メソッドを使用してインポートできるjavascriptライブラリである必要があります。

私はhttps://github.com/jvandemo/generator-angular2-libraryを使ってプラグインをライブラリに変換しました。 index.jsファイルをインポートしようとしました。しかし、エラーメッセージが表示されます"ERROR Error: Uncaught (in promise): Error: No NgModule metadata found for 'undefined'."

次のコードは、モジュールとコンポーネントを動的にインポートするために使用したコードです。

export class DynamicComponent {  
     injector: Injector; 
     compiler: Compiler; 
     @ViewChild('container', {read: ViewContainerRef}) 
     container: ViewContainerRef; 
     componentRef: any; 

     constructor(private compFactoryResolver: ComponentFactoryResolver, injector: Injector, 
      private apiService: apiService) { 

      this.injector = ReflectiveInjector.resolveAndCreate(COMPILER_PROVIDERS, injector); 
      this.compiler = this.injector.get(Compiler); 
     } 
     addWidget(){ 

      apiService.getMoudleUrls().subscribe(module_url=>{ 
      let module_= import(module_url); //e.g './data-widget/data-widget.module'  
      module_.then(module_data =>{ 

      const keys = Object.getOwnPropertyNames(module_data); 
      let moduleFactories = this.compiler.compileModuleAndAllComponentsSync(module_data[keys[1]]); 
      const moduleRef = moduleFactories.ngModuleFactory.create(this.injector); 
      const componentFactory = moduleFactories.componentFactories 
      .find(e => e.selector === 'data-widget'); // find the entry component using selector  
      this.componentRef = this.container.createComponent(componentFactory, null, moduleRef.injector); 

      const newItem: WidgetComponent = this.componentRef.instance; 
     }, 
     error=>{}); 
    } 
    } 

例モジュールとコンポーネントは

データ-widget.module.tsは

@NgModule({ 
    imports: [ ..., 
    declarations: [DataWidget], 
    exports: [DataWidget],  
    providers: [], 
    entryComponents: [DataWidget]    
}) 
export class DataWidgetModule { 
    constructor(private widgetService: widgetService) { 
     widgetService.register('weather', DataWidget); 
    }   
} 

データ-widget.componentされていますので、

@Component({ 
    selector: 'data-widget', 
    templateUrl: 'data-widget.component.html' 
    }) 
    export class DataWidget{} 

、どのように私は、外部ロードすることができますモジュールは生産モードにありますか?

答えて

0

あなたが話しているライブラリは、npm packagesを構築するためのもので、角2/4です。

npm packageを作成し、npm registryに公開します。アップロードしたら、npmでプロジェクトにパッケージをインストールしてインポートできます。

例:

は、あなたの中myLib

と呼ばれるライブラリは、サービスがごnpm registryにライブラリをアップロードすると、あなたがして、プロジェクトでそれをインポートすることができ/exports.tsファイルに

を輸出していますMyService呼ばれていてください最初にnpm install --save myLibとインストールします。

import { MyService } from 'myLib/exports';

+0

などのモジュールでインポートします。これは通常の処理です。しかし、私は動的にモジュールをインポートしていますが、モジュールはアプリケーションによって不明です。私の上記のコードでは、 'myLib/exports'からimport {MyService}のようなコードでモジュールをインポートする必要はありません; 'import()'メソッドのパラメータとモジュールロードを動的に渡し、モジュールをロードした後、コンパイルしてentryコンポーネントを取得するモジュールのurlだけを提供する必要があります。だから、これらはすべて動作しています。私の問題は、私がモジュールのURLを与えて、ロードするときに自動的にロードするような、スクリプトを生成したスクリプトです。 – Khaled

+0

あなたは 'レイジーローディング'を実装しようとしていますか?そうであれば、 'npm packages'を作成する必要はなく、通常のモジュールを' app.module'に登録しないようにするべきです。 依存関係を動的に読み込むにはどうすればよいか分からないので、私は知らない。このリンクが役立つかどうかを確認してください:https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html –

+0

はい、遅延読み込みですが、動的で、 'import() 'typescriptの特徴2.4。 'import()'モジュールを動的に読み込みます。あなたはモジュールのURLを渡す必要があり、アプリケーションのどこにモジュールを記述する必要はありません。ここでは例を見つけることができますhttps://coryrylan.com/blog/angular-tips-dynamic-module-imports-with-the-angular-cli。私のコードは開発モードで正常に動作します。私はプロダクション生成スクリプト用のソリューションが必要です。 – Khaled

関連する問題