This article is based on my experience building a multi-terminal component library in a business

The background,

1.1 background

  • Team business: C-terminal mall, need to support small programs, H5
  • Team technology stack: Taro+React Multi-terminal

The beating process is as follows: step1: When the department was just established, the business ran very fast, from 0-1 to build multi-terminal mall, giving us almost no time to do technology, so at first, we chosetaro-uiComponent library, use down we found that there are few good component library, and many problems, the official also stopped updating, the last version in April 20

Step2: In order to meet the business requirements, we began to write components directly in the business, and the exposed problems were naturally more obvious: components were difficult to reuse and expand

Step3: So in October, 21, when we added two new businesses of multi-terminal mall, it was foreseeable that a component library was necessary to help the team improve the development efficiency, so we built our own component library while doing business, and released the first version in December, 21 (an article written by a colleague at that time).

Step4: After a quarter, we have made some breakthroughs in technology, such as replacing class with hook, replacing less variable with CSS variable in full, adding ConfigProvider global configuration component, supporting self-defining style prefix, dynamic switching theme… (More on component library Design and Implementation in Part 3)

1.2 Taro-React component library analysis in the industry

Before getting started, we searched the taro-React component library.

Component library introduction

A multiterminal React UI component library based on the Taro framework

Tard is named from Taro React Design short, pronunciation special

Post a few component library renderings first

  1. Component Library official website

2.2 Component Examples

2.3 Component Classification

At present31Two components (all used in our business) +ConfigProvider Global configuration component, divided into6Class, as shown in the figure below

More information about the component library can be found on the official website (url: tard-ui.selling.cn/)

Component library design and implementation

As a component library, the basic requirement consists of three parts

  • Component: THE NPM package that the business actually uses
  • Demo: Component library H5, small program demo; Component usage effects
  • Documentation: Component library official website and documentation, tell others how to use

3.1 Component library specification

Before you start writing code, make sure you have a set of specifications. Unless one person writes components, multiple people can end up writing different component libraries.

During the development process, we often argued with each other for many times. After discussion, we reached an agreement. It was not an easy process. Make the specification as early as possible, otherwise it will be expensive to change it in the middle of the journey, because you don’t want to change the code repeatedly

3.1.1 Code management mode

1, monorepo

Packages include

  • UI: Component library
  • Sites: Component library official website and documentation
  • Demo: Package includes H5, small program Demo

2. UI (component library) code organization

We looked at how other component libraries organize component code. A component includes files such as component type TS files, style files, demos, usage documents. Finally, the code involved in a component is concentrated in a folder, to avoid repeated folder switching to a certain extent and improve development efficiency

3.1.2 Component design specifications

1. Component coding

Use Hook+TypeScript

2. Component naming

Large hump, multi-component to. To expose only one component to an external component, as follows

  • Button, the Button
  • DropdownMenu: DropdownMenu, dropdownmenu.item
  • Dialog boxes: Modal, modal. Header, modal. Content, modal. Action

Component apis

  • The outermost layer of each component requires a packageCompContainerComponents have some general parameters, as follows
    • className
    • style
  • Different components have the same type parameter name, for example
    • The text content of the element: text
    • Display overlay or not: Overlay
    • .

4. Component styles less+BEM+ CSS variables

  • Use uniform prefixes (defaulttard), the effect is as follows
    • CSS: @ – CSS – prefix: tard
    • Js: cssPrefix () {return} ‘tard’
  • Follow the BEM specification
  • Style variables: Component variables rely on base variables and provide a friendlier way to modify component styles than traditional forced style changes
    • Common base variable
    • Component variables: in each component foldervar.lessIn the file
  • Compatible with diverse
    • :root, page{… }

The CSS variable H5 takes effect when mounted under :root. Small programs take effect when mounted under Page

3.2 Custom Style prefixes

You can call the configProvider.config configuration method to set the component’s class prefix name, which is tard by default, for example, custom

// entry js file
import { ConfigProvider } from 'tard'
ConfigProvider.config({
    cssPrefix: 'custom'
});
Copy the code

You also need to configure the style file prefix name, in the entry style file configuration as follows

@--css-prefix: 'custom'
Copy the code

Configprovider. config cssPrefix must be the same as @–css-prefix. Otherwise, the class name does not correspond to the style and the style is invalid

3.3 Customizing themes

Theme customization is essential as the most basic feature of a component library, and falls into two categories

  • Customizing themes at compile time; This type is most common and supported by basic industry component libraries. It is usually overridden by custom style variables or handled in combination with packaging tools such as WebPack configuration Loader
  • The runtimeCustom theme: generally, the front end provides centralized mode for users to switch or get theme data through the interface; The former commonly used scheme in the industry has several sets of style variables built in the front end to switch, while the latter is generally required in the decoration scene. Our business involves this, so we provide itConfigProviderImplement runtime switchover, as detailed in 3.3.2

3.3.1 Customizing CSS Variables

In the case of the Button component, you can view the style of the component in the official website documentation. You can see the following variables in the name of the Button class

:root.page {
  --button-height: 76px;
  --button-default-v-padding: 40px;
  --button-min-width: 192px;
  --button-min-width-mini: 120px;
  --button-height-mini: 32px;
  --button-mini-text-size: 24px;
  --button-mini-v-padding: 6px;
  --button-min-width-small: 144px;
  --button-height-small: 56px;
  --button-small-text-size: var(--font-size-base); --button-small-v-padding: 24px;
  --button-min-large-width: 360px;
  --button-large-height: 96px;
  --button-large-text-size: var(--font-size-lg); --button-large-v-padding: 48px;
  --button-radius: var(--border-radius-md);
}
Copy the code

(1) CSS coverage

You can override these CSS variables directly in your code, and the style of the Button component changes accordingly:

:root.page {
    --button-radius: 10px;
    --color-primary: 'green'
}
Copy the code

The default values for these variables are defined on the root node and can be accessed by any node in the HTML document

This is also a common solution for customizing themes at compile time

(2) Overwrite using ConfigProvider

The ConfigProvider component provides the ability to override CSS variables. You need to wrap a ConfigProvider component around the root node and configure theme variables using the style property

This makes it possible to change themes dynamically at run time

 // For example, button-radius is converted to '--button-radius'
<ConfigProvider style={{ 'button-radius': '0px'.'color-primary': 'green'}} ><Button className="button-box__item" type="primary">The main button</Button>
</ConfigProvider>
Copy the code

Note: ConfigProvider only affects the styles of its child components, not the global root node

3.3.2 Dynamic themes at runtime

In the websiteConfigProvider ConfigProvider global configurationYou can experience dynamic theme change onlinecallConfigProvider.configSetting Method Set the theme color

ConfigProvider.config({
    theme: {
        'color-primary': 'purple'."button-radius": '20px'}});Copy the code

3.4 Document Implementation

3.5 Packaging Implementation

4. Component library construction experience

This part mainly write component library construction experience, if the above is the technical experience, this part is the experience of people and things, after all, a component library to make and can continue to expand is really not easy, even more difficult than technology

4.1 Birth Path

In fact, the process of making this component library was very difficult at the beginning, there was no professional UI support; On the one hand, the UI resources are tight, and on the other hand, the team has no corresponding KPIs to build the component library, which is only used to satisfy the business

We are responsible for packaging components for other colleagues to use, write business colleagues components urgent, we are using the business design draft to achieve components, such as the business design draft dropdown menu zhang so, we will be implemented in accordance with the business design draft, there is no way…

But component libraries can hardly help the business without the UI, after all, the UI gives the design to the front end; Is it possible to meet this one business, there are similar scenarios behind? As a result, the early component library is in a non-standard situation

Turning point appeared in the process of writing business, we found that the same business of different page design is not unified, such as button rounded corners, screening list screening conditions… Because we will be encapsulated into a component, then the corresponding style must be relatively fixed, because the design style of a system is definitely need to maintain consistent, in addition to being able to change by style variables, so we are discussing with the UI students in the process of discussion, we revealed the thought of component library, the necessity of visual specification is consistent, It can improve front-end development efficiency and UI design efficiency

Then a UI colleague was interested in it, so we talked about it a lot and spent time to support us privately. UI colleagues helped design the official website

4.2 Looking for breakthroughs

In the middle of the process, we tried to communicate with the supervisor that there is no UI in the component library. Could we coordinate with the supervisor that the component library we made needs UI support? However, currently there is no UI to support, and the focus is to meet the business, so the component library has not invested resources

Out of interest or out of the mentality of learning technology, we have three front-end + one UI to do a good job in the component library, so we began to learn from the technical implementation of the component library industry, how to combine the design language and front-end code

If the design gives the style of a button, she needs to know what the button element should include (width, height, font, interior spacing, etc.). These are the design specifications, and the values of these specifications are the design language. What is the logic behind the content, the principles of the specification that can be abstracted from the design principles

Here the design language corresponds to the front end, which is the style variable

UI colleagues started to draft each component, and each component had a design in different forms; The front end began to formulate specifications. When implementing components, we considered whether the API and style variable definitions were standardized, supplemented the demo and documents of components, and carried out code review

The weekly meeting mechanism has been established, and the path for a component to meet the requirements from design draft design, front-end development, code review and UI review is as follows

I began to design the official website of the component library. I wanted to make the component library bigger and stronger, and really help large departments and multi-terminal businesses (the dream is still there).

We were in full swing, though quarrelling frequently, very happy!

We know that the visual specification of the component library can only play a role under the premise that the major departments agree with it. Therefore, when our component library has a good shape, we reported our results to the supervisor, hoping that the supervisor can coordinate the UI and front end of the major departments to unify the specification

These reports (or the future planning of the component library) can also be considered as a recognition of the overall value of the component library (or the higher level of c-side visual specification unification) when we are making the component library. These are also summarized by referring to a lot of materials, which are roughly as follows

May write are more ideal, we can be rational reference… That was our goal, but we don’t have the time The future planning

4.3 the wrong way

Originally, it is a good thing that technology can really help business, ideal is beautiful, reality is difficult, late Q1, maybe resource coordination is really difficult, coupled with the frequent adjustment of the organizational structure, visual unity and construction is difficult to be implemented, so the component library really meets the business is the best choice

Write in the last

The reason for writing this article and making the component library open source is that we hope to give you some experience with the holes we have trod through, and if you are interested in making the component library open source, or if you need the taro-React multi-terminal component library, you can try using TARD

GitHub address: github.com/jd-antelope…