vue-svg-loader
vue-svg-loader copied to clipboard
Please create a new version to support svgo 2.x
The dev branch seems to support svgo 2.x now, could you please help build a new package to npm?
Please @visualfanatic
What I did for SVGO 2.x support is just chaining svgo-loader, before passing to vue-svg-loader, and set svgo: false
for vue-svg-loader.
At that point the only thing this package does is wrap the SVG in <template></template>
tags though, so you could write your own loader instead of relying on this unmaintained package. If you ignore all the vue checking, all you need is below.
module.exports = function vueSvgLoader(svg) {
return `<template>${svg}</template>`;
};
@Excalibaard Can you please show exactly how you did it? Would like to do it your way so I can get rid of this package since @visualfanatic has stopped maintaining or responding for a long time3.
@Excalibaard is your solution for Vue2 or Vue3? Because looking at the latest dev
branch for commit WIP SVGO 2.x
, it seems that if you are supporting Vue2 you need to add:
if (semverMajor(version) === 2) {
svg = svg.replace('<svg', '<svg v-on="$listeners"');
}
return `<template>${svg}</template>`;
https://github.com/visualfanatic/vue-svg-loader/blob/dev/index.js#L16-L18
@rightaway Easiest solution is to pick a different package that's actively maintained, though it has a different way to use it:
~~https://github.com/oliverfindl/vue-svg-inline-loader~~
EDIT: This package also relies on SVGO 1.x.
Otherwise, you can still use this package, but without the svgo part. The below example shows importing SVG as component using the 'inline' query, for example import SVGIcon from '@/assets/SVGIcon.svg?inline'
. This allows you to still use svg as an image when necessary.
// webpack.config.js
module.exports = {
...,
module: {
rules: [
{
test: /\.svg$/,
resourceQuery: /inline/,
use: [
{
loader: 'vue-loader'
},
{
loader: 'vue-svg-loader',
options: {
svgo: false,
}
},
{
loader: 'svgo-loader',
options: {
// configFile: false // uncomment if not using a svgo.config.js file in your project root
.... // add your svgo options here
}
}
]
},
{
test: /\.svg$/,
use: [
{
loader: 'file-loader'
},
{
loader: 'svgo-loader'
},
]
}
]
}
}
or with VueCLI:
// vue.config.js
module.exports = {
chainWebpack: (config) => {
const svgRule = config.module.rule('svg');
svgRule.uses.clear();
svgRule
.test(/\.svg$/)
.oneOf('inline')
.resourceQuery(/inline/)
.use('vue-loader')
.loader('vue-loader')
.end()
.end()
.use('vue-svg-loader')
.loader('vue-svg-loader')
.options({
svgo: false
})
.end()
.end()
.use('svgo-loader')
.loader('svgo-loader')
.options({
// configFile: false // uncomment when you have no svgo.config.js at project root
.....
})
.end()
.end()
.oneOf('normal')
.use('file-loader')
.loader('file-loader')
.end()
.end()
.use('svgo-loader')
.loader('svgo-loader')
.end()
.end()
}
}
The solution I ended up using in that codebase was to make a folder specifically for my custom loaders, and making sure it's added to webpack's resolveLoader
option.
// webpack.config.js
module.exports = {
//...
resolveLoader: {
modules: [
'node_modules',
path.resolve(__dirname, 'loaders') // [workspaceRoot]/loaders
]
}
};
Then, create the file [workspaceRoot]/loaders/vue-svg-loader.js
.
// loaders/vue-svg-loader.js
const { version } = require('vue');
const semverMajor = require('semver/functions/major')
module.exports = function vueSvgLoader(svg) {
if (semverMajor(version) === 2) {
svg = svg.replace('<svg', '<svg v-on="$listeners"');
}
return `<template>${svg}</template>`;
};
Then, add the vue-svg-loader
rule as normal (without options). Because webpack now looks in your [root]/loaders
folder as well as node-modules
, it will find a match with your own loader. Make sure you have removed the vue-svg-loader
package from your dependencies, so it doesn't find one in node-modules.
Here's a gist of the loader I used that replaces both svgo-loader and vue-svg-loader..
@darrinmn9 You're correct, if you use Vue 2 you may need to add v-on="$listeners"
to make sure any events within your SVG component are emitted to the parent. However, since there components are created within the webpack tool chain, I'm not quite sure what kind of events those may be, Clicking specific elements perhaps. Anyhow, my SVGs work fine without it, in both Vue 2 and Vue 3 (where v-on="$listeners" is deprecated, as listeners are automatically included in $attrs). I've included the version checker in my example above for completeness.
@Excalibaard vue-svg-inline-loader is not actively maintained.
@ChrisRoss5 You're correct. It has been updated more recently, but also uses SVGO 1.x. I'll remove that recommendation.