sup*_*ize 2 webpack vue.js vue-component vuejs2 storybook
我已经创建了一个Vue项目,vue-cli并作为依赖项安装了storybook以后,npm install --save-dev storybook以显示我创建的组件。
故事书的webpack配置如下所示:
const path = require('path')
module.exports = async ({ config, mode }) => {
  config.module.rules.push(
    {
      test: /\.svg$/,
      use: ['vue-svg-loader']
    },
    {
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        {
          loader: 'sass-loader',
          options: {
            sourceMap: false,
            data: '@import "./src/assets/styles/main.scss";'
          }
        }
      ],
      include: path.resolve(__dirname, '../')
    }
  )
  return config
}
和这样的故事index.js:
import Vue from 'vue';
import { storiesOf } from '@storybook/vue';
import Alert from '../src/components/buttons/Alert.vue';
storiesOf('Components', module)
  .add('Alert', () => ({
    components: { Alert },
    template: '<Alert />'
  }))
由于某些原因,当尝试加载包含SVG的组件时,我得到了:
显示了组件本身,但未显示SVG所在的部分。
有趣的是,当尝试在Vue的主应用程序中显示组件时,它工作得很好。该vue.config如下所示:
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `@import "./src/assets/styles/main.scss";`
      }
    }
  },
  chainWebpack: config => {
    const svgRule = config.module.rule("svg");
    svgRule.uses.clear();
    svgRule.use("vue-svg-loader").loader("vue-svg-loader");
  }
};
为什么storybook在主Vue应用程序可以加载的同时无法正确加载svg?
编辑:我已经前进,也只是使用了webpack file-loader来确保它与无关vue-svg-loader:
{
  test: /\.(png|jpg|gif|svg)$/,
  use: [
    {
      loader: 'file-loader',
      options: {},
    },
  ],
},
但是我遇到了同样的错误。在尝试将第一个答案替换push()为规则后,出现unshift()此错误:Error in parsing SVG: Non-whitespace before first tag。
编辑2:
这是我要加载的SVG之一:
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="exclamation-triangle" class="svg-inline--fa fa-exclamation-triangle fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path></svg>
Edit3:* Alert.vue在projectroot/src/components/banners/Alert.vue,Storybook的Webpack配置在projectroot/.storybook/webpack.config.js
<template>
  <div v-if="show" :class="`alert_wrap ${model}`">
    <IconBase>
      <component :is="iconComponent" />
    </IconBase>
    <div class="alert_text">
      <p v-if="title">{{ title }}</p>
      <p>{{ msg }}</p>
    </div>
    <IconBase>
      <TimesIcon @click="show = !show" aria-hidden="Close" />
    </IconBase>
  </div>
</template>
<script>
import IconBase from "../icons/IconBase.vue";
import CautionIcon from "../../assets/icons/exclamation-triangle-solid.svg";
import InfoIcon from "../../assets/icons/info-circle-solid.svg";
import SuccessIcon from "../../assets/icons/check-circle-solid.svg";
import TimesIcon from "../../assets/icons/times-solid.svg";
export default {
  name: "Alert",
  components: {
    CautionIcon,
    InfoIcon,
    SuccessIcon,
    TimesIcon,
    IconBase
  },
  props: {
    msg: {
      type: String,
      required: true
    },
    title: {
      type: String
    },
    model: {
      type: String,
      default: "info",
      validator(type) {
        return ["caution", "info", "success"].includes(type);
      }
    }
  },
  computed: {
    iconComponent() {
      return `${this.model}-icon`;
    }
  },
  data() {
    return {
      show: true
    };
  }
};
</script>
<style scoped lang="scss">
  /* some styles depending on the props passed */
</style>
@liximomo的答案几乎是正确的。您应该svg从file-loader处理规则中删除文件,但是规则搜索条件应该稍有不同:
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;
}
在不更改Webpack配置规则的情况下导入SVG的另一种方法是指定内联加载器,当某些组件已经将CSS或HTML中的SVG仅仅用作文件路径时,这样做可以避免出错。例:
// disable all rules with !! and use just vue-svg-loader
import CautionIcon from "!!vue-svg-loader!../../assets/icons/exclamation-triangle-solid.svg";
| 归档时间: | 
 | 
| 查看次数: | 645 次 | 
| 最近记录: |