Redux DevToolsとの連携
少しおさらい
前回の最後の方に紹介した。Redux DevToolsだけど、このままだとちょっと嬉しくない。
何が嬉しくないってRedux DevToolsに問題があるわけじゃなくて、この書き方だと常にRedux DevToolsが機能してしまうという点。さすがに配布versionにはいれなくていいと思うのです。
というわけでうまく切り分けてみようと思う。
directoryを整理
ちょっとdirectory構成を変更。/route
以下に直接bundleのindexとなるjsxを配置することにした。
. ├── Makefile ├── config │ ├── entry.js │ ├── webpack-dev.config.js │ ├── webpack-production.config.js │ └── webpack.config.js ├── package.json ├── pages │ └── index.html └── src ├── components │ ├── HelloWorld │ └── index.jsx └── route └── test.jsx
当然/config/entry.js
も修正。
const path = require('path'); const entry = { test: path.resolve(__dirname, '../src/route', "test.jsx"), }; module.exports = entry;
余計なところが消えた気分に浸れる。実際消えている。はず。
develop modeの時だけonにする条件分岐をいれたい
いじるのはここ。
const initialState = { value: null, }; const store = createStore( formReducer, initialState, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() );
何か無いかなあと探してみる。
ふむ。process.env.NODE_ENV === "production"
というものがあるのか。で、これはbuildするときにNODE_ENV
とかで定義している、と。
あーなんかあった気がする。NODE_ENVの定義で分岐するというやつ。
あ。そもそも/config/ webpack-production.config.js
で使ってた。
plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ]
これを使うと以下のような感じでproductionでないときは消せるのか。
if (process.env.NODE_ENV !== 'production') { console.log('development only') }
良いことを聞いた。とするとこれでいいかな。
if (process.env.NODE_ENV !== 'production') { const store = createStore( formReducer, initialState, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); }else{ const store = createStore( formReducer, initialState ); }
……scopeが美しくない。でもまずは動くかどうかの確認だ。
test.jsx:71 Uncaught ReferenceError: store is not defined
駄目であったか。まあconstだからな。むしろ良い。こうなってくれると安心できる。さて修正。三項演算子でいいか。
const store = createStore( formReducer, initialState, (process.env.NODE_ENV !== 'production') ? window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() : undefined );
さらに美しくないけどこっちは動いた。undefined……まあいいけど……。
createStoreの定義をちゃんと見てみたいなこれ。こういう入力していいのか。たぶんargsで取ってるんだろうけど。
createStore
createStore(reducer, [preloadedState], [enhancer])
んなこたぁなかったぜ。
ああ。ふうん。へぇ。enhancerってなんだろ。
[enhancer] (Function): The store enhancer. You may optionally specify it to enhance the store with third-party capabilities such as middleware, time travel, persistence, etc. The only store enhancer that ships with Redux is applyMiddleware().
middlewareを使ってstoreを拡張できると。そりゃdevtoolsみたいなものが入るわけだ。
今気づいたけどBasic StoreではpreloadedStateをcomment outしてるわ。enhancerじゃないの?
Note that preloadedState argument is optional in Redux' createStore.
ああ別に問題なさそう。sourceも無事通過しているので動作はこれでよし。
じゃあenhancerって何っていうのをもう少し調べてみよう。
enhancer
applyMiddlewareは、redux-promiseやredux-thunkなどのMiddlewareを適用するのに使う関数。applyMiddlewareを使うことでdispatch関数をラップし、actionがreducerに到達する前にmiddlewareがキャッチできるようにする。
enhancerはcreateStoreを引数に受け取って、ラップしたcreateStoreを返す関数。applyMiddlewareの場合、ラップしたdispatch関数を持つstoreを生成するためのcreateStoreを返す。
へぇー。楽しそう。なんか作ってみたい。
memo
githubへの反映などは週末に。