前回、Rollupについて書きました。
Rollupの中心的な概念として、”tree shaking”というものがあるそうです。今回はその仕組について調べましたのでメモします。
※筆者は最近フロントエンドの世界にやってきました。この記事はあくまで勉強メモです。誤りがありましたら、ご指摘いただけると助かります。
Tree Shaking
Tree Shakingとは、直訳すると「木を揺らすこと」。転じて、何かを実行することという意味があるようです。
Rollupの文脈においては、「不要なものを削ぎ落とす」という意味合いだと思われます。
不要なものを削ぎ落とす?
では、不要なものとはなんでしょうか?
それは、bundleファイルからの不使用なexportです。Rollup.jsは、ES6の静的なモジュール構造を利用して、不使用なexportを判別しています。
静的なモジュール構造?
静的なモジュール構造は、実行時ではなくコンパイル時に構造が決定します。つまり、コンパイル時に、静的にimportとexportを決定することができます。実行時にimportやexportが変わることはありません。
詳しくはこちら ⇛ http://exploringjs.com/es6/ch_modules.html#static-module-structure
静的なモジュール構造の利点
静的なモジュール構造にはいくつかの利点があります。
1. bundle時のDeadCodeElimination
静的にモジュール構造が決定されるので、コンパイル時に不要なexportを判定することができます。
この際に、不要なexportが排除されて、おおいにムダが排除されます。これがDeadCodeEliminationです。
2. すばやいルックアップ
静的モジュール構造ならば、importしたライブラリの中身を静的に知る事ができます。また、ライブラリのコンテンツへのアクセスもすばやくなります。
以下、例です。
3. 変数のチェック
静的なモジュール構造においては、コンパイル時にモジュールの中身を知ることができます。つまり、モジュール内の変数をチェックすることができるのです。
この利点はJSLintや、JSHintに用いられているようです。
上記の他にも、マクロ、型チェックなどの利点もあるそうです。ただ、ready for...とのことなのでまだ実現は先のようですが。
Webpackの場合
さて、話を戻します。冒頭でも述べたように、Rollup.jsは静的なモジュール構造を利用してtree-shakingを実現しています。
一方で、Webpackも似たような手法を取っています。
Webpack2では、もし静的なモジュール構造が利用された場合のみ、ビルド時に不使用なexportsを探知することができます。そのため、Webpack2はES6を理解し、パースすることができます。
ただし、importとexportしかES5にトランスパイルされないので、もし全てをES5にbundleしたいのならBabel6のようなものを別途使ってね!とのこと。
Rollupでは
ご存知の通り、RollupではES6がデフォルトで採用されています。
そのため、全てに静的なモジュール構造が適用されます。なので、我々がDeadCodeEliminationを意識することなく、裏側で良い感じにコンパイルしてくれるのです。
まとめ
TreeShakingについて勉強しました。途中で横道に逸れてEcmaの仕様を読むことになってしまいましたが、良い勉強になりました。
TreeShakingという観点で言えば、Rollupの方が優勢っぽいですね。