# 博睿组件库(bonree-design)

博睿组件库严格遵循博睿最新 UI 规范，基于 ant-design 进行二次开发，实现一套博睿统一 UI 组件库。

在对 ant-design 组件兼容的前提下，结合博睿的业务场景，提供更多的公共组件能力。

为了便于组件库维护与质量，`bonree-design`与 [antd-4.17.4](https://github.com/ant-design/ant-design/tree/4.17.4) 保持一致并固定此版本。

## 一、组件库整体架构

![image](/download/attachments/25460942/企业微信截图_20220921142628.png)

`bonree-design`中每一个组件的功能都封装在 rc 组件中，rc 组件由社区维护，rc 组件可以当作独立的第三方组件在所有 react 环境中使用。 `bonree-design`本质是对 rc 组件样式进行统一封装。

`bonree-design`引入的 rc 组件如下图：

![image](/download/attachments/25460942/企业微信截图_20220921143644.png)

当部分 rc 组件不能满足博睿 UI 规范功能时，我们需要 git clone 对应 rc 组件，当作 bonree 组件由我们来维护。

## 二、主要文件目录

```
├── components
└── button # 组件源码和demo
└── demo # 组件demo
└── style # 组件样式
└── button.tsx # 组件源码
└── index.zh-CN.md # 组件说明和API文档
├── docs # 文档markdown内容
├── site # 文档网站布局和代码
├── _site # 执行npm run site命令生成的文档编译文件，用于发布组件库文档网站
├── dist # 执行npm run build命令生成的全量js文件和css文件，用于发布npm包
├── es # 执行npm run build命令生成的按组件划分的es6文件和样式文件，用于按需引入和发布npm包
├── lib # 执行npm run build命令生成的按组件划分的es5文件和样式文件，用于按需引入和发布npm包
└── package.json
```

## 三、本地开发

### git 分支说明

- master

与 antd-4.17.4 代码保持一致，用来与 antd 仓库同步，不要在此分支上做任何改动

- bonree-green

用于绿色系 UI 规范开发

- bonree-blue

用于蓝色系 UI 规范开发

蓝色系 UI 规范推出时间晚于绿色系规范，bonree-blue 分支基于 bonree-green 分支开发，**只能将 bonree-green 分支合并到 bonree-blue**,不能反过来合并。

### 安装依赖

```shell
$ npm install
```

### npm install 时 node-gyp 报错解决方案：

1、 mac 环境报错

[点击查看解决方案](https://github.com/nodejs/node-gyp/issues/1779#issuecomment-502456135)

[如何查看 npm 全局安装路径](https://juejin.cn/post/6946594249093677069)

2、windows 环境下 node-gyp 提示要安装 Python

```shell
Run CMD as Administrator:
npm --add-python-to-path='true' install --global windows-build-tools
```

如果安装 windows-build-tools 失败，可以尝试[安装 python](https://segmentfault.com/a/1190000023271417)

### 启动开发模式

```shell
$ npm run start
```

### 启动开发模式时遇到了报错

![image](/download/attachments/25460942/image-20220928155504751.png)

原因：webpack 版本 5.37.1 太高的原因

解决：npm install --save-dev webpack@4.46.0 降低 webpack 版本

## 四、构建发布

### 构建

> 执行 build 命令之前，需将 package.json 中的 name 加上`-antd`后缀，要不然会编译报错。

```shell
$ npm run build
```

### 发布

1、更改 package.json 中 version 字段为最新版本号。

2、 执行一下命令：

> 执行 pub 命令之前，需去除 package.json 中 name 的`-antd`后缀，要不然会发布失败。

```shell
// 如果没有登录npm账号，请先登录
// 登录前确定当前源是https://registry.npmjs.org/ bonree-design发布包时是发布到官方源下面
npm login
Username: 填写 npm 用户名（bonree_psc）
Password: 填写 npm 登陆密码（bonree@2021）
Email: 填写 npm 登录邮箱（psc_fe@bonree.com)
Enter one-time password: 填写验证码（新电脑登录时psc_fe@bonree.com会收到来自npm官方的验证码邮件）

# 出现下面这句表示登录成功
Logged in as **** on https://registry.npmjs.org/.

// 已经登录npm账号，可跳过登录步骤
$ npm run pub


// 同步更新npm包到淘宝源
$ npm run sync
```

> 注意
>
> 1. npm 官方源不允许删除包，发包前请确保包名称、版本号正确。
> 2. 包发布到 npm 官方源，立即执行 npm run sync 会有一点概率同步失败。为了避免此问题，请在淘宝源同步操作结束后，查看淘宝源包版本，如果仍是老版本，在网页上再执行一次同步操作。

### 更新组件库文档网站

1. 编译生成文档网站 html、js、css 文件

```shell
$ npm run site
```

2. 进入\_site 文件夹，压缩全部文件，并命名为\_site.zip

```shell
$cd _site
```

3. 打开 shell 软件，连接 10.241.110.35 服务器，然后执行一下操作：

```shell
// 进入组件库文档目录
cd /data/frontend/bonree-design

// 删除压缩文件
rm _site.zip

// 重新上传_site.zip
rz

// 解压缩
unzip -o _site.zip -d dist/
```

## 五、开发指南

### 组件功能

`bonree-design`中组件都是引入 rc 组件并加以简单的封装，在开发过程中，应该尽量通过 rc 组件的各种属性互相搭配来满足博睿 UI 规范。 如果 rc 组件的功能不满足博睿 UI 规范，则需要基于 rc 组件维护一套 bonree 组件。

#### 如何维护 bonree 组件？

```shell
克隆rc组件代码-----》新建开发分支-----》开发调试-----》发布到npmjs-----》调整组件库依赖项
```

1. git clone rc-xxxx 到本地。
2. 根据组件库代码中 package.json 中 rc-xxx 组件的版本号，找到对应的 tag，以此 tag 新建开发分支。
3. 修改 rc-xxxx 代码中 package.json 的 name 字段为 bonree-xxxx。
4. 执行`npm run start`进行本地开发。
5. 执行`npm run compile`进行编译.
6. 在组件库代码中可以通过 npm link、npm workspace、替换组件库 node_modules 中 rc-xxxx npm 包三种方式引入。替换 npm 包的方式的操作：将编译完成后新增的 lib、es 文件夹放入到组件库 node_modules 的 rc-xxxx npm 包中，然后组件库会自动热更新。
7. rc 组件一般都集成修改版本号、编译、发布命令，执行`npm run pub`按照提示操作后就能完成发布发布成功后会自动提交最新版本的更新信息，会收到来自 npm 官方的发布成功邮件 ![image](/download/attachments/25460942/image-20220928155124307.png) ![image](/download/attachments/25460942/企业微信截图_16643497537311.png)
8. 全局替换组件库中 rc-xxxx 为 bonree-xxxx

目前由我们维护的 bonree 组件有 5 个：

![image](/download/attachments/25460942/企业微信截图_20220921144559.png)

> 其中 bonree-cascader、bonree-tree-select 并没有改动代码，只是更新其 packa.json 中 bonree-select 依赖版本。

### 组件样式

> 基本原则： 多覆盖，少修改

`bonree-design`将 UI 规范中的投影、圆角、字体、色彩规范以 less 变量的形式统一维护在以下三个主题文件中：

- `components\style\themes\default.less`
- 默认主题
- `components\style\themes\dark.less`
- 暗黑主题，基本上用不到
- `components\style\themes\variable.less`
- css 变量主题，antd-4.17.0 新增的主题，内容和 defaul 主题一致，一些基础的颜色会保存在 css 变量中方便网站换肤操作

每一个组件的 less 样式文件会引用主题 less 文件,进而可以使用主题变量。

**执行不同 npm 命令，使用的样式主题不一样：**

- 执行打包命令`npm run build`，通过`.antd-tools.config.js`将`@root-entry-name:default;`插入到`lib|es`目录下的 `index.less` 文件，同时通过`.antd-tools.config.js`设置 less 变量`'root-entry-name': 'default'`将每个组件的样式按照 default 主题编译并生成`lib|es`目录下的 `index.css`

- 执行文档打包命令`npm run site`，通过`site\bisheng.config.js`设置 less 变量`'root-entry-name': ANT_THEME || 'variable'`将每个组件的样式按照 variable 主题编译

#### 样式改动

- 所有样式改动只能注释源代码再新增代码
- css 或者 less 语言缺乏逻辑性，但是互相耦合性又极强，保留源代码可以方便以后进行 debug
- 在`components\style\themes\index.less`中配置主题
- **不要对三个主题文件做任何改动**（非常重要）
- 如果需要覆盖原有 less 变量，必须重新赋值
- 如果需要新增 less 变量，必须以`br-`开头命名变量
- less 变量必须要有注释

```less
// 全局主色
@primary-color: #00ccd9;
// 页面、按钮文字颜色
@text-color: #4e4e4e;
// 字体最大
@br-font-size-largest: 16px;
// 主要用于页面卡片
@br-border-radius-lg: 5px;
```

#### 组件图标

`bonree-design`不能使用博睿图标库`bonree-icons`npm 包，建立`components\_util\bonreeIcons`来维护组件库中所需的博睿图标。

新增一个图标需要按照如下操作：

- 进入[图表库](http://10.241.110.35:8888/icons)找到对应图标，点击图标以获取优化后的图标源码（**图标下方的复制源码是复制完整的 svg 源码，不要点击**）
- 按照以下代码格式在`components\_util\bonreeIcons`目录下新建 Xxxx.tsx 文件

```typescript
import * as React from 'react';
import Icon from '@ant-design/icons/lib/components/Icon';
import { IconProps } from '../type';

const Xxxx = (props: IconProps) => <Icon component={() => 将复制的图标源码复制在此} {...props} />;

export default Xxxx;
```

### 组件 Demo

#### Demo 配置

我们使用[YAML](https://yaml.org/)来设置文档的配置。

```yaml
---
order: 10 // 示例序号（正常的demo应该从0开始到n，debug的demo应该从-1开始-n）,可用来调整示例顺序
title:
zh-CN: 按钮类型 // 中文标题
en-US: Type // 英文标题
hidden: true // 是否隐藏示例
debug: true // 开发模式下不隐藏示例，打包文档文件时隐藏示例
---
```

#### Demo 改动

按照 react 写法修改 jsx 代码块中代码

## 六、 如何更改组件库类名前缀？

目前`bonree-dsign`组件库的绿色系和蓝色系的类名前缀都是`bonree`，这样可以方便在不同项目中进行样式覆盖，但是在微前端使用场景可能主应用是绿色系，而子应用是蓝色系，要达到样式隔离目标，则需要对类名前缀做区分。

我们可以通过修改项目中配置来实现类名前缀的替换，步骤如下：

通过 umi 构建的项目，将类名前缀`bonree`改为`bonree-blue`

```
// 更改config.ts中的babel-plugin-import配置
['import', { libraryName: 'bonree-design', style: false}]
⬇️⬇️⬇️
['import', { libraryName: 'bonree-design', style: true}]


// 更改global.less中的组件库样式引入文件(这一步可以省略，babel-plugin-import的style设为true已经实现按需加载样式)
@import '../node_modules/bonree-design/dist/bonree-design-antd.variable.min.css';
⬇️⬇️⬇️
@import '../node_modules/bonree-design/dist/antd.variable.less';

// themes.ts中新增变量
'ant-prefix': 'bonree-blue'

// 在BrFrame.tsx中<ConfigProvider />组件上新增prefix属性
<ConfigProvider prefixCls='bonree-blue' ... />
```

自行搭建或者通过 create react app 构建的项目，需要修改 less-loader 配置

```
// webpack.config.js
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
+ options: {
+ modules: {
+ auto: (url) => {
+ if (/[\\/]node_modules[\\/](bonree-design)[\\/]/.test(url)) {
+ return false;
+ }
+ return true;
+ },
+ },
+ },
}, {
loader: 'less-loader', // compiles Less to CSS
+ options: {
+ lessOptions: { // 如果使用less-loader@5，请移除 lessOptions 这一级直接配置选项。
+ modifyVars: {
+ 'ant-prefix': 'bonree-blue',
+ },
+ javascriptEnabled: true,
+ },
+ },
}],
// ...other rules
}],
// ...other config
}
```

> 注意：umi 构建的项目中，less-loader 中设置的 less 变量会覆盖 themes.ts 中设置的变量。

## 七、一键换肤

后续补充

## 八、版本号规则

版本号规则：

总体原则：和设计规范的版本号保持相对一致

设计规范：两位版本号

1. 主版本号，稳定版 or 大的设计规范更新
2. 次版本号，设计规范持续优化迭代

组件库：三位版本号

1. 主版本号，和设计规范保持一致
2. 次版本号，和设计规范共用，组件库重要的依赖变化更新则单独更新
3. fix 版本号，组件库单独使用，组件库 fix 问题修复

## 九、常见问题

[antd FAQ](https://ant.design/docs/react/faq-cn)

### form 表单校验错误提示没有实时同步国际化？

[官方 issue](https://github.com/ant-design/ant-design/issues/20704)

form 表单错误提示的中英文切换需要在项目代码中额外添加

```javascript
useEff(() => {
  FormInstance.validateFields;
}, [i18n.local]);
```
