Skip to content

减少代码体积

Tree shaking

移除 JavaScript 中的没有使用上的代码,依赖 es module

开发中当定义了一些工具函数库,或者引用第三方工具函数库或组件库。如果没有特殊处理打包时将会引入整个库,但实际上只用上极小部分的功能,这样会增加打包体积

使用

  • wbpack 默认开启 tree shaking,无需配置
  • 手动添加有副作用的文件
json
// package.json
{
  "name": "your-project",
  "sideEffects": ["./src/some-side-effectful-file.js"]
}
  • css 文件处理

    对于直接引入到 js 文件的 css 文件,它们并不会被转换成一个 CSS 模块,开启 tree shaking 后样式会丢失

js
// main.js
import "./styles/reset.css";

上面通过 import 引入的 css 会被当做无效代码处理,可以通过下面其中一种配置保留:

json
// package.json
{
  "name": "your-project",
  "sideEffects": ["*.css"]
}
js
// webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
        sideEffects: true,
      },
    ],
  },
};

Babel

@babel/plugin-transform-runtime:禁用了 Babel 自动对每个文件的 runtime 注入,而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用

Babel 为编译的每个文件都插入了辅助代码,导致代码体积增大。应该将这些辅助代码作为一个独立模块,来避免重复引入

处理 Babel

  1. 安装依赖

    shell
    npm i @babel/plugin-transform-runtime -D
  2. 配置

    js
    // webpack.congfig.js
    module.exports = {
      //...
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: [
              {
                loader: "babel-loader",
                options: {
                  plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
                },
              },
            ],
          },
        ],
      },
      //...
    };
  • 处理前:
js
"use strict";

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

var Person = /*#__PURE__*/ (function () {
  function Person() {
    _classCallCheck(this, Person);
  }

  _createClass(Person, [
    {
      key: "sayname",
      value: function sayname() {
        return "name";
      },
    },
  ]);

  return Person;
})();

var john = new Person();
console.log(john);
  • 处理后:
js
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var Person = /*#__PURE__*/ (function () {
  function Person() {
    (0, _classCallCheck2["default"])(this, Person);
  }

  (0, _createClass2["default"])(Person, [
    {
      key: "sayname",
      value: function sayname() {
        return "name";
      },
    },
  ]);
  return Person;
})();

var john = new Person();
console.log(john);

image minimizer

image-minimizer-webpack-plugin: 用来压缩图片的插件

项目中如果引用了较的多本地图片,当图片体积比较大时,会影响请求速度。可以对图片进行压缩,减少图片体积

1. 安装依赖

shell
npm i image-minimizer-webpack-plugin imagemin -D

还有两种模式的依赖供下载,按需选择:

  • 无损压缩
shell
npm i imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
  • 有损压缩
shell
npm i imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D

有损/无损压缩的区别

2. 配置

以无损压缩为例:

js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  //...
  optimization: {
    minimizer: [
      // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminGenerate,
          options: {
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              [
                "svgo",
                {
                  plugins: [
                    "preset-default",
                    "prefixIds",
                    {
                      name: "sortAttrs",
                      params: {
                        xmlnsOrder: "alphabetical",
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
    ],
  },
};
//...

3. 额外安装的依赖文件

  • jpegtran.exe

    需要复制到 node_modules\jpegtran-bin\vendor 下面

    jpegtran 官网

  • optipng.exe

    需要复制到 node_modules\optipng-bin\vendor 下面

    OptiPNG 官网