フロントエンドの最適化。 パート2. webpackプロジェクトのツリーシェーキングを修正する



そのため、特に修復しない限り、webpackのツリーシェーキングは機能しません。 誰が信じないか、私の前の記事を読んでください 。 本当に修正したい場合は、catへようこそ。 私ができるいくつかのオプションがあります スパイ 見つける 思い付く。







テストコード



次のような2つのファイルで行ったすべての実験:







// module.js class Wheel { pump(){ console.log('puuuuf');} } class Rudder { turn(){ console.log('turn');} } export {Wheel, Rudder}
      
      





 // index.js import {Wheel} from './module.js'; class Car { constructor() { this.wheel = new Wheel(); } } const car = new Car(); car.wheel.pump();
      
      





明白なオプションは曲線です:uglify-> babel-> uglify



コード







前の記事へのコメントで、私は明らかな解決策を提供されました。 babelがアセンブリに干渉し、UglifyJSが余分なコードをスローすることを防ぐためにすべてが壊れる場合、まずUglifyJSを起動して余分なコードを捨ててからbabelを捨ててみませんか?







webpack専用の何かを書くのは面倒なので、コンソールでnpmスクリプトを使用してすべてのステップを実行しました。







babel-loaderを使用せずにサンプルからファイルをコンパイルし、UglifyJSをスキップしようとしました。 UglifyJSが落ちました。 新しいjavascript構文をよく理解していません!







大丈夫だと思って掘り出した スチュワーデス uglify-es 問題は、バベルは縮小について何も知らず、出力は縮小されていないコードであるということです。







バベルの後、再びUglifyJSを実行する必要があります。







おそらく誰かがこのアプローチを使用すると思いますが、私自身はあまり好きではありません。







合理的なオプション:babel 7を待つ



コード







顧客はあなたのコードを使用しますか? 彼は生産中ですか? その場合、新しいbabelのリリース後に更新をスケジュールします。 アプリケーションはツリーシェーキングなしで常に機能しているため、災害は発生しません。

プロジェクトをゼロから開発し始めていると同時に大胆な場合は、テストバージョンを既に接続できます。 アプリケーションの作業中に、新しいバージョンのbabelがリリースされます。

いずれにせよ、バベルはオープンソースです。つまり、彼が早く出て行くのを手伝うことができます。







ラジカルオプション:ロールアップ



コード







Webpackにあまり慣れていない場合は、Rollupにジャンプするのに遅すぎることはありません。 単純なアプリケーションとライブラリの場合、ロールアップは適切な選択です。







このオプションは急進的で、松葉杖を使用しますが、時には機能します:typescript



コード







タイプスクリプトを使用してbabelをスローし、アプリケーションをコンパイルできます。 結局のところ、javascriptはすでにtypescriptであると約束されていました;)

ディレクティブ#__PURE__



typescriptが立つべき場所に、 @class



ディレクティブを残します。そして、ご理解の@class



、この@class



を必要なものに変更するローダーを作成する費用はかかりません。







 module.exports = function(content) { return content.replace(/\/\*\* @class \*\//g, '\n /*#__PURE__*/ \n'); };
      
      





フローで何かを思いつくこともできると思います。 ちなみに、私は執筆中に、おそらくバベルも何らかの形で役立つと思った。 たぶんあなたの一人が答えを知っていますか?







最適化ファンのための根本的なオプション:Google Closure CompilerとAdvanced Mode



コード







これは私が一番好きなものです。 私が話していることを理解するために、コンパイル後に取得されたバンドルの最適なバージョンを一度に1つずつ比較してみましょう。







Webpack + Babel:
 !function(n){function e(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return n[r].call(o.exports,o,o.exports,e),ol=!0,o.exports}var t={};em=n,ec=t,ed=function(n,t,r){eo(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:r})},en=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return ed(t,"a",t),t},eo=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},ep="",e(es=0)}([function(n,e,t){"use strict";function r(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=t(1);(new function n(){r(this,n),this.wheel=new oa}).wheel.pump()},function(n,e,t){"use strict";function r(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}function o(n,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}function u(n,e,t){return e&&o(n.prototype,e),t&&o(n,t),n}td(e,"a",function(){return c});var c=function(){function n(){r(this,n)}return u(n,[{key:"pump",value:function(){console.log("puuuuf")}}]),n}()}]);
      
      





ロールアップ:
 !function(){"use strict";var classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")},Wheel=function(){function Wheel(){classCallCheck(this,Wheel)}return Wheel.prototype.pump=function(){console.log("puuuuf")},Wheel}();(new function Car(){classCallCheck(this,Car),this.wheel=new Wheel}).wheel.pump()}();
      
      





拡張モードのGoogleクロージャーコンパイラ

console.log('puuuuf');









これ以上の説明は必要ないと思います。 しかし、問題もあります。 メイン2:









GCCは次のように始まります。







 java -jar node_modules/google-closure-compiler/compiler.jar --compilation_level ADVANCED --language_in=ES6 --js ./src/index.js ./src/module.js > out.dev.js
      
      





最初の問題は完全に解決可能です。特にブレーキがかかっていますが、それでもJavaScriptバージョンです。

このシリーズの次回の記事では、2番目の問題について説明します。Googleクロージャーコンパイラをアセンブリに統合することを試みます。







PS:

最近、同僚がwebpackのプラグインがGCC向けにリリースされたことを提案しました。 私は立ち上げ 、チェックしました。コードは明らかに少ないですが、ツリーシェーキングは機能しませんでした。 どうやらGCCのセットアップに関する記事がまだ必要です。







私が手に入れたコード
 var __wpcc;void 0===__wpcc&&(__wpcc={}),function(c){"use strict";var n;void 0===n&&(n=function(){}),np="",n.src=function(c){return n.p+""+c+".out.dev.js"}}.call(this,__wpcc);var __wpcc;void 0===__wpcc&&(__wpcc={}),function(c){"use strict";var n=function(){},o=function(){},t={};n.prototype.pump=function(){window.console.log("puuuuf")},o.prototype.turn=function(){window.console.log("turn")},t.Wheel=n,t.Rudder=o,(new function(){this.wheel=new t.Wheel}).wheel.pump()}.call(this,__wpcc);
      
      





出力の代わりに



質問があるかもしれません:どのくらい正確に このすべて ツリーシェーキングはビルドに影響しますか?

正直に言うと、現時点ではこの質問に全責任で答えることはできません。 悪化することはなく、改善されると考えられています。 いくら 質問は複雑です。 試してみたら、コメントを共有してください。 私は、あなたにイベントの最新情報をお届けすることを約束します。このテーマについて注目に値する考えが出たらすぐに、喜んで共有します。








All Articles