Quasar Vue3 TS集成Storybook无法解析模块的配置问题
问题根因
当前配置存在3处明确错误,直接导致静态资源404、全局属性无法解析:
.storybook/main.js中重复定义module.exports,前半段写的@路径别名配置被后半段的配置对象完全覆盖,别名实际未生效,~@/assets/...格式的路径被当成普通相对路径请求,才会返回404- webpack规则中缺失svg、图片类静态资源的处理逻辑,Quasar框架内置的资源加载规则没有同步到Storybook构建流程
.storybook/preview.js中仅注册了Quasar基础框架,没有同步项目内自定义的全局属性挂载(如$api)、Quasar插件注册逻辑,Storybook运行时无法识别全局挂载的属性
修复步骤
1. 重写.storybook/main.js配置
删除旧版Storybook兼容的函数式导出写法,补全静态资源处理规则,正确配置路径别名,完整配置如下:
const path = require('path') module.exports = { stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'], framework: '@storybook/vue3', core: { builder: '@storybook/builder-webpack5' }, webpackFinal: async (config) => { // 配置路径别名 config.resolve.alias = { ...config.resolve.alias, '@': path.resolve(__dirname, '../src') } config.resolve.modules = [ path.resolve(__dirname, '..', 'src'), path.resolve(__dirname, '..', 'node_modules'), ...config.resolve.modules ] // 处理scss样式、pug模板 config.module.rules.push( { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'], include: path.resolve(__dirname, '../') }, { test: /\.pug$/, use: [{ loader: 'pug-plain-loader' }] } ) // 处理svg、图片等静态资源 const existingAssetRule = config.module.rules.find(rule => rule.test && rule.test.test('.svg')) if (existingAssetRule) existingAssetRule.exclude = /node_modules/ config.module.rules.push({ test: /\.(png|jpe?g|gif|svg|webp)$/i, type: 'asset/resource', generator: { filename: 'static/assets/[name].[hash][ext]' } }) return config } }
注意:修改配置前先删除node_modules/.cache目录,避免Storybook的构建缓存导致新配置不生效。
2. 补全.storybook/preview.js全局注册逻辑
Storybook不会自动读取项目主入口(main.ts)的全局注册代码,所有全局依赖、属性、插件都需要在这里手动注册,和项目内的注册逻辑保持一致:
import '@quasar/extras/roboto-font/roboto-font.css' import '@quasar/extras/material-icons/material-icons.css' import '@quasar/extras/animate/fadeInUp.css' import '@quasar/extras/animate/fadeOutDown.css' import '@quasar/extras/animate/fadeInRight.css' import '@quasar/extras/animate/fadeOutRight.css' import 'quasar/dist/quasar.css' import { app } from '@storybook/vue3' import { Quasar } from 'quasar' // 替换为你项目中api实例的实际导入路径 import api from '@/api/index' // 注册Quasar,项目用到的Quasar插件(如Notify、Dialog等)统一放在plugins字段中 app.use(Quasar, { plugins: {} }) // 挂载全局$api属性,和项目主入口的挂载逻辑一致 app.config.globalProperties.$api = api export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/ } } }
如果项目中还用到了Pinia、Vue Router、全局指令、全局过滤器,都按照相同逻辑在preview.js中注册即可。
3. 资源路径适配(可选)
如果重启后svg仍加载异常,可以将组件内的资源路径从~@/assets/images/no-result.svg修改为@/assets/images/no-result.svg,去掉~前缀,Quasar和Storybook的webpack配置都可以原生识别这种别名路径写法。
验证
执行npm run storybook重启服务,NoResult组件的svg资源可以正常渲染,组件内调用this.$api不会再出现未定义报错。
如果后续新增其他全局依赖,记得同步在preview.js中注册,不要依赖项目主入口的自动加载逻辑。
内容的提问来源于stack exchange,提问作者Cedric Smith
相关产品推荐
相关产品推荐

