webpack4のTree Shakingを基本的なimport/exportで試してみる
webpack4のTree Shakingを基本的なimport/exportで試してみる:
今まで大して意識をせずに
え、そんな危険なの?と。なんとなく、
めっちゃありがたい先駆者の記事がありましたので、そのソースコードをフォークしました。ありがたや。
今回のソースコードはこちらになります。
環境は以下のような感じ。
webpackは4系で試しています。3系でも試したところ、結構結果変わったので、注意してください。
かなりバリエーションに富んだ、import & export & default を試しました。以下の「単体export」は
つまり、上記の例では、
画像
お、all3.js以外はTree Shakingが効いていることがわかりました。
アンチパターン検証記事によれば、
個人的に気になっていたこととして、「
結果としては、Tree Shaking は効いていました。こうなってくると、多量にexportが存在するファイルでは、
今回の実験の目的として、これがありました。ReactとReduxのファイル構成パターンであるre-ducksなどで構成が深くなる場合、どうしてもindex.jsにexportを集約させたほうが楽になります。そうした、1クッションおく場合の実装はどのようなimport/exportが最適なのかを知りたかったのですが、それがわかりました。
以下の通りにやると、しっかりTree Shakingが効くことがわかりました。
ちなみに、構文的に
かなり違いました。3系では、アンチパターン検証記事が正しく、オブジェクトの場合は全くTree Shakingが効きません。object.js、object2.js、object3.jsが全滅でした。また同様に、all3.jsとall4.jsでもTree Shakingは効いていませんでした。
3系でも効くのは、solo.jsとall.js、all2.jsのみでした。つまり、単体でimport/exportするか、直接
自分で確認したい方は、webpack3用にブランチを切ったので、そちらをクローンし、ビルドしてください。その結果をここでminifyすると、何がTree Shakingされるかが確認できます。
圧縮率も違うみたいだし、webpack3からwebpack4に移行しましょう!!
今まで大して意識をせずに
import
やexport
を行ってきましたが、TypeScriptについていろいろ調べていたところ、このようなものを見つけ。。export default
considered harmfulえ、そんな危険なの?と。なんとなく、
import
書くの楽だし使っていたのですが、ビビりました。まぁ読んでみるとそこまで害悪でもなかったのですが、調べているとアンチパターンについて言及があったりなど、何も考えずに使っていると無駄にbundleされたファイルが大きくなってしまうようなので、ここらでTree-Shakingをテストすることにします。
テスト環境
めっちゃありがたい先駆者の記事がありましたので、そのソースコードをフォークしました。ありがたや。今回のソースコードはこちらになります。
環境は以下のような感じ。
package.json
"devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "babel-plugin-transform-imports": "^1.5.0", "babel-preset-env": "^1.6.1", "webpack": "^4.14.0", "webpack-cli": "^3.0.2" }
テストしたもの
かなりバリエーションに富んだ、import & export & default を試しました。以下の「単体export」はexport func, export func2
のようにexportだけを使ったもの、「単体でimport」はimport { func }
、「全体でimport」はimport * as hoge
でhoge.func
を実行といった感じです。詳しくは、ソースコード見てください。- 「単体export」を「単体でimport」: solo.js
- 「単体export」を「全体でimport」: all.js
- 「単体exportをそのまま全体でexportしたファイル」を「全体でimport」: all2.js
- 「単体exportを全体でimportし、それを単体exportしたファイル」を「単体でimport」: all3.js
- 「export default した object を default as で受けたものを export したファイル」を「単体でimport」: all4.js
- 「object を export default」を「普通にimport」: object.js
- 「object を export default」を「default as で import」: object2.js
-
「アンチパターン検証記事で試されていたもの」を「普通にimport」: object3.js
// all.js export const allA = () => console.log('allA'); export const allB = () => console.log('allB'); // index.js import * as all from './all'; all.allA();
console.log('allA');
のみ見つかれば「Tree Shakingが効いている」、console.log('allB');
も見つかると「Tree Shakingが効いていない」と判断できます。
実行結果
yarn build
でビルドできます。実行したときの結果は以下の通り。画像
dist/bundle.js
// 上の方は省略 var r = function () { return console.log("soloA") }, l = function () { return console.log("all3A") }, u = function () { return console.log("all3B") }, c = function () { return console.log("all4A") }, f = function () { return console.log("objectA") }, i = function () { return console.log("object2A") }; r(), console.log("allA"), console.log("all2A"), r(), t.all3A(), c(), f(), i(), console.log("foo") }]);
テストからわかったこと1:オブジェクトでexportしてもTree Shakingは効く
アンチパターン検証記事によれば、export default object
ではTree Shakingが効かないとありましたが、webpack4では効くようです。(※webpack3では、効かないですが!詳細は後述。)
テストからわかったこと2:全体指定でexportしてもTree Shakingは効く
個人的に気になっていたこととして、「import * as all from './all';
として、その一部分しか使用しなかった場合に、Tree Shakingが効くのか否か」があります。結果としては、Tree Shaking は効いていました。こうなってくると、多量にexportが存在するファイルでは、
*
でimportしてそこから呼び出した方が気持ちよくなりますね。
テストからわかったこと3:ワンクッションおいてexportしたい場合はexport { default as name }
を使う
今回の実験の目的として、これがありました。ReactとReduxのファイル構成パターンであるre-ducksなどで構成が深くなる場合、どうしてもindex.jsにexportを集約させたほうが楽になります。そうした、1クッションおく場合の実装はどのようなimport/exportが最適なのかを知りたかったのですが、それがわかりました。以下の通りにやると、しっかりTree Shakingが効くことがわかりました。
// all4.js export { default as all4 } from './forAll4'; // forAll4.js const all4A = () => console.log('all4A'); const all4B = () => console.log('all4B'); export default { all4A, all4B };
export * as all4 from './forAll3
などのようなことはできないみたいなので、これを実現したい場合は上記のようにexport default
を使う必要があります。
webpack 3系で試すと全然違った
かなり違いました。3系では、アンチパターン検証記事が正しく、オブジェクトの場合は全くTree Shakingが効きません。object.js、object2.js、object3.jsが全滅でした。また同様に、all3.jsとall4.jsでもTree Shakingは効いていませんでした。3系でも効くのは、solo.jsとall.js、all2.jsのみでした。つまり、単体でimport/exportするか、直接
import * as all
などのようにimportする場合は、Tree Shakingが効くということです。自分で確認したい方は、webpack3用にブランチを切ったので、そちらをクローンし、ビルドしてください。その結果をここでminifyすると、何がTree Shakingされるかが確認できます。
コメント
コメントを投稿