This article introduces the necessity and practical operation of a cross-framework component library. The title caught my interest, so I'll provide a quick review. I will quote the original article, and my understanding and thoughts will be marked as my own.
OpenTiny is a component library developed by Huawei, which includes TinyNG, TinyVue, TinyEngine, and other components.
The ability to output a unified set of component libraries and APIs that can be used across different technology stacks can enhance user confidence, increase development efficiency, and achieve consistent UI performance across different technology stacks. Additionally, it helps establish a reputation for your own component library and explore potential users.
Of course, there are challenges involved. It requires abstracting logic and smoothing out differences between different solutions.
This is the architecture diagram provided by the official source. The diagram and the article may not be very well-explained, but "Talk is cheap, show me the code." The article provides a GitHub repository demo that can help with understanding.
The article mentions two technologies or approaches, abstracted as follows:
- Common adaptation layer
- Renderless layer without rendering logic
For example, a tab menu or button can be divided into UI presentation and logic. UI presentation can be classified under the common adaptation layer, while inputs and outputs can be classified under the logic layer.
pnpm + monorepo to manage the component library.
Technical implementation approach:
Prepare different scripts, such as
solid, and use micro-frontends to achieve management without boundaries.
Some dependencies need to be differentiated between Vue2 and Vue3, so
pnpm.packageExtensions is used for differentiation, which is a usage I haven't seen before.
- The article gives an example of how to simultaneously support React and Solid. First, define
- Also, create the
- Interestingly, the article mentions the purpose of the
ahooksdependency, which is to provide reactive capabilities in React similar to Vue's reactive data. It's funny to see that: https://ahooks.gitee.io/zh-CN/hooks/use-reactive
- Solid itself is based on Signal and comes with reactivity.
- React uses
ahooksto simulate reactive data.
- Simulating Vue's
- Simulating Vue's
The article provides an example of how to write React and Solid code, implementing
useSetup returns the content of the render method.
Code is omitted.
Understanding Renderless Logic#
This part of the code can be divided into two parts:
- Framework-related entry functions
- Framework-independent pure functions
The article is not very clear, and after reading it several times, I'm still a bit confused. It may require practical implementation to fully understand.
Taking the button component as an example, it needs to implement the click event and the timer for disabling repeated clicks on different platforms.
For example, in the renderless approach, how to write code for React and Solid is similar. Both need to implement the
renderless method, which returns the
state and the methods that need to be referenced, such as
timer. Since this is the adaptation layer, it only focuses on defining common state and framework-related methods.
index file, the framework-independent logic is implemented. Here, the
timer related logic is implemented.
For the button component:
solid.js, state management and click timer methods are implemented.
- The specific implementation of click and timer is done in
index.jsusing a framework-independent approach.
The general understanding of how the logic is implemented is as follows. Next is the UI presentation, which doesn't involve any black magic. It's just implementing the render method, but React and Vue both support JSX, so the logic is similar.
In the end, a demo example is provided, which makes it much clearer:
packages/components/react as an example, this is the demo content of the React component library. You can see the
common/src/index.js file, which is used to simulate framework differences and define
useSetup. It also exists in Solid, Vue2, and Vue3.
Next, look at
src/button/src/pc.jsx, which defines the UI presentation of the button component.
These two files define the UI part. How is the logic part handled? Let's look at the following diagram:
renderless/src/button is the logic of the button component. The common part is placed in
index.js, and the adaptation part is placed in
Continuing with the example, how is the button component defined in Vue? It is defined in both
Earlier, I mentioned micro-frontends, which is used to create a playground and display different framework effects on a single page.
This corresponds to the
packages/home directory. Here, the micro-frontend
wujie is used to embed different pages.
This demonstrates a design approach for components, abstracting and smoothing out differences.
Given the opportunity, further understanding can be achieved.