8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-07-22

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

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

設定ファイル編 ← prev | next → browserifyなライブラリ(pixi.js)をrequireしようとした編

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

まとめ

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

entryに配列渡した時にexportされるもの

entry: ["a.js","b.js"] という設定ができるがどんなjsが出力されるのか?

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

適当にこんな感じの設定をして出力されたファイルを確認した。

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. である。

/*!******************!*\
  !*** 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で実行してみた。

//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.jsmodule.exportsに何も代入しないからっぽく、例えば↓みたいになってればイケそう。

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

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

だいたい理解した。 (合わせて読みたい -> LIBRARY AND EXTERNALS)

[hash][chunkhash]

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

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

適当にこんな感じの設定をして出力されたファイルを確認した。

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"をためしたところ、
出力されたファイルは1つで中身は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使った時だけ有効? )

8
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?