<h1 align="center">rux-design</h1>
ruxd 是基于 中国联通软件研究院政企中台 设计体系的 React UI 组件库，并支持各中台设计体系开发的 UI组件库


## 1. 本地开发

### 1.1 前序准备

我们的技术栈基于 ES2015+、React、dumiJS 、umiJS、webpack、 antd等，提前了解和学习这些知识会非常有帮助

### 1.2 组件库

##### 环境要求

- 首先得有 [node](https://nodejs.org/en/)，并确保 node 版本是 10.13 或以上。（mac 下推荐使用 [nvm](https://github.com/creationix/nvm) 来管理 node 版本））

```bash
$ node -v
v10.13.0
```

- 推荐使用 yarn 管理 npm 依赖，并[使用国内源](https://github.com/yiminghe/tyarn)（阿里用户使用内网源）。

```bash
# 国内源
$ npm i yarn tyarn -g
# 后面文档里的 yarn 换成 tyarn
$ tyarn -v
```

##### 底层框架

- 基于[umi3.X](https://umijs.org/zh-CN) 版本以上前端底层框架
- 使用 [dumi](https://d.umijs.org/zh-CN) 文档工具
- [father](https://github.com/umijs/father) + webpack 组件打包 
- 集合[antd4.x](https://ant.design/components/overview-cn/) 版本以上 UI组件库

##### 框架实现功能

- [x] 实现无antd JS源码并且不打包源码情况下，通过依赖导出antd 组件，antd升级只需要依赖升级即可
- [x] 导出自定义组件
- [x] 组件文档查看以及部署
- [x] 灵活定制主题，现系统默认定制符合政企中台规范样式的主题
- [x] 配置按需加载ruxd，在demo中引用，可去掉antd引用或者相对路径引用组件。（demo如果引用antd，则在文档demo中主题未跟着系统主题设置）
- [x] 脚本配置，在package.json中，配置了多个命令，可执行，其中包含了私有库发布
- [x] 支持jest框架的自动测试
- [x] prettier前端代码格式化
- [x] eslint代码校验



### 1.3 安装源码

从[天梯](http://10.124.128.2:8888/unilab/frontend/uni_design)中安装uni-design最新代码

```bash
$ git clone --depth=1 http://10.124.128.2:8888/unilab/frontend/uni_design.git

```

### 1.4 目录结构

```javascript
|--- dist                                # 源码编译生成的目录
|--- docs                                # 组件库文档目录
|    |--- index.md                       # 组件库文档首页
|    |--- guide                          # 组件库文档其他路径
|    |    |--- index.md                       
|--- es                                  # 源码编译生成的目录
|--- lib                                 # 源码编译生成的目录
|--- public   
|--- scripts                             # 存放脚本目录
|--- src                                 # 组件库源码目录                  
|    |--- assets                         # 静态资源 
|    |--- count-down                     # CountDown组件库源码
|    |    |--- __tests__                 # 测试文件目录
|    |    |    |--- index.test.js              
|    |    |--- demo                      # 模板目录
|    |    |    |--- base.md              # 基础语法
|    |    |--- style                     # 样式目录
|    |    |    |--- index.less           
|    |    |    |--- index.tsx            # 页面样式入口（按需加载使用））
|    |    |--- index.tsx                 # 组件源码
|    |    |--- index.md                  # 组件文档
|    |--- locales                        # 国际化
|--- .babelrc    
|--- .editorconfig
|--- .fatherrc.js                        # father打包工具配置文件
|--- .gitignore                          
|--- .prettierignore                     
|--- .prettierrc                         
|--- .umirc.ts                           # dumi配置文件(也可以是config/config.ts)
|--- .fatherrc.js                        # father打包工具配置文件
|--- package.json                        # 依赖包配置文件
|--- README.md                      
|--- tsconfig.json                       # typeScript配置文件
|--- typings.d.ts  
|--- webpack.config.js 
|--- yarn.lock

```

### 1.5 本地开发

#####  安装依赖

```bash
$ yarn
yarn install v1.21.1
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.71s.
```
#####  启动项目

```bash
$ yarn start
Starting the development server...
✔ Webpack
  Compiled successfully in 17.84s
 DONE  Compiled successfully in 17842ms                                       8:06:31 PM
  App running at:
  - Local:   http://localhost:8000 (copied to clipboard)
  - Network: http://192.168.12.34:8000
```

- 在浏览器里打开 [http://localhost:8000/](http://localhost:8000/)，能看到以下界面
- 因为umi升级，不再支持自动打开浏览器，所以需要手动打开

### 1.6 组件开发

开发带有图片裁剪功能的ImageCrop 组件

##### 开发步骤
1. 创建文件夹ImageCrop，文件名不支持驼峰式命名，多单词用 “-” 链接
2. 创建index.ts 编写组件源码
3. 创建demo文件夹，增加base.tsx 增加组件基础例子
4. 在src/index 中导出ImageCrop 组件
5. 创建index.md 编写ImageCrop文档API，增加demo的应用。格式规范查看文档[dumi](https://d.umijs.org/zh-CN/guide)
6. 创建style文件夹，并在其文件夹下创建index.tsx，用于组件源码样式引用。另外文件中引用项目定义好的一些样式变量。 

##### 修改组件样式

如果组件样式不满足规范样式，可以在src文件夹下找到对应组件的文件夹。在其style中找对应主题文件中，修改其引用变量，以达到满足。[参考less](https://less.bootcss.com/)


### 1.7 多主题开发（以公众平台为例）

1、在src/style/themes路径下增加主题配置文件pop.less,并将配置的变量放在文件中
```less
...
@primary-color: #E50017;
...

```

2、在src/style路径下增加pop.less,增加对主题变量的引用

```less

@import './themes/pop.less';
@import './core/index';

```

3、在Scripts 文件中创建 pop-vars.js,并获取主题文件的变量,注意修改读取文件名

```javascript
const fs = require('fs');
const path = require('path');
const lessToJs = require('less-vars-to-js');

const stylePath = path.join(__dirname, '..', 'src', 'style');
const popLess = fs.readFileSync(path.join(stylePath, 'themes', 'pop.less'), 'utf8');

const darkPaletteLess = lessToJs(popLess, {
  stripPrefix: true,
  resolveVariables: false,
});

module.exports = darkPaletteLess;
```
4、在webpack.config.js 中，增加配置的新竹主题，并使用webpack多配置文件打包。

```javaScript
...
const popVars = require('./scripts/pop-vars');
...
const defaultConfig = webpackConfig();
const webpackPOPConfig = webpackConfig();

processWebpackThemeConfig(webpackPOPConfig, 'pop', popVars);

module.exports = [...defaultConfig, ...webpackPublicConfig];

```

5、scripts/finalizeDist.js文件中构建主题

```javascript
/**
 * 在lib/style文件中，新增components.less,作用引用所有组件的样式
 */
...
const popVars = require('./pop-vars');
...

function finalizeDist() {
  if (fs.existsSync(path.join(__dirname, '../dist'))) {
    // Build less entry file: dist/antd.less
    fs.writeFileSync(
      path.join(process.cwd(), 'dist', 'ruxd.less'),
      '@import "../lib/style/index.less";\n@import "../lib/style/components.less";',
    );
    // eslint-disable-next-line no-console
    fs.writeFileSync(
      path.join(process.cwd(), 'dist', 'theme.js'),
      `const defaultTheme = require('./default-theme.js');\n`,
    );
    // eslint-disable-next-line no-console
    console.log('Built a entry less file to dist/ruxd.less');
    buildThemeFile('default', defaultVars);
    buildThemeFile('pop', popVars);

    fs.writeFileSync(
      path.join(process.cwd(), 'dist', `theme.js`),
      `
function getThemeVariables(options = {}) {
  let themeVar = {
    'hack': \`true;@import "\${require.resolve('antd/lib/style/color/colorPalette.less')}";\`,
    ...defaultTheme
  };
   if(options.public){
    themeVar = {
      ...themeVar,
      ...popThemeSingle
    }
  }
  return themeVar;
}

module.exports = {
  popThemeSingle,
  getThemeVariables
}`,
      {
        flag: 'a',
      },
    );
  }
}

finalizeDist();
```


### 1.7 注意事项
1. 自定义组件命名不支持驼峰式，多单词用-链接，因为兼容antd命名规范，且按需加载引用名默认引用

2. 开发需要使用自定义类名，尽量使用前缀变量，便于灵活配置以及维护

```less
@import '../../style/themes/index';

.@{rux-prefix}-uploadSize {
  .ant-upload {
    height: 200px;
    width: 200px;
  }
}
```
3. 私有库发布脚本使用 simple-git校验git-commit，check只有在master分支且代码已经提交情况下才会进行发布

4. demo中引用组件从ruxd
```javascript
import {Button} from 'ruxd'
```

### 1.8 什么时候不用ruxd
1. 需要支持 IE 8 或更低版本的浏览器
2. 需要支持 React 16.8.0 以下的 React
3. 需要跑在 Node 10 以下的环境中
4. umi 版本在3.0以下版本
5. antd 版本在4.0以下版本

---
## 2. 业务系统使用

### 2.1 环境要求

1. react 16.8 版本以上 
2. umi3.X 版本以上
3. antd4.X 版本以上

### 2.2 安装

##### 切换镜像

通过切换npm或yarn 镜像至天梯私有库地址

```bash
$ npm config set registry  http://ccp.tianti.tg.unicom.local/artifactory/api/npm/npm-virtual/

```

##### 安装依赖

```bash
$ npm install ruxd@1.0.1

```
### 2.3 配置主题

1、配置默认主题

通过umi配置文件可配置使用主题（config/config.js或.umirc.ts中）

```javascript
import defaultTheme from 'ruxd/dist/default-theme';
export default {
  ...
  theme:defaultTheme,
  ...
}
```

2、配置其他主题，通过import 引用其他主题文件,
-以公众中台为例：
```javascript
import popTheme from 'ruxd/dist/pop-theme';
export default {
  ...
  theme:popTheme,
  ...
}
```

### 2.4 配置按需加载

通过umi配置文件配置组件按需加载（config/config.js或.umirc.ts中）
- 使用按需加载组件，默认引用政企中台规范主题，并支持通过theme改变主题色。
- 如果想使用antd默认样式，则不需要配置按需加载，且在全局less中引用css方式即可。
```
extraBabelPlugins: [
    [
      'import',
      {
        libraryName: 'ruxd',
        libraryDirectory: 'lib',
        style: true,
      },a
      "ruxd"
    ],
  ],
```

### 2.5 使用

```javascript
import React from 'react';
import { Button } from 'ruxd';

export default function Loading() {
  return (
    <div>
      <Button type="primary">按钮</Button>
    </div>
  );
}

```

### 组件实现功能

- [x] 引用全部antd组件和自定义组件（封装了antd design pro V2组件）
- [x] 组件库默认主题以及组件样式更改成政企中台规范样式，且满足各平台自定义
- [x] 满足业务系统按需加载，且业务系统可通过umi 配置[定制主题](https://ant.design/docs/react/customize-theme-cn)

### 参考文献

- [Umijs](https://umijs.org/zh-CN/docs)
- [DumiJS](https://d.umijs.org/zh-CN/guide)
- [Antd](https://ant.design/index-cn)
- [father](https://github.com/umijs/father)

