webpack中Tree-Shaking性能优化

Tree-Shaking的作用

  • Tree-shaking的本质是消除无用的js代码:在 webpack 项目中,当我们在入口文件中引入一个模块的时候,可能不会引入这个模块的所有代码,只引入了我们需要的代码,那么在使用webpack进行打包时,tree-shaking会自动帮我们把不用的代码过滤掉。
  • 提升项目性能:JS绝大多数情况需要通过网络进行加载,然后执行,加载的文件越小,整体执行时间更短,所以去除无用代码以减少文件体积, 从而提升项目性能。

Tree-Shaking的模块引入方式

tree-shaking只支持ES模块的引入(import方式的引入),如果使用CommonJS的引入方法,tree-shaking是不支持的。因为CommonJS底层是动态引入的方式,import底层是静态引入的方式,tree-shaking只支持静态引入的方法,所以只支持ES模块引入。

// 正确的引入方式
import { add } from './math.js';
// 错误的引入方式 (tree shaking不支持)
// const add = require('./math.js');

Tree-Shaking的用法(配置)

目录结构:

|--demo
	|--node_modules
	|--src
		|--index.html
		|--index.js
		|--math.js
	|--package-lock.json
	|--package.json
	|--webpack.config.js

index.js

// 引入math.js模块中的一个方法
import { add } from './math.js';
add(1, 2);

math.js

// 导出两个方法
export const add = (a, b) => {
  console.log(a + b)
}

export const minus = (a, b) => {
  console.log(a - b)
}
开发模式下的使用(development)

在开发模式下(development), 默认是没有tree-shaking这个功能的,如果想在此模式下添加tree-shaking, 需要配置optimization项: (webpack.config.js具体如下)

// 在这里做打包配置
const path = require('path'); // 引入node的path模块(loader模块)
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// Common.js语法
module.exports = {
  mode: 'development', // 开发模式
  devtool: 'cheap-module-eval-source-map', // 开发环境下的devtool
  entry: {
    main: './src/index.js'
  },
  devServer: {
    contentBase: './dist',
    open: true,
    port: 8080
  }, 
  module: {
    rules: [{ 
      test: /\.js$/, 
      exclude: /node_modules/,
      loader: "babel-loader",
      options: {
        presets: [["@babel/preset-env", {
          targets: { 
            chrome: "67"
          },
          useBuiltIns: "usage"
        }]]
      }
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }), 
    new CleanWebpackPlugin()
  ],
  optimization: { // 在开发环境里需要使用此配置
     usedExports: true // 哪些导出的模块被使用了,再做打包
  },
  output: {
    filename: 'dist.js', // 打包之后的输出文件
    path: path.resolve(__dirname, 'dist') 
  }
}
  • optimization :开发环境下需要此配置项,使用usedExports属性,来帮助webpack识别哪些导出的模块被使用了,再做打包。

在package.json里做如下配置:

也可以通过数组的形式配置:

"sideEffects": false,
// "sideEffects": ["@babel/polyfill"],
// "sideEffects": ["*.css"], 

sideEffects配置的含义:遇到任何的css文件和@babel/polyfill需要填充注入的特性,不使用tree-shaking。如果某些文件,不想让它做tree-shaking, 那么就可以通过数组的形式配置在sideEffects里边就可以了。若没有要配置的东西,此值就设置为false.

打包:

npx  webpack

在打包后的dist.js中,可以看出,tree-shaking已经帮我们做了处理,已经区分了哪些是导出模块,哪些是导出使用了的模块。但在development环境下做打包的时候,即时用了tree-shaking, 也不会帮我们把导出没有使用的模块从打包生成的dist.js文件里去除掉,只是会在代码里给与提示。⭐️(这个问题出现的原因是:因为在开发环境中,我们可能会对代码做一定的调试,如果tree-shaking 把部分代码去除,可能在调试时,代码对应的行数都会出错,所以开发环境下,tree-shaking还会保留代码)

生产模式下的使用(production)

当我们的项目要打包上线的时候,mode的值为production的时候。此时tree-shaking就会生效了,配置如下:

// 在这里做打包配置
const path = require('path'); // 引入node的path模块(loader模块)
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// Common.js语法
module.exports = {
  mode: 'production', // 生产模式
  devtool: 'cheap-module-source-map', // 生产环境下的devtool
  entry: {
    main: './src/index.js'
  },
  devServer: {
    contentBase: './dist',
    open: true,
    port: 8080
  }, 
  module: {
    rules: [{ 
      test: /\.js$/, 
      exclude: /node_modules/,
      loader: "babel-loader",
      options: {
        presets: [["@babel/preset-env", {
          targets: { 
            chrome: "67"
          },
          useBuiltIns: "usage"
        }]]
      }
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }), 
    new CleanWebpackPlugin()
  ],
  output: {
    filename: 'dist.js', // 打包之后的输出文件
    path: path.resolve(__dirname, 'dist') 
  }
}

由于在生产环境下,tree-shaking是默认配置好的,所以生产环境下,不需要写以下配置项:

扫描二维码关注公众号,回复: 8502509 查看本文章
optimization: { // 在开发环境里需要使用此配置
    usedExports: true // 哪些导出的模块被使用了,再做打包
}

在package.json中同样做如下配置:

执行打包:

npx  webpack

由此可以看出,在我们打包生成线上代码的时候,Tree-Shaking已经把导出未使用的模块代码剔除掉了。使项目在运行时,加载脚本体积减小,缩短了加载时间,从而提升项目性能。✨

发布了54 篇原创文章 · 获赞 22 · 访问量 7244

猜你喜欢

转载自blog.csdn.net/Riona_cheng/article/details/100520523