webpackちゃんと理解しとこ わからなかった設定編

※ これは古いWebpackの情報です。(どのバージョンの話か忘れるぐらいには古く多分webpack２とかそういう時期の話です。)

設定に関するドキュメントを読んで、それだけではわからなかったことを一個ずつ確認していく。

[設定ファイル編](http://qiita.com/umezo@github/items/e2dde7d1f66dbf8aec3a) ← prev | next → [browserifyなライブラリ(pixi.js)をrequireしようとした編](http://qiita.com/umezo@github/items/5a68469179565660c81c)

実際に動かして確認した結果であり確認手順などが間違っていて誤解している可能性もある。
鵜呑みにしないように

### まとめ
- entryを配列で指定した場合、ドキュメント通り最後尾のファイルがexportしたものがexportされる
    - それを利用する場合は`output.library`などを正しく設定する
    - 成果物を他のjsから読み込まなければ関係ない
- `[hash]`はコンパイル時に算出され、全く同じものをコンパイルする限り同じ値になる
- `[chunkhash]`は今回確認できなかった
    - CommonChunkPluginなどとの併用がひつよう？

### entryに配列渡した時にexportされるもの
`entry: ["a.js","b.js"]` という設定ができるがどんなjsが出力されるのか？

これはwebpackでライブラリ系のjsを作るときに関係ある挙動で`output.library`と`output.libraryTarget`が正しく設定されていれば、その方法で成果物を読み込むと、`b.js`がexportしたものが返る。
 (デフォだと`var`なのでnodeでrequireしても`{}`しか得られない

適当に[こんな感じ](https://gist.github.com/umezo/e7d2cc8445e00af0172d4e15ce519d73)の設定をして出力されたファイルを確認した。

```js
module.exports = {
  entry:["./entryA.js","./entryB.js"],
  output: {
    filename:"bundle.js",
    path: __dirname + '/dest',
    pathinfo:true
  }
}
```

出力されたjsのここを見るとどういうことがよく分かる。
なるほど確かに `All modules are loaded upon startup. The last one is exported.` である。

```js
/*!******************!*\
  !*** multi main ***!
  \******************/
/***/ function(module, exports, __webpack_require__) {

  __webpack_require__(/*! ./entryA.js */1);
  module.exports = __webpack_require__(/*! ./entryB.js */4);


/***/ },

```

これはつまりコンパイルされて出てきた`bundle.js`をrequireすると`entryB.js`がexportしたものが使えるということか？


そこで`bundle.js`を読み込む`test.js`を作り、nodeで実行してみた。

```js
//test.js
console.log("- start test.js ----------------");
console.log(require("./dest/bundle.js"));
console.log("- end test.js ----------------");
```
結果はこちら

```
- start test.js ----------------
- entryA.js -------------------
A
B
- entryB.js -------------------
A
B
{}
- end test.js ----------------
```

え？ `{}`?? object？？？？？ (期待していたのは`"entryB.js"`

あぁ targetが`web`(デフォ)だからで、それをnodeでrequireしたら最期に評価した値`return __webpack_require__(0);`が返ってきたのか。

と思って `target:"node"` を足してみたものの結果変わらず。 (そもそもbundle.jsの中身が変わることを期待していたが変わらず。

単純に`bundle.js`が`module.exports`に何も代入しないからっぽく、例えば↓みたいになってればイケそう。

```js
//bundle.js
module.exports = (function(modules){
        ....
      return module.exports;
    })([
        ....
    ]);
```

`target:"node"`ではなく`output.libraryTarget:"commonjs2"`が正解で、
まさに上記のようなコードが生成されていた。
(逆に`target`設定は何なんだ・・・・)

だいたい理解した。 (合わせて読みたい -> [LIBRARY AND EXTERNALS](http://webpack.github.io/docs/library-and-externals.html))




### `[hash]`と`[chunkhash]`
複数のentryを指定してる場合に、これらの代替文字(substitutions)を使っていないとファイルを上書きながらコンパイルされてしまう。
そしてこの`[hash]`と`[chunkhash]`は具体的にどのような値なのか確認する。

- `[hash]`はコンパイル時に算出されて、対象が完全に一致していれば同じ値をとる
- `[chunkhash]`今回の検証ではエラーとなり使えなかった。CommonChunkPluginを使う場合に使える？

適当に[こんな感じ](https://gist.github.com/umezo/df567f28a8c6b974cb0fc29629aa0214)の設定をして出力されたファイルを確認した。

`filename:"bundle-[hash]-[chunkhash].js"` と設定したところ、コンパイルで怒られた。
使えないの・・・？

```
ERROR in chunk A [entry]
bundle-[hash]-[chunkhash].js
Cannot use [chunkhash] for chunk in 'bundle-[hash]-[chunkhash].js' (use [hash] instead)
```



そこで`filename:"bundle-[hash].js"`をためしたところ、
出力されたファイルは１つで中身はentryB.jsであったので、同名ファイルで上書きされたのだろう。

```
$ npm run build

> compcheck-substitutions@1.0.0 build /Users/.........
> webpack

Hash: e52256d16e419cbf8652
Version: webpack 1.13.1
Time: 63ms
                         Asset     Size  Chunks             Chunk Names
bundle-e52256d16e419cbf8652.js  1.78 kB    0, 1  [emitted]  A, B
   [0] ./entryA.js 77 bytes {0} [built]
   [0] ./entryB.js 113 bytes {1} [built]
   [1] ./a.js 22 bytes {0} [built]
   [2] ./b.js 22 bytes {1} [built]



$ ls dest
bundle-e52256d16e419cbf8652.js
```

コンパイル時のメッセージにもあるが`[hash]`は`Hash: e52256d16e419cbf8652
`で示される値をとり、 __何も変更しなければ毎回同じ__ になる。
cache bustingなんかに使いそう。
ただしentry毎に算出される値ではないのでentry Aにだけ影響のある変更でもBのキャッシュバストが発生してしまう。
この辺を`[chunkhash]`が解決してくれると思ってたんだけど結局わからず。
( [CommonsChunkPlugin使った時だけ有効？](https://github.com/webpack/webpack/tree/master/examples/chunkhash) )