Windowsでも今すぐReact+Reduxで開発できる環境を用意したから見てくれ

こんにちはみなさん。フロントエンドの開発はお好きですか？僕はReact.jsが大好きです！

今回、フロントエンドに興味があるけどまだ始めていない人向けにWindowsでも本格的な開発が始められる環境を用意したのでぜひ使ってみてください！

踏みそうな罠はあらかた踏み尽くしたはずなのでこの手順にさえ従えば楽チン環境構築が実現します！！

今回扱うVagrantファイルとReact+Reduxのサンプルプロジェクトの内容を先に見たい方はこちらから。

- [Vagrantfile](https://gist.github.com/gutchom/ee216e47431f40370d71e2516d1be8e3)
- [react-tutorial-redux](https://github.com/gutchom/react-tutorial-redux)

## 構成

- OS
  - ホスト: Windows
  - ゲスト: CentOS 7.2
- ツール
  - VirtualBox 5.1.
  - Vagrant 1.8.6
  - ndenv 0.4.0-4-ga339097

## 環境構築手順

### 下準備

#### VirtualBoxのインストール

下記リンクからWindows版をダウンロードしてインストール
https://www.virtualbox.org/wiki/Downloads

#### Vagrantのインストール

下記リンクからWindows版をダウンロードしてインストール
https://www.vagrantup.com/downloads.html

#### 仮想マシン用ディレクトリ作成

まずはVagrantで作業するディレクトリを作成します。

Vagrantはディレクトリ内の`Vagrantfile`などを参照し仮想マシンの操作を行うため、仮想マシンごとに専用のディレクトを用意する必要があります。

僕はまず`vagrant`というディレクトリを作成し、その中にそれぞれの仮想マシン用ディレクトリを用意しています。

例: `C:\vagrant\front-dev`

#### Vagrantファイルの設置

次に、Vagrantで作成する仮想マシンの設定や構成を記述したVagrantfileを設置します。

[Vagrantfile](https://gist.github.com/gutchom/ee216e47431f40370d71e2516d1be8e3)
こちらのリンクから「Download ZIP」をクリックしてダウンロードしたファイルを解凍し、中にあるVagrantfileを先ほど作成した仮想マシン用のディレクトリの中に移動します。

Vagrantfileの中身は以下の通りです。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "centos72"
  config.vm.box_url = "https://github.com/CommanderK5/packer-centos-template/releases/download/0.7.2/vagrant-centos-7.2.box"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder "./share", "/home/vagrant/share", create: true
  config.ssh.forward_agent = true

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "1024"
    vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
  end

  config.vm.provision "shell", inline: <<-EOT
    yum update
    yum install -y git
  EOT

  config.vm.provision "shell", privileged: false, inline: <<-EOT
    git clone https://github.com/riywo/ndenv.git ~/.ndenv
    git clone https://github.com/riywo/node-build.git ~/.ndenv/plugins/node-build
    echo 'export PATH="$HOME/.ndenv/bin:$PATH"' >> ~/.bash_profile
    echo 'eval "$(ndenv init -)"' >> ~/.bash_profile
  EOT
end
```

これによってローカルIP`192.168.33.10`にGitとndenvのインストールされた仮想マシンが立ち上がります。また、Vagrantで立ち上げた仮想マシンとの共有ディレクトリもこのディレクトリに作成されます。

### 仮想マシン

#### 仮想マシンの起動

それでは仮想マシンを起動しましょう。

まずは**コマンドプロンプトを管理者権限で実行**します。
コマンドプロンプトが起動したら次のコマンドを実行します。
`fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1`
(参考) [Windowsホスト上のVagrantの共有フォルダでnpmに失敗する問題の解決](http://qiita.com/yuichiroTCY/items/ab9b198cd2aaccb446ff)


そして仮想マシン用のディレクトリへ移動し`vagrant up`コマンドで仮想マシンを起動します。
失敗した場合は`vagrant destroy`を実行してから起動をやり直してください。

#### 仮想マシンへのログイン

こちらを参考にSSHクライアントをインストールします。
[[Vagrant] VagrantでSSH接続するためのSSH client導入法 for Windows ユーザー [PuTTY]](http://qiita.com/pakiran/items/eeeb736cbef5d8b609db)

上記手順でPuTTYからSSHでのログインが始まったかと思います。パスワードを訊ねられているはずなので`vagrant`と入力し仮想マシンへのログインを完了します。

この仮想マシンには、Gitとndenv(Node.jsのバージョン管理ツール)がインストールされ、ホームディレクトリ直下にWindowsと同期される`share`ディレクトリが存在した状態が用意されています。

仮想マシンの`~/share`以下にあるファイルはWindows側の`Vagrantfile`が設置されたディレクトリの`share`以下との間で同期されます。なので、UNIXコマンドを使う操作が必要な場合は仮想マシン、その他のコーディングやGit操作などはWindowsのGUIを利用するという使い分けが可能です。

### サンプルプロジェクトの実行

[react-tutorial-redux](https://github.com/gutchom/react-tutorial-redux)
今回はこちらのリポジトリを使って作業を進めていきます。

ログイン中の仮想マシンでこちらのコマンドを叩いていきましょう。
これでリポジトリが仮想マシンとWindowsの同期フォルダにクローンされます。

```
cd ~/share
git clone https://github.com/gutchom/react-tutorial-redux.git
```

続いてリポジトリのREADMEにも書いてある通り以下のコマンドを実行します。しかしこれでは`npm install`が成功しない可能性があります。

```
cd react-tutorial-redux
ndenv install
npm install
npm start
```

なので、失敗した場合は以下を実行し、`npm install`をやり直しましょう。
`ln -sf ~/react-tutorial-redux/node_modules ./node_modules`
(参考) [Symbolic Links With Vagrant Windows](http://blog.rudylee.com/2014/10/27/symbolic-links-with-vagrant-windows/)

各コマンドの解説

- `ln -sf ~/react-tutorial-redux/node_modules`
  - ホームディレクトリ以下にライブラリの実体を保存するためのエイリアスを作成します。
  - Windowsとの共有ディレクトリ内での`npm install`失敗を防ぐための措置です。
- `ndenv install`
  - `.node-version`で定義されたバージョンのNode.jsをインストール
- `npm install`
  - プロジェクトと依存関係にあるパッケージのインストール
- `npm start`
  - `package.json`で定義されたコマンドの実行

さて、コマンドプロンプトに動作状況が表示されたでしょうか？
以下の表示が含まれていれば成功です。

```
Server started: http://localhost:3000/
[BS] Proxying: http://localhost:3000
[BS] Access URLs:
 ----------------------------------
       Local: http://localhost:3333
    External: http://10.0.2.15:3333
 ----------------------------------
          UI: http://localhost:3001
 UI External: http://10.0.2.15:3001
 ----------------------------------
[BS] Watching files...
```

Windowsから仮想マシンへは`192.168.33.10`というIPでアクセスできるので、ブラウザから以下のURLへアクセスしてみましょう。
`http://192.168.33.10:3333`

いかがでしょうか？こちらのような画面がブラウザから表示されていれば成功です！

![起動成功画面](https://qiita-image-store.s3.amazonaws.com/0/8766/ed052308-babe-f96e-303d-c3e8d6bdd434.png)

表示されない場合やエラーが出た場合はコマンドプロンプトから`vagrant reload`で仮想マシンを再起動してPuTTYからログインしたのち、プロジェクトのディレクトリへ移動し`npm start`で再開してみてください。

## 使い方と解説

後述する詳細の前に、まずは触って実際の動きを見てみましょう。というわけで以下のファイルを開きます。

```js:src/scripts/components/CommentBox.jsx
import React, { PropTypes } from 'react'
import CommentListContainer from '../containers/ComentListContainer'
import CommentFormContainer from '../containers/CommentFormContainer'

const defaultProps = {
  pollInterval: 2000,
}

const propTypes = {
  pollInterval: PropTypes.number,
}

function CommentBox({ pollInterval }) {
  return (
    <div className="comment__box">
      <h1>Comments</h1>
      <CommentListContainer pollInterval={pollInterval} />
      <CommentFormContainer />
    </div>
  )
}

CommentBox.defaultProps = defaultProps
CommentBox.propTypes = propTypes

export default CommentBox

```

それでは16行目の`<h1>Comments</h1>`を`<h1>CommentBoard</h1>`とでも変更して保存します。
ブラウザの表示が自動で更新されれば成功です！これならWindowsでもフロントエンドの開発が捗りますね。

というわけで環境構築はこれにて終わりです。ここからは自由にWebアプリケーションの開発を行っていきましょう！

最後に、構築した環境について以下にまとめます。

### 仮想マシンの環境

仮想マシンは最低限のシンプルな構成です。

- [Vagrantfile](https://gist.github.com/gutchom/ee216e47431f40370d71e2516d1be8e3)
- `~/share`
    - ホストOSとの共有フォルダ
    - とりあえず作業はこのディレクトリ内で行う
- ndenv
    - 頻繁にバージョンが上がるrbenvライクなNode.jsの管理ツール
    - `ndenv local`でディレクトリ内で使用するNode.jsのバージョンを固定できたりして便利
    - 使い方はこちらから
        - https://github.com/riywo/ndenv
        - https://github.com/rbenv/rbenv

### サンプルプロジェクトについて

リポジトリはこちら。[react-tutorial-redux](https://github.com/gutchom/react-tutorial-redux)
このリポジトリは旧ReactチュートリアルをES6とReduxでリファクタしたものがベースとなっています。React+Reduxで開発を始めるにあたって不自由無い環境になっているかと思われます。

#### ディレクトリ構成

- gulp/
    - Gulpから呼び出すタスクやWebpackの設定など
- server/
    - Node.js+Express.jsで記述したAPIサーバのモック
    - `routes.js`にAPIを記述しています
- src/
    - scripts/
        - このディレクトリ内でReact+Reduxを使用したアプリケーションを記述していきます
        - Webpack+babelでのビルドもこのディレクトリを対象としています
    - styles
        - `.scss`でアプリケーションのスタイルを記述していきます
    - templates
        - `.pug`(旧Jade)で記述したテンプレートから静的なHTMLファイルを出力します
- www/
    - 変換された静的なファイルの出力先

#### コマンド

- `npm start`
    - 開発用のサーバが立ち上がります
    - `src/`以下のファイルの変更を監視し自動でビルドを行います
    - もちろんブラウザのオートリロード機能もあります
    - `Ctrl+C`で終了します

不具合などがありましたらご報告お願いします。