はじめに
Storybook with Vue上でSVGを表示するのに失敗していたので解決策をメモします。
SVGはvue-svg-loaderを使ってバンドルしています。
結論だけみたい方は以下リンクだけみてください。
解決策です
環境
Vue: 2.6.10
Storybook: 5.1.9
vue-svg-loader: 0.12.0
表示できない
設定アイコンを表示するコンポーネントを用意します。
<template>
<setting-svg />
</template>
<script lang="ts">
import Vue from "vue";
import SettingSvg from "@/assets/img/svg/setting.svg";
export default Vue.extend({
name: "SettingIcon",
components: {
SettingSvg
}
});
</script>
Storybookを準備します。
import { storiesOf } from "@storybook/vue";
import SettingIcon from "./SettingIcon.vue";
storiesOf("Icon", module).add("設定アイコン", () => ({
components: { SettingIcon },
template: "<setting-icon />"
}));
これでアイコンを表示する用意ができました。
Storybookを起動します。
$ start-storybook
エラーは出ません。うまくいったと思いStorybookを表示します。
何も表示されません。辛いです。
Storybookの webpack.config.js
を確認します。
const path = require("path");
const rootPath = path.resolve(__dirname, "../src");
module.exports = async ({ config, mode }) => {
config.resolve.alias["@"] = rootPath;
config.resolve.alias["~"] = rootPath;
config.module.rules.push({
test: /\.s?css$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
});
config.module.rules.push({
test: /\.svg(\?.*)?$/,
loaders: ["vue-svg-loader"]
});
return config;
};
config.module.rules
のSVG部分を出力してみます。
[
{
test: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/,
loader: '/Users/numatakeisuke/working/project/memory-album/node_modules/file-loader/dist/cjs.js',
query: { name: 'static/media/[name].[hash:8].[ext]' }
},
{ test: /\.svg(\?.*)?$/, loaders: [ 'vue-svg-loader' ] }
]
SVGにデフォルトで file-loader
が当たっていることがわかります。
png
などは残しておきたいので、 svg
だけローダーの設定を変えます。
解決策
webpack.config.js
を修正します。
SVGを file-loader
の対象から外しています。
const path = require("path");
const rootPath = path.resolve(__dirname, "../src");
module.exports = async ({ config, mode }) => {
config.resolve.alias["@"] = rootPath;
config.resolve.alias["~"] = rootPath;
config.module.rules = config.module.rules.map(rule => {
if (rule.test.toString().includes("svg")) {
const test = rule.test
.toString()
.replace("svg|", "")
.replace(/\//g, "");
return { ...rule, test: new RegExp(test) };
} else {
return rule;
}
});
config.module.rules.push({
test: /\.s?css$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
});
config.module.rules.push({
test: /\.svg(\?.*)?$/,
loaders: ["vue-svg-loader"]
});
return config;
};
Storybookを再起動すると無事に表示されました。
参考