(2017-05) React.js の前に Webpack と Babel ちょっと触ったメモ

ちょっと触った程度のメモです。
標準的なやり方からは外れている(ちょっと試す程度ならいいけど本番には使えない)と思います。

準備

mkdir work && cd work
npm init -y

Babel

Babel で JSX から素の JS に変換できるとのことなので、試す。
なんで Babel で変換できるかは調べてない。とにかくできる。

npm install --save-dev babel-cli

テスト用のファイル。

// test.js
class Foo extends React.Component {
  render() {
    return (
      <p>foo content</p>
    );
  }
}
$ node_modules/.bin/babel test.js
SyntaxError: test.js: Unexpected token (4:6)

babel コマンドは使えるが JSX の部分でエラーになる。
プリセットというのが必要っぽい。

# npm install --save-dev と同じ
npm i -D babel-preset-react

.babelrc で react preset を使うように指定

{
  "presets": [
    "react"
  ]
}

変換できるようになった。
何も指定しないと標準出力に出る。

$ node_modules/.bin/babel test.js
class Foo extends React.Component {
  render() {
    return React.createElement(
      "p",
      null,
      "foo content"
    );
  }
}

-d (--out-dir) で指定したディレクトリに出力。

$ node_modules/.bin/babel test.js -d dist/
test.js -> dist/test.js

$ ls dist
test.js

変換元ファイルの拡張子が .jsx の場合、.js に置き換えられる。

$ node_modules/.bin/babel test.jsx -d dist/
test.jsx -> dist/test.js

変換元にファイルではなくディレクトリを指定すると、そのディレクトリにあるファイルを全部変換してくれる。

$ node_modules/.bin/babel src -d dist
src/test1.jsx -> dist/test1.js
src/test2.jsx -> dist/test2.js

Webpack

だいたい分かったので次は Webpack。
JSX の部分がなくなって素の JS ができてしまえば、後は Webpack のフローに乗せてしまえるという寸法。

src/
↓ Babel で JSX を変換
src_babeled/
↓ Webpack でまとめる
dist/bundle.js

のようにしてみる。

npm i -D webpack

上で作った余計なファイルを消して、src/entry.jsx を作る。

$ ls src
entry.jsx

$ cat src/entry.jsx
class Foo extends React.Component {
  render() {
    return (
      <p>foo content</p>
    );
  }
}
 
window.onload = function(){
  ReactDOM.render(<Foo />, document.querySelector("#content"));
};

webpack.config.js を書く。

module.exports = {
  entry: "./src_babeled/entry.js",
  output: {
    path: __dirname + "/dist",
    filename: "bundle.js"
  }
};
$ node_modules/.bin/babel src -d src_babeled
src/entry.jsx -> src_babeled/entry.js

$ node_modules/.bin/webpack --config webpack.config.js
Hash: 436e069420e6239a9f13
Version: webpack 2.6.1
Time: 37ms
    Asset     Size  Chunks             Chunk Names
bundle.js  2.89 kB       0  [emitted]  main
   [0] ./src_babeled/entry.js 257 bytes {0} [built]

毎回これやるのだるいのでビルド用のスクリプトを書く。

#!/bin/bash

node_modules/.bin/babel src -d src_babeled
node_modules/.bin/webpack --config webpack.config.js

dist/bundle.js が生成された。
html からはこれを使う。

<html>
  <head>
    <script src="dist/bundle.js"></script>
  </head>
  <body>
    <div id="content"></div>
  </body>
</html>

ブラウザで開くとエラーが出る。

Uncaught ReferenceError: React is not defined

React 自体をまだインストールしていなかった。
あと、react-dom も必要なので一緒にインストールする。

npm install --save react react-dom

require する。

// src/entry.jsx の先頭に追加
var React = require("react");
var ReactDOM = require("react-dom");

ビルドして index.html をブラウザで見ると、画面に "foo content" と表示された。

バージョン

$ npm list --depth=0
work@1.0.0 /path/to/work
├── babel-cli@6.24.1
├── babel-preset-react@6.24.1
├── react@15.5.4
├── react-dom@15.5.4
└── webpack@2.6.1

$ node -v
v7.3.0