首先,咱們來看一張圖。(很形象,借用別處)css
如圖所示,咱們的js文件就至關於這棵樹,tree-shaking就至關對搖動這個操做,目的是讓枯黃的葉子和壞掉的蘋果掉下來。說到這裏,tree-shaking的原理就是,經過搖動咱們的js文件,剔除掉DCE(Dead Code Elimination)。是一種優化性能的方式。前端
具體說,每個webpack項目中,都有一個入口,至關於樹的主幹,依賴了不少模塊,至關於樹枝。在咱們的實際使用的過程當中,咱們其實只是使用了模塊裏的某個方法,咱們須要把不使用的樹枝給搖落下來,也就是過濾掉這些無用的代碼。起到性能優化的目的。webpack
用到這一方法的工具備rollUp,webpack,cc。該文章只介紹webpack中tree-shaking的使用。web
tree-shaking的本質是消除無用代碼。無用代碼也就是所謂的dead code elimination。json
function test(){
const a = 1;
return a+1;
// dce 不會被執行的代碼
const b = 2;
return b;
}
test();
複製代碼
function test(){
const a = 1;
if(false){
....
}
const b = 2;
return b;
}
test();
複製代碼
傳統的編譯型語言中,都是將DCE從AST(抽象語法樹)中刪除掉。那JavaScript是怎麼作到呢?性能優化
webapck的DCE是uglify作的,你可能會問,那tree-shaking 是作什麼呢?tree-shaking只是幫助DCE。打個比方,就好像咱們要從一堆水果裏面,拿掉蘋果。首先咱們得把蘋果選出來。tree-shaking就是一個選蘋果的過程。可是拿掉蘋果是選出來以後的操做。bash
目錄結構: babel
// ./src/index.js
import printMe from "./print.js"; // unused
import { cube } from './math.js';
import menu from './menu.js'; // unused
import './styles.css';
// if(process.env.NODE_ENV !== 'production'){
// console.log('development mode!')
// }
function component(){
var element = document.createElement('pre');
element.innerHTML = [
'hello webpack',
'5 cubed is equal to ' + cube(5)
].join('\n\n')
return element;
}
document.body.appendChild(component());
複製代碼
webpack的mode='development'會將 DefinePlugin 中 process.env.NODE_ENV 的值設置爲 development。啓用 NamedChunksPlugin 和 NamedModulesPlugin。app
打包結果:ide
mode='production'會將 process.env.NODE_ENV 的值設爲 production。啓用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
打包結果:
先思考一個問題,爲何tree-shaking是最近幾年流行起來了?而前端模塊化概念已經有不少年曆史了,其實tree-shaking的消除原理是依賴於ES6的模塊特性。
// import _ from "lodash";
import printMe from "./print.js";
import { cube } from './math.js';
// import menu from './menu.js';
const menu = require('./menu.js');
import './styles.css';
.....
複製代碼
production模式下,require的也被打進去了。因此require這種動態引入的是不行的。require須要js執行的時候才知道。import是屬於靜態引入。
借用官網注意事項: