What is the vite

Vite is a new build tool developed by VuE3. So what build tools have you been updating like crazy this New Year? What is the magic of it?

After vite was developed, even the core members of the Webpack team exclaimed

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

Note: Vite is a new front-end build tool (emphasis: build tools), many people always ask the difference between Vite and vue-CLI. Vue-cli is a scaffolding tool for automatically generating vue.js+ WebPack project templates. Convenient for our rapid development. Vite is a build tool that we use to build projects (similar to WebPack functionality). It is not ruled out that vite will be integrated in VUe-CLI in future

The past and present of building tools

What the build tool does

Building tools: Tools that allow us to stop doing repetitive things and free up our hands. Early in the development process. There’s a lot to be upset about

    1. Js is weakly typed
    1. Maintaining dependencies manually is cumbersome
    1. Browser Compatibility
    1. No hot update

.

That’s where front-end build tools come in. Build tools can help us do the following

    1. Code review
    1. Code compression, obfuscation
    1. Dependency analysis, packaging
    1. Language compilation (e.g. Ts to JS, SCSS to CSS)

.

Before looking at Vite, let’s look at some of the other build tools, so we can better compare the strengths of Vite. There are many front-end build tools. For example, Grunt Gulp FIS3 Webpack Rollup Parcel Snowpack vite

Workflow for common packaging tools

Gulp

Gulp.js is an automated build tool that developers can use to automate common tasks during project development. Gulp.js is built on top of Node.js, and with the power of node.js streams, you can quickly build projects

var gulp = require('gulp');
    var jshint = require('gulp-jshint');
    var concat = require('gulp-concat');
    var rename = require('gulp-rename');
    var uglify = require('gulp-uglify');

    // Lint JS
    gulp.task('lint', function() {
    return gulp.src('src/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'));
    });

    // Concat & Minify JS
    gulp.task('minify', function(){
        return gulp.src('src/*.js')
        .pipe(concat('all.js'))
        .pipe(gulp.dest('dist'))
        .pipe(rename('all.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'));
    });

    // Watch Our Files
    gulp.task('watch', function() {
        gulp.watch('src/*.js', ['lint', 'minify']);
    });

    // Default
    gulp.task('default', ['lint', 'minify', 'watch']);
Copy the code

Gulp execution executes tasks from the top down. The file contents are then piped through. Pass. If you want to learn more about Gulp, go to the gulp website

Webpack

Webpack is a static module packaging tool for modern JavaScript applications. When WebPack processes an application, it builds a dependency graph internally that maps to each module required by the project and generates one or more bundles.

Let’s look at a working schematic of WebpackAs you can see from the figure above, WebPack packaging is divided into the following steps

    1. Find entry file

      Find the entry file by looking for the entry configuration from the WebPack configuration file

    1. Analyzing dependencies

      After receiving the import file, start from the import file, analyze which files the import file depends on, and these dependent files may also depend on other files, so recursive search down.

    1. Module functions

      Find all the files in the dependency and turn them into module functions that webPack can call later

    1. packaging

      The packaged file can be output to the output path of the configuration file to generate a bundle

    1. Start the service

      Node creates the local server and starts the static page

This is probably the main process of packaging webPack in our development environment.

Familiarize yourself with the workflow of our common packaging tools. Let’s see how Vite works. See why Vite is being called the next generation of development and build tools.

Vite principles and advantages

The current dilemma of packaging tools

In the current work, we mainly use WebPack + VUE (WebPack + React) for project development. However, as we build larger and larger applications, the amount of javascript code that packaging tools need to handle increases exponentially. More and more large projects contain hundreds or even thousands of modules. We started to run into performance bottlenecks, and tools that used javascript often took a long time to get the development server started

This is a real project I work on. It’s not a big project, but it took 30 seconds to start the server. This must be intolerable to an efficient programmer

As the project gets bigger and bigger, the HRM thermal renewal rate of the project becomes slower and slower. Sometimes even change a field, the page will be dozens of seconds after the hot update.

Why does this problem arise

In fact, this has something to do with the principles of WebPack packaging. We already have a general understanding of the main workflow of WebPack, so we won’t go into details here

  1. Starting the server is slow because before each server starts. Webpack needs to perform a number of things. Find the dependencies between modules, merge each module, generate a build, save it in memory, and finally start the server. So the speed will get slower and slower as the number of projects increases
  2. Webpack HRM. When you change a file, Webpack’s hot update will re-build the package with the current modified file as the entry point, and all the dependencies involved will be reloaded once. Therefore, the speed also decreases as the projects increase (I will write an article on the IMPLEMENTATION of HRM for WebPack later).

.

The advantage of vite

Three features of Vite

    1. In development preview, it is not packaged.
    1. Hot Module Replacement (HMR)
    1. Really load on demand

Of course, vite has its problems,

  1. Vite’s ecology is not yet perfect.

  2. Packaging is still needed in production mode. Although the native ESM is now widely supported, it is still inefficient to publish an unpackaged ESM in a production environment (even with HTTP/2) because of the additional network round-trips that nested imports cause. In order to get the best load performance in a production environment, it is best to do tree-shaking, lazy loading, and chunk splitting (for better caching).

The principle of vite

From the above, we already know many advantages of using Vite, so let’s take a look at how vite is implemented.

ES Modules

Vite’s success is due to modern browsers’ implementation of ES Modules based on the ECMAScript standard. It is currently supported by all major browsers (except IE11). It allows us to import and export modules from the browser using the export and import methods, and set type=”module” in the script tag.

<script type="module">
  import { createApp } from '/ main js' createApp () < / script >Copy the code

The browser recognizes

Vite workflow and cold start

Let’s start with a picture

  1. The first is to start a static resource server
  2. Find the entry to the project and start loading the entry file
  3. When you declare a script tag of type Module, the browser sends a GET to the server
  4. Vite by hijacking the browserBrowser hijackingThese requests are hijacked by the browser and processed in the back end to simply decompose and integrate the files used in the project and return them to the browser.

From the analysis above, vite mainly does the following things

    1. A static resource server is started
    1. You simply convert the source when the browser requests it and make it available on demand

Vite runs much faster than the original WebPack development and compilation because no files are packaged and the rest of the loading is done by the browser.

Vite’s hot update

Traditional packagers store the project’s packaged resources in the computer’s memory, so they only need to deactivate the corresponding modules when files change, but they still need to rebuild and reload the page. So packaging tools like WebPack support dynamic module hot reloading (HRM), which allows a module to replace itself with no impact on the rest of the page. But in practice. We found that HRM speed decreases as the project grows (for reasons that have been analyzed in the current packaging tool dilemma section).

In Vite HMR is executed on the native ESM. When editing a file, Vite only needs to precisely break the chain between the edited module and its nearest HMR boundary (most of the time just the module itself), making HMR updates always fast, regardless of the size of the application.

Vite load on demand

Why is Vite truly on-demand? Isn’t WebPack really loading on demand? If you want to know, then you can take a look and see how WebPack works, but here’s a little bit about how WebPack actually starts with a package build, you do one package build for all the files, It is only when WebPack encounters the import(*) syntax that another chunk is generated; It is only appropriate to load the contents of the import from the analysis above. Whenever our import code is executed, we need to package it

The browser only sends an import request to the contents of the file when you actually need to load it, so vite is truly loaded on demand

Implement a base version of Vite

Now that we know how Vite works, let’s implement a basic vite

The difference between vite and WebPack compiled files

Webpack compiled file

Vite the compiled file

main.js Step 1: As you can see from the image above, vite first finds an entry file and then changes the path of some dependent modules, such as replacing vue with /@modules/vue.js. Replace./ app.vue with an absolute path

Step 2: First find the first component, app.vue. Copy js from app.vue to a constant, then convert HTML from app.vue to a render function, and mount it to the js constant.

Implement our own vite

First we initialize a project

 npm init vite-app <project-name>
 cd  <project-name>  
 npm i 
 npm run dev 
Copy the code

In this way, we can successfully launch a vite+ Vue project. Next we’ll implement our own vite instead of vite

From the analysis of vite above, we can know that there are several steps to implement vite

Set up a server

We mainly use KOA here

Then performnode yj-vite.js

As you can see, a static resource server has been set up

Intercept the request and replace the module

If we request the home page, we get the absolute address, splice it, read the file, and return, if not, we just read the file. And return

At this point we see that the request was actually successful, but the console reported an error

The reason is that the browser does not recognize import.. Form ‘vue’ changes vue to an absolute path address

Change the path

Therefore, we need to modify the content of the previous step. When the third-party module is loaded with import in the file ending with js, we will first

Import vue from '/@modules/vueCopy the code

This way we can see that the substitution has been successful in main.js

So what do we do with /@module/vue

So we can handle third-party modules correctly. And the third-party module has been successfully loaded.

But there will be an error in the browserThis is because the vue source code contains the process.env environment variable, so we can add the following in the index. HTML to do a simple processing.

<script>
  window.process = {
    env: {
      NODE_ENV: 'dev'
    }
  }
</script>
Copy the code

So we can execute successfully.

Identify the VUE file

But we don’t usually do that in main.js

createApp({
  render: () => h('div','3333333')
}).mount('#app')
Copy the code

Instead, code is written as a single file component

import App from './App.vue'
createApp(App).mount('#app')
Copy the code

So how do we identify the contents of the files in.vue and successfully obtain them? Here is a brief overview of the following ideas

  1. Match the.vue ending file and read the js code in itexport default replaceconst __script =
  2. Hang the relevant parts of the template on the page after rendering __scriptUnder the

So we succeeded in hand-writing a Vite

conclusion

The source address

Github.com/yujun96/myv…

vite

In fact, the official Vite is far more complicated than that. Before the HTTP request, vite actually does a pre-packaging. The purpose of pre-packaging is to reduce the HTTP request, because one module may depend on hundreds or thousands of modules, too many requests increase the burden of the browser. If you want to see how Vite implements pre-packaging, you can check out EsBuild

Of course how vite implements on-demand loading, hot updates… And so on function, you can follow me, wait for the follow-up update

Future updates

Vite next generation front-end development and construction tool (II) Main content: Realization of more functions of Vite, and realization principle of how to migrate vuE2 project to Vite Webpack HRM This paper mainly explains the principle of VUE2 realization of HRM in Webpack. The main content of VUE2 is the realization of MVVM, virtual DOM Diff algorithm and so on