Babelを使おう

# Babel

Reactやる時に生のJSを書くとシンドイので、ES2015やJSXで書きます。だけど、生のJSとは違いES2015やJSXはブラウザで直接実行できません。ですのでトランスパイラとよばれるプリプロセッサを使ってそれらをブラウザで動く生のJSに変換します。このトランスパイラの1つがBabelです。

他にもJavaScriptの世界にはたくさんのトランスパイラが有ります。※JS初心者なんで間違ってたらツッコミをお願いします。

- TypeScript...静的型付けのできるのでより安全にJavaScriptを書けるのが特徴です
- CoffeeScript...Ruby親和性の高い書き方ができて、それをJavaScriptに変換します

## Babelのインストールと使い方

### とにかく使う場合

```
$ npm install --global babel-cli
```

使い方

```
$ babel example.js --out-file compiled.js
```
※ `--global` babel-cliをインストールするのはあまりイケてないので、使い方に慣れたら、 `$ npm uninstall --global babel-cli` しておきましょう

### プロジェクトで単独で使う場合

```
$ mkdir my-project && cd $_
$ npm init
$ npm install --save-dev babel-cli
$ mkdir src lib
```

```diff
$ vi package.json

  {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }
```

```
$ npm run build
```

### browserifyで使う場合

browserifyはブラウザ側でCommonJS(サーバサイドJS)のrequireが動作するようにプリプロセスするものです。サーバサイドのモジュール化機能をブラウザサイドでも動作するように変換しているんです。

似たものに「RequireJS」などが有ります。こちらは複数ファイルにわかれたJavaScriptのファイルをブラウザでそれぞれ読み込んで依存性の解決を行なうものです。RequireJSはファイルを非同期で複数読み込むため、ファイルを纏めて読み込むbrowserifyの方が高速のようです。

browserifyを使った時の処理の順番はbrowserify→babelifyです。

```
$ mkdir my-project && cd $_
$ npm init
$ npm install --save-dev browserify babelify
$ mkdir src lib
```

```diff
$ vi package.json

  {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "browserify ./src/app.js -t babelify --outfile ./lib/app.js"
+   },
    "devDependencies": {
	   "babelify": "^7.3.0",
	   "browserify": "^13.0.1"
    }
  }
```

```
$ vi src/app.js
console.log("Hello world!");
```

```
$ npm run build
```

### gulpで使う場合

browserifyやbabelifyはタスクランナーで実行すると楽です。タスクランナーの1つであるgulpで実行してみましょう。

browserifyのtransformメソッドでbabelifyを指定してbabelの変換を実行した後、browserifyでbundleしてファイルストリームにして、vinyl-source-streamを使ってviniylオブジェクトにして、最後にgulpに渡します。

```
$ mkdir my-project && cd $_
$ npm init
$ npm install --save-dev browserify babelify gulp vinyl-source-stream
$ mkdir src lib
```

```js
$ vi gulpfile.js
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require("vinyl-source-stream");

gulp.task('browserify', function() {
  browserify('./src/app.js', { debug: true })
    .transform(babelify)
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source("app.js")) 
    .pipe(gulp.dest('./lib/'))
});

gulp.task('default', ['browserify']);
```

```js
$ vi src/app.js
console.log("Hello world!");
```

```
$ gulp
```

### ES2015、Reactも載せてみよう

最後にES2015でReactなBabelをgulpで処理してみましょう。ついでにgulp-webserverでライブリロードにしましたが、良い子はgulp-webserverよりいいテクニックを知っていると思います。

```
$ mkdir my-project && cd $_
$ npm init
$ npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-react gulp gulp-webserver vinyl-source-stream react react-dom
$ mkdir src app app/lib
```

```js
$ vi .babelrc 
{
  "presets": ["es2015", "react"],
  "plugins": ["transform-react-jsx"]
}
```

```js
$ vi gulpfile.js
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require("vinyl-source-stream");
var webserver = require('gulp-webserver');

gulp.task('browserify', function() {
  browserify('./src/app.js', { debug: true })
    .transform(babelify)
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source("app.js"))
    .pipe(gulp.dest('./app/lib/'))
});

gulp.task('watch', function() {
  gulp.watch('./src/*', ['browserify'])
});

gulp.task('webserver', function() {
  gulp.src('./app/')
    .pipe(webserver({
      host: '127.0.0.1',
      livereload: true
    })
  );
});

gulp.task('default', ['browserify', 'watch','webserver']);
```

```js
$ vi src/app.js
var React = require('react');
var ReactDOM = require('react-dom');

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

```

```html
$ vi app/index.html
<!DOCTYPE html>
<html>
<head lang="ja">
  <meta charset="UTF-8">
</head>
<body>
<div id="container"></div>
<script src="lib/app.js"></script>
</body>
</html>
```

```
$ gulp
```

**Have fun!!**

### 参考

- [React.js + Babel + Browserify + gulp の環境を作ってみた](http://qiita.com/hkusu/items/e068bba0ae036b447754)
- [React preset · Babel](https://babeljs.io/docs/plugins/preset-react/)
- https://github.com/babel/babelify