2016年から始めるフロントサイド~実装編~

## 余談：react-reduxを使用しているWebサイト(アプリケーション)
https://github.com/reactjs/redux/issues/310
わかる範囲でもこれだけあるみたいです。すごいですね。

## 実装
1. es6
2. react, react-dom,
3. react-router
3. redux

テストまで書くと長くなって読みづらいので分けます。

### es6
* [公式サイト](http://www.ecma-international.org/ecma-262/6.0/)
* 基本的には公式サイトのspecを見ていく感じになりますが、英語かつ専門用語辛い。。
* Reduxは基本es6で書かれているので、spec読みながらExampleを見るのが良さそうだ！

実装で一番重要と思われるコードの再利用だけピックアップ。

```js:register_name.js
// addという名前が名前空間に登録される
export function add(x, y) {
  return x + y
}
```

`export`で名前を登録していく。前までは`module.exports`だったもの？
セミコロンがないのは間違いではなく、es6?es7?から省略可能らしい。
このコードを別のファイルで使う場合は`import`する。前までは`require`だったもの？

```js:index.js
import { add } from 'register_name'

console.log(add(1, 2))
```

`export default`で登録するとimport方法が変わるらしい。

```js:register_default.js
export default function add(x, y) {
  return x + y
}
```

```js:index.default.js
import add from 'register_default' // import apple from 'register_default' でも問題ない

console.log(add(1, 2))
```

[spec](http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records)を見ると、`default`を指定すると`default`名前空間に登録されるようだ。
また、一つのモジュールには`default`が一つしか存在してはいけない(syntax error)ので、`import`する名前はなんでも良い。
`default`名前空間に登録されているものは`{}`をつけず取り出せる。
逆に`default`を指定しないと定義した名前が登録され、`import`の祭に`{}`で名前を囲んであげなければならない。
ちなみに、`module.exports`で登録した名前は、各ライブラリを見る限り`default`名前空間に登録されるようだ。それ以外の`var`などは`{}`で取り出せるところを見ると`default`以外で登録されている？

### react, react-dom
* `npm install --save-dev react react-dom`
* [React, ReactDOM公式サイト](https://facebook.github.io/react/docs/getting-started.html)
* [React作者によるHowTo](https://github.com/petehunt/react-howto)
* `React`自体は[この箇所](https://github.com/facebook/react/blob/master/src/React.js#L23)で`ReactIsomorphic`が[assign](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)されているように、実態は[ReactIsomorphic](https://github.com/facebook/react/blob/master/src/isomorphic/ReactIsomorphic.js)にあるようだ。
* `ReactDOM`は[この箇所](https://github.com/facebook/react/tree/master/packages/react-dom)がnpmでインストールされるようだ。

React, ReactDOMの使い方は公式サイトを見るとしてビルド方法だけピックアップ。
前提として、`es6+babel+webpack`を想定しています。

```json:package.json
{
  ...,
  // npm runの引数を定義します
  "scripts": {
    "compile": "babel --presets es2015 src/ -d lib/",
    // 素のReactはdevelopモードで遅いらしいのでproductionモードでビルドする
    // npm install --save-dev cross-envが前提です
    "build": "cross-env NODE_ENV=production webpack",
    "build:dev": "npm run compile && npm run build",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...,
}
```

```bash:build
$ npm run build:dev
```

あとは`webpack.config.js`で指定したビルド先のPATHを`<script src='dist/index.js'></script>`のようにhtmlに書けばOK。
すごく簡単！
`cross-env`を使いたくない場合は、[Reactの公式サイト](https://facebook.github.io/react/docs/getting-started.html)のように`webpack.config.js`の中でハードコード。

### react-router
* [React Router公式サイト](https://github.com/reactjs/react-router/tree/master/docs)
* `npm install --save-dev react-router`

公式サイトのTutorialのlesson2,3だけ試します。

```bash:directory構成
$ tree -a -I 'node_modules|.git|.DS_Store|dist|lib|.vscode|.gitignore'
├── .babelrc
├── .eslintrc
├── index.react.router.html
├── package.json
├── src
│   ├── index.react.router.js
│   └── modules
│       ├── About.js
│       ├── App.js
│       └── Repos.js
└── webpack.config.js
```

```js:index.react.router.js
import React from 'react'
import { Router, Route, hashHistory } from 'react-router'
import { render } from 'react-dom'
import App from './modules/App'
import About from './modules/About'
import Repos from './modules/Repos'

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
    <Route path="/about" component={About}/>
    <Route path="/repos" component={Repos}/>
  </Router>
), document.getElementById('app'))
```

```js:App.js
import React from 'react'
import { Link } from 'react-router'

export default React.createClass({
  render() {
     return (
      <div>
        <h1>Hello, world!</h1>
        <ul role='nav'>
          <li><Link to='/about'>About</Link></li>
          <li><Link to='/repos'>Repos</Link></li>
        </ul>
      </div>
    )
  }
})
```

```js:About.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>About</div>
  }
})
```

```js:Repos.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>Repos</div>
  }
})
```

```html:index.react.router.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>React and React Router Example</title>
</head>

<body>
  <div id="app"></div>
  <script src="dist/index.react.router.js"></script> <!-- dist/はcompile後のPATH -->
</body>
<html>
```

わかりやすくていいですね！

### redux
* [公式Example](https://github.com/reactjs/redux/tree/master/examples)
* 作者が`You’ll know when you need Flux. If you aren’t sure if you need it, you don’t need it.`と言っているように、`React`を使っていくうちに`Flux`を導入すべきと感じるまでは使わないほうが良いようだ。

まずは、`React`, `ReactDOM`, `Router`を頑張るかぁ。

テスト編に続く・・（完）