我们在日常开发的时候会引入非常多的模块文件,每个模块文件可能会有很多的方法逻辑,但有些方法我们并不能保证一定能用到,比如:

    1. export const add = (a, b) => {
    2. console.log(a + b)
    3. }
    4. export const minus = (a, b) => {
    5. console.log(a - b)
    6. }
    1. import { add } from './math';
    2. add(1, 2)

    在上面文件中,math.js文件暴露出两个方法,index.js文件只引入math.js文件中的add方法。
    当我们运行npm run build进行打包的时候,查看产出文件夹dist下面的main.js文件后发现,math.js里面的minus文件方法也被打包了出来,这很显然是没有必要的。
    WX20210317-145543@2x.png

    最理想的打包方式是我引入了什么,你就给我打包什么,这样就把没用到的方法进行了移除,减少文件的大小。
    webpack2.0+已经支持Tree Shaking这个概念,它的作用实际上就是把一个模块没用的东西都摇晃掉。
    拿上面的代码举例,我src/index.js文件只引入了add方法,你只给我打包add方法就好了,这就是Tree Shaking的作用。 :::warning ⚠️ 注意
    另外它只支持ESModule的模块化,不支持CommonJS的模块导入。
    这是因为ESModule引入文件的时候是静态引入的,编译时引入(代码还没运行就要知道引入了哪些资源)
    CommonJS是动态引入,执行时引入,是可以根据逻辑决定是否要引入的,这就对Webpack来说有点困难了。 :::

    现在我们的配置文件是development开发模式,而development实际上是没有开启Tree Shaking的。
    webpack.config.js进行配置:

    1. module.exports = {
    2. mode: "development",
    3. devtool: "eval-cheap-module-source-map",
    4. // ...
    5. optimization: {
    6. // 当 src/index.js 文件使用了导出的函数时,这个函数才会被打包
    7. usedExports: true
    8. }
    9. }

    package.json进行设置:

    1. {
    2. "name": "chapter01",
    3. // sideEffects: false 表示对所有的文件都进行 Tree Shaking 分析
    4. "sideEffects": false,
    5. "version": "1.0.0",
    6. "description": "",
    7. "main": "index.js",
    8. "scripts": {
    9. "dev": "webpack serve",
    10. "build": "webpack"
    11. },
    12. "author": "",
    13. "license": "ISC",
    14. "devDependencies": {
    15. // ...
    16. },
    17. "dependencies": {
    18. // ...
    19. }
    20. }

    sideEffects用来设置对一些文件不使用Tree Shaking,例如我们要使用的@babel/ployfile

    1. import "@babel/ployfile";
    2. import "./index.css"

    像这样直接导入整个文件,而不是导入导出某个功能的时候就需要我们进行排除,让Tree Shaking不进行分析,否则Tree Shaking会认为src/index.js没有使用任何的导出功能!!!

    1. {
    2. // ...
    3. "sideEffects": ["*.css", "@babel/ployfile"]
    4. // ...
    5. }

    **pakcage.json**中的**sideEffects: false**表示对所有文件都进行**Tree Shaking**

    配置了以上的两个文件之后再进行打包:
    WX20210317-153326@2x.png
    从代码中可以看出math.js文件提供了两个方法,但是只使用了一个。虽然现在minus方法依然被打包出来,但是现在webpack知道只有add方法被使用了。 :::warning ⚠️ 注意
    development的模式下即使你开启了Tree Shakingminus方法也不会被移除掉,这是因为方便我们使用source-map进行调试,当使用production的模式打包时Tree Shaking才会真正的生效,而production模式其实默认配置了Tree Shaking。 :::

    使用production模式进行打包:

    1. {
    2. // ...
    3. "sideEffects": false
    4. // ...
    5. }
    1. module.exports = {
    2. mode: "production",
    3. devtool: "cheap-module-source-map", // 需要设置为 cheap-module-source-map
    4. // 使用了导出内容的话就进行导出
    5. optimization: {
    6. usedExports: true,
    7. },
    8. // ...
    9. };

    这个时候进行打包就会把无用的功能进行了移除(摇晃掉)。