Home >Web Front-end >JS Tutorial >Teach you step by step how to use Vite+React for component development (Practice)
In the previous article, we introduced the use of TypeScript AST syntax tree parsing to extract React component Props type definitions and comments, and automatically generate component corresponding screenshots, usage, parameter descriptions, README, and Demo wait. It has achieved relatively good response in the community, and the application has also achieved relatively good results in the team. Now a total of 1,000 React components have been deposited using this solution in the internal component system.
Previously we used webpack TypeScript to make a scaffolding kit for developing React components. When developers want to develop components, they can directly use the scaffolding to initialize the corresponding project. structure is developed.
Although the main path does solve the internal problems encountered in component development such as components without pictures and facts, missing component parameter documents, missing component usage documents, missing component Demo, components that cannot be indexed, and non-standard component products, etc. There are problems with component management and deposition, but Webpack's solution will always add an extra layer of compilation to component development. When a component library has more than 300 components, the introduced dependencies will continue to grow, which will still bring a load on component compilation and cause developers to develop Experience decline.
一 The dawn brought by Vite
What Vite brings to the front-end is definitely a revolutionary change, and it is no exaggeration to say so.
Perhaps it should be said that the advanced tools and ideas on JS compilation and development in these communities such as esbuild, Browser es modules, HMR, Pre-Bundling and other communities integrated behind Vite, driven by integration such as Vite, provide front-end development brought about revolutionary changes.
I have long said that the most valuable thing about the emergence of any framework or library must not be its code itself, but the new ideas and new inspirations behind these codes. So when I write articles, I also pay great attention to clearly explaining the entire process of my thinking and final execution.
Why Vite is fast? It is mainly because esbuild performs pre-bundles dependencies and browser native ESM dynamic compilation. I won’t go into too much detail here. Please refer to: Vite: The Problems
In the context of this idea, if we go back to our component development scenario and look at it, we will find that the following issues are highly consistent:
Component library development, actual There is no need to compile all components.
Component development, compilation preview page is mainly used by developers, browser compatibility is controllable.
HMR (hot update) capability is even more immediate with the support of Vite, which was where component development and debugging took the most time in the past.
All source code modules in Vite are dynamically compiled, that is, TypeScript type definitions and JS annotations can also be dynamically compiled, greatly reducing the scope of compilation.
Then, in the past, things like StoryBook and the ideas we used to extract tsx component type definitions will be able to make a relatively big change.
Previously, in order to obtain the type data of component input parameters, a plug-in was made at the Wwebpack level to dynamically analyze the exported tsx component. A static attribute variable of __docgenInfo was dynamically added under the component, and the type obtained from AST analysis was Data and annotation information are injected into the component JS Bundle, which is further processed into dynamic parameter settings:
TypeScript’s definition of component Props
Analysis is injected into the JS Bundle The content in
Analyze the parameter interaction settings implemented after conversion
So for the component, actually get This type definition metadata is redundant for the component itself. Regardless of whether this part of the metadata in the component is used or not, it will be parsed, extracted and injected into the component Bundle during the Webpack compilation process. This is obviously is very inefficient.
In Vite's idea, you can obtain the metadata information when using the component metadata. For example, loading a React component is:
import ReactComponent from './component1.tsx'
Then loading its metadata is:
import ComponentTypeInfo from './component1.tsx.type.json'; // or const ComponentTypeInfoPromise = import('./component1.tsx.type.json');
Load the .type.json file type through the plug-in capability of Rollup in Vite, so as to parse the corresponding component metadata. At the same time, with the help of Rollup's own ability to collect compilation dependencies and HMR, hot updates of component type changes can be achieved.
2 Design Ideas
The above is some inspiration and inspiration I got from seeing Vite’s module loading ideas, so I made a preliminary Imagine.
但如果真的要做这样一个基于 Vite 的 React 、 Rax 组件开发套件,除了组件入参元数据的获取以外,当然还有其他需要解决的问题,首当其冲的就是对于 .md 的文件解析。
1 组件 Usage
参照 dumi 及 Icework 所提供的组件开发思路,组件 Usage 完全可以以 Markdown 写文档的形式写到任何一个 .md 文件中,由编译器动态解析其中关于 jsx、tsx、css、scss、less 的代码区块,并且把它当做一段可执行的 script 编译后,运行在页面中。
这样既是在写文档,又可以运行调试组件不同入参下组件表现情况,组件有多少中Case,可以写在不同的区块中交由用户自己选择查看,这个设计思路真是让人拍案叫绝!
最后,如果能结合上述提到 Vite 的 esbuild 动态加载和 HMR 能力,那么整个组件开发体验将会再一次得到质的飞跃。
所以针对 Markdown 文件需要做一个 Vite 插件来执行对 .md 的文件解析和加载,预期要实现的能力如下:
import { content, modules } from "./component1/README.md"; // content README.md 的原文内容 // modules 通过解析获得的`jsx`,`tsx`,`css`,`scss`,`less` 运行模块
预期设想效果,请点击放大查看:
2 组件 Runtime
一个常规的组件库目录应该是什么样的?不论是在一个单独的组件仓库,还是在一个已有的业务项目中,其实组件的目录结构大同小异,大致如下:
components ├── component1 │ ├── README.md │ ├── index.scss │ └── index.tsx ├── component2 │ ├── README.md │ ├── index.scss │ └── index.tsx
在我们的设想中你可以在任意一个项目中启动组件开发模式,在运行 vite-comp 之后就可以看到一个专门针对组件开发的界面,在上面已经帮你解析并渲染出来了在 README.md 中编写的组件 Usage,以及在 index.tsx 定义的 interface,只需要访问不同的文件路径,即可查看对应组件的表现形态。
同时,最后可以帮你可以将这个界面上的全部内容编译打包,截图发布到 NPM 上,别人看到这个组件将会清晰看到其组件入参,用法,截图等,甚至可以打开 Demo 地址,修改组件参数来查看组件不同状态下的表现形态。
如果要实现这样的效果,则需要一套组件运行的 Runtime 进行支持,这样才可以协调 React 组件、README.md、TypeScript 类型定义串联成我们所需要的组件调试+文档一体的组件开发页面。
在这样的 Runtime 中,同样需要借助 Vite 的模块解析能力,将其 URL 为 **/*/(README|*).html 的请求,转换为一段可访问的组件 Runtime Html 返回给浏览器,从而让浏览器运行真正的组件开发页面。
http://localhost:7000/components/component1/README.html -> /components/component1/README.html -> /components/component1/README.md -> Runtime Html
3 组件 Props Interface
正如我上述内容中讲到的,如果利用 Vite 添加一个对 tsx 的组件 props interface 类型解析的能力,也可以做成独立插件用于解析 .tsx.type.json 结尾的文件类型,通过 import 这种类型的文件,从而让编译器动态解析其 tsx 文件中所定义的 TypeScript 类型,并作为模块返回给前端消费。
其加载过程就可以当做是一个虚拟的模块,可以理解为你可以通过直接 import 一个虚拟的文件地址,获取到对应的 React 组件元信息:
// React Component import Component from './component1.tsx'; // React Component Props Interface import ComponentTypeInfo from './component1.tsx.type.json'; // or const ComponentTypeInfoPromise = import('./component1.tsx.type.json');
由于这种解析能力并不是借助于 esbuild 进行,所以在转换性能上无法和组件主流程编译同步进行。
在请求到该文件类型时,需要考虑在 Vite 的 Serve 模式下,新开线程进行这部分内容编译,由于整个过程是异步行为,不会影响组件主流程渲染进度。当请求返回响应后,再用于渲染组件 Props 定义及侧边栏面板部分。
在热更新过程中,同样需要考虑到 tsx 文件修改范围是否涉及到 TypeScript 类型的更改,如果发现修改导致类型变化时,再触发 HMR 事件进行模块更新。
三 组件 Build
以上都是在讨论组件在 Vite 的 Serve 态(也就是开发态)下的情况,我们上文中大量借助 Vite 利用浏览器 es module 的加载能力,从而做的一些开发态的动态加载能力的扩展。
但是 Vite 在组件最终 Build 过程中是没有 Server 服务启动,当然也不会有浏览器动态加载,所以为了让别人也可以看到我们开发的组件,能够体验我们开发时调试组件的样子,就需要考虑为该组件编译产出一份可以被浏览器运行的 html。
所以在 Vite 插件开发过程中,是需要考虑在 Build 状态下的编译路径的,如果是在 Build 状态下,Vite 将使用 Rollup 的编译能力,那么就需要考虑手动提供所有组件的 rollup.input(entries)。
During the plug-in writing process, you must follow the plug-in loading life cycle provided by Rollup to ensure that the module loading logic and compilation logic of the Build process and the Serve process are consistent.
In the beginning, during the implementation process, I did not fully understand the relationship between Vite and Rollup. During the module parsing process, I relied on a large number of server middleware provided by Vite's Server. software capabilities. As a result, I realized the problem when I considered the Build state, and ended up almost rewriting the previous loading logic.
Four Summary
Let me call this solution (suite) vite-comp. Its general composition is Vite 3 Vite Composed of Pugins, each plug-in is not coupled to each other and has different responsibilities. That is to say, you can get any Vite plug-in for other purposes. In the future, separate open source will be considered, respectively:
Markdown is used to parse .md files. After loading, the original text and runnable blocks such as jsx and tsx can be obtained.
TypeScript Interface, used to parse the props type definition of the export component in the .tsx file.
Vite Comp Runtime is used to run the component development state and compile the final component document.
Combined with Vite, React and Rax component development in Vite mode has been implemented. Compared with the previous component development using Webpack, it has been It reflects the following major advantages:
No fear of large component libraries, even if there are 2000 components in the same project, the startup time is still
Efficient component metadata loading flow, all project dependencies are compiled on demand.
Millisecond hot update response, with the help of esbuild, you can see the change effect almost as soon as you press save.
Preview experience:
Start
Markdown component document milliseconds Level response
TypeScript type recognition
Vite is still just getting started , this brand-new compilation mode has brought me a lot of development benefits. The gameplay combined with Vite will definitely emerge in endlessly in the future. For example, the front-end integration solution of Midway lambda Vite is also amazing. In this In the prosperous front-end era, I believe that different front-end products will be combined with Vite to create the next legendary story.
I am a front-end engineer who loves life! Yooh!
[Related tutorial recommendations: React video tutorial]
The above is the detailed content of Teach you step by step how to use Vite+React for component development (Practice). For more information, please follow other related articles on the PHP Chinese website!