Skip to content
On this page

如何更好的管理公共组件?

想要真正实现组件化开发,管理和维护好公共组件无法避免。

有些公司没有公共组件,有了公共组件,文档也很烂,使用体验极差,基于开源组件库封装的,干脆连文档都没有,就是换了一个皮,调整一下布局,加入的特殊用法,也没有说明。我在某公司用那个基于 element-ui 二次封装的表单,一直有问题,被那个问题搞惨了,最后询问组件开发者,才定位到问题。坑爹啊......

有些公司在内网部署类似 codepen 的组件可视化平台,功能还是不够强大,而且使用体验不佳。

组件化开发,会涉及三个问题:

  1. 如何设计组件? 这主要看组件开发者对框架、业务的理解
  2. 如何展示组件? 文档完善吗?修改输入,能实时看到变化吗?
  3. 如何共享组件? 发布到 npm? 搭建私有源?

storybook 对第二个问题给出了解决方案。

storybook 是一个开源的组件管理工具,支持大部分流行的 UI 框架,为组件编写故事,类似需求故事,可为组件提供文档可视化测试插件系统实现功能加强。 对于有自己定制的组件库的前端团队来说,给组件编写文档是无法避免的工作,想要更好的实现组件华开发、组件更加易用,可使用 storybook 管理组件。

类似的工具有:

  • dumi 只支持 react
  • Bit 组件托管网站 不支持私有部署
  • Codesandbox, Stackblitz & friends 这三家更像在线编辑器

曾经试着在 Bit 上发布组件,预览时总是报错,试了几次还是一样,就没有再继续看了。

storybook 初步体验

根据Storybook + Vue 搭建 UI 组件库 手动安装,运行时遇到的问题:

storybook 从 6.2.0 起,移除了内置的 postcss 支持,需要手动安装postcss-flexbugs-fixesautoprefixer 和 story 插件。

安装 postcss 相关依赖

bash
npm i -D postcss-flexbugs-fixes autoprefixer

配置文件: postcss.config.js

js
module.exports = {
  plugins: [
    require('postcss-flexbugs-fixes'),
    require('autoprefixer')({
      flexbox: 'no-2009',
    }),
  ],
}

安装 storybook 插件 @storybook/addon-postcss

bash
npm i -D @storybook/addon-postcss

修改 main.js

js
module.exports = {
  addons: ['@storybook/addon-postcss'], // 添加插件
}

storybook 默认使用 webpack4,而其他依赖使用其他版本,版本不一致,导致 :Error: Rule can only have one resource source (provided resource and test + include + exclude) 安装 webpack4

bash
npm i -D webpack@^4 -f # 有的依赖的依赖的要求 webpack5, -f 强制安装4,否则可能安装失败

最后的依赖如下:

json
{
  "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"
  }
}

再运行,成功。

storybook 运行成功

  1. 编写 story

安装必备的插件

bash
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 中注册插件:

js
module.exports = {
  // 添加它们
  addons: [
    // 核心插件,开箱即用,包含的功能:
    // 1. 控制props实时查看组件的ui变化
    // 2. 修改 viewport 查看不同尺寸下的组件表现
    // 3. 查看组件的尺寸等
    '@storybook/addon-essentials',
    // 处理组件的行为:事件
    '@storybook/addon-actions',
    // 查看组件源码
    '@storybook/addon-storysource',
    '@storybook/addon-links',
  ],
}

修改故事:

js
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 ,安装依赖:

bash
npm i -D @storybook/addon-viewport

配置 MyButton.stories.js

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

bash
npm i -D @storybook/addon-notes

修改 main.js 后创建一个 MyButton.md,在 story 配置:

js
import MyButtonMd from './MyButton.md'
//...
Default.story = {
  parameters: {
    viewport: {
      defaultViewport: 'iphonex',
    },
    // markdown
    notes: { MyButtonMd },
  },
}

markdown

显示组件 markdown

我们的组件往往是发布在私有的 npm 或者公开的 npm,如何为这些组件编写文档呢?

为独立的组件编写故事

编写了,有时候没有渲染出来。渲染了,没和数据,还不知道问题在哪儿。以后再来看了。

storybook 有哪些问题

  1. 有的故事会无法渲染
  2. 组件的 api 配置很繁琐,最好能根据 ts 的类型直接推断出来

Released under the MIT License.