yarnでReactアプリを立ち上げる

これは[ユニキャストアドベントカレンダー](https://qiita.com/advent-calendar/2017/unicast) 10日目の記事です。

私は[株式会社ユニキャスト](http://www.unicast.ne.jp/)で、フロントエンドを中心にプログラムを書いています。

最近、弊社でもReact.jsを利用してSPAを構築することも多く、手始めに、React.jsアプリのブートストラップの手順を書いていきたいと思います。

`create-react-app`等ボイラープレートを使ってもいいと思いますが、ここでは必要になる要素を理解するため、必要なものを手動で用意していきたいと思います。

# 必要なもの
* Node.js
* [yarn](https://yarnpkg.com/ja/)
    * 言わずと知れたJavascriptパッケージマネージャ。npmと比べて大分高速という印象です。

# 初期化
まずはアプリを開発するディレクトリを作成し、yarn initで初期化しましょう。

```shell-session
$ mkdir sample-app
$ cd sample-app
$ yarn init
```

色々と聞かれますが、ここではEnter連打で構いません。

# 必要なパッケージの追加
`yarn init`によって、`sample-app`ディレクトリに`package.json`が生成されていると思います。

次に、必要になるパッケージを追加していきます。

```shell-session
$ yarn add react react-dom
$ yarn add -D webpack webpack-dev-server babel-loader babel-core babel-preset-react babel-preset-env
```

以下のようにpackage.jsonに依存関係が追加されていると思います。

```package.json
{
  "name": "sample-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.9.7"
  }
}
```

# コードを書く
依存するパッケージを追加出来たので、コードを書いていきます
今回は以下のようなディレクトリ構成にしたいと思います。

```
.
├── index.html
└── src
    └── App.jsx

```

```index.html
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Sample App</title>
    </head>
    <body>
        <div id="app" />
        <script src="./dist/bundle.js"/>
    </body>
</html>
```
`index.html`では、Reactのレンダリング先として`div`タグを書き、idを付けます。

また、この後の手順でビルドしたjsファイルを`dist/bundle.js`に置くため、`script`タグで指定しておきます。


```App.jsx
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
    <h1>Hello, World!</h1>,
    document.querySelector("#app")
)
```
コード内にJSXを含むため、拡張子をjsxにしています。

# .babelrcを書く
実行するアプリを書けたので、次は`.babelrc`にbabelの設定を書きます。今回は特別込み入ったことをしていないので、

```.babelrc
{
    "presets": ['env', 'react']
}
```

と、`presets`だけ指定します。

# webpack.config.jsを書く
次に、webpackの設定を書きます。

```webpack.config.js
module.exports = {
    entry: './src/App.jsx',
    output: {
        path: __dirname + '/dist',
        filename: 'bundle.js',
        publicPath: '/dist/'
    },
    devtool: 'inline-soruce-map',
    module: {
        loaders: [
            {
                test: /\.js(x?)$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            }
        ]
    },
    devServer: {
        historyApiFallback: {
            index: 'index.html'
        },
        port: '3000'
    }
}
```
`entry`でエントリーポイントとなるJavascriptファイルを指定し、`output`の中で出力先を設定します。今回は`dist/bundle.js`となるように設定しています。

また、この後で使う`webpack-dev-server`の設定を`devServer`に書いています。

# package.jsonにscriptsを書く
```package.json
{
  "name": "sample-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.9.7"
  },
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack -p"
  }
}
```

ひとまずここでは、デバッグ用の`webpack-dev-server`と、Javascript生成用の`webpack -p`を書きました。

# webpack-dev-server立ち上げ、アプリにアクセス
一通りの設定が完了したので、アプリを立ち上げてみます。

```shell-session
$ yarn start
yarn run v1.3.2
$ webpack-dev-server
Project is running at http://localhost:3000/
webpack output is served from /dist/
404s will fallback to index.html
Hash: 53c2dfe2b3b2fb0e3616
Version: webpack 3.10.0
Time: 991ms
    Asset     Size  Chunks                    Chunk Names
bundle.js  1.05 MB       0  [emitted]  [big]  main
   [4] ./node_modules/react/index.js 190 bytes {0} [built]
  [16] multi (webpack)-dev-server/client?http://localhost:3000 ./src/App.jsx 40 bytes {0} [built]
  [17] (webpack)-dev-server/client?http://localhost:3000 7.95 kB {0} [built]
  [18] ./node_modules/url/url.js 23.3 kB {0} [built]
  [25] ./node_modules/strip-ansi/index.js 161 bytes {0} [built]
  [26] ./node_modules/ansi-regex/index.js 135 bytes {0} [built]
  [27] ./node_modules/loglevel/lib/loglevel.js 7.86 kB {0} [built]
  [28] (webpack)-dev-server/client/socket.js 1.05 kB {0} [built]
  [30] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]
  [31] ./node_modules/ansi-html/index.js 4.26 kB {0} [built]
  [32] ./node_modules/html-entities/index.js 231 bytes {0} [built]
  [35] (webpack)/hot nonrecursive ^\.\/log$ 170 bytes {0} [built]
  [37] (webpack)/hot/emitter.js 77 bytes {0} [built]
  [39] ./src/App.jsx 415 bytes {0} [built]
  [43] ./node_modules/react-dom/index.js 1.36 kB {0} [built]
    + 37 hidden modules
webpack: Compiled successfully.
```

このように、`webpack-dev-server`が立ち上がり、ブラウザで`http://localhost:3000`にアクセスするとアプリが開きます。

<img width="774" alt="スクリーンショット 2017-12-20 21.03.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/38529/5bbef071-e7eb-7bce-4616-c4e1a35e6f4f.png">

この先は、`index.html`や`App.jsx`やその他諸々を書き足して行けばOKです。Javascriptの変更は、`webpack-dev-server`を起動している限り、リアルタイムに反映されます。

# まとめ
yarnにて、Reactアプリを立ち上げる手順を紹介しました。

次回はReactでのルーティングについて書きたいと思っています :P