histoire
1、在monorepo中使用
方案1:
- 1.1、在根目录下创建一个histoire.config.ts文件,然后使用histoire的api来配置histoire
- 1.2、但是涉及到packages中,有vue2和vue3情况,写两个histoire.config.ts文件,分别走不同的配置js
const mode = process.env.MODE || 'vue3' import histoireConfigVue2 from './histoire.config.vue2.js' import histoireConfigVue3 from './histoire.config.vue3.js' export default mode === 'vue2' ? histoireConfigVue2 : histoireConfigVue3
- 1.3、plugins配置:走不同的vue2
@histoire/plugin-vue2
和vue3@histoire/plugin-vue
的插件 - 1.4、vite配置:vue插件使用不同的插件 vue3
@vitejs/plugin-vue
vue2@vitejs/plugin-vue2
- 1.5、但是应该是依旧报错,vue如何区分是一个问题,使用包别名来区分,还是?尝试各种配置无果,改用方案2
方案2:
- 2.1、在packages vue3、vue2的文件夹中配置histoire.config.ts文件、并且安装histoire
- 2.2、在根目录下创建一个使用
pnpm --filter @play/vue3 dev:story
调用内部执行 - 2.3、这样就避免的了冲突报错
2、histoire 配置
vue2中的配置
- histoire.config.js
js
import { defineConfig } from 'histoire'
import { HstVue } from '@histoire/plugin-vue2'
export default defineConfig({
plugins: [
HstVue(),
],
outDir: '../../docs/vue2',
storyMatch: [
'**/src/**/*.story.vue',
],
storyIgnored: [
'**/node_modules/**',
'**/dist/**',
],
vite: {
base: '/play/vue2/',
},
setupFile: './histoire.setup.js',
})
- histoire.setup.js
js
import { defineSetupVue2 } from '@histoire/plugin-vue2'
// 给histoire 中的vue2添加全局样式 以及 其他全局配置
import 'element-ui/lib/theme-chalk/index.css'
import 'vxe-table/lib/style.css'
import '@/directives/index'
import store from '@/store'
import EventBus from '@/utils/eventBus'
import Vue from 'vue'
Vue.prototype.$EventBus = EventBus
export const setupVue2 = defineSetupVue2(({ story, variant }) => {
return {
store,
}
})
vue3中的配置
- histoire.config.ts
ts
import { defineConfig } from 'histoire'
import { HstVue } from '@histoire/plugin-vue'
export default defineConfig({
plugins: [
HstVue(),
],
outDir: '../../docs/vue3',
storyMatch: [
'**/src/**/*.story.vue',
],
storyIgnored: [
'**/node_modules/**',
'**/dist/**',
],
vite: {
base: '/play/vue3/',
// optimizeDeps: {
// include: ['vueuc','date-fns-tz'], // 不起作用
// },
ssr: {
// 因为引入ui组件,naive-ui在histoire build 的时候报错
// vueuc 和 date-fns-tz 都是按照commonjs 加载了
// 这里要错一层处理
/*
Histoire 在收集 stories 时,其实是跑在 Node ESM 环境下(类似 SSR)。
默认情况下,Vite 会把 node_modules 的依赖标记为 external,也就是 Node 自己去解析。
这条配置告诉 Vite:
“不要把这些包当外部模块,让 Vite 直接打包/编译成 ESM 再给 Node 用。”
因为 date-fns-tz 的 ESM 包和 CommonJS 包混合,Node 直接去解析目录导入就会报错 (ERR_UNSUPPORTED_DIR_IMPORT)。
加了 noExternal 后,Vite 自己处理成干净的 ESM,Node 就能直接执行,不再报错。 */
/*
为什么本地没问题,CI 报错
本地 Windows/macOS 文件系统大小写不敏感,Node 对导入目录有容错。
CI 是 Linux,大小写敏感,Node 的 ESM loader 对目录导入严格检查 → 如果不经过 Vite 编译,就会报 ERR_UNSUPPORTED_DIR_IMPORT。
ssr.noExternal 让 Vite 在收集 stories 阶段先把模块打包成 ESM → Node 就能正确加载。
https://chatgpt.com/c/68ba9b4a-d4a4-832c-9167-642e78450e25
*/
noExternal: ['naive-ui', 'vueuc', 'date-fns-tz'], // 确保 SSR / 构建时不会当作 CJS 起作用
},
// resolve: {
// alias: {
// 'date-fns-tz/dist/esm': 'date-fns-tz/dist/esm/index.js', // 不起作用
// },
// },
},
setupFile: './histoire.setup.ts',
})
- histoire.setup.ts
ts
import { defineSetupVue3 } from '@histoire/plugin-vue'
import { setupDirectives } from '@/directives'
import { setupStore } from '@/store'
import AppProvider from '@/common/AppProvider/index.vue'
export const setupVue3 = defineSetupVue3(({ app,addWrapper }) => {
// 添加 provider
addWrapper(AppProvider);
// 添加 store
setupStore(app);
// 添加 directive
setupDirectives(app);
})