
React + WebPack + Babel + HotLoaderでReactの簡単な雛形を作ってみた
Reactを試すときいちいち環境作るの面倒なので、勉強ついでにスターターキット的なのを作ってみました。
中身はこんな感じです。
- React
- Babel
- CSS Loader
- Webpack
- React Hot Loader
Hot Loaderがあれば変更時に自動でリロードしてくれるので楽です。また、Hot Loaderはただ単にブラウザ全リロードではなく、変更箇所のみ更新してくれるので、stateを保持したまま部分更新できます。
基本的に以下を参考にして、CSS Loaderほしいなーと思ったので追加しました。
React + Babel + Webpack + HMR な環境をつくるだけ
参考になりました。ありがとうございます。
作ったものはGitHubで公開してます。
React-starterkit
以下、一から作る場合の手順です。
ライブラリのインストールなどの準備
まずはプロジェクトフォルダでpackege.jsonを作ります。
npm initでエンター連打するぐらいなら、-yか-fをつけましょう。
npm init -y
babelで変換するとき、古いブラウザでもいい感じにしてくれる「babel-polyfill」とReact関連を入れます。
npm install --save babel-polyfill react react-dom
その他使うもの一式インストールします。
npm install --save-dev babel-core babel-loader babel-plugin-add-module-exports babel-preset-es2015 babel-preset-react babel-preset-stage-0 webpack style-loader css-loader react-hot-loader webpack-dev-server
.babelrc
プロジェクトフォルダ直下に「.babelrc」を作って以下を書きます。
{ "presets": [ "es2015", "stage-0", "react" ], "plugins": [ "add-module-exports" ] }
webpack.config.js
プロジェクトフォルダ直下に「webpack.config.js」を作って以下を書きます。
require('babel-polyfill'); var path = require('path'); var webpack = require('webpack'); var DEBUG = !process.argv.includes('--release'); var plugins = [ new webpack.optimize.OccurenceOrderPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"' + (process.env.NODE_ENV || (DEBUG ? 'development' : 'production')) + '"' }) ]; if(!DEBUG){ plugins.push( new webpack.optimize.DedupePlugin(), new webpack.optimize.UglifyJsPlugin({ compress: { screw_ie8: true, warnings: true } }), new webpack.optimize.AggressiveMergingPlugin() ); } module.exports = { cache: DEBUG, debug: DEBUG, stats: { colors: true, timings: true, hash: true, version: true, chunks: true, chunkModules: true, cached: true, cachedAssets: true, reasons: DEBUG }, entry: [ './src/js/app.js' ], output: { path: path.join(__dirname, 'public', 'assets'), filename: 'app.js', publicPath: '/assets/' }, target: 'web', devtool: DEBUG ? 'cheap-module-eval-source-map' : false, plugins: plugins, module: { loaders: [ { test: /\.js?$/, include: [path.resolve(__dirname, 'src/js')], loaders: ['react-hot', 'babel'] }, { test: /\.css$/, include: [path.resolve(__dirname, 'src/js')], loaders: ['style', 'css?modules'], }, ] } };
はっきり言ってまだwebpackの書き方理解していません(笑)
server.js
React Hot Loaderを使うためserver.jsを作り以下を記述します。
var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config.js'); config.entry.push( 'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server' ); config.plugins.push(new webpack.HotModuleReplacementPlugin()); console.log(config); new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, contentBase: 'public/', historyApiFallback: true }).listen(3000, 'localhost', function (err, result) { if (err) { return console.log(err); } console.log('Listening at http://localhost:3000/'); });
これも書き方よく理解してないので、勉強します(笑)
package.jsonの修正
package.jsonの「script」のところに追記します。
// 省略 "scripts": { "start": "node server.js", "release": "webpack --release", "debug": "webpack", "test": "echo \"Error: no test specified\" && exit 1" }, // 省略
動かしてみる
大した例ではないですが、Reactで文字を表示させるまでやってみます。
まずは、「public」ディレクトリを作って、その中にindex.htmlを作り以下を記述します。
public/index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="root"></div> <script type="text/javascript" src="assets/app.js"></script> </body> </html>
次に、「src」ディレクトリを作って、jsディレクトリを作ります。
その中にapp.jsを作ります。
src/js/app.js
import React from 'react'; import ReactDOM from 'react-dom'; import { Main } from './components/main.js'; ReactDOM.render( <Main/>, document.getElementById('root') );
そして、コンポーネント単位でディレクトリを切って、その中にjsファイルとそのコンポーネント専用のcssファイルを作っていきます。
src/js/components/main.js
import React from 'react'; import { Sub } from '../subcomponents/sub.js'; import style from './style.css'; export class Main extends React.Component{ render(){ return( <span> <h1 className={style.normal_ttl}>Title</h1> <Sub /> </span> ); } }
src/js/components/style.js
.normal_ttl { border-bottom: 1px solid #ddd; color: #666; }
src/js/subcomponents/sub.js
import React from 'react'; import style from './style.css'; export class Sub extends React.Component{ render(){ return( <h1 className={style.subtitle}>Sub title</h1> ); } }
src/js/subcomponents/style.js
.subtitle { color: #666; }
以上が完了したら、コマンドで以下を打ちます。
npm start
そして以下にアクセスすると表示されます。
http://localhost:3000
jsやcssを修正して、保存すると自動でブラウザが更新されます。
快適ですねー。
また、以下コマンドでpublic/assets以下にデバッグ用ファイルが作られます。
npm run debug
このコマンドで作られたapp.jsはAtomで開くとほぼ確実にクラッシュします。
そして、以下コマンドで圧縮されたapp.jsが作られます。
npm run release
まだこの構成でいいのかも分からないですし、理解できてないとこもあるので、まだまだ変更していくかもしれませんが、今のところこんな感じで。
ここが変だよっていうのがあれば、プルリクくれるとありがたいです。
React-starterkit