在Vue故事书中导入错误的路径

时间:2020-04-05 12:39:30

标签: javascript vue.js webpack storybook

我是Vue的新手,在使用别名导入文件时,我遇到了有关它和Storybook的问题:

我有一个SvgIcon组件:

<template>
    <div>
        props from the icon: {{this.$props}}
        <svg v-if="icon" class="svg-icon">
            <title v-if="title">{{ title }}</title>
            <use v-bind="{ 'xmlns:xlink':'http://www.w3.org/1999/xlink', 'xlink:href': icon }"></use>
        </svg>
        <img v-else-if="image" :src="image" class="image-icon"/>
    </div>
</template>

<script>
export default {
    name: 'SvgIcon',
    data: function() {
        return {
            icon: null,
            image: null
        }
    },
    props: {
        title: {
            type: String,
            default: ''
        },
        iconFallback: {
            type: String,
            required: false
        },
        iconId: {
            type: String,
            required: true,
            validator(iconName) {
                if (!iconName) {
                    console.warn('icon can not be empty')
                    return false
                }
                return true
            }
        }
    },
    watch: {
        iconId: {
            immediate: true,
            handler(iconId) {
                iconId && import(`@/assets/icons/${iconId}.svg`)
                    .then(svg => {
                        // debugger
                        console.log(this, 'this from SvgIcon')
                        if (Object.prototype.hasOwnProperty.call(svg, 'default')) {
                            this.icon = svg.default
                        } else {
                            this.icon = svg
                        }
                    }).catch(() => {
                        this.image = this.iconFallback && require(`@/assets/icons/${this.iconFallback}.png`)
                    })
            }
        }
    }
}
</script>

<style scoped lang="scss">

svg {
    width: 32px;
    height: 32px;
    vertical-align: middle;

    &.icon-status {
        width: 14px;
        height: 14px;
        min-width: 14px;
        transform: translateY(-6%);
        fill: $light-orange;
    }

    &.icon-size-small {
        width: 14px;
        height: 14px;
    }

    &.icon-size-medium {
        width: 18px;
        height: 18px;
    }

    @include only_mini {
        @include skip_element;
    }
}

</style>

如您所见,它正在使用@别名导入另一个组件:

import(`@/assets/icons/${iconId}.svg`)

在查看应用程序时,它在localhost:3000上运行良好,但是对于Storybook(在端口6006上运行),它会出现以下错误:

ERROR in ./src/js/globalComponents/SvgIcon.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/js/globalComponents/SvgIcon.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve '@/assets/icons' in 'src/js/globalComponents'
ERROR in ./src/js/globalComponents/SvgIcon.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/js/globalComponents/SvgIcon.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve '@/assets/icons' in 'src/js/globalComponents'

内部vue.config.js(在根目录中)是应用别名的地方:

configureWebpack: {
    resolve: {
        alias: require('./aliases.config').webpack
    },
...
}

及其引用的文件:./aliases.config

const path = require('path')
function resolveSrc(_path) {
    return path.join(__dirname, _path)
}
const aliases = {
    '@': 'src',
    '@src': 'src'
}
module.exports = {
    webpack: {},
    jest: {}
}
for (const alias in aliases) {
    module.exports.webpack[alias] = resolveSrc(aliases[alias])
    module.exports.jest['^' + alias + '/(.*)$'] =
    '<rootDir>/' + aliases[alias] + '/$1'
}

这是我的Storybook(.storybook/main.js)的配置:

const path = require('path');

module.exports = {
  stories: ['../stories/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async (config, { configType }) => {
    // `configType` 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', 'css-loader', 
        {
          loader: 'sass-loader',
          options: {
            prependData: `@import "src/project/test/vars.scss"; @import "src/project/common/mixins.scss"; @import "src/styles/styles.scss";`
          }
        }
      ],
      resolve: {
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': path.dirname(path.resolve(__dirname, "../src")),
        },
      },
      include: path.resolve(__dirname, '../'),
    });


    // Return the altered config
    return config;
  },
};

有人在这里看到我在做什么错吗?

1 个答案:

答案 0 :(得分:0)

更新到Storybook 5.3.19时,我遇到了同样的问题。 我只能使用

可以解决的导入错误

'@': path.resolve(__dirname, '../src'),

我认为不需要与path.dirname()嵌套。

这是故事书的.storybook/main.js

module.exports = {
  stories: ['../stories/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],

  webpackFinal: async (config, { configType }) => {
    // `configType` 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.

    // Use Sass loader for vuetify components
    config.module.rules.push({
      test: /\.s(a|c)ss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
    });

    config.module.rules.push({
      resolve: {
        alias: {
          '@': path.resolve(__dirname, '../src'),
          vue: 'vue/dist/vue.js',
          'vue$': 'vue/dist/vue.esm.js',  
        },
      },
    });

    return config;
  },
};