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
中使用