2016-01-26 4 views
5

button.core.jsxに次WebPACKのテーマローダー

import React from 'react'; 
import Themed from './button.[theme]'; 

export default class Button extends React.Component { 
    render() { 
     if (Themed) { 
      return <Themed />; 
     } 
     return <button>default button</button>; 
    } 
} 

つまり、私はwebpack.config.jsにテーマを定義し、そのファイルがあればロードしたいと思っています。そうでない場合は、デフォルトの動作をレンダリングします。私はこれが非常に強力なセットアップになると思います!

私はカスタムローダーの作成について調査してきましたが、まだ成功していません。誰かが私を正しい方向に向けることができますか?

答えて

4

私は、カスタム「リゾルバ」を書き込むと協力し、これを持っている:

const ThemeResolver = { 
    apply: function(resolver) { 
     resolver.plugin('file', function(req, cb) { 
      if (req.request.indexOf('[theme]') == -1) { 
       return cb(); 
      } 

      const defaultFile = req.request.replace('[theme]', 'Default'); 
      const themedFile = req.request.replace('[theme]', process.env.THEME); 
      req.request = themedFile; 

      this.doResolve(['file'], req, (err) => { 
       if (!err) { 
        return cb(); 
       } 
       req.request = defaultFile; 
       this.doResolve(['file'], req, cb); 
      }) 
     }); 
    } 
}; 

module.exports = { 
    // ... 
    plugins: [ 
     new webpack.ResolverPlugin([ThemeResolver]), 
    ] 
    // ... 
}; 

それは環境変数として定義されたテーマとしたパスにそのパスで[theme]を持つファイルを解決しようとします。失敗した場合は、代わりにデフォルトファイルにフォールバックします。この方法で私はそうのようなテーマにしたファイルを必要とすることができます:主成分は私の質問に比べて少し異なることが判明し

import Presentation from './button-[theme]'

を、私はそれで実際にはかなり内容だ:

import React from 'react'; 
import Presentation from './button-[theme]'; 

export default class Button extends React.Component { 
    onClick = (e) => console.log('some logic'); 

    render() { 
     return <Presentation onClick={ this.onClick } />; 
    } 
} 

button.core.jsxの内部に生きることができ、このボタンコンポーネントのロジック、プレゼンテーションは、これらの成分のいずれかによって処理されつつ:

THEME=theme-a npm start // button-[theme] resolves to button-theme-a.jsx 
THEME=theme-c npm start // button-[theme] resolves to button-default.jsx 

免責事項:私はこれを大規模な生産環境ではまだ使用していませんでしたが、小さなPOCで動作するようです。私が何か賢明なことをしているかどうか教えてください!

+0

これで1つの問題が発生しました。他のプラグインはそれを見ていないようです。だから私の場合は、faviconに 'html-webpack-plugin'を使って、決してthemeタグを解決しません。 – Ben

+0

それは実際には理にかなっています。なぜなら、あなたはその時点で何も必要とせず/何もインポートしていないからです。あなたは参照を作成するだけで、ブラウザはfaviconをロードします。あなたのテンプレート内にいくつかのロジックを追加することはできませんか? – Jpunt

+0

これはおそらく私がやることです。上記の "私のブランドファイルが存在する"コードをモジュール化して、リゾルバの外で使用することができます。 – Ben