Load svg using vue-svg-loader not working
gsaada opened this issue · 2 comments
gsaada commented
.storybook/webpack.config.js
const path = require('path');
const fs = require('fs');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
// `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
config.module.rules.push({
test: /\.scss$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"sass-loader" // compiles Sass to CSS, using Node Sass by default
]
});
config.module.rules.push({
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {name: 'assets/[name].[hash:8].[ext]'},
},
],
});
config.module.rules.push({
test: /\.vue$/,
use: [
{
loader: "vue-svg-inline-loader",
options: { /* ... */ }
}
]
});
config.module.rules.push({
test: /\.svg$/,
loader: 'vue-svg-loader',
options: {name: 'assets/[name].[hash:8].[ext]'},
});
config.resolve.alias['@'] = path.resolve('src')
// Return the altered config
return { ...config, node: { fs: 'empty' } };
};
index.vue
<template>
<div>
<IconTest/>
</div>
</template>
<script>
import IconTest from "@/assets/svg/test-icon.svg"
export default {
components:{
IconTest
}
}
</script>
error:
[Vue warn]: Invalid Component definition: static/media/test-icon.d9ed9e17.svg
LeBenLeBen commented
@gsaada There are existing rules that test for /\.vue$/
or /\.svg$/
files like you do and my guess is that they are conflicting. You should leverage Webpack include/exclude rule parameters to avoid conflicts.
Here’s an example on how to modify an existing rule in Storybook Webpack config to add an exclude
option:
// .storybook/main.js
const path = require('path');
module.exports = {
// ...
webpackFinal: (config) => {
// Prevent Storybook generic SVG loader from taking care of SVG icons going in the sprite
const fileLoader = config.module.rules.find((rule, i) => {
return rule.loader && rule.loader.match(/file-loader/);
});
fileLoader.exclude = path.resolve('./src/assets/icons');
// Custom loader with an `include` to limit the loader to only icons
config.module.rules.push({
test: /\.svg$/,
include: path.resolve('./src/assets/icons'),
use: [
{
loader: 'svg-sprite-loader',
},
],
});
}
// ...
};
ecarrera commented
This config solved the issue for me:
module.exports = ({ config }) => {
let rule = config.module.rules.find(r =>
// it can be another rule with file loader
// we should get only svg related
r.test && r.test.toString().includes('svg') &&
// file-loader might be resolved to js file path so "endsWith" is not reliable enough
r.loader && r.loader.includes('file-loader')
);
rule.test = /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/;
config.module.rules.push(
{
test: /\.svg$/,
use: ['vue-svg-loader']
}
)
// ...
return config;
}
Original post: https://stackoverflow.com/questions/56971513/storybook-does-not-load-svgs-in-components-of-vue-project