Article/spirit Xi

Vite author Yu Xi quote:

Vite (French for “fast”, pronounced /vit/, similar to veet) is a new front-end build tool. You can think of it as a combination of out-of-the-box development server and packaging tools, but lighter and faster. Vite leverages the browser’s native ES module support and tools compiled into native languages such as EsBuild to provide a fast and modern development experience.

Development of reason

Before browsers supported the ES module, developers didn’t develop JavaScript’s native mechanics in a modular way. Therefore, we usually use webpack, Rollup and other build tools to pack modules into js bundles that can be read by browsers in advance during local development.

However, with the development of business, more and more applications are built, and there may be hundreds or even thousands of modules, which will encounter performance bottlenecks. It usually takes a long time to start up. After starting up, even after using HMR hot update, the modification of files will take several seconds to see the effect in the browser.

Now, however, browser natively supports ES modularity, and you can write the following code directly in HTML:

Browsers that support native introduction of ES modules:

Instead of building tools, you can use the browser’s self-loading module functionality.

Problem settlement method

Suppose you had to build a development server from scratch using the browser’s ability to introduce ES modules?

Lead-in path problem

First of all, it’s not possible to change the way you write your code, usually we introduce a module, usually we use what’s called bare import, import lodash from ‘lodash’, webpack or something like that will go to node_modules and look for that module, Help us deal with dependencies between JS. Try importing lodash from ‘lodash’ directly in the browser. It will tell you that only relative or absolute paths are recognized:

Let’s use a demo to see how Vite handles this problem:

Import React from ‘React’ as import __vite__cjsImport_react from “/node_modules/.vite/react.js? V =6c9747e8”

Look at the source code for how to do this:

  1. The first step is to start a server

  1. Modifying the Import Mode
  • The ES-module-Lexer parsing code generates the AST syntax tree, gets the contents of the import, and transforms the path

Large number of scattered modules

Rely on prebuilt prebuilds

By default, Vite 2.0 pre-builds detected dependencies with esBuild before starting the development server for the user.

Why do you want to do this, for example:

When you use import debounce from ‘lodash-es/debounce’, the ideal scenario is for the browser to load only the files for this function. But since debounce relies on three more modules internally: isObject, Now, toNubmer, and these three modules have other dependencies, the function actually ends up importing 14 modules, meaning 14 requests:

Exclude lodash-es from optimizeDeps. Exclude lodash-es from optimizeDeps. Exclude lodash-es from optimizeDeps.

There were 14 requests related to Lodash-es, so to fix this, Vite took advantage of Esbuild’s super-fast build speed, Allows you to pre-package all the internal modules used by Debounce into a traditional JS bundle at startup without being aware of it.

Esbuild is written using Go and is 10-100 times faster than a JavaScript builder prebuild dependency:

Let’s look at Vite source code here is how to implement:

First, before the server starts, hijacks http.listen, overrides the function, and executes the runOptimize dependent prebuild:

Here’s what runOptimize does:

  1. Scan dependencies to form dependency path map, similar to the following structure

{ “lodash-es_debounce”: “node_modules/lodash-es/_debounce” }

  1. Use Esbuild to pre-bundle them into single-file bundles and write them into a cache file

For those of you interested in runOptimize, see this article: Pre-built source code parsing for Vite 2.0

We turned off the lodash-es prebuild with vite. Config. js, and now we can look at the resulting file and see that lodash-es_debecos.js is a file that aggregates all the modules it depends on internally:

In addition, CommonJS modules will also be analyzed during the pre-build step, so that they can be processed into ES modules that can be executed by the browser.

Take advantage of HTTP 2 features

There will always be scenarios where you don’t want a dependency to be pre-built and want the browser to load it directly, so how do you optimize for multiple concurrent requests?

In HTTP 1.x, multiple TCP connections must be used if multiple requests are to be made concurrently. In addition, the browser limits the number of TCP connection requests for a single domain name to 6-8 in order to control resources. HTTP 2 can use multiplexing instead of sequence and blocking mechanisms. All requests are made concurrently over a TCP connection.

Vite also supports http2. If server. HTTPS is set to true, TLS + HTTP/2 will be enabled.

True load on demand

Also, unlike WebPack, Vite actually loads on demand, only the code used on screen is actually loaded:

webpack

Esm-based construction mode:

The gray areas are the routes that are not used for the time being, or even don’t participate in the build process at all. As more and more routes are added to the project, the build will not slow down.

other

React hot update

React hot updates are implemented in webPack with react-hot-loader. This tool is awesome, but it has so many bugs that you need to read the problem list to use it properly.

React-refresh: react-hot-loader react-refresh: React-hot-loader react-refresh: React-hot-loader react-refresh: React-hot-loader react-refresh: React-hot-loader react-refresh: React-hot-loader The react-refresh webpack-plugin was implemented with react-refresh, and The React-refresh plugin was integrated with Vite.

Applicable scenarios based on services

Possible problems if you want to use Vite in your business

  1. Check whether the standard ESM module is exported from the third-party package

  2. Internally developed packages, try to export a copy of the ESM module

  3. For external packages, it is recommended not to use packages without ESM modules (in this age, the quality of exported packages without ESM modules is questionable), or to use tools to convert them into ESM modules

  4. Vite only supports modern browsers with native ESM support by default, but older browsers can be supported through the official @Vitejs/plugin-Legacy. The Legacy plug-in automatically generates an additional package for the older browser and inserts code in HTML that selectively loads the corresponding package based on the browser’s ESM support (similar to modern Mode in VUe-CLI).

  5. Local agent debugging problem

  6. The supporting ecology is perfect. For example, babel-plugin-import can be replaced with vite-plugin-IMP, but more needs to wait for the ecological enrichment of Vite

Applicable scenarios:

  1. Component library development

  2. Internal application development, browser compatibility requirements are not stringent

  3. Other applications can be developed locally using Vite and built online in the old way. Some people may worry that this will not be consistent with the local environment and cause some strange problems, but the production environment of Vite is also built with mature rollup, not with esbuild

All in all, try Vite if you’ve ever faced the following pain points:

  • The project takes a long time to get started

  • The second compilation time after the change is long

  • Use the React-refresh webpack-plugin to react-refresh webpack-plugin.

The sample

Finally, the author used Vite to transform a module developed in the previous work process and compared the startup time:

Old scaffolding, start time, 6586ms:

With Vite, first boot, 1861ms, second boot, 260ms:

Refer to the article

How is Rollup compatible with Vite 2.0? What is React Fast Refresh?