---
url: /articles/mpx-cube-ui.md
---
# 小程序跨端组件库 Mpx-cube-ui 开源啦 {#mpx-cube-ui-open-source}

> 作者：[CommanderXL](https://github.com/CommanderXL)

Mpx-cube-ui 是一款基于 [Mpx 小程序框架](https://www.mpxjs.cn/) 的移动端基础组件库，一份源码可以跨端输出所有小程序平台及 Web，同时具备良好的拓展能力和可定制化的能力来帮助你快速构建 Mpx 应用项目。

Mpx-cube-ui 提供了灵活配置的主题定制能力，在组件设计开发阶段对表现层的结构和样式进行抽离，利用预编译器和 CSS 变量的能力，提供细粒度（颜色、字体、圆角、阴影等）的样式定制能力，你的项目可以按需使用主题的编译方案还是运行时方案来满足不同样式风格的业务场景开发。

Mpx-cube-ui 提供了开箱即用的跨端输出能力，源码基于 Mpx 小程序框架进行开发，依托于 Mpx 提供的[跨平台能力](2.0.md#跨平台开发)即基于微信小程序跨平台编译输出为支付宝、百度、QQ、头条等目标平台的小程序代码，同时还可以输出到 Web。

接下来会通过这篇文章去分享一下 Mpx-cube-ui 是如何诞生的。

## 业务现状 {#business-status}

### 集团产品的迭代 {#group-product-iteration}

越来越多的业务产品开始借助小程序的渠道来拓展产品的推广和使用，不同的技术团队承接的不同业务产品方向的需求。在滴滴所有的小程序产品当中，滴滴出行小程序作为最大的C端流量入口，承接了不同业务产品流量分发。在具体到小程序产品的研发环节，不同业务的小程序都被集成到了滴滴出行小程序当中，一同打包上线并发布。
当然在这种跨业务、技术部门的产品研发当中，不同的技术团队都会有自身配套的基础能力建设。就拿小程序的组件库来说，每个独立的业务产品都会依据对应的交互设计规范来搭建一套满足自身业务述求的基础组件用以提高日常的业务开发效率，例如按钮、半浮层弹窗、Toast、Dialog、表单等等。

### 团队内的业务迭代 {#team-business-iteration}

除了跨业务产品研发的场景外，在同一个技术团队内部也可能会承接来自不同业务产品方向的需求，这些不同业务产品同样也会有独立发展迭代的述求。由于业务场景的约束，团队内部同样也会面临如何做基础能力的沉淀和复用的议题，在节省研发资源的同时去提升业务项目交付的质量和效率。

那么在不同的业务产品发展初期，为了快速交付产品的功能保障上线时间，研发侧会尽量利用之前已有的基础能力来快速搭建产品功能。就拿小程序组件库的复用来说，常见的方式有：

* 直接侵入到原有的组件代码当中进行 Hard Code，不同的业务产品依赖同一份组件代码，利用一些 if/else 或者条件编译等手段来使得原有的组件在满足最新的业务述求的同时，还要确保不会影响到原有的业务使用；
* Fork 一份原有组件库的代码，在此基础上单独迭代维护，做到和原有组件的彻底隔离而不会造成污染；

对于第一种方案来说：组件本身因为增量的差异化需求使得组件本身的维护成本变高，同时对于差异化的代码处理难免在编译打包环节出现代码冗余问题，也就是原本不属于当前业务产品的代码实现也被一同打包；
对于第二种方案来说：组件库维护的数量变多，使得后续的组件迭代和更新需要修改多处代码；

此外，在小程序的场景下还面临着包体积等平台规范的硬性约束，特别是对于像滴滴出行小程序这种体量大的小程序来说，众多小程序业务产品被集成到同一个小程序当中，包体积也是日常研发过程中重点关注的一个指标。模块或组件的可复用性好、可拓展性强也意味着不需要重复去开发同一份功能相同代码，随之代码包体积也不会因重复实现相同功能而增速过快。

## Mpx 技术生态 {#mpx-tech-ecosystem}

在 Mpx 整个技术生态当中，组件体系目前是不完备的。

在我们目前使用 Mpx 去搭建实际的业务产品的过程中，我们基于小程序平台的基础组件去搭建了特定业务场景的基础业务组件，因为业务场景、功能和代码实现等各方面的原因，这些业务场景的基础组件是没法开放给社区的 Mpx 开发者来使用的。因此对于社区来说，要么只能同样基于平台的基础组件去开发上层基础组件，或者是使用第三方的原生小程序组件库，不管哪种方式对于社区的开发者而言，都有不少的上手和开发成本。

因此在社区当中也有比较强的述求，期望 Mpx 能提供更为基础通用的组件来更好的支持上层的业务开发。

## 组件库自身的维护 {#component-library-maintenance}

* 文档示例一体化

不管是我们内部维护的业务组件库还是之前我们开源的基于 Vue 的 Web 组件库 [Cube-ui](https://didi.github.io/cube-ui/#/zh-CN)，组件本身的文档示例也是在组件库迭代过程中也是比较占用时间精力的，在示例和文档方面往往需要重复写多份文案，还要确保它们之间是同步更新的。那么针对组件库自身的维护，如何尽量减少组件库本身的维护成本也是我们需要深入思考的一部分工作。

以上这些问题促使我们重新思考整个 Mpx 组件体系的构建和发展。

## Mpx 组件体系 {#mpx-component-system}

经过业务的长期迭代和验证，Mpx-cube-ui 作为 Mpx 技术生态当中组件体系的基础设施：脱离于业务的基础组件库，同时又要有良好的拓展能力和可定制化的能力来更好的支持上层业务。

![组件分层设计](https://gift-pypu-cdn.didistatic.com/static/driver_miniprogram/do1_6wEnx7fVXGlK8hILtuYa)
在整个组件体系的搭建过程中，我们依据组件的特性将组件拆分为如下几种类型：

* 业务组件一般来源于某一个具体的产品功能，用以解决特定问题域，更加强调关注点分离，代码的维护成本；
* 基础业务组件一般来源于某一类的业务产品，在特定的业务背景下抽象的比较通用的，较少糅合业务逻辑，介于基础组件和业务组件之间，强调解决效率，可复用性，可维护性；
* 基础组件一般来源于我们设计交互元语言，用以定义业务产品和用户的交互、反馈，更加强调一致性，效率，可复用性；

底层的基础组件（可组合性、可拓展性、稳定性）是为了更好的服务于上层的（基础）业务组件。

从底层的基础组件到业务组件（由下至上），组件的业务属性越来越强，所要解决的问题域更加聚焦，更贴合具体的问题和场景，同时它们的可复用性也随之降低。

## Mpx-cube-ui 组件设计 {#mpx-cube-ui-design}

这里通过乘客交易、司机运营两个不同业务方向的组件来举例说明 Mpx-cube-ui 在组件的设计和开发当中所做的一些思考。
在这两个业务场景当中都有 Modal 半浮层组件，不过在司乘业务不同的设计规范约束下，组件间的差异还是比较大的。

![mpx-cube-ui-modal](https://gift-pypu-cdn.didistatic.com/static/driver_miniprogram/do1_1EABWsPUeVHTim2iwTUf)

那么为了解决上文当中组件库在跨业务产品的的可复用性、可拓展性的问题，核心所遵循的原则是：

**弱化不同业务场景的设计规范（去业务），回归到组件本身的行为（逻辑）、结构和样式（表现）：**

* 行为，组件所特有的行为方法：展示（show），隐藏（hide），关闭（close）；
* 结构，方便组件间的重新组合：头部区，标题区，内容区，底部操作区；
* 样式，方便业务场景的主题定制：颜色、字号、圆角、边距等；

![组件设计原则](https://gift-pypu-cdn.didistatic.com/static/driver_miniprogram/do1_ceWLvE8RbZIIduHHTdtu)

对于 Mpx-cube-ui 组件的主题定制有个简单的逻辑关系：

* 全局基础样式变量：提供了基本色值、字号等，会影响到所有组件的展示；
* 组件样式变量：对于基本的色值、字号等继承于全局基础变量，涉及到组件自身的结构、样式变量会单独定义；
* 组件渲染样式：直接依赖组件样式变量；

![mpx-cube-ui-modal](https://gift-pypu-cdn.didistatic.com/static/driver_miniprogram/do1_b4uBKbP8yIwdip7pBZAq)

通过定制[全局基础样式变量](https://www.mpxjs.cn/mpx-cube-ui/guide/design-tokens.html)和[组件样式变量](https://www.mpxjs.cn/mpx-cube-ui/components/base/button.html#css-variable)都能达到定制主题的目的，有关主题定制的功能具体参见[文档](https://www.mpxjs.cn/mpx-cube-ui/guide/theme.html)。

在 Mpx-cube-ui 实现的定制主题的方案当中是利用预编译器和 Css Varaibles 的能力来提供细粒度的样式定制能力：

![业务架构图](https://gift-pypu-cdn.didistatic.com/static/driver_miniprogram/do1_3ZVcQITsryAG4k96hFrH)

* 利用预编译器可编程的能力，在编译阶段就可以完成主题能力的定制，当你的业务项目作为独立应用迭代，可以只利用预编译器的能力，从而使得你的 css 代码体积尽可能的小；
* 利用 Css Varaibles 的能力，可以解决更为复杂的场景，例如同一个组件在巨型应用当中，在不同业务场景页面需要有不同的主题样式；

在[官网示例](https://www.mpxjs.cn/mpx-cube-ui/guide/intro.html)当中可以直接体验主题切换功能。

## 未来的规划 {#future-plan}

1. 开源更多我们内部所沉淀出的基础组件，去满足多样化的业务场景开发；
2. 将文档示例一体化的能力独立打包开源，用以组件库的快速建站以及降低文档、示例代码的维护成本。
