因为没太怎么了解过 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
}
})
}
...
})