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 esbuild
, Browser es modules
, HMR
, 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 esbuild
does 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.
- The
HMR
(hot update) capability is even more immediate withVite
, which used to be the most time-consuming area for component development and debugging. - All source modules in
Vite
are dynamically compiled, i.e.TypeScript
type definitions andJS
annotations 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 JS Bundle
:
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 Bundle
during 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.
Load .type
.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 Vite
.
But if we really want to make such a React
and 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 .md
files
2.1 Component Usage
Referring to the component development ideas provided by dumi
and 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 jsx
, tsx
, css
, scss
, 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
So for 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 README.md
and 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 React
components, README.md
, 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 URL
is *//(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.
2.3 components Props Interface
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 .tsx
.type
.json
by 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 Vite
’s 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.
But 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 Build
state, Vite
will use the Rollup
compilation ability, then you need to consider manually provide all components of the rollup.input(entries)
.
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 Vite
and Rollup
well enough in the beginning, and relied a lot on the server-side middleware capabilities provided by Vite
’s 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
4. Summary
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.md
files and load them to get the original text and runnable blocks such asjsx
andtsx
.TypeScript Interface
, used to parse.tsx
files forprops
type definitions ofexport
componentsVite Comp Runtime
, used to run the component development state and compile the final component documentation
Preview Experience
Start:
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.
Reference https://mp.weixin.qq.com/s/j4F2KVTlJjbMs99FjBn_6A