webpack2 的 tree shaking
阿新 • • 發佈:2021-07-12
tree shaking
[ʃeɪk]
- v.搖;發抖;震動;動搖
- n.抖動;搖動;顫動
即 webpack 在打包的過程中會將沒用的程式碼進行清除(dead code)。
一般 dead code 具有一下的特徵:
- 程式碼不會被執行,不可到達
- 程式碼執行的結果不會被用到
- 程式碼只會影響死變數(只寫不讀)
使 tree shaking 生效:
首先,模組引入要基於 ES6 模組機制,不再使用 commonjs 規範,因為 es6 模組的依賴關係是確定的,和執行時的狀態無關,可以進行可靠的靜態分析,然後清除沒用的程式碼。而 commonjs 的依賴關係是要到執行時候才能確定下來的
這就涉及到es6模組的知識了
commonJS 模組
commonJS的模組規範在Node中發揚光大,總的來說,它的特性有這幾個:1.動態載入模組
commonJS和es6的最大區別大概就在於此了吧,commonJS模組的動態載入能夠很輕鬆的實現懶載入,優化使用者體驗。2.載入整個模組
commonJS模組中,匯出的是整個模組。3.每個模組皆為物件
commonJS模組都被視作一個物件。4.值拷貝
commonJS的模組輸出和 函式的值傳遞相似,都是值的拷貝es6 模組
1.靜態解析
即在解析階段就確定輸出的模組,所以es6模組的import一般寫在被引入檔案的開頭。2.模組不是物件
在es6裡,每個模組並不會當做一個物件看待3.載入的不是整個模組
在es6模組中經常會看見一個模組中有好幾個export 匯出4.模組的引用
es6模組中,匯出的並不是模組的值拷貝,而是這個模組的引用
瞭解原理後開始測試
初始化專案
npm init
安裝webpack包
npm install webpack webpack-cli --save-dev
配置檔案
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>起步</title> </head> <body> <script src="./dist/main.js"></script> </body> </html>
index.js
import vue from './vue'; import test from './test'; vue.methods.fnA() test.funcB()
test.js
export function funcA() { console.log('func A'); } // src/es6/js/utilB.js export function funcB() { console.log('func B'); }
vue.js
export default { data() { }, methods: { fnA() { console.log(11) }, fnB() { console.log(222) }, }, }
package.json
{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.44.0", "webpack-cli": "^4.7.2" } }
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, };
編譯後的main.js檔案
(()=>{"use strict";var e={};(e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),
Object.defineProperty(e,"__esModule",{value:!0})})(e),{data(){},methods:{fnA(){console.log(11)},fnB(){console.log(222)}}}.methods.fnA(),e.default.funcB()})();
可以看出test.js檔案的funcB函式進行了清除