Skip to content

webpack打包体积优化

使用cdn

使用cdn引入外部库,通过设置external可以将某些库打包时排除在外

强调:在externals这个对象中

  1. lodash 作为属性名(key): 这表示当你在代码中导入 lodash 时,实际上不会将 lodash 包含在你的输出文件中,而是期望它在运行时从外部引入。
  2. '_' 作为属性值(value): 假定在运行环境中已经有一个全局的 _ 对象或者模块
html
 <!-- 导入第三方库的CDN -->
    <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

js代码压缩

压缩JavaScripte文件可以使用Terser压缩工具,webpack v5 开箱即带有最新版本的 terser-webpack-plugin,通常所有注释、空格和换行都被删除,代码变量名也会被压缩或混淆。

在Webpack中,有一个名为minimizer属性,它在生产模式下默认使用TerserPlugin来处理代码。这意味着Webpack会自动使用TerserPlugin来压缩和优化JavaScript代码,以减小文件大小并提高性能。

如果你不满意默认配置,你可以自己创建TerserPlugin的实例,并覆盖相关配置。这允许你根据项目的需求自定义代码压缩和优化,使Webpack配置变得灵活而适应各种场景。总之,minimizer属性允许你控制生产模式下的代码压缩,提供了定制化的选项以满足你的需求。

js
optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({
      extractComments: true,
      terserOptions: {
        compress:{
          ecma: 5,  // 设置输出所需的EcmaScript标准版本
          unused: false // 是否删除未引用的函数和变量
        },
        toplevel: true, // 是否在顶级作用域中声明的名称。
        keep_classnames: true, // 防止丢失类名,
        keep_fnames: true // 防止丢失函数名
      }
    })],
  },

这里面的配置非常多,具体可以看terser文档

CSS压缩

压缩CSS通常是去除无用的空格,压缩CSS可以使用另外一个插件:css-minimizer-webpack-plugin

安装css-minimizer-webpack-plugin

在optimization.minimizer中配置

js
js复制代码  optimization: {
    minimizer: [new cssMinimizerPlugin({
           parallel: true
       }
      )],
  },

被压缩后的代码

image.png

Tree Shaking

Tree Shaking,又称为“树摇”,是一项用于优化项目打包的技术,其核心目标是在构建过程中自动删除未被引用的函数或变量,从而减小最终生成的文件大小,提高应用程序的性能和加载速度。

JS

usedExports

在生产环境下webpack默认会将usedExports设置为true,在usedExports设置为true时,会有一段注释:unused harmony export mul,这段注释意味着Terser在优化(上面讲到了Terser压缩)时,可以删除掉这段代码.所以我们还得讲minimize设置true

js
optimization: {
  // 在生产环境下都帮我们配置了
  minimize: true,
  usedExports: true
}

sideEffects

如果只使用usedExports会出现一个问题,如下:

以下需要tree Sharking的模块

js
js复制代码// format.js
export function formatUTC(date) {
  return date;
}

export function formatPrice(price) {
  return price.toFixed(2);
}

window.effect = "我是一个副作用代码";

以下是主入口文件

js
js复制代码// main.js
// 由于只对模块进行导入,但是未用到内部函数,按理来说format.js整个模块不应该被打包
import "./utils/format";

console.log("main");

以下是打包后的产物

js
js复制代码// build/bundle.js
(()=>{"use strict";window.effect="我是一个副作用代码",console.log("main")})();

我们发现window.effect="我是一个副作用代码"的副作用代码被打包进去了,那么我们应该如何解决这个问题?

可以通过 package.json 的 "sideEffects" 属性,来实现这种方式。

json
// package.json
{
  "sideEffects": false,
}

sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports;

如果有一些我们希望保留,可以设置为数组;

json
{
    // package.json
    "sideEffects": [
    // 打包后的文件就不会保留format中的如何代码
    "./src/utils/format.js"
  ],
}

CSS

上述我们学习的都是关于JS的Tree Shaking,同样我们也要对CSS代码做Tree Shaking

CSS的Tree Shaking需要借助于一些其他的插件purgecss-webpack-plugin

npm install purgecss-webpack-plugin -D
js
// webpack.config.js
    new PurgeCSSPlugin({
      paths: glob.sync(path.join(__dirname, "src/**/*"), { nodir: true }),
    }),