如何更好的管理公共组件?
想要真正实现组件化开发,管理和维护好公共组件无法避免。
有些公司没有公共组件,有了公共组件,文档也很烂,使用体验极差,基于开源组件库封装的,干脆连文档都没有,就是换了一个皮,调整一下布局,加入的特殊用法,也没有说明。我在某公司用那个基于 element-ui 二次封装的表单,一直有问题,被那个问题搞惨了,最后询问组件开发者,才定位到问题。坑爹啊......
有些公司在内网部署类似 codepen 的组件可视化平台,功能还是不够强大,而且使用体验不佳。
组件化开发,会涉及三个问题:
- 如何设计组件? 这主要看组件开发者对框架、业务的理解
- 如何展示组件? 文档完善吗?修改输入,能实时看到变化吗?
- 如何共享组件? 发布到 npm? 搭建私有源?
storybook 对第二个问题给出了解决方案。
storybook 是一个开源的组件管理工具,支持大部分流行的 UI 框架,为组件编写故事,类似需求故事,可为组件提供文档、可视化测试、插件系统实现功能加强。 对于有自己定制的组件库的前端团队来说,给组件编写文档是无法避免的工作,想要更好的实现组件华开发、组件更加易用,可使用 storybook 管理组件。
类似的工具有:
曾经试着在 Bit 上发布组件,预览时总是报错,试了几次还是一样,就没有再继续看了。
storybook 初步体验
根据Storybook + Vue 搭建 UI 组件库 手动安装,运行时遇到的问题:
storybook 从 6.2.0 起,移除了内置的 postcss 支持,需要手动安装
postcss-flexbugs-fixes
、autoprefixer
和 story 插件。
安装 postcss 相关依赖
npm i -D postcss-flexbugs-fixes autoprefixer
配置文件: postcss.config.js
module.exports = {
plugins: [
require('postcss-flexbugs-fixes'),
require('autoprefixer')({
flexbox: 'no-2009',
}),
],
}
安装 storybook 插件 @storybook/addon-postcss
:
npm i -D @storybook/addon-postcss
修改 main.js
module.exports = {
addons: ['@storybook/addon-postcss'], // 添加插件
}
storybook 默认使用 webpack4,而其他依赖使用其他版本,版本不一致,导致 :
Error: Rule can only have one resource source (provided resource and test + include + exclude)
安装 webpack4
npm i -D webpack@^4 -f # 有的依赖的依赖的要求 webpack5, -f 强制安装4,否则可能安装失败
最后的依赖如下:
{
"dependencies": {
"@storybook/vue": "^6.3.8"
},
"devDependencies": {
"@babel/core": "^7.15.5",
"@storybook/addon-postcss": "^2.0.0",
"autoprefixer": "^10.3.4",
"babel-loader": "^8.2.2",
"babel-preset-vue": "^2.0.2",
"postcss-flexbugs-fixes": "^5.0.2",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.46.0"
}
}
再运行,成功。
- 编写 story
安装必备的插件
npm i -D @storybook/addon-controls @storybook/addon-essentials @storybook/addon-links
可能遇到类似错误 npm ERR! syscall rename,npm ERR!
解决办法 :npm ERR! code ENOENT npm ERR! syscall rename
还可以使用 yarn 安装。
发现 vue 版本依赖出现问题,安装vue@2.6.14
。
安装查看源码的插件 npm i -D @storybook/addon-storysource
在 main.js 中注册插件:
module.exports = {
// 添加它们
addons: [
// 核心插件,开箱即用,包含的功能:
// 1. 控制props实时查看组件的ui变化
// 2. 修改 viewport 查看不同尺寸下的组件表现
// 3. 查看组件的尺寸等
'@storybook/addon-essentials',
// 处理组件的行为:事件
'@storybook/addon-actions',
// 查看组件源码
'@storybook/addon-storysource',
'@storybook/addon-links',
],
}
修改故事:
import { action } from '@storybook/addon-actions'
import MyButton from './MyButton.vue'
export default {
title: 'MyButton',
component: MyButton,
}
// vue2 的写法
const withText = (args, { argTypes }) => {
return {
components: {
MyButton,
},
props: Object.keys(argTypes),
template: `<my-button v-bind="$props" @click="clickHandler"/>`,
methods: {
clickHandler: action('click'), // action 的参数是事件名称
},
}
}
export const Default = withText.bind({})
// NOTE 组件参数必需收 args
Default.args = {
text: 'hello storybook',
}
改变输入,看组件效果
组件事件处理和源码
虽然 @storybook/addon-essentials
启用了很多功能,想要自定义某些功能,需要单独安装相应的插件。
希望自定义 viewport ,安装依赖:
npm i -D @storybook/addon-viewport
配置 MyButton.stories.js
:
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
import MyButton from './MyButton.vue'
export default {
title: 'MyButton',
component: MyButton,
parameters: {
viewport: {
viewports: INITIAL_VIEWPORTS, //INITIAL_VIEWPORTS 必须语句
defaultViewport: 'iphone6', //设置默认窗口大小
},
},
}
export const Default = withText.bind({})
// NOTE 组件参数必需收 args
Default.args = {
text: 'hello storybook',
}
// 这里可覆盖默认配置
Default.story = {
parameters: {
viewport: {
defaultViewport: 'iphonex',
},
},
}
切换视图的效果
显示组件的 markdown
npm i -D @storybook/addon-notes
修改 main.js 后创建一个 MyButton.md
,在 story 配置:
import MyButtonMd from './MyButton.md'
//...
Default.story = {
parameters: {
viewport: {
defaultViewport: 'iphonex',
},
// markdown
notes: { MyButtonMd },
},
}
显示组件 markdown
我们的组件往往是发布在私有的 npm 或者公开的 npm,如何为这些组件编写文档呢?
为独立的组件编写故事
编写了,有时候没有渲染出来。渲染了,没和数据,还不知道问题在哪儿。以后再来看了。
storybook 有哪些问题
- 有的故事会无法渲染
- 组件的 api 配置很繁琐,最好能根据 ts 的类型直接推断出来