webpack で始めるイマドキのフロントエンド開発


## webpack とは
[webpack](http://webpack.github.io/) は WebApp に必要なリソースの依存関係を解決し、アセット（配布物）を生成するビルドツール（要するにコンパイラ）です。JavaScript だけでなく、CoffeeScript や TypeScript、CSS 系、画像ファイルなどを扱うことができます。

WebApp のビルドツールは Grunt や Gulp が有名です。これらは基本的に、ビルド手順をタスクという形で自ら定義する必要があり、フロントエンド開発に馴染みのない開発者にとっては敷居が高いものでした（少なくとも、自分はそうでした）。

webpack を使えば、Grunt も Gulp も必要ありません！覚えるべきことはほとんどありません。（必要なら）簡単な設定ファイルを書いて webpack コマンドを実行するだけです。

以下では基本的な使い方を見ていきます。

※もちろん Grunt/Gulp と組み合わせて、ワークフローの中にビルドツールとして組み込むこともできます。

※同様のツールに [Browserify](http://browserify.org/) があります。webpack が最適化したアセットの生成を目的にしているのに対して、Browserify は依存解決してひとつの JavaScript を生成することを目的にしている違いがあります。

## インストール
グローバルにインストールしても、プロジェクト毎にインストールしても大丈夫です。

グローバル:

```bash
$ npm install webpack -g
```

プロジェクト毎:

```bash
$ cd /path/to/project
$ npm init
$ npm install webpack --save-dev
```

`npm init` は `package.json` を生成するために必要です。すでに同ファイルがあるなら実行する必要はありません。

## Hello webpack
[公式チュートリアル](http://webpack.github.io/docs/tutorials/getting-started/)を参考に進めます。

### エントリーポイント
最初にエントリーポイントとなる js ファイルを作成します。名前は `main.js` としておきます。

```javascript
document.write("Hello webpack");
```

次に、生成された js を読み込む `index.html` を作成します。

```html
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
  </body>
</html>
```

`bundle.js` というのは webpack で生成する出力ファイルの名前です。

### ビルド
準備完了したので、実際にビルドしてみます。

```bash
$ webpack main.js bundle.js
Hash: c2f39b0a6cfb9cd0d808
Version: webpack 1.4.15
Time: 28ms
    Asset  Size  Chunks             Chunk Names
bundle.js  1529       0  [emitted]  main
   [0] ./main.js 33 {0} [built]
```

`index.html` ファイルをブラウザで開くと *Hello webpack* と表示される事が確認できます。

## モジュール化
先の例では大したことはしていないので、webpack の存在意義はよくわからないと思います。
より実践的な例として、プログラムを複数のモジュール（ファイル）に分割し、依存解決が必要なケースを扱ってみます。

### ファイル分割
`print.js` ファイルの中に、画面に文字列を書き出す関数を定義します。

```javascript
module.exports = function(msg) {
  document.write("[print] " + msg);
};
```

続いて、それを利用するように `main.js` を修正します。

```javascript
var print = require("./print");
print("Hello webpack");
```

### ビルド
```bash
$ webpack main.js bundle.js
Hash: 16b1755528d260b71262
Version: webpack 1.4.15
Time: 29ms
    Asset  Size  Chunks             Chunk Names
bundle.js  1694       0  [emitted]  main
   [0] ./main.js 56 {0} [built]
   [1] ./print.js 59 {0} [built]
```

`index.html` をブラウザで開けば print 関数が実行されているのが確認できます。

## 外部モジュールの利用
自分で作成したモジュールと同様に、一般公開されている外部モジュールを使うことができます。
まずは使いたいモジュールを npm でインストールします。ここでは MVVM ライブラリの Vue.js を使ってみます。

```bash
npm install vue --save
```

次に Vue.js を使いたい箇所で `require` します。今回は `main.js` を書き換えます。

```javascript
var Vue = require('vue');
var demo = new Vue({
  el: '#demo',
  data: {
    message: 'Hello Vue.js!'
  }
});
```

続いて Vue.js のテンプレートとなるよう `index.html` を書き換えます。body タグ内を以下のように書き換えてください。

```html
<div id="demo">
  <div>{{message}}</div>
  <input v-model="message">
</div>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
```

### ビルド
```bash
$ webpack main.js bundle.js
Hash: 8bd5cc0129397bf5744f
Version: webpack 1.4.15
Time: 256ms
    Asset    Size  Chunks             Chunk Names
bundle.js  181297       0  [emitted]  main
   [0] ./main.js 109 {0} [built]
    + 62 hidden modules
```

必要なことは全て webpack がやってくれます。`index.html` を開いて動作確認してください。

### npm or bower
依存モジュールのインストールに npm を使ったところをみて「おや？」と思われた方がいるかもしれません。Node.js 用の npm に対して、クライアントサイドには bower というパッケージマネージャがありますが、webpack では [npm の利用を推奨](http://webpack.github.io/docs/usage-with-bower.html#prefer-modules-from-npm-over-bower)しています。その理由は主に、webpack が最適化しやすいようにということです。

webpack を使えば bower すら不要というわけです。とはいえ、bower でしか提供されていないモジュールもありますので、[bower と連携する方法](http://webpack.github.io/docs/usage-with-bower.html)もちゃんと用意されています。

## webpack.config.js
今までは webpack コマンドに引数を渡してきましたが、他のビルドツールと同様に設定ファイルを作成することもできます。
ファイル名は `webpack.config.js` になります。

```javascript
module.exports = {
  entry: './main.js',
  output: {
    path: __dirname,
    filename: 'bundle.js'
  }
};
```

設定ファイルを作成しておけば、引数を渡す必要はなくなります。

```bash
$ webpack
Hash: 1e37faf49db800f67a24
Version: webpack 1.4.15
Time: 265ms
    Asset    Size  Chunks             Chunk Names
bundle.js  181297       0  [emitted]  main
   [0] ./main.js 109 {0} [built]
    + 62 hidden modules
```

## おわりに
本記事では最新の JavaScript 開発ツールである webpack を紹介しました。あまり JavaScript に馴染みがない人でも、webpack を使えば WebApp の開発を手軽に始められます。webpack はここで紹介した以外にも、プラグインを導入することで CSS や CoffeeScript、TypeScript、イメージ等を扱うこともできます。また、生成物を複数のファイルに分割して、ページの読み込みを高速化する方法も提供されています。

webpack に興味を持たれた方は[公式ドキュメント](http://webpack.github.io/docs/)に目を通されることをおすすめします。