Storybook集成Quasar时字体加载路径出现undefined的问题求助
Storybook集成Quasar时字体加载失败问题
问题现象
开发者工具中字体请求路径包含undefined前缀:
http://localhost:6006/undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOmCnqEu92Fr1Mu4mxM.woff
查看编译后的CSS文件,发现原相对路径被替换为undefined/node_modules/...:
import {createHotContext as __vite__createHotContext} from "/@vite/client"; import.meta.hot = __vite__createHotContext("/node_modules/@quasar/extras/roboto-font/roboto-font.css"); import {updateStyle as __vite__updateStyle, removeStyle as __vite__removeStyle} from "/@vite/client" const __vite__id = "/var/www/html/node_modules/@quasar/extras/roboto-font/roboto-font.css" const __vite__css = "@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 100;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOkCnqEu92Fr1MmgVxIIzQ.woff) format('woff');\n}\n@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 300;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOlCnqEu92Fr1MmSU5fBBc-.woff) format('woff');\n}\n@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 400;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOmCnqEu92Fr1Mu4mxM.woff) format('woff');\n}\n@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 500;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOlCnqEu92Fr1MmEU9fBBc-.woff) format('woff');\n}\n@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 700;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOlCnqEu92Fr1MmWUlfBBc-.woff) format('woff');\n}\n@font-face {\n font-family: 'Roboto';\n font-style: normal;\n font-weight: 900;\n src: url(undefined/node_modules/@quasar/extras/roboto-font/web-font/KFOlCnqEu92Fr1MmYUtfBBc-.woff) format('woff');\n}\n" __vite__updateStyle(__vite__id, __vite__css) import.meta.hot.accept() export default __vite__css import.meta.hot.prune(()=>__vite__removeStyle(__vite__id))
而@quasar/extras/roboto-font/roboto-font.css原文件中字体路径为相对路径:
@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 100; src: url(./web-font/KFOkCnqEu92Fr1MmgVxIIzQ.woff) format('woff'); } @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 300; src: url(./web-font/KFOlCnqEu92Fr1MmSU5fBBc-.woff) format('woff'); } @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 400; src: url(./web-font/KFOmCnqEu92Fr1Mu4mxM.woff) format('woff'); } @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 500; src: url(./web-font/KFOlCnqEu92Fr1MmEU9fBBc-.woff) format('woff'); } @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 700; src: url(./web-font/KFOlCnqEu92Fr1MmWUlfBBc-.woff) format('woff'); } @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 900; src: url(./web-font/KFOlCnqEu92Fr1MmYUtfBBc-.woff) format('woff'); }
该问题仅在执行npm run storybook时出现,npm run dev环境下字体加载正常。
相关配置文件
.storybook/main.js
/** @type { import('@storybook/vue3-vite').StorybookConfig } */ const config = { stories: [ "../**/*.mdx", "../**/*.stories.@(js|jsx|mjs|ts|tsx)", ], addons: [ "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions", ], framework: { name: "@storybook/vue3-vite", options: {}, }, staticDirs: ['../node_modules'], docs: { autodocs: false, } }; export default config;
.storybook/preview.js
import { setup } from '@storybook/vue3'; import { Quasar } from 'quasar'; // Import icon libraries import '@quasar/extras/roboto-font/roboto-font.css' import '@quasar/extras/material-icons/material-icons.css' import '@quasar/extras/material-symbols-outlined/material-symbols-outlined.css' import '@quasar/extras/fontawesome-v6/fontawesome-v6.css' import '@quasar/extras/line-awesome/line-awesome.css' // Import Quasar css import 'quasar/src/css/index.sass' import '../resources/css/app.css' /** @type { import('@storybook/vue3').Preview } */ const preview = { parameters: { actions: { argTypesRegex: "^on[A-Z].*" }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/i, }, }, }, }; export default preview; setup((app) => { app.use(Quasar, {config: {}, directives: {}}) app.config.globalProperties.$storybook = true; });
package.json
{ "private": true, "scripts": { "dev": "vite", "build": "vite build", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, "devDependencies": { "@inertiajs/vue3": "^1.0.0", "@quasar/vite-plugin": "^1.3.0", "@storybook/addon-essentials": "^7.5.0", "@storybook/addon-interactions": "^7.5.0", "@storybook/addon-links": "^7.5.0", "@storybook/blocks": "^7.5.0", "@storybook/testing-library": "^0.2.2", "@storybook/vue3": "^7.5.0", "@storybook/vue3-vite": "^7.5.0", "@vitejs/plugin-vue": "^4.0.0", "autoprefixer": "^10.4.12", "axios": "^1.1.2", "laravel-vite-plugin": "^0.7.2", "lodash": "^4.17.19", "postcss": "^8.4.18", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.32.12", "storybook": "^7.5.0", "vite": "^4.0.0", "vue": "^3.2.41" }, "dependencies": { "@quasar/extras": "^1.16.7", "quasar": "^2.13.0", "vue-i18n": "^9.2.2" } }
解决方案
方案1:配置Quasar Vite插件到Storybook
修改.storybook/main.js,添加viteFinal配置,引入Quasar的Vite插件,确保资源路径被正确解析:
/** @type { import('@storybook/vue3-vite').StorybookConfig } */ import { quasar, transformAssetUrls } from '@quasar/vite-plugin'; const config = { stories: [ "../**/*.mdx", "../**/*.stories.@(js|jsx|mjs|ts|tsx)", ], addons: [ "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions", ], framework: { name: "@storybook/vue3-vite", options: {}, }, staticDirs: ['../node_modules'], docs: { autodocs: false, }, viteFinal: async (config) => { // 添加Quasar Vite插件 config.plugins.push( quasar({ // 若有自定义Quasar变量文件可配置,无则删除此行 sassVariables: 'src/quasar-variables.sass' }) ); // 配置Vue的资源转换规则 config.vue = { template: { transformAssetUrls, }, }; return config; }, }; export default config;
方案2:修改字体导入为绝对路径
在.storybook/preview.js中,将字体CSS的导入改为从静态资源根路径引入:
// 替换原有的字体导入语句 import '/node_modules/@quasar/extras/roboto-font/roboto-font.css' import '/node_modules/@quasar/extras/material-icons/material-icons.css' import '/node_modules/@quasar/extras/material-symbols-outlined/material-symbols-outlined.css' import '/node_modules/@quasar/extras/fontawesome-v6/fontawesome-v6.css' import '/node_modules/@quasar/extras/line-awesome/line-awesome.css'
确保.storybook/main.js中的staticDirs已配置为['../node_modules'],Storybook会将node_modules作为静态资源目录,字体文件可被正确访问。
方案3:配置Vite路径别名
在.storybook/main.js的viteFinal中添加路径别名,帮助Vite正确解析Quasar资源路径:
viteFinal: async (config) => { config.resolve = config.resolve || {}; // 添加路径别名 config.resolve.alias = { ...config.resolve.alias, '@quasar/extras': '../node_modules/@quasar/extras' }; return config; }
验证
修改配置后重启Storybook,查看开发者工具中的字体请求路径,正常路径应为:
http://localhost:6006/node_modules/@quasar/extras/roboto-font/web-font/KFOmCnqEu92Fr1Mu4mxM.woff
此时字体应能正常加载。
内容的提问来源于stack exchange,提问作者prodigy7
相关产品推荐
相关产品推荐

