2017-06-27 19 views
4

私はプラグインをインストールできるWebアプリケーションの構築について考えています。私は、プラグインをインストールした後にメインのJavaScriptバンドルを再コンパイルすることなく、ページにレンダリングされるReactコンポーネントを定義できるようにしたいと考えています。 WebPACKのを使用して、external libraryとして反応して動的に反応コンポーネントをロードする

  • バンドルメインJavaScriptを:

    だからここで私はと思っていたアプローチです。

  • プラグイン作成者は、外部ライブラリとしてReactを使用してコンポーネントをコンパイルします。

このように、私はReactのインスタンスを1つだけ実行しています。他の頻繁に使用されるライブラリと同じことをやることもできます。

問題は、これらのプラグインコンポーネントをサーバーから動的にロードする方法です。どのようにgetPluginComponent

class PluginRenderer extends React.Component{ 
    componentWillMount() { 
    getPluginComponent(`/plugins/${this.props.plugin}/component.js`).then((com) => { 
     this.setState({pluginComponent: com}); 
    }) 
    } 

    render() { 
    var Plugin = this.state.pluginComponent; 
    return Plugin ? <Plugin {...this.props} /> : "Loading..." 
    } 
} 

を実装することができますのは、私は次のコンポーネントがあるとしましょうか?

+0

これを達成するには、NodeJSを使用してファイルシステムにアクセスするためのサーバー側のレンダリングが必要ですが、可能であれば、まだコンポーネントがBabelによって何らかの形でコンパイルされる必要があることを心に留めておいてください。実行時には発生しません。 – Foxhoundn

+0

はい、コンポーネントをコンパイルする必要があることはわかっています。コンパイルされたソースは静的資産として提供されます。 – bigblind

答えて

4

私は数ヶ月前にカスタマーの仕事に直面したことも面白い問題です。そこにはあまりにも多くのドキュメントアプローチがありませんでした。私たちがやったことです:

  1. 個々のプラグインは、我々はテンプレートまたはプロジェクトテンプレートを作成するCLIツールのいずれかを提供するための別のWebPACKのプロジェクトになります。このプロジェクトで

  2. 我々はすでにコアアプリケーションで使用される共有ベンダー・ライブラリ用のWebPACK externalsを定義します。これは、windowに変数からそれらをつかむことではなく、バンドルのものを含まないようにプラグインを伝えるなど、Reduxの反応し、我々コアアプリで設定します。私は知っていますが、吸うように聞こえますが、すべてのプラグインに1000個の共有モジュールを再追加するよりも優れています。

  3. externalの概念を再利用して、コアアプリケーションは、ウィンドウオブジェクトを介してプラグインにいくつかのサービスも提供します。最も重要なのは、プラグインが初期化時に呼び出さなければならないメソッドPluginService.register()です。ここではコントロールを逆転させています。プラグインは、コアアプリケーションに「こんにちは、ここは主なエクスポート(UIプラグインの場合はComponent)」と言っています。 ( - >どのプラグインがエクスポート、FN、クラス、何のPluginID)

  4. コアアプリケーションは、単にロードされたプラグインのキャッシュを保持PluginCacheクラス/モジュールを有しています。いくつかのコードでレンダリングするプラグインが必要な場合は、このキャッシュにそのプラグインを要求します。これは、プラグインが正しくロードされなかったときに<Loading />または<Error />コンポーネントを返すことを許可するという利点があります。

  5. このPluginService/Managerはプラグインの設定(プラグインを読み込む必要がありますか?)を読み込み、動的に挿入されたscriptタグを作成して各プラグインバンドルを読み込みます。バンドルが終了すると、手順3で説明したregister呼び出しが呼び出され、手順4のキャッシュにはコンポーネントが含まれます。

  6. プラグインをコンポーネントから直接ロードするのではなく、キャッシュから要求してください。

これはかなり(それは、ユーザーが追加/その場でパネルを削除し、すべてのそれらのウィジェットは次のように実施された可能性がダッシュボードのようなアプリケーションだった当時、私たちの要求に結び付けられている、非常に高いレベルの概要ですプラグイン)。

場合によっては、<Provider store={ theCoreStore }>でプラグインをラップすることもできるので、Reduxにアクセスするか、プラグインが相互にやり取りできるようにイベントバスを設定する必要があります。先を理解するためのもの。 :)

何とか助けてくれるといいですね!

+0

2.依存関係をどこにウィンドウに公開するのかを記述してください。私はまったく同じことをしようとしていますが、私はどのようにしているのか分かりません。私は今、私の髪を失っている、いくつかのサンプルコードを提供してうれしいだろう。 – AmazingTurtle

+0

ちょっと@BlackHat私は単に 'window.React = React; window.redux = redux'をindex.jsに入れてください(実際には、アプリの減速機などを準備する別のファイルにあります)。メインアプリで依存関係をインポートし、ウィンドウに再エクスポートするだけです。プラグインは最終的に実行されたときに非同期にロードされるため、window.XXXX変数はすでに準備されています。 – CharlieBrown

+0

require()を使用する代わりに、プラグインにwindow。*からのインポートを使用するように指示するにはどうすればよいですか? – AmazingTurtle

関連する問題