我们在日常开发的时候会引入非常多的模块文件,每个模块文件可能会有很多的方法逻辑,但有些方法我们并不能保证一定能用到,比如:
export const add = (a, b) => {console.log(a + b)}export const minus = (a, b) => {console.log(a - b)}
import { add } from './math';add(1, 2)
在上面文件中,math.js文件暴露出两个方法,index.js文件只引入math.js文件中的add方法。
当我们运行npm run build进行打包的时候,查看产出文件夹dist下面的main.js文件后发现,math.js里面的minus文件方法也被打包了出来,这很显然是没有必要的。
最理想的打包方式是我引入了什么,你就给我打包什么,这样就把没用到的方法进行了移除,减少文件的大小。webpack2.0+已经支持Tree Shaking这个概念,它的作用实际上就是把一个模块没用的东西都摇晃掉。
拿上面的代码举例,我src/index.js文件只引入了add方法,你只给我打包add方法就好了,这就是Tree Shaking的作用。
:::warning
⚠️ 注意
另外它只支持ESModule的模块化,不支持CommonJS的模块导入。
这是因为ESModule引入文件的时候是静态引入的,编译时引入(代码还没运行就要知道引入了哪些资源)
而CommonJS是动态引入,执行时引入,是可以根据逻辑决定是否要引入的,这就对Webpack来说有点困难了。
:::
现在我们的配置文件是development开发模式,而development实际上是没有开启Tree Shaking的。
对webpack.config.js进行配置:
module.exports = {mode: "development",devtool: "eval-cheap-module-source-map",// ...optimization: {// 当 src/index.js 文件使用了导出的函数时,这个函数才会被打包usedExports: true}}
对package.json进行设置:
{"name": "chapter01",// sideEffects: false 表示对所有的文件都进行 Tree Shaking 分析"sideEffects": false,"version": "1.0.0","description": "","main": "index.js","scripts": {"dev": "webpack serve","build": "webpack"},"author": "","license": "ISC","devDependencies": {// ...},"dependencies": {// ...}}
sideEffects用来设置对一些文件不使用Tree Shaking,例如我们要使用的@babel/ployfile:
import "@babel/ployfile";import "./index.css"
像这样直接导入整个文件,而不是导入导出某个功能的时候就需要我们进行排除,让Tree Shaking不进行分析,否则Tree Shaking会认为src/index.js没有使用任何的导出功能!!!
{// ..."sideEffects": ["*.css", "@babel/ployfile"]// ...}
而**pakcage.json**中的**sideEffects: false**表示对所有文件都进行**Tree Shaking**。
配置了以上的两个文件之后再进行打包:
从代码中可以看出math.js文件提供了两个方法,但是只使用了一个。虽然现在minus方法依然被打包出来,但是现在webpack知道只有add方法被使用了。
:::warning
⚠️ 注意
在development的模式下即使你开启了Tree Shaking,minus方法也不会被移除掉,这是因为方便我们使用source-map进行调试,当使用production的模式打包时Tree Shaking才会真正的生效,而production模式其实默认配置了Tree Shaking。
:::
使用production模式进行打包:
{// ..."sideEffects": false// ...}
module.exports = {mode: "production",devtool: "cheap-module-source-map", // 需要设置为 cheap-module-source-map// 使用了导出内容的话就进行导出optimization: {usedExports: true,},// ...};
这个时候进行打包就会把无用的功能进行了移除(摇晃掉)。
