Webpack+BabelでReactを使ってみる
モジュールバンドラWebpackとJavaScriptコンパイラBabelをインストールし、UIライブラリReactを使ってみる。
環境
Ubuntu 14.04.4 LTS 64bit版
$ uname -a Linux vm-ubuntu64 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.4 LTS Release: 14.04 Codename: trusty $ nodejs --version v4.4.2 $ npm --version 2.15.0
Node.js、npmのインストール
Webpack、Babel、ReactはどれもJavaScriptで書かれているため、まずはJavaScriptエンジンであるNode.jsとパッケージマネージャnpmをインストールする。 Ubuntuの場合、公式のパッケージリポジトリを利用するとよい。
$ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - $ sudo apt-get install -y nodejs
ディレクトリの作成
まず、スクリプトを置くディレクトリを作成する。
$ mkdir helloreact $ cd helloreact
次に、npm initコマンドでnpmのコンフィグファイルであるpackages.jsonを生成する。
$ npm init -y
Wrote to /home/user/tmp/helloreact/package.json:
{
"name": "helloreact",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Webpack、Babel、Reactのインストール
作成したディレクトリ以下にWebpack、Babel、Reactをインストールする。
$ npm install --save-dev webpack babel-loader babel-core babel-preset-react babel-preset-es2015 $ npm install --save react react-dom
コンフィグファイルの準備
実際にスクリプトを書く前に、npmとWebpackそれぞれのコンフィグファイルを準備する。
まず、npmのコンフィグファイルpackage.jsonを編集し、npmからWebpackを実行できるようにする。
{
"name": "helloreact",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -rf scripts/*.js && webpack",
"watch": "rm -rf scripts/*.js && webpack -w"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.7.6",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"webpack": "^1.12.15"
},
"dependencies": {
"react": "^15.0.1",
"react-dom": "^15.0.1"
}
}
ここで、buildはWebpackで最終的なJavaScriptファイルを生成するコマンド、watchはファイルの書き換えられたタイミングごとにbuildを行うコマンドである。
次に、Webpackのコンフィグファイルwebpack.config.jsを作成し、Babelで./src/app.jsを./scripts/bundle.jsにコンパイルするよう指定する。
module.exports = {
entry: "./src/app.js",
output: {
path: __dirname + "/scripts",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ["react", "es2015"]
}
}
]
}
};
ここでは、presetsでReactとES2015を扱えるようにしている。
最後に、コンパイル前のソースを置くディレクトリとコンパイル後のファイルを置くディレクトリを作成する。
$ mkdir src scripts
文字数カウンタを書いてみる
準備ができたので、実際にスクリプトを書いてみる。 ここでは、簡単な文字数カウンタを行うページを作ることにする。
まず、コンパイルされたJavaScriptを読み込んで実行するHTMLファイルを作成する。
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Hello, React!</title>
</head>
<body>
<div id="content"></div>
<script type="text/javascript" src="scripts/bundle.js"></script>
</body>
</html>
次に、Reactを使いテキストボックスへの入力に合わせて文字数を表示するスクリプトを書く。
// src/app.js
import React from "react";
import ReactDOM from "react-dom";
var WordCountBox = React.createClass({
getInitialState: function() {
return {text: ""};
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
render: function() {
return (
<div className="wordCountBox">
<h1>Hello, React!</h1>
<textarea rows="8" cols="80" placeholder="Type something..." autoFocus="true" onChange={this.handleTextChange}>
{this.state.text}
</textarea>
<p>Count: {this.state.text.length}</p>
</div>
);
}
});
ReactDOM.render(
<WordCountBox />,
document.getElementById("content")
);
ここで、冒頭のimport文はBabelでモジュールをincludeする構文である。 上のコードは、テキストボックスのonChangeハンドラでWordCountBoxコンポーネントのstateを更新する。 ここで、JSXではHTMLにおけるプロパティ名(class、onchange)ではなくDOMにおけるプロパティ名(className、onChange)を用いることに注意する。
コンパイルして表示してみる
npm経由でWebpackを実行し、上のスクリプトをJavaScriptコードにコンパイルしてみる。
$ npm run build
> helloreact@1.0.0 build /home/user/tmp/helloreact
> rm -rf scripts/*.js && webpack
Hash: eca136dc8b77e7b77879
Version: webpack 1.12.15
Time: 4646ms
Asset Size Chunks Chunk Names
bundle.js 687 kB 0 [emitted] main
+ 166 hidden modules
Python等を用いてWebサーバを起動した後、ブラウザでindex.htmlにアクセスした際のスクリーンショットを示すと次のようになる。
$ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...

適当にテキストボックスに文字列を入力すると、入力するたびに文字数カウンタが更新されることが確認できる。