2016-05-15 4 views
9

ReactアプリケーションをWebpackにバンドルして、CDN上に置かれた分散コピーをクライアントに関連した多数の設定でソースと呼ばれ、初期化されるようにしたい。埋め込み可能なJavascriptプラグインをReactとWebpackで作成する

次のようにthisthisを読んだ後、私は私のWebPACKのエントリファイルを設定していは:

// ... React requires etc. 

(() => { 
    this.MyApp = (config) => { 
    // some constructor code here 
    } 

    MyApp.prototype.init =() => { 
    ReactDOM.render(<MyReactApp config={MyApp.config} />, someSelector); 
    } 
})(); 

アイデアは私のクライアントでは、私は以下のような何かを行うことができますさ:

<script src="./bundle.js" type="text/javascript"></script> 
<script type="text/javascript"> 
    MyApp.init({ 
    some: "config" 
    }); 
</script> 

私のMyApp#init関数は、クライアント上のいくつかのコンテナ内にReactアプリケーションをレンダリングします。

私は正しい方法でこれについて考えていますか?これについてもっと簡単で効率的な方法がありますか?

私のエラーはUncaught TypeError: Cannot set property 'MyApp' of undefinedです。これは、の中にthisがあるためです。私は本当にこれが起こっている理由とそれを修正する方法のアドバイスの両方を理解したいと思っています。

ありがとうございます!

答えて

14

私はoutputオブジェクトに次の属性を追加するために、私のwebpack.config.jsファイルを変更した場合here

を説明したように、私は一種のすなわち

var config = { 
    // ... 
    output: { 
    // ... 
    library: 'MyApp', 
    libraryTarget: 'umd', 
    umdNamedDefine: true, 
    } 
} 

これは、ファイルIを指定し、これに対する解決策を見つけました「... UMDモジュールなどのWebPACKで束ねるM、私は、そのファイル内の関数を持っている場合は、それをエクスポート

export const init = (config) => { 
    ReactDOM.render(<MyReactApp config={config} />, someSelector); 
} 

私は、私のクライアントで次のことをすることができます。

<script src="./bundle.js" type="text/javascript"></script> 
<script type="text/javascript"> 
    MyApp.init({ 
    some: "config" 
    }); 
</script> 

私のReactアプリケーションはレンダリングされます。

これはやっかいな方法だと誰もが考えているなら、それを聞いてみたいです!

+0

こんにちは、mattsch。これは素晴らしい解決策です。唯一の質問は、ウィジェットがクライアントのウェブサイトに統合されていることを確認する方法です。だからアプリを持ってウィジェットを作ってみましょう。私はいくつかのユーザー(IDまたはホスト名で)が自分のサイトにウィジェットを埋め込んでいることをアプリでチェックします。 –

+0

@To_wave私は 'init'関数の一環として、クライアントの詳細をあなたのサーバに要求することができます - それはうまくいくでしょうか? – mattsch

+0

私はそれについて考えましたが、その解決策ではクライアントが自分のWebサイトからウィジェットを削除したかどうかを確認できません。だからコールバックで私は唯一のチェックは、統合されたウィジェットですが、削除されていない可能性があります –

0

あなたのクラスの周りにエンクロージャがあります。

MyAppは、そのように呼び出す前に、グローバルウィンドウオブジェクトにエクスポートまたは添付する必要があります。

実際にMyApp.init()を呼び出すのではなく、window.MyApp.init()を呼び出していますが、グローバルオブジェクトウィンドウにはオブジェクトMyAppが関連付けられていません。

// ... Simple attaching MyApp to the window (as a function) 
window.MyApp = (config) => { 
    ... 
} 

// ... Using class and export 
class MyApp { 
    constructor(config){...} 
} 
export default MyApp 

// or simply attach to the window 
window.MyApp = MyApp 

エクスポートを使用してクラスとエクスポートモジュールを作成することをお勧めします。次に、ウィンドウに接続するためだけに別のファイルを作成します。そのようなウィンドウにクラスを付けるのはベストプラクティスとは考えられないからです。

// Import module and attach it to the window 
import MyApp from '.my-app' 
window.MyApp = MyApp 

あなたはUMD、AMDとしてエクスポートモジュールの高度なオプションを探すことができます...

関連する問題