快速搭建属于自己的组件库

1,696 阅读2分钟

1. 开发组件库的几种方式

打包组件库工具有很多

  • rollup,打包js利器,非常轻量,集成tree-shaking
  • create-react-app/vue-cli3,可快速改造一个组件库的脚手架
  • webpack自行封装
  • umi/father,基于rollup和babel组件打包功能,集成docz的文档,支持TypeScript等
  • 直接去ant-design或者elementUI的github仓库,把代码copy下来改成自己的组件库脚手架 关于如何使用webpack4.0和rollup,可以参考笔者的以下几篇文章:

如何使用rollup打包前端组件
用webpack4.0撸单页/多页脚手架(jquery,react,vue,typescript)

组件系统设计思路和模式

我们可以把功能或者需求类似的有机体封装成一个业务组件,并对外暴露接口来实现灵活的可定制性,这样的话我们就可以再不同页面不同子系统中复用同样的逻辑和功能了。

  • 通用型组件: 比如Button, Icon等.
  • 布局型组件: 比如Grid, Layout布局等. 
  • 导航型组件: 比如面包屑Breadcrumb,
  • 下拉菜单:Dropdown, 菜单Menu等.
  • 数据录入型组件: 比如form表单, Switch开关, Upload文件上传等. 
  • 数据展示型组件: 比如Avator头像, Table表格, List列表等.
  • 反馈型组件: 比如Progress进度条, Drawer抽屉, Modal对话框等.
  • 其他业务类型 组件案列:手摸手实现一个轻量级可扩展的模态框(Modal)组件

组件搭建实战

基于react+umi/father+react搭建的

原理:

  • 采用react封装各组件,在index.js export采用暴露出去
  • 基于umi/father脚手架,提供组件库或者工具库打包的集成工具,我们只需要更改配置文件就能轻松搭建一款自带说明文档的组件库。docz文档
  • npm发版
  • import直接使用 项目:
    xui——基于react的轻量级UI组件库
    ant-design

基于Vue-cli3+插件挂载搭建的

componentlib
element

组件测试

小案列:model组件

  • 确保取消事件必须申明
  it('onCancel should be called', () => {
    const onCancel = jest.fn();  //jest.fn()返回一个新的、未使用的[模拟函数](https://www.jestjs.cn/docs/mock-function-api)。
    const wrapper = mount(<Modal visible onCancel={onCancel} />);
    wrapper.find('.ant-btn').first().simulate('click');
    expect(onCancel).toHaveBeenCalled(); //确保模拟功能得到调用
  });
  • 确保type传的值是真实的,即非:false0''nullundefined,和NaN
  it('danger type', () => {
    const wrapper = mount(<Modal okType="danger" visible />);
    expect(wrapper.find(Button).last().props().danger).toBeTruthy();
  });
  • 单击关闭按钮时应关闭确认模式
  it('should close confirm modal when click close button', () => {
    jest.useFakeTimers();
    const onCancel = jest.fn();
    Modal.confirm({
      title: 'title',
      content: 'content',
      closable: true,
      closeIcon: 'X',
      onCancel,
    });
    act(() => {
      jest.runAllTimers();
    });
    expect($$(`.ant-modal-close`)).toHaveLength(1);
    $$('.ant-btn')[0].click();
    act(() => {
      jest.runAllTimers();
    });
    expect($$(`.ant-modal-close`)).toHaveLength(0);
    expect(onCancel).toHaveBeenCalledTimes(1);
    jest.useRealTimers();
  });

可参考:
react jest
ant-design
jest官网