最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 教你使用Dumi和father-build快速搭建React组件库

    正文概述 掘金(赵_叶紫)   2020-12-11   3441

    1. 背景

    目前我所在业务组是负责后台管理系统,但是对于使用的组件并没有引入第三方库,全有开发人员自己编写。但是对于Common Project还是处于拷贝的方式。然后萌生了对公共组件库进行管理的想法。这个方式有什么好处呢?

    • 能够沉淀组内组件,避免重复造轮子的缺陷。
    • 统一维护组件,使不同开发人员遵循同一套使用标准。
    • 自己的UI库,能够保证系统视觉和交互一致性。
    • 提高产品研发效率,资源重复利用,减少重复开发。
    • 项目统一设计、编码语言规则,沟通更轻松。
    • 专注业务,在视觉要求方面减少花费时间,争取更好的时间写业务。

    2. 技术选择(dumi + father-build)

    当然,在网上进行查询,发现很多很多人都做过类似的事情,我们可以借鉴很多的经验。有人是自己编写的配置。而我在芸芸博客中,筛选了满足我的条件的技术(dumi + father-build)。为何选择它呢?

    • dumi 是蚂蚁金服插件化的企业级前端框架,专门为组件开发场景而生的文档工具。与father的文档打包相比,构建编译速度更快,更友好。
    • father-build属于father(集文档与组件打包一体的库)的一部分。专注于组件打包。

    为什么我不选择自己编写呢?不仅仅是搭建时间的成本,还有后续优化等,目前我没有自信会比专注于该业务的人做的更好。后续也会去好好学习一下大神是如何实现的,但是迫在眉睫的是我希望完成我的组件库搭建,因此先偷个小懒了^^。

    3. 文档库搭建

    @umijs/create-dumi-lib是基于Umi的文档工具,开箱即用,专注于开发和文档编写。运行以下命令,会初始化项目结构。

    $ npm init
    $ npx @umijs/create-dumi-lib
    

    文档目录结构

    教你使用Dumi和father-build快速搭建React组件库

    .umirc.ts

    是umi项目的配置文件,而dumi是umi在组件库开发中的一个最佳实践,但是它本质还是一个umi插件,因此只要umi的配置,都是可以在dumi中正常使用的。

    .fatherrc.ts

    是father-build的配置文件,组件库如何编译以及编译后产生的类型都需要在这里使用。

    启动

    运行npm start即可启动。 教你使用Dumi和father-build快速搭建React组件库

    4. 编写组件以及引用文档

    编写一个简单的实例和docs。

    4.1 配置官网logo(.umirc.ts)

    tips: 资源需要放在public目录下面。例如public/image/xxx.png。不然会访问不了。

    // .umirc.ts
    
    import { defineConfig } from 'dumi';
    let BaseUrl = ''
    export default defineConfig({
        mode: 'site', // site: 站点模式(导航头 + 左侧菜单 + 右侧内容)。 doc:文档
        title: 'Biz Library', // 组件库名称
        favicon: BaseUrl + '/images/favicon.ico', 
        logo: BaseUrl + '/images/photos.svg',
        description: '用于Biz Web Dev 前端组件开发。',
    });
    

    4.2 编写组件与组件文档

    component:/src/Dialog/index.tsx

    import React, { FC } from 'react';
    import './index.less';
    interface DialogProps {
      onClick?: React.MouseEventHandler<HTMLElement>;
      type?: 'default' | 'primary' | 'secondary';
      disabled?: boolean;
    }
    const Dialog: FC<DialogProps> = ({ children, onClick, type = 'dialog' }) => {
      return (
        <div className={'biz_dev_dialog'} onClick={onClick}>
          {children}
        </div>
      );
    };
    export default Dialog;
    

    css:/src/Dialog/index.less

    @btn-prefix-cls: ~'biz_dev';
    
    .@{btn-prefix-cls} {
      &_dialog {
        padding: 6px 16px;
        font-size: 12px;
        min-width: 64px;
        color: red;
      }
    }
    

    文档编写

    • 组件文档en: docs/component/dialog.md
    • 组件文档中文: docs/component/dialog.zh-CN.md
    • 包名biz-web-library: 是package.json 中的name
    import React from 'react';
    import { Dialog } from 'biz-web-library'; // 可通过包名引入,而不是相对路径
    export default () => <Dialog>dialog example</Dialog>;
    

    启动

    运行npm run start,至此本地的开发环境就已经完成啦,你可以一边开发一边调试了。 教你使用Dumi和father-build快速搭建React组件库

    5. CI 测试

    测试对于组件库来说,是必不可少的。在father-build 中,集成了jest用于单元测试。但是对于React组件进行测试还需要进行额外的配置。

    jest.config.js

    module.exports = {
      setupFiles: ['<rootDir>/testSetUp.js'],
      testEnvironment: 'jsdom', // default: jsdom, 可配置: node
    };
    

    testSetUp.js

    记得安装 enzyme-adapter-react-16enzyme

    import { configure } from 'enzyme';
    import Adapter from 'enzyme-adapter-react-16';
    configure({ adapter: new Adapter() });
    

    编写测试用例

    import React from 'react';
    import { render } from 'enzyme';
    import Button from '../../src/Button';
    
    describe('test', () => {
    	it('test render', () => {
    		let Wrapper = render(<Button>case one</Button>);
    		expect(true).toBeTruthy();
    	})
    })
    

    运行npm run test,执行通过。
    教你使用Dumi和father-build快速搭建React组件库

    6. 全量加载 和 按需加载

    我们知道,很多组件库是将组件统一打包,通过以下方式引入。默认情况下father-build也是这样的。

    import { componentName } from 'biz-library';
    

    常见的库(例如antd)是通过配置babel插件实现按需引入。而我希望我的组件库可以不通过配置插件,即可实现按需引入。

    import componentName from 'biz-library/componentName';
    

    6.1 实现按需加载

    .fatherrc.ts

    作为father-build的配置文件,用于配置组件库被如何编译和编译产物的类型。一般设置 esm: 'rollup'就够用了。但它缺点是会打包在一起,无法实现按需引入。因此我采用esm: 'babel'

    export default {
      target: 'browser',
      esm: 'babel',
      lessInBabelMode: true, // babel 模式下做 less 编译
      entry: ['src/Button/index.tsx', 'src/Dialog/index.tsx'],
      autoprefixer: {
        browsers: ['ie>9', 'Safari >= 6'],
      },
      pkgs: [
        // 组件依赖构建顺序, 例如 a组件依赖于b组件,那么需要先编译 b,在编译a,则 这里可以控制组件编译顺序
      ],
    };
    

    tsconfig.json

    其他属性没什么好说的, "declaration": true是必须配置的,生成typescript项目中.d.ts后缀的文件。

    {
      "compileOnSave": true,
      "compilerOptions": {
        "target": "es6",
        "module": "esnext",
        "lib": ["es2018", "dom"],
        "rootDir": "./",
        "outDir": "es",
        "moduleResolution": "node",
        "importHelpers": true,
        "jsx": "react",
        "esModuleInterop": true,
        "sourceMap": true,
        "baseUrl": "./",
        "strict": true,
        "declaration": true, // 只有declaration设置为true才能生成.d.ts后缀的文件
        "allowJs": true,
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": false,
        "suppressImplicitAnyIndexErrors": true,
        "noUnusedLocals": true,
        "experimentalDecorators": true,
        "skipLibCheck": true,
        "paths": {
          "@/*": ["src/*"],
          "@@/*": ["src/.umi/*"],
          "@@@/*": ["docs/*"]
        },
        "allowSyntheticDefaultImports": true,
        "typeRoots": ["typings", "node_modules/@types"]
      },
      "include": ["src/**/*", "dosc/**/*"],
      "exclude": [
        "node_modules",
        "lib",
        "es",
        "dist",
        "typings",
        "**/__test__",
        "test"
      ]
    }
    

    打包发布至npm

    运行npm run build命令,本地打包后,将组件一个个拆分了的,为我们按需引入做好了铺垫。
    教你使用Dumi和father-build快速搭建React组件库

    运行npm run release,将其发布到npm上,便可以通过npm进行安装,在项目中进行使用。发布至npm需注意version: 1.0.0每一次不能相同。

    import React from 'react';
    import Button from 'biz-web-library/es/Button';
    function App() {
      return (<Button>click me</Button>);
    }
    export default App;
    

    打包路径修改

    从上面的使用方式可以看出,Button并没有在biz-web-library的下面,我其实期待按需引入使用以下方式:

    import Button from 'biz-web-library/Button';
    

    经过查询,终于找到了一个比较优雅的使用方式,Click Me
    package.json中配置以下语句,然后直接运行npm publish即可。

    "prepublishOnly": "npm run build && cp -r ./es/* . && rm -rf ./es",
    "postpublish": "git clean -fd",
    "release": "npm publish",
    

    7. 发布组件官网 到 GitHub Pages

    至此,我希望的组件库编写已经完成,既可以全量引入,也可以按需引入。那么如何让别人能够看到我们的组件库呢。这里我使用github pages

    github 配置

    运行npm run deploy可将文档部署至github的github pages上。这相当于你组件的官网。请确保github组件仓库的设置如下:(Path: Settings => Options => GitHub Pages:)
    教你使用Dumi和father-build快速搭建React组件库

    我们可以看到生成的地址https://yezizhao.github.io/biz-web-library/,它包含了厂库的名称,因此你访问改地址时,会发现jscss出现404不能访问了。此时不要慌,说明打包产生的路径不正确。在.umirc.ts文件中,将let BaseUrl = '/biz-web-library';修改即可。然后在重新运行npm run deploy进行发布即可。

    import { defineConfig } from 'dumi';
    
    let BaseUrl = '/biz-web-library'; // 仓库的路径
    
    export default defineConfig({
      // 网站描述配置
      mode: 'site',
      title: 'Biz Library',
      favicon: BaseUrl + '/images/favicon.ico',
      logo: BaseUrl + '/images/photos.svg',
      description: '用于Biz Web Dev 前端组件开发。',
    
      // 打包路径配置
      base: BaseUrl,
      publicPath: BaseUrl + '/', // 打包文件时,引入地址生成 publicPath/xxx.js
      outputPath: 'docs-dist',
      exportStatic: {}, // 对每隔路由输出html
      dynamicImport: {}, // 动态导入
    
      hash: true, //加hash配置,清除缓存
      manifest: {
        // 内部发布系统规定必须配置
        fileName: 'manifest.json',
      },
    
      // 多国语顺序
      locales: [
        ['en-US', 'English'],
        ['zh-CN', '中文'],
      ],
    
      // 主题
      theme: {
        '@c-primary': '#16c35f',
      },
    });
    
    

    dumi css丢失

    现在,你的网页可以访问了,但是此时的css却不见了。其实是因为 md中引入的css是指向构建后的目录,不能直接指向源码目录。我是在package.json中配置sideEffects解决了该问题。

    "sideEffects": ["./src/**/*.less"],
    

    78. 结束语

    至此,一个简易的组件库开发环境和发布环境就已经搭建完成,但是上面的例子其实是用的公网的github。而公司内部组件并不应该发布到公网,因此你还需要搭建一个内部的私有npm。就不进行描述了。

    • 私有库搭建
    • nrm

    github example实例: github.com/YeziZhao/bi…


    起源地下载网 » 教你使用Dumi和father-build快速搭建React组件库

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元