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
-
- Js is weakly typed
-
- Maintaining dependencies manually is cumbersome
-
- Browser Compatibility
-
- No hot update
.
That’s where front-end build tools come in. Build tools can help us do the following
-
- Code review
-
- Code compression, obfuscation
-
- Dependency analysis, packaging
-
- 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
-
-
Find entry file
Find the entry file by looking for the entry configuration from the WebPack configuration file
-
-
-
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.
-
-
-
Module functions
Find all the files in the dependency and turn them into module functions that webPack can call later
-
-
-
packaging
The packaged file can be output to the output path of the configuration file to generate a bundle
-
-
-
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
- 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
- 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
-
- In development preview, it is not packaged.
-
- Hot Module Replacement (HMR)
-
- Really load on demand
Of course, vite has its problems,
-
Vite’s ecology is not yet perfect.
-
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
- The first is to start a static resource server
- Find the entry to the project and start loading the entry file
- When you declare a script tag of type Module, the browser sends a GET to the server
- Vite by hijacking the browser
Browser hijacking
These 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
-
- A static resource server is started
-
- 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
- Match the.vue ending file and read the js code in it
export default
replaceconst __script =
- Hang the relevant parts of the template on the page after rendering
__script
Under 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