コンパイラかく語りき

import { Fun } from 'programming'

Tree shakingの話

前回、Rollupについて書きました。

chuckwebtips.hatenablog.com

 

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したライブラリの中身を静的に知る事ができます。また、ライブラリのコンテンツへのアクセスもすばやくなります。

以下、例です。

gist729b214b9bfc9a38b8a8

 

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の方が優勢っぽいですね。

 

参考文献:Tree-shaking with webpack 2 and Babel 6