Babelの使い方③ - Babel + Webpack


[Babelの使い方① - Babel単体](http://qiita.com/takap235711/items/343fb4a898413116be64)
[Babelの使い方② - Babel + Gulp](http://qiita.com/takap235711/items/c059f772b563d436b850)

今回はBabelとモジュールシステムのWebpackを組み合わせた場合のビルド環境についてまとめます。
WebpackにおけるBabelのビルドは、webpackで利用される`loader`の内、`babel-loader`を利用して、モジュールのビルド前（依存解決前）のタイミングでES6のコンパイルを行います。

## Babel + WebpackのES6ビルド環境の構築
[Babel built-systems -> Webpack](https://babeljs.io/docs/setup/#installation)

前提として、node.jsとbabelとwebpackがグローバルインストールされている状態を想定
> webpackコマンドが見つからない的なメッセージが出た場合は、webpackをグローバルインストールして下さい
`$ sudo npm install -g webpack`

- 適当なディレクトリを用意  

 ```terminal
$ mkdir babel_test/cap3
$ cd babel_test/cap3
```

- package.jsonを作成
`$ npm init`で対話的に下記のようなファイルを作成しました↓

 ```package.json
 {
 		"name": "babel-test-webpack",
 		"version": "1.0.0",
 		"description": "hoge",
 		"repository": "piyo",
 		"main": "index.js",
 		"scripts": {
 			"test": "echo \"Error: no test specified\" && exit 1"
 		},
 		"author": "",
 		"license": "ISC"
}
```
> ミスって、descriptionとかrepositoryが空になっちゃっても`sudo vi package.json`で編集出来ます。
（自分の環境だとread-onlyなpackage.jsonが生成されました）

- 諸々のプラグインをインストール

  ```terminal 
 $ npm i --save-dev webpack babel-core babel-loader babel-preset-es2015
 ``` 
> iはinstall、webpackはプロジェクトディレクトリにもインストールしないと動きませんでした。

- .babelrcを作成
 
 ```terminal
 $ touch .babelrc
 $ echo '{ "presets": ["es2015"] }' > .babelrc
```

- webpack.config.jsを作成

 ```webpack.config.js
 module.exports = {
 		// ビルドの基点となるファイル
 		entry: './src/entry.js',
 		// ビルド後のファイル
 		output: {
 			path: __dirname + '/dist',
 			filename: 'bundle.js'
    	},
    	// 拡張子が.jsのファイルはbabel-loaderを通してビルド(node_modulesは除外)
    	module: {
       		loaders: [{
       			test: /\.js$/,
       			exclude: /node_modules/,
       			loader: 'babel-loader'
       		}]
       	}
};
```

- コンパイル元のファイルを作成
class構文、デフォルトパラメータ、テンプレート文字列、文字列埋め込みを利用
モジュールの吐き出し/読み込みはwebpack（CommonJS）を利用

 ```src/sampleClass.js
 class Sample {
 		constructor(num = 1) {
 			this.number = num;
 		}
 		getNumber() {
 			console.log(`Number is ${this.number}`);
 		}
 		setNumber(num) {
 			this.number = num;
 		}
 }

 module.exports = Sample;
 ```

 ```src/sampleClass.js
	var Sample = require('./sampleClass.js');

	var sample = new Sample;
	sample.getNumber(); // -> Number is 1
	sample.setNumber(5);
	sample.getNumber(); // -> Number is 5
 ```

- ビルドする

 ```terminal
 $ pwd # -> ~/babel_test/cap3
 $ webpack
```

 ![スクリーンショット 2016-05-20 14.06.49.png](https://qiita-image-store.s3.amazonaws.com/0/36492/9c43a912-47e7-58e7-4cdc-c0cd081dea18.png "スクリーンショット 2016-05-20 14.06.49.png")

- ウォッチも出来る

 ```terminal
 $ webpack --watch
```

 ![スクリーンショット 2016-05-20 14.11.29.png](https://qiita-image-store.s3.amazonaws.com/0/36492/02fe8186-5d8b-08bb-3cc2-49016231acd1.png "スクリーンショット 2016-05-20 14.11.29.png")

- 一応、コンパイル結果

 ```dist/bundle.js
...略...

 /************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var Sample = __webpack_require__(1);

	var sample = new Sample();
	sample.getNumber();
	sample.setNumber(5);
	sample.getNumber();

 /***/ },
/* 1 */
/***/ function(module, exports) {

	"use strict";

 ...略...

	var Sample = function () {
	    function Sample() {
	        var num = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];

	        _classCallCheck(this, Sample);

	        this.number = num;
	    }

	    _createClass(Sample, [{
	        key: "getNumber",
	        value: function getNumber() {
	            console.log("Number is " + this.number);
	        }
	    }, {
	        key: "setNumber",
	        value: function setNumber(num) {
	            this.number = num;
	        }
	    }]);

	    return Sample;
	}();

	module.exports = Sample;

 /***/ }
/******/ ]);
```
> bundle.jsのビルド（モジュールの依存解決）は出来ているけど、ES6がコンパイルされていない（bundle.jsにclassとか記述されたまま）の場合、プラグインが足りていない、もしくはwebpack.config.jsのmodule{}内において、babel-loaderの処理が通っていない可能性があります。
（自分は、タイポで詰まりました）

### 参考記事

[Babel built-systems -> Webpack](https://babeljs.io/docs/setup/#installation)
[webpack + babel-loaderでES6デビューしつつ、gulpもES6で書く](http://qiita.com/inureo/items/6ac74fb19e12f395e4c1)
[ECMAScript6で書こう！WebPackとES6-loaderで環境を作り、ES6を先取り体験する方法](http://liginc.co.jp/web/js/other-js/132046)