[NOTES] vue-cli5(defineConfig) + chainWebpack 设置 10kb 下资源转 base64

362 阅读1分钟

因为没太怎么了解过 webpack5,所以关于 svg 静态资源资源这块不太熟悉,尝试网上的方法都没有用,所以记录下

首先提出需求:希望将 10kb 以下的 svg 资源打包成 base64

然后查阅vue-cli 文档是否有相应配置。但是我们只看到一个关于 svg 的配置样例,且没有提供 limit 相关的配置。根据之前网上搜到的配置 images 方法无效我猜测 vue-cli 将 svg 和其他格式图片的处理分开了。所以查看源码,刚好看到 vue-cli 里是这样处理静态资源的。

vue-cli/packages/@vue/cli-service/lib/config/assets.js

module.exports = (api, options) => {
  const getAssetPath = require("../util/getAssetPath");

  const genAssetSubPath = (dir) => {
    return getAssetPath(
      options,
      `${dir}/[name]${options.filenameHashing ? ".[hash:8]" : ""}[ext]`
    );
  };

  api.chainWebpack((webpackConfig) => {
    webpackConfig.module
      .rule("svg")
      .test(/\.(svg)(\?.*)?$/)
      // do not base64-inline SVGs.
      // https://github.com/facebookincubator/create-react-app/pull/1180
      .set("type", "asset/resource")
      .set("generator", {
        filename: genAssetSubPath("img"),
      });

    webpackConfig.module
      .rule("images")
      .test(/\.(png|jpe?g|gif|webp|avif)(\?.*)?$/)
      .set("type", "asset")
      .set("generator", {
        filename: genAssetSubPath("img"),
      });

    webpackConfig.module
      .rule("media")
      .test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
      .set("type", "asset")
      .set("generator", {
        filename: genAssetSubPath("media"),
      });

    webpackConfig.module
      .rule("fonts")
      .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
      .set("type", "asset")
      .set("generator", {
        filename: genAssetSubPath("fonts"),
      });
  });
};

根据注释我们可以知道 vue-cli 将所有的 svg 都打包成 resource 类型,因此我们只需要重写下这个配置即可

const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  ...
  chainWebpack: config => {
    // svg 10kb 以下转 base64
    const svgRule = config.module.rule('svg')
    svgRule.test(/\.(svg)(\?.*)?$/)
      .set('type', 'asset')
      .set('parser', {
        dataUrlCondition: {
          maxSize: 10 * 1024
        }
      })
  }
  ...
})