webpack2 的 tree shaking
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函数进行了清除