1. Vite brings the light
It’s no exaggeration to say that
Vite has brought an absolute revolution to the front-end.
Or we can say that the integration of
Browser es modules,
Pre-Bundling, and other advanced tools and ideas about
JS compilation development in the community behind
Vite has brought about a revolutionary changes.
The main reason why
Vite is faster is that
pre-bundles dependencies + browser
native ESM dynamic compilation, which I won’t go into too much detail here
In the context of this idea, going back to our component development scenario and looking at it again will reveal the following issues that are highly compatible:
- Component libraries are developed without actually compiling all the components.
- Component development, compilation of preview pages mainly for developers, browser compatibility can be controlled.
HMR(hot update) capability is even more immediate with
Vite, which used to be the most time-consuming area for component development and debugging.
- All source modules in
Viteare dynamically compiled, i.e.
TypeScripttype definitions and
JSannotations can also be compiled dynamically, greatly reducing the scope of compilation.
Then, the old way of thinking like
StoryBook and the previous way we used to extract
tsx component type definitions will be able to make a relatively big change
Previously, in order to get the type data of the component input, a plugin was made at the
Wwebpack level to dynamically analyze the
tsx component of
export, and a static attribute variable of
__docgenInfo was dynamically added under the component to inject the type data and annotation information obtained from
AST analysis into the component
JS Bundle, which can be further processed into dynamic parameter settings.
TypeScript’s definition of component Props:
Analyze the content injected into the
Analysis of the parameter interaction settings achieved after conversion
So for the component, actually getting this metadata for the type definition is redundant for the component itself. Whether or not this metadata is used in the component, it will be extracted and injected into the component
Webpack compilation, which is obviously very inefficient.
In the idea of
Vite, it is perfectly possible to get the metadata information of a component when it is used, for example, loading a
React component as:
Then load its metadata i.e.
.json file type through
Rollup plugin capability in
Vite to parse component metadata. Also, with the ability of
Rollup itself for compilation dependency collection and
HMR, we can do the hot update of component type changes
2. Design ideas
The above is a preliminary idea inspired by the module loading idea of
But if we really want to make such a
Rax component development kit based on
Vite, there are certainly other problems that need to be solved besides the acquisition of component entry metadata, the first of which is the parsing of
2.1 Component Usage
Referring to the component development ideas provided by
Icework, the component
Usage can be written to any
.md file in the form of a
Markdown write document, which is dynamically parsed by the compiler for
less code block, and compiles it as an executable
script to run on the page
This is not only in writing the document, but also can run debugging components under the different components into the performance of the component, how many components in the
Case, can be written in different blocks for the user to choose to see, this design idea is really let people applaud!
Finally, if you can combine the
esbuild dynamic loading and
HMR capabilities of
Vite mentioned above, the whole component development experience will take another quantum leap
Markdown files a
Vite plugin needs to be made to perform file parsing and loading of
.md, with the following expected capabilitieswill be as follows:
Please click to enlarge to see the expected effect.
2.2 Components Runtime
What should a regular component repository directory look like? Whether it is in a separate component repository or in an existing business project, the directory structure of components is actually similar, roughly as follows:
In our scenario you can start the component development mode in any project, and after running
vite-comp you will see a component-specific interface, where the component
Usage written in
index.tsx defined in
index.tsx are already parsed and rendered for you.
interface, you just need to access the different file paths to see how the corresponding component is represented
At the same time, you can finally compile and package all the contents of this interface and publish the screenshots to
NPM, so that others can see the component clearly and see the component parameters, usage, screenshots, etc. You can even open the
Demo address and modify the component parameters to see how the component behaves in different states.
To achieve this effect, a set of component runtime
Runtime support is needed to coordinate
TypeScript type definitions in tandem into the component debugging + documentation we need for the integrated component development page.
In such a
Runtime, it is also necessary to use the module parsing capabilities of
Vite to convert the request whose
*//(README|*).html into an accessible component
Runtime Html that is returned to the browser, thus allowing the browser to run the real component development page.
As I mentioned above, if you use
Vite to add a component
props interface type resolution capability to
tsx, you can also make a standalone plugin for parsing file types ending in
importing such types of files which allows the compiler to dynamically parse the
TypeScript types defined in its
tsx files and return them to the front-end for consumption as modules
The loading process can be treated as a virtual module, which means that you can directly
import a virtual file address and get the corresponding
React component meta information
Since this parsing capability is not performed with the help of
esbuild, it is not possible to synchronize the conversion performance with the compilation of the main flow of the component.
When requesting this file type, consider opening a new thread in
Serve mode to compile this part, as the whole process is asynchronous and will not affect the component main flow rendering progress. When the request returns a response, it is then used to render the component
Props definition and the sidebar panel part.
During the hot update process, it is also necessary to consider whether the scope of the
tsx file modification involves
TypeScript type changes, and then trigger the
HMR event to update the module if the modification is found to result in a type change
3. Components Build
The above are discussing the situation of components in the
Serve state of
Vite (that is, the development state), and we heavily relied on
Vite above to take advantage of the loading capabilities of the browser’s
es module to do some extensions to the dynamic loading capabilities of the development state.
Vite does not have a
Server service to start during the final
Build of the component, and of course it will not be dynamically loaded by the browser, so in order to allow others to see the component we have developed and to experience how we debug the component during development, we need to consider compiling a
html for the component that can be run by the browser.
So in the
Vite plugin development process, it is necessary to consider the compilation path in the
Build state, if it is in the
Vite will use the
Rollup compilation ability, then you need to consider manually provide all components of the
During the plugin writing process, it is important to follow the plugin loading lifecycle provided by
Rollup to ensure that the module loading logic and compilation logic of the
Build process and the
Serve process are consistent.
I didn’t understand the relationship between
Rollup well enough in the beginning, and relied a lot on the server-side middleware capabilities provided by
Server in the module parsing process. It was only when considering the
Build state that I realized the problem, and ended up almost rewriting the previous loading logic
I will call this program (kit)
vite-comp, its general composition is composed of
Vite + 3 Vite Pugins, each plug-in is not coupled with each other, mutual responsibilities are not the same, that is, you can get any one
Vite plug-in to do other purposes, the follow-up will consider separate open source, respectively.
Markdown, used to parse
.mdfiles and load them to get the original text and runnable blocks such as
TypeScript Interface, used to parse
propstype definitions of
Vite Comp Runtime, used to run the component development state and compile the final component documentation
Millisecond response for Markdown component documents:
TypeScript type recognition
This new compile mode has already brought me a lot of development state gains, combined with the
Vite play in the future will certainly be endless, such as
Midway + lambda + Vite front-end integration program is also to see the people to applaud, in this thriving front-end era, I believe that different front-end products will be combined with the
Vite out of the next legendary story.