vite、vue3和storybook
关于storybook
storybook是什么?
Storybook is a tool for UI development. It makes development faster and easier by isolating components. This allows you to work on one component at a time. You can develop entire UIs without needing to start up a complex dev stack, force certain data into your database, or navigate around your application.
storybook可以干什么?
- 根据组件注释生成对应的文档信息
 - 根据组件
prop类型自动生成对应类型的交互控制 - 可以编写组件交互示例
 - 可以进行组件测试
 etc
概览

基于vite和vue3使用storybook
基本步骤
- 
初始化
storybook[1]:1
npx sb@next init --builder storybook-builder-vite
 - 
平移需要用到的
vite配置到.storybook/main.js里面,其中viteFinal方法[2]就是专门设置自定义vite配置的地方,可以在这里修改或覆盖对应的配置,然后返回配置对象即可,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// ...
module.exports = {
// ...
async viteFinal(config) {
// 这里修改或覆盖配置
config.resolve.alias = [
{
find: /^@\//,
replacement: path.resolve(__dirname, '..', 'src') + '/'
},
{
find: 'vue',
replacement: 'vue/dist/vue.esm-bundler.js'
}
]
// ...
return config
}
} - 
自定义
storybook vite打包缓存目录,如果不自定义一个缓存目录,则会导致storybook和正常开发的vite项目共用同一个缓存目录,那么里面的文件很有可能就是相互覆盖,导致两边一启动就会重新pre-building;1
config.cacheDir = 'node_modules/.vite-storybook' // 避免跟开发环境一个缓存目录,以免相互覆盖;
 - 
如果组件中用到了一些和
app实例相关的全局配置,那么同样地需要平移地把相应的配置在.storybook/preview.js(这个文件也可以用.ts)中,可以把这里当做storybook的入口文件:1
import { app } from '@storybook/vue3'; // 这里的app就是storybook vue实例
 - 
上面的都配置好了之后,剩下的就是补充组件注释和增加对应组件的
story文件了,最后yarn storybook就可以看到组件交互文档了; 
关于组件注释
组件文档关心的地方无非就是老三样(props,events,slots)和组件自身的描述,只需要在对应的地方写上jsdoc风格的注释即可:


需要注意的是:
- 由于
@storybook/vue3依赖的上游解析器vue-docgen-api还不支持emits这种事件类型的注释,所以events目前貌似无法通过注释来生成对应的描述; - 同理,对于
setup风格的vue文件支持度也要取决于vue-docgen-api; slot注释需要增加@slot装饰符;
关于story文件
- 文件格式:
*.stories.@(js|jsx|ts|tsx|mdx);默认是这些格式,关于探测story文件的规则可以在.storybook/main.js进行配置; - 本质上一个
story文件对应一个组件,然后里面的每一个story实例就是这个组件的一个交互示例;所以完全可以把一个story实例当做是对当前组件的props/events/slots的一种组合; 


其他问题
无法正确解析props类型
当使用函数来输出prop定义信息时,会发现storybook得到的类型推断直接就是对应的代码,而非最终类型:
这个可以理解,因为一般这种提取注释生成文档的工具都是从AST信息中进行获取的,如果AST推断得到的是一个函数节点当然就没法正确解析执行后的结果;目前解决思路有
- 
把这种函数当做宏,然后
storybook在加载前把宏输出成结果字符串;其实利用rollup的虚拟文件玩法,这种思路是可以实现的[3]; - 
根据解析后的
VNode信息来补充,因为Vue解析成VNode后其prop类型就是执行后的结果,即运行时真正用到的信息;
当然这种方式得到的不是最准确的
ts interface定义,因为在运行时这些类型都被分解成原子类型了(就是vue2中所熟悉的各种原始类型和数据结构的构造函数),不过至少能看; 
和volar的冲突
如果你发现volar在推导template的组件类型突然全变成了any时,可能就是storybook的锅;
推荐解决方案:https://github.com/johnsoncodehk/volar/discussions/592#discussioncomment-1763880
自动化生成对应组件的story
如果你仅仅只想用storybook来快速查看组件文档,而不需要各种定制化的示例编写时,可以尝试用node脚本直接从一个story文件模板快速生成对应组件的story文件,省的一个个填写;
1  | const template = `import ${name} from '@/components/${name}.vue';  | 
这样就可以快速查看文档了;
更多
更多storybook的用法推荐看官方文档,真的是极其详细的文档;
 用默认的webpack打包器
storybook的vite版本目前还是测试阶段,所以如果用默认的webpack实际上也能用;关于这种用法也有很多坑,以下遇到的问题仅供参考:
Error: PostCSS plugin tailwindcss requires PostCSS 8.;javascript - Error: PostCSS plugin tailwindcss requires PostCSS 8 - Stack Overflow- 编译成功后打开网址报错:
CANNOT get /;Storybook が CANNOT get / と表示された時 - Qiita - 使用
sass配置报错:Type Error: this.getOptions is not a function For style-loader;reactjs - Type Error: this.getOptions is not a function For style-loader - Stack Overflow webpack配置(因为storybook默认使用webpack4进行打包配置):https://storybook.js.org/docs/vue/configure/webpack#extending-storybooks-webpack-config
相关文章
- Document & Test Vue 3 Components With Storybook - Michael Hoffmann (Mokkapps) - Senior Frontend Developer (Freelancer):简单地介绍
storybook在vue3中使用