読者です 読者をやめる 読者になる 読者になる

コンパイラかく語りき

文系新卒プログラマーのメモ

webpackはどのように動いているのか(2)

引き続き、webpackの仕組みについて見ていきます。

 

chuckwebtips.hatenablog.com

 

前回書いたコードはこちらでした。

 

gist.github.com

 

本当に単純な定数定義ですね。

実際の開発では、JavaScriptはモジュール単位で書くのが基本だと思います。なので、まずはモジュール化を行います。

 

ES6 export

 

gist.github.com

 

まずは、CommonJS形式ではなくES6のexport を使います。また、実行されたかどうかがわかりやすいように、処理分にconsole.logを書きました。

変換後のbundle.jsがこちら。

 

gist.github.com

 

前半部分は前回解説したものと変わっていなさそうです。

後半のモジュール部分が変わりましたね。

 

gist.github.com

 

Object.definePropertyを使用している部分と、関数定義部分に分けることができそうです。

 

まずはObject.defineProperty部分について。

 

gist.github.com

 

exportsオブジェクトに対して、__esModule__ というキー名で、true値をセットしています。

definePropertyを使うことによって、暗示的にプロパティの属性をfalseにすることができます。

プロパティの属性については、以下の記事がとてもわかりやすかったです。

十一章第四回 Objectとプロパティ — JavaScript初級者から中級者になろう — uhyohyo.net

 

つまり、exportsに__esModule__プロパティを追加したけど、それは上書き不可能だし、列挙されないし、そういった設定を変更することは不可能、ということです。

なので、console.log(exports)で表示しても、__esModule__プロパティは見えません。

 

次に、関数定義部分について。

gist.github.com

 

var helloとfunction(){...} の間にexports.helloが挟まりましたね。

exportsのプロパティとしてhello関数を定義しているんですね。

 

exportsプロパティはmoduleオブジェクトに含まれており、moduleオブジェクトはinstalledModulesというオブジェクトに含まれているので、すべてのexportはinstalledModulesから辿れることになりますね。

 

 

CommonJS export

では、これをexportではなくCommonJS形式のmodule.exportsに変えてみます。

 

gist.github.com

 

変換後のモジュール定義部分がこちら。

 

gist.github.com

 

なるほど!w

引数で受け取っているmoduleのexportsプロパティに追加を行っていますね。ただし、module.exportsはもう1つの引数であるexportsと同じものです。

そして、CommonJS式の場合は特に__esModule__: trueのような目印はつけないんですね。

 

複数モジュールの定義

なんとなく予想はつきますが、複数のモジュールを定義した場合も見てみます。

gist.github.com

 

変換後はこんな感じ。

gist.github.com

 

exportsプロパティとして複数定義される感じですね。

 

export default 

では、ES6式のexport defaultによるモジュール化はどうなるでしょう。

 

一番最後にdefault exportを追記しました。

 

gist.github.com

 

変換後はこのとおり。

 

gist.github.com

 

なるほどw

exports.defaultのプロパティとして追加されました。import時にどのように処理されるのか、楽しみです。

 

 

 

以上、JavaScriptコードのモジュール化をwebpackがどのように処理するか見てみました。

次回は定義したモジュールを外部からimport/requireしてみます。