引き続き、webpackの仕組みについて見ていきます。
前回書いたコードはこちらでした。
本当に単純な定数定義ですね。
実際の開発では、JavaScriptはモジュール単位で書くのが基本だと思います。なので、まずはモジュール化を行います。
ES6 export
まずは、CommonJS形式ではなくES6のexport を使います。また、実行されたかどうかがわかりやすいように、処理分にconsole.logを書きました。
変換後のbundle.jsがこちら。
前半部分は前回解説したものと変わっていなさそうです。
後半のモジュール部分が変わりましたね。
Object.definePropertyを使用している部分と、関数定義部分に分けることができそうです。
まずはObject.defineProperty部分について。
exportsオブジェクトに対して、__esModule__ というキー名で、true値をセットしています。
definePropertyを使うことによって、暗示的にプロパティの属性をfalseにすることができます。
プロパティの属性については、以下の記事がとてもわかりやすかったです。
十一章第四回 Objectとプロパティ — JavaScript初級者から中級者になろう — uhyohyo.net
つまり、exportsに__esModule__プロパティを追加したけど、それは上書き不可能だし、列挙されないし、そういった設定を変更することは不可能、ということです。
なので、console.log(exports)で表示しても、__esModule__プロパティは見えません。
次に、関数定義部分について。
var helloとfunction(){...} の間にexports.helloが挟まりましたね。
exportsのプロパティとしてhello関数を定義しているんですね。
exportsプロパティはmoduleオブジェクトに含まれており、moduleオブジェクトはinstalledModulesというオブジェクトに含まれているので、すべてのexportはinstalledModulesから辿れることになりますね。
CommonJS export
では、これをexportではなくCommonJS形式のmodule.exportsに変えてみます。
変換後のモジュール定義部分がこちら。
なるほど!w
引数で受け取っているmoduleのexportsプロパティに追加を行っていますね。ただし、module.exportsはもう1つの引数であるexportsと同じものです。
そして、CommonJS式の場合は特に__esModule__: trueのような目印はつけないんですね。
複数モジュールの定義
なんとなく予想はつきますが、複数のモジュールを定義した場合も見てみます。
変換後はこんな感じ。
exportsプロパティとして複数定義される感じですね。
export default
では、ES6式のexport defaultによるモジュール化はどうなるでしょう。
一番最後にdefault exportを追記しました。
変換後はこのとおり。
なるほどw
exports.defaultのプロパティとして追加されました。import時にどのように処理されるのか、楽しみです。
以上、JavaScriptコードのモジュール化をwebpackがどのように処理するか見てみました。
次回は定義したモジュールを外部からimport/requireしてみます。