An overview,

The text is designed to analyze why vite is needed and what solutions Vite solves this problem by comparing webpack-dev-Server. And through the analysis of Vite, a simple Vite code is realized.

Second, the webpack — dev server

1. Introduction to Webpack-dev-server

“Webpack-dev-server uses WebPack with a development server that provides real-time reloads. This should only be used for development. It uses Webpack-dev-middleware in the background, which provides fast memory access to Webpack assets.” Webpack-dev-server starts a server in a development environment, which greatly improves front-end development efficiency through the following advantages. (1) Separation of front and rear ends. Previous front-end development required the launch of a full front-end and back-end generation environment, which is often complicated and unnecessary for a pure front-end. Through webpack-dev-server, the front-end students can directly use the interface of other background to students, or start the background of the generation environment (usually a script command) to complete daily work. (2) The front-end server is the premise of hot loading. Hot loading is a function that can only be completed by controlling and monitoring files. Only when the front-end starts the server, can hot loading become possible. (3) Multi-function configuration, such as proxy, etc.

2, Webpack-dev-server process, problems

Webpack-dev-server Starts the server through the following process: (1) Start the service, listen to the port, and package all files. (2) Request the home page and return the complete package file app.js, etc. (3) Establish websocket for hot loading. (4) Update files, analyze all files, websocket returns to inform the front end of the file update. (5) The front end requests to update the file, returns the file, and executes the render function. As can be seen from the above process, (1) and (3) all files are analyzed and processed, which is not necessary. If the project is very large, this part of work will become very time-consuming, which is why it takes a long time to start the project (NPM Run Dev). Developers often only need to focus on the current state of the page, so this time is meaningless.

Iii. Introduction and core process of VITE

Vite startup is a server for modern browser development environment, because modern browsers basically support the native ES Module module loading way, so Vite uses this way to let the browser help us deal with the problem of file dependency. This allows you to start the server without having to deal with all file dependencies, just the current file. The following is the general process for vite to start the server: (1) Start the server and listen to the port (resolveHttpServer). Start the websocket server (createWebSocketServer). (2) Request the home page, through the configuration item plugins in viet.config. js, use pre-transoform to preprocess the home page, insert client. Execute main.js from the main page. (3) Request corresponding files in turn according to the logic of main.js. (4) File update, background returns message via websocket to front end, front end sends “await import XXX? import&t= timestamp{timestamp}timestamp{query ? &${query} : “}” rerequests the file, executes the render function.

Four, vite core logic implementation

1. Code directory structure

Project directory structure. Lib stands for node_modules, which houses the third-party library where the core logic of vite here resides. Others, such as SRC and index.html, have the same file structure as common projects.

---vite-test-code
   ---lib
      ---vite
         ---client
            client.js
         ---node
            server.js
            wsServer.js
   ---src
      App.vue
      main.ts
   index.html
   package.json
Copy the code

2. Project file code

(1) /index.html, copied directly from the Vite project, note that the script tag needs to add type=”module”.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script type="module" src="src/main.ts"></script> </body> </html>Copy the code

(2)/SRC /main.ts, the main logical entry of the project.

import App from './App.vue';

document.getElementById("app").innerHTML = App;
Copy the code

(3)/SRC/app. vue, which returns a div directly, rendered in # App. This file can be updated directly when testing the HMR.

Export default '<div> render <div>';Copy the code

3. Vite core process implementation

(1) /lib/vite/node/server.js, start the server core logic code file, the detailed process and code are as follows: ① Start the server, listen to port 4000. Set up the Websocket server.

const http = require("http"); const port = 4000; Const ws = createWebSocketServer(); Let server = http.createserver ((req, res) => {// Parse the request url let pathName = getPathname(req.url); Let filePath = getFilePath(pathname); // return the file readFile(filePath, res, pathname); }); server.listen(port); // Listener port console.log(' service started successfully :localhost:4000');Copy the code

② If the home page is index.html, inject the client.js file.

Function injectWs(data) {return '<script SRC =${clientFile}></script>' + data; }Copy the code

③ Listen for files

function watchFile(url, pathname) { if (! watchList[url]) { fs.watchFile(url, {interval: 1000}, () => { if (ws) { ws.clients.forEach((client) => { client.send(JSON.stringify({ type: "update", path: pathname })); }}})); watchList[url] = true; }}Copy the code

The.ts and.vue files are content-type processed so that the browser treats them as a.js file.

function readFile(filePath, res, pathname) { fs.readFile(filePath, (err, data) => { if (err) { res.writeHead(404, { 'content-type': 'text/plain' }); res.write('404,not found'); res.end(0); } else { const type = path.extname(filePath); if (type === ".ts" || type === ".vue") { res.writeHead(200, { 'content-type': 'application/javascript' }); } if (filePath. EndsWith (indexHtml)) {// Inject websocket data = injectWs(data); } // HMR watchFile(filePath, pathname); res.write(data); res.end(0); }}); }Copy the code

⑤ Complete code

// const HTTP = require(" HTTP "); const url = require("url"); const path = require("path"); const fs = require("fs"); // wsServer const createWebSocketServer = require("./wsServer.js"); // Const port = 4000; const indexHtml = `index.html`; const clientFile = "./lib/vite/client/client.js"; let watchList = {}; Const ws = createWebSocketServer(); Let server = http.createserver ((req, res) => {// Parse the request url let pathName = getPathname(req.url); Let filePath = getFilePath(pathname); // return the file readFile(filePath, res, pathname); }); Function getPathname(reqUrl) {let pathName = url.parse(reqUrl).pathName; return pathname === `/` ? `index.html` : pathname; } function getFilePath(pathname) {// index.html root directory return path.join(__dirname, ".. /.. /.. /", pathname) } function readFile(filePath, res, pathname) { fs.readFile(filePath, (err, data) => { if (err) { res.writeHead(404, { 'content-type': 'text/plain' }); res.write('404,not found'); res.end(0); } else { const type = path.extname(filePath); if (type === ".ts" || type === ".vue") { res.writeHead(200, { 'content-type': 'application/javascript' }); } if (filePath. EndsWith (indexHtml)) {// Inject websocket data = injectWs(data); } // HMR watchFile(filePath, pathname); res.write(data); res.end(0); }}); } function watchFile(url, pathname) { if (! watchList[url]) { fs.watchFile(url, {interval: 1000}, () => { if (ws) { ws.clients.forEach((client) => { client.send(JSON.stringify({ type: "update", path: pathname })); }}})); watchList[url] = true; Function injectWs(data) {return '<script SRC =${clientFile}></script>' + data; } server.listen(port); // Listener port console.log(' service started successfully :localhost:4000');Copy the code

(2)/lib/vite/node/wsServer js, establish the websocket server, listen on port 4002

const ws = require("ws");

function createWebSocketServer() {
    let WebScoketServer = ws.Server;

    let wsServer = new WebScoketServer({port: 4002}) || null;

    wsServer.on(`connection`, (ws) => {
        ws.send(JSON.stringify({
            type: 'connect'
        }));
    });

    return wsServer;
}

module.exports = createWebSocketServer;
Copy the code

(3)/lib/vite/client/client, js, front-end request websocket code. Here a page refresh is triggered when a new file is requested. What happens is that the render function is executed, which simplifies things

const wsPort = 4002; const socket = new WebSocket(`ws://${location.hostname}:${wsPort}/`); Socket. AddEventListener ("message", async({data}) => {// Get file data = json.parse (data); if(data.type === 'update') { await import(`${data.path}? import&t=${Math.random() * 1000}`); // The component render function should be triggered to re-render, temporarily using reload instead of location.reload(); }}); socket.addEventListener("close", () => { console.log("close"); });Copy the code

Five, the use of Vite experience

After pre-studying Vite, the author also chose WebPack for the construction of engineering capability in the new project, specifically considering the following issues: (1) scaffold integration is not enough, considering the project management, JEST, ELint and other components are essential, and the current Vite project does not have the choice of these components, and one by one configuration is more troublesome, their own configuration and often appear some version of the problem. (2) Fast update, not stable enough. The author’s new project also introduces VUe3, both of which are in the stage of rapid update. In addition, vue3’s view ecology is not perfect (Element +, Ant), which often has problems with version matching. (3) Based on the current project and future planning, the project is not and will not be very large, so there will be no trouble in using Webpack.

Six, summarized

This article is just a simple talk about the reasons for the emergence of Vite, and on the basis of reading the source code, the basic process of vite code implementation. This paper is only a superficial understanding of the author, which is bound to be inadequate and wrong. Some conclusions in this paper are independent thinking of the author based on reality, rather than official solutions, so they are only for reference. Thank you for your time.