I believe that with the efforts of Yuxi, many front-end partners have been familiar with Vite, which is a next generation construction tool with the release of Vue3.0, its name is from the French single Fast. You can see that most of Yu Creek’s recent work has been on Vite, which shows why it’s important

In this article, we’ll take a look at what makes Vite special.

The world has suffered webpack for a long time

If you’re in the front end, you’ve probably heard of WebPack. Most of the big front-end applications in the modern world are built with webPack, but as the project grew, there were a few things you didn’t know about WebPack.

  • As the project size increases, the project cold start time increases exponentially
  • Hot update times also increase as the project size increases

Hence the common joke: NPM run dev, then go to the bathroom, have a cup of coffee, may not be finished, greatly affecting the development efficiency. Although WebPack provides many ways to do build optimization, it is still inadequate in increasingly large front-end projects. Is there a way to solve this problem once and for all? The answer is Vite!

Vite came out of nowhere

How does Vite solve the problem of the centurynative ES modules. In the days when browsers didn’t have native modularity support, we often needed to use build tools like WebPack to package the entire project into a JS file that the browser could easily call. However, with the continuous efforts of browser manufacturers, almost all modern browsers now support the import/ export syntax. The following figure shows the specific compatibility of browsers.

Most browsers can already parse import statements in JS files, so the webpack process is a bit of a farting experience.

If YOU had to sum up Vite in one word, it would be fast. This is the data listed in THE Vite PPT by UVU

  • Service startup time < 300ms
  • Module hot replacement time (HMR) < 100ms

From the data point of view, it is indeed a drop Webpack, let’s see how it does

Why is Webpack so slow

Also mentioned above, in before the browser did not modular design, so expect to compile all source code into a js file provide for the use of the browser, so when we run a start command in the development, webpack always need from entrance to index the entire project file, compiled into one or more separate js file, Even if code split is used, compiled files under all routes need to be generated at once (which is why code split does not help development mode performance). This also results in service startup times increasing exponentially with project complexity

How does Vite solve the problem

How is Vite usednative ES modulesTo optimize service startup time, Vite does not need to compile files in advance to start the development server (there is a similar process, which is detailed below). Instead, it provides the corresponding files when the browser requests the corresponding URL. The process of providing only the compilation file of the module under the corresponding route without indexing the entire code, and the project startup time is always constant. It doesn’t keep growing as the project gets more complex, so how do we do that

How is Vite implemented

Depend on prebuild

Native ES Modules do not support the following raw module import, so what?

import { someMethod } from 'my-dep'
Copy the code

Yarn Create @vitejs/app create a react+ TS project. SRC /main.tsx

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>.document.getElementById('root'))Copy the code

This is the Vite compiled SRC /main.tsx file

/node_modules/.vite/react.js? v=432aac16″

It looks like Vite will cache pre-built dependencies in node_modules/. Vite. You can see that the file name is followed by a random string, which you can easily imagine is used to control the browser cache. V =432aac16 This file request header take a look:

Sure enough, the cache-control property is written to: max-age=31536000,immutable, setting the file to be permanently forced Cache, which means always fetching files locally and then controlling version updates by adding hash values to the file names. This leaves file-dependent caching decisions in the hands of browser Big Brother, reducing the workload on the Vite side.

You think that’s it? It’s not. Open react.js? V = 432aAC16 file a look

What the hell is this? Why not the react buddy? What else did Vite do secretly? Yes, Vite didn’t just rewrite the path at this point. At service startup, Vite checks all source code for raw module import statements like import {someMethod} from ‘my-dep’ and does the following

  • pre-built
  • Rewrite to a valid URL

The “pre-build” is the “pre-build file” mentioned above, and Vite uses esBuild to “rely on pre-build” at the start of the project for two purposes

During the development phase, Vite’s development server treats all code as native ES modules, so dependencies released as CommonJS or UMD need to be converted to ESM during the pre-build phase.

2. Optimize load performance Vite converts ESM dependencies with many internal modules into a single module to improve subsequent page load performance (and reduce the number of requests). For example, LoDash-ES has over 600 built-in modules that send over 600 HTTP requests at once. Even if HTTP2 is used, it is not acceptable. The large number of web requests on the browser side can cause network congestion, resulting in slow page loading. By pre-building LoDash-es as a module, only one HTTP request is required!

More details on “dependent prebuild” can be found in the official documentation.

After pre-building the dependencies, use ES-module-lexer + magic-String to rewrite the lightweight bare module import statement. Because there is no complete AST traversal, it is very fast, less than 1ms for most files!

File to compile

After solving the problem of raw module import, can we develop happily? In fact, there is no. Note that our project is built using TypeScript+React. Browsers can’t parse TSX directly. The old-fashioned way is to look at compiled filesIn Vite, babel-loader does not have a loader function, so how do you implement this functionesbuildVite uses esbuild as a parser for some file types (such as TSX & TypeScript). Unlike WebPack, Vite does not pre-compile all files to a browser acceptable type. Instead, after receiving the HTTP request from the browser, the corresponding file is compiled and provided to the browser. So there’s a very legitimate question, is it fast enough?

The file needs to be compiled every time the page loads, which seems to affect the loading speed. Again, Vite uses esBuild, a build tool written in Go that, according to the website, is 10-100 times faster than existing build tools (WebPack is not talking about you). itswebsiteMore detailed performance test data

Why is Esbuild so fast?

Why is EsBuild, the same build tool, so good? The details are as follows (from esBuild website)

1. Written with Go and compiled into machine code

Today’s build tools are typically written in JavaScript, and for such interpreted (dynamic) languages, performance at the command line is very poor. Since the V8 engine is encountering the code for the first time every time it runs a build, no tuning can be done. Esbuild, on the other hand, is written in a compiled (static) language called Go, which has been compiled into machine code that the machine can execute directly. While EsBuild is compiling your javaScript code, Node is probably still parsing your build tool code.

On top of that, Go is a language designed for concurrency, while JavaScript is clearly not.

  • Go shares memory space between threads, whereas JS needs to serialize data to pass between threads.
  • Both Go and JS have a garbage collection mechanism for concurrency, Go shares the heap between all threads, and JS has a separate heap for each thread.

According to tests by the esbuild authors, this seems to cut the parallel processing power of the JavaScript worker thread in half, probably because one half of your CPU core is busy collecting garbage for the other half

2. Extensive use of parallel algorithms

In addition to Go’s innate concurrency advantage, which makes it far superior to JavaScript in handling concurrent tasks, Esbuild’s internal algorithms are also carefully designed to squeeze as much of the CPU core as possible.

3. Everything in EsBuild is written from zero

There are many performance benefits to writing everything yourself rather than using third-party libraries. You can think about performance from the start, and you can make sure that everything uses a consistent data structure to avoid expensive conversions. The downside, of course, is that it’s a lot of work.

4. Use memory more efficiently

  • Esbuild reduces the impact of memory access speed on packaging speed by reducing the number of AST traversals (three)
  • Go also has the benefit of being able to store data more tightly in memory, which allows high-speed CPU caches to hold more content

Vite2.0 has just been released as a stable version, in which the pre-built tool has been switched from Rollup to esBuild, and performance is dozens of times faster.

Vite function

Now that we know some of the principles, let’s see what Vite can do.

Module thermal overload

Vite supports hot reloading of Vue and React modules, which can accurately update pages without reloading pages or deleting application state

TypeScript

Vite supports importing.ts files out of the box, but it’s worth noting that Vite only performs translation of TS files and does not perform any type checking, because Vite uses esbuild for translation and does not contain type information. So TypeScript specific features such as “constant enumeration” and “implicit type-only import” are not supported. You must set “isolatedModules”: true to the compilerOptions in your tsconfig.json so that TS will warn you about features that don’t work with standalone compilation mode.

Vue

As a brother, Vite naturally provides first priority support for Vue

  • Vue 3 single file component support: @vitejs/plugin-vue
  • Vue 3 JSX support: @vitejs/plugin-vue-jsx
  • Vue 2 supports underfin/ viet-plugin-vue2

JSX

React and.tsx are also available out of the box. The translation is done via ESBuild, and the default is React16. JSX support for React17 in ESBuild is shown here

CSS

The import.css file inserts the content into the label and also supports hot overloading. It can also retrieve the processed CSS exported as its module’s default as a string. It also supports “@import inline” “PostCSS” “CSS Modules” “CSS preprocessor”. For details, see the documentation

Vite also supports many file types, such as “JSON”, “Web Assembly” and “Web Worker”. You can go to the official documentation for more information

Write in the last

In fact, there are a lot of things I want to write about Vite, such as optimization in production environment, server-side rendering, etc., but due to the limitation of time, space and ability, I can only regret to leave it to the next article. It won’t take long!

The resources

  • Vite document
  • Why is esbuild fast?
  • React 17 new JSX conversions
  • Vite & VitePress @ Vue Toronto 2020 PPT