Reactの「Getting Started」を読む

# 概要

Reactを初めて触ったのですが、FacebookのGetting Startedページを読み進めるにあたってわからないことが多かったので、いろいろ調べながら進めた際のメモです。
（※この記事のソースコードや引用部分は基本的に次のReactのGetting Startedのページから引用しています。それ以外の引用は下にリンクをつけています。）

Getting Started | React
https://facebook.github.io/react/docs/getting-started.html

**対象読者**
reactをこれから始める人で、node.jsもまだよく知らない人


# [JSFiddle](https://facebook.github.io/react/docs/getting-started.html#jsfiddle)

まず手軽にReactに触れるためにJSFiddleというWebサービスを紹介している。

Create a new fiddle - JSFiddle
https://jsfiddle.net/
HTML, CSS, JavascriptをWeb上で記述してシミュレートできるサービス。

React Base Fiddle (JSX)
https://jsfiddle.net/reactjs/69z2wepo/
これをフォークしてReactを体験できる。

# [Using React from npm](https://facebook.github.io/react/docs/getting-started.html#using-react-from-npm)


JSFiddleではなくローカルのnode.jsで実行するための準備。

main.jsの作成

```js

// main.js
var React = require('react');
var ReactDOM = require('react-dom');

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
```

npm（node.jsのモジュール）のインストールと実行

```bash
$ npm install --save react react-dom babelify babel-preset-react
$ browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js
```

> We recommend using React with a CommonJS module system like browserify or webpack. Use the react and react-dom npm packages.


browserifyやwebpackのようなCommonJSと一緒に使うべきとのこと。

#### CommonJS

便利なJavascriptを誰もが簡単に使えるように、共通仕様を規定しているプロジェクト。この後出てくるbrowserifyやwebpackはCommonJSの仕様に従ったモジュール。

> Welcome to CommonJS, a group with a goal of building up the JavaScript ecosystem for web servers, desktop and command line apps and in the browser.

(CommonJS Spec Wiki http://wiki.commonjs.org/wiki/CommonJS より)

#### browserify

* Browserify http://browserify.org/

> Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.

node.jsがモジュールを読み込む際に使用するrequire()メソッドをjsファイルから抽出して一つのjsファイルにまとめ、ブラウザから読めるようにしてくれるもの。

#### webpack

モジュールの依存関係を解決して束ねる。browserifyと同等機能を提供するが、用途によってそれぞれ特徴がある模様（未調査）。Getting Startedではbrowserifyを使用している。

> webpack is a module bundler.
> 
> webpack takes modules with dependencies and generates static assets representing those modules.

(what is webpack http://webpack.github.io/docs/what-is-webpack.html より)

#### Babel

Javascriptを読み込んで別のソースに変換してくれるツール。ReactではJSXという独自XMLフォーマットを使用するが、これを解析してブラウザが読める形式のJavascript（createElement）に変換するために必要。

> Babel is a generic multi-purpose compiler for JavaScript. More than that it is a collection of modules that can be used for many different forms of static analysis.

( thejameskyle/babel-plugin-handbook https://github.com/thejameskyle/babel-plugin-handbook#introduction より)



#### その他

* react（[react](https://www.npmjs.com/package/react)）: Reactのコア。
* react-dom（[react-dom](https://www.npmjs.com/package/react-dom)）: DOM操作を行うためのモジュール。
* babelify（[babelify](https://www.npmjs.com/package/babelify)）: browserifyようにBabelを実行するためのモジュール。
* babel-preset-react（[React preset · Babel](https://babeljs.io/docs/plugins/preset-react/)）: react用babelifyプラグイン

```
$ browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js
```
つまり上記のコマンドは「main.jsをBabelで変換しつつ、bundle.jsというブラウザが読み込み可能な1つのJSファイルとして出力する」という意味

# [Quick Start Without npm](https://facebook.github.io/react/docs/getting-started.html#quick-start-without-npm)

### Starter Kit

Download Starter Kitをクリック。zipを解凍し、ルートにhelloworld.htmlを作成。

helloworld.html

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>
```

htmlをブラウザで開くと動作する。
`<script type="text/babel">`の中身はbrowser.min.jsによってBabel変換が行われる。

### [Separate File](https://facebook.github.io/react/docs/getting-started.html#separate-file)

React部分のjsを外に出してみる。
Javascriptが直で書かれている`<script type="text/babel">`部分をsrc/helloworld.jsとして新規作成。

src/helloworld.js

```js
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
```

helloworld.html

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel" src="src/helloworld.js"></script>
  </body>
</html>
```

### [Offline Transform](https://facebook.github.io/react/docs/getting-started.html#offline-transform)

ここまではbrowser.min.jsによって読み込み時にhelloworld.htmlのReact部分を変換していたが、あらかじめBabelによって変換してみる。コンパイル済みのファイルを実行する感覚。

Babelコマンドラインツールをインストールする。

```bash
$ npm install --global babel-cli
$ npm install babel-preset-react
```

変換する。

```bash
$ babel --presets react src --watch --out-dir build
```

babelコマンドのオプションとして`--watch`をつけるとファイルが更新されるたびに変換処理を実行してくれる。
つまり上記のコマンドは「srcフォルダ下のReactのjsファイルを、更新があるたびにBabelで変換し、buildフォルダに出力する」という意味

コマンド実行後、build/helloworld.jsが作成されていることを確認。

build/helloworld.js

```js
ReactDOM.render(React.createElement(
  'h1',
  null,
  'Hello, world!'
), document.getElementById('example'));
```

helloworld.htmlは次のように変更してOK。

helloworld.html

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <!-- No need for Babel! -->
  </head>
  <body>
    <div id="example"></div>
    <script src="build/helloworld.js"></script>
  </body>
</html>
```

helloworld.htmlをリロードしても同じように「Hello World!」と表示されるはず。
`--watch`によりhelloworld.jsを更新してページをリロードすると、直ちに内容が更新される。