在Storybook中Mock Hook返回值:是否需为每个Hook配置子路径?
Storybook中自定义Hook Mock配置优化方案
问题核心
在React+Vite+TypeScript项目中,自定义Hook(如./hooks/queries/getWallets.tsx、./hooks/mutations/addWallet.tsx)需创建同名.mock.tsx文件,按Storybook文档要求要在package.json的imports字段逐个配置子路径模块,这种方式过于繁琐,想确认是否必须逐个配置,以及能否用相对导入替代。
解决方案
1. 批量替换的别名方案(推荐)
无需逐个配置package.json,利用Vite的别名+环境变量实现自动切换:
- 在
vite.config.ts中添加环境区分的别名配置:
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig(({ mode }) => { const isStorybook = mode === 'storybook'; return { plugins: [react()], resolve: { alias: { '@hooks': isStorybook ? '/src/hooks/mocks' : '/src/hooks' } } }; });
- 调整mock文件结构:把所有
.mock.tsx文件移到src/hooks/mocks目录下,保持和原Hook一致的层级(比如src/hooks/mocks/queries/getWallets.tsx对应原src/hooks/queries/getWallets.tsx)。这样在Storybook环境下,导入@hooks/queries/getWallets会自动指向mock文件,生产环境则指向原文件。
2. 相对导入的兼容处理
如果坚持用相对导入,需要在Storybook配置文件(.storybook/main.ts)中完善Vite解析规则:
import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], addons: ['@storybook/addon-links', '@storybook/addon-essentials'], framework: { name: '@storybook/react-vite', options: {} }, async viteFinal(config) { if (!config.resolve) config.resolve = {}; // 保留原有配置,确保mock文件路径能被正确解析 config.resolve.extensions = [...(config.resolve.extensions || []), '.tsx', '.mock.tsx']; return config; } }; export default config;
不过相对导入在切换环境时需要手动替换路径,灵活性差,不建议大规模使用。
3. 简化package.json配置的通配符方案
若一定要用package.json的imports字段,可尝试通配符批量配置(需Node.js 16+支持):
"imports": { "#hooks/*": { "storybook": "./src/hooks/*/mock.tsx", "default": "./src/hooks/*.tsx" } }
注意:通配符匹配规则需和文件结构严格对应,建议先在本地测试验证。
内容的提问来源于stack exchange,提问作者samplecode3300
相关产品推荐
相关产品推荐

