vue-cli 最新版本使用 SvgIcon 不生效
背景
用 vue-cli 创建的项目,在借助 svg-sprite-loader 使用 SvgIcon 时,一般的做法是在 vue.config.js 里加如下的配置
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.test(/\.svg$/)
.include.add(resolve('src/svgIcon/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
对于 .svg 文件,我们只希望使用 svg-sprite-loader 来处理,所以,在之前,我们会使用 clear 方法来清掉应用到 .svg 文件上的 loader。这个操作在 vue-cli 之前的版本都是可以的。然而在最新版本的 vue-cli 创建的项目中,不生效
分析原因
我的第一想法是打印出 svgRule ,看看和之前的有什么不同,这里我起了之前的 vue-cli 版本创建的项目,所有的配置都一样,且 SvgIcon 是可以正常显示的。下面让我们来来看看新旧 vue-cli 版本下的 svgRule。
旧的 vue-cli 版本
新的 vue-cli 版本
通过上面两张图可以发现,新版的 vue-cli 对于 .svg 文件,不仅使用了 svg-sprite-loader,还多了点什么东西,下面我们就进一步分析多出来的究竟是什么东西。
我把 vue.config.js 中配置做了如下修改
const svgRule = config.module.rule('svg')
// svgRule.uses.clear()
svgRule
.test(/\.svg$/)
.include.add(resolve('src/svgIcon/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
把之前适用 .svg 文件上的 loader 清除语句删掉,然后接着打印 svgRule,看看新旧 vue-cli 版本下的差异。
旧的 vue-cli 版本
新的 vue-cli 版本
观察上面两张图,我发现,在旧版的 vue-cli 中,是使用 file-loader 来处理 .svg 文件的,而新的 vue-cli 版本使用的是 type: 'asset/resource',这个其实就是 webpack5 的用法,它的作用就等同于 webpack4 中的 file-loader。
接下来我们使用 vue inspect --rule svg 来查看 rule 的配置
旧的 vue-cli 版本
新的 vue-cli 版本
上面两张图进一步证实了上面所说的 vue-cli 新旧版本的差异
解决问题
根据上面打印的 svgRule 的结构,我们发现它其实是多了 type 和 generator 两个属性,我尝试把这两个属性删掉
const svgRule = config.module.rule('svg');
svgRule.uses.clear();
svgRule.delete('type');
svgRule.delete('generator');
svgRule
.test(/\.svg$/)
.include.add(resolve('src/svgIcon/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
});
页面确实是可以正常展示 svgIcon 了,但这只是我们的尝试做法,我想知道 vue-cli 是否有暴露出方法来处理。于是我去查找了 vue-cli 的官方文档,并没有找到。我又去了 vue-cli 的 github 上的 issues,大家的写法也是这个。 github issue 地址