preface

The author took a look at Vite earlier, and if you understand how fast it is, I’m sure you’ll love Vite and doubt anyone will ever abandon the build tools that need to be packaged. Vue3+Vite+Ts will definitely become the trend of the new technology era, causing a new round of technology update upsurge. Now follow me from shallow to deep, light up your front-end skill tree together, empower technology, and have your own habitat in the blue ocean of the future.

🎈 i. What is a Vite?

Vite, a next-generation front-end development and build tool based on the browser’s native ES MODULE. Using the browser to parse import to send Http requests, the server interception returns a given resource, completely abandon the packaging operation, the server is ready to use. Not only does it support Vue files, but it also handles hot updates, which don’t go down as fast as modules go up (the downside of other build tools), loads on demand, and only uses modules as needed. Build on production environment using Rollup.

🐬 ii. Vite features

🎃 1. True on-demand compilation

Return whatever you need.

💡 2. Start the extreme service

Use native ESM modules without packaging

⚡️ 3. Lightweight and fast thermal overload HMR

Always-on-one module hot overload regardless of application size.

🛠️ 4. Rich functions

Support for TypeScript, JSX, CSS, and more out of the box.

📦 5. Optimized build

Optional pre-configured Rollup builds in multi-page application or Library mode

🔩 6. Common plug-ins

Plug-ins for Vite and Rollup can be shared

🔑 7. Fully typed apis

API complete and complete TS type declarations

Three. 🦞 ESModule

ESModule is a browser-supported modularity scheme that allows modularity in code. Here we take the vite project’s app.vue as an example

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3 + Vite" />
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

When we request app.vue, the browser makes the request, as shown in the figure below

🦝 4. Browser compatibility

  1. Development environment: Vite needs to be used in browsers that support dynamic import of native ES modules.

  2. Online environment: Default supported browsers need to support the introduction of native ES modules via script tags.

The ESModule is currently based on the Web standards specification and covers 90% of the browsers on the market.

In Vite we can see this code in the entry index.html:

We can tell if the browser supports es modules by checking the script type=”module”. If it doesn’t, the script won’t run. For unsupported browser solutions we can use SystemJS to support it, which is polyfill for browser support. You can also use the official vite plugin @vitejs/ plugin-Legacy to support older browsers. This is not the point and we will not mention it.

🐧 5. Why use Vite

1. Pain points of packaging-based build tools

Before browsers supported ES modules, there was no native mechanism for developers to develop in a modular way. Hence the concept of packaging, the use of tools to link, transform, manipulate, crawl, etc., source code into files that can be run in a browser. To this day, we’ve seen the creation of packaging tools and a wave of new technologies (Webpack,Parcel,rollup, etc.) that have greatly improved the development experience for front-end developers. In large enterprise applications, as the number of modules increases (thousands of modules), these “packaged” build tools introduce a real pain point, where development productivity plummets and development servers start up in minutes. Even with HMR, it is possible to change a line of code and heat reload it for a few seconds, wasting a lot of time over and over again.

(1) The development server starts slowly

When cold starting the development server, the packager-based approach is to build your application through a series of processes before providing the service.

As you can see from the figure, before the server is ready, modules are packaged into bundles, whether you use them or not.

(2) Slow thermal overload

When we start the development server based on the packer, updating one piece of code will refactor the entire file, and obviously we should not rebuild the entire package, otherwise the update speed will drop with the size of the file. Some packers load files into memory, and when the file changes, it only takes a part of the module to become inactive, and even then the file needs to be rebuilt and reloaded, which is still expensive. The packer supports dynamic module hot overloading (HMR) : allowing a module to “hot replace” itself without affecting the rest of the page. This greatly improves the development experience, however, it has been found in practice that even HMR update rates decrease significantly as the application size increases.

This is done in Vite, citing official answers and screenshots:

In Vite, HMR is executed on native ESM. When editing a file, Vite only needs to precisely invalidate 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 serves source code in a native ESM way. This essentially lets the browser take over part of the packaging: Vite simply transforms the source code when the browser requests it and makes it available on demand. Code that is dynamically imported according to the situation is only processed if it is actually used on the current screen.

Vite also uses HTTP headers to speed things up. Modules are treated as two types in Vite, one is a dependency module (the dependency library we use, usually unchanged, generally pure JS) and one is a source module (we write code such as.vue,.tsx,.less, etc.). Vite uses a negotiated cache (304 Not Modified) when requesting source code; Cache-control (max-age=31536000,immutable) is used when requesting dependent modules, so that no further requests can be made if the Cache is refreshed. Knowledge portal 🚀

Some students will ask, that if you want to update how to do: strong look at the big guy Zhang Yunlong’s answer

So here comes Vite, designed to address the pain points mentioned above, designed to take advantage of new advances in the ecosystem, using browsers to start natively supporting ES modularity, true load on demand, hot update speed is not affected by file size.

🦂 vi. Why do production environments need to be packaged

Even though ES Modules are widely supported, nesting imports can cause additional network requests, and publishing as packaged ESModules in production environments is not the most efficient (even with HTTP2). For best performance, it’s better to tree-shaking code, lazy loading, and chunk splitting for efficiency.

🧰 7. Core principles

1. Module declaration

First declare that this is a module by putting type= “module” in the

    <script type="module" src="main.js"></script>
Copy the code

Files imported via SRC or import will make HTTP requests; Vite intercepts these requests and specialises in the request file.

2. Replace the raw module

When you try to request a file from the node_modules folder, a bare module replacement is performed (the force is converted to a relative force), and only relative and absolute forces are recognized in the browser.

Import Vue from ‘Vue’ will be converted to import Vue from ‘/@modules/ Vue ‘

3. Analytical / @ modules

Next, parse /@modules into the actual file address and return it to the browser. Other packaging tools, such as WebPack packaging, do this for us.

The webpack file imported by import looks for moduel properties in the node_modules/ package name /package.json file, as shown in the following example.

{ 
  "license": "MIT"."main": "index.js"."module": "dist/vue.runtime.esm-bundler.js"."name": "vue"."repository": {
    "type": "git"."url": "git+https://github.com/vuejs/vue-next.git"
  },
  "types": "dist/vue.d.ts"."unpkg": "dist/vue.global.js"."version": "3.2.20"
}
Copy the code

Just return dist/vue.runtime.esm-bundler.js.

4. Parse single file (SFC) components

We know that the.vue file contains three parts: Template,script, and style. Vite handles these three parts separately

(1) Parse the template

/@vue/compiler-dom is used to compile the template in vite, and the result is similar to the following figure

(2) Process script

Vite uses /@vue/ Compiler-sFC to handle single-file components, just like vue-loader. It should parse as follows.

(3)

Vite tostyleIn particular, you can see the vite project requesttype=styleIs called in the content of the returnupdateStyleMethods,ViteIs put it inHot updateIn the mini-Vite module, we simulate the implementation of the way inclientImplement a simplified version of this feature.

🔥 eight. Mini-vite implementation

1. Project preparation

Create folder mini-vite, then go to the folder and perform NPM init -y initialization

Open the editor and modify the package.json file as shown below:

{
  "name": "mini-vite"."version": "1.0.0"."description": ""."main": "mini-vite.js"."scripts": {
    "dev": "nodemon mini-vite"."test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": []."author": ""."license": "ISC"."devDependencies": {
    "koa": "^ 2.13.4." "."vue": "^ 3.2.20"}}Copy the code

NPM I install dependency, after completion of the index.js, rename to mini-viet. js, as the entry file of the project, the modified project structure is as follows:

Add the following code to mini-viet.js:

const Koa = require('koa')

const app = new Koa();

app.use(ctx= > {
    ctx.body = "hello Vite"
})

app.listen(3000.function() {
  console.log('started vited')})Copy the code

Running in terminal, NPM run dev starts

The browser opens the project, as shown below, and the project is ready to complete

2. Return to the HTML file

Create a new index. HTML file in the root directory and write the following code

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Hello, mini - Vite!!!!!!</title>
</head>
<body>
    <div id="app"></div>
    <script src="/main.js" type="module"></script>
</body>
</html>
Copy the code

Create main.js in the project root directory and write the following code

alert('hello mini-Vite!!! ')
Copy the code

Modify the Mini-Vite code as follows:

// mini-vite.js
const Koa = require("koa");
const path = require("path");
const fs = require("fs");

const app = new Koa();

app.use((ctx) = > {
  const { url } = ctx.request;
  const home = fs.readFileSync('./index.html'.'utf-8')
  // 1. Return HTML
  if (url === "/") {
    ctx.type = "text/html"
    ctx.body = home
  }
});

app.listen(3000.function () {
  console.log("started vited");
});
Copy the code

The project structure is as follows:

Re-open the browser to browse:

We can clearly see that localhost returns our index.html. Some partners will ask, why main.js request reported red?? At this point we can consider that we only processed the “/” request, not the other request, and look at the main

Is it suddenly realized, we are not as long as the REQUEST URL matching JS can be, we look down

3. Return the JS request

Let’s think, how do we file all the JS files and return them correctly?

Some children have already found that all JS request urls end with.js, we just need to fetch the corresponding file under the corresponding URL, and return it directly, let’s look at the code.

Modify the Mini-vite code, add the following code

. app.use((ctx) = > {
  const { url } = ctx.request;
  const home = fs.readFileSync('./index.html'.'utf-8')
  // 1. Return HTML
  if (url === "/") {
    ctx.type = "text/html"
    ctx.body = home
  } else if(url.endsWith('.js')) {
    // return js
    const filePath = path.join(__dirname,url) // Get absolute strength
    const file = fs.readFileSync(filePath, 'utf-8')
    ctx.type = "application/javascript"ctx.body = file } }); .Copy the code

We refresh in the browser, and the result is shown

We can clearly see that we have achieved the desired result.

Main.js is not too young too simple!! We made the following changes to the main.js code:

// main.js
import { createApp, h } from "vue";

createApp({
  render() {
    return h("div".""."hello mini-vite!!!");
  }
}).mount('#app');
Copy the code

We refresh the browser:

Vue module cannot be recognized by browsing/.. /.../This road force is at the beginning, so how do we solve it, let’s go down

4. Replace the raw module

According to the vite principle, first we should replace the bare module with /@modules/vite. We modify the mini-vite.js code as follows:

// main.js
app.use((ctx) = > {
   // ...
   else if (url.endsWith(".js")) {
    // return js
    const filePath = path.join(__dirname, url); // Get absolute strength
    const file = fs.readFileSync(filePath, "utf-8");
    ctx.type = "application/javascript";
    // ctx.body = file
    // Replace bare modules with /@modules/, and the browser will initiate the requestctx.body = rewirteImport(file); }});/ * * *@description: raw module replacement, import XXX from "XXX" -----> import XXX from "/@modules/xxx"
 * @param {*} content
 * @return {*}* /
function rewirteImport(content) {
  return content.replace(/ from ['"](.*)['"]/g.(s1, s2) = > {
    // s1, match part, s2: match group content
    if (s2.startsWith(". /") || s2.startsWith("/") || s2.startsWith(".. /")) {
      // Return directly with relative strength
      return s1;
    } else {
      return ` from "/@modules/${s2}"`}}); }// ...
Copy the code

We refresh the browser and the result looks like this:

As a result, we’ve made a preliminary substitution; Now just return the request starting with /@modules/ to the module attribute value file in node_modules/ package name /package.json. We add it under the mini-Vite code. As follows:

app.use((ctx) = > {
  // ...
   else if (url.startsWith("/@modules/")) {
   // 3. Return the real file referenced by node_modules/ package name /package.json.module
    ctx.type = "application/javascript";
    /** The file prefix */
    const filePrefix = path.resolve(
      __dirname,
      "node_modules",
      url.replace("/@modules/".""));/** Get moudule in node_modules/ package.json */
    console.log(filePrefix, "ttt");
    const module = require(filePrefix + "/package.json").module;
    const file = fs.readFileSync(filePrefix+'/'+module."utf-8");
    // If you need to import XXX, continue to replace itctx.body = rewirteImport(file); }});// ...
Copy the code

We refresh the browser and the result looks like this:

We can see it clearlyVueIt has returned successfully.

We found that the page reported an error:

Because some libraries call process, such as Vue3 here, to determine if it is production, and we do not have the process variable, the question is, what should we do??

σ (⊙▽⊙” A, some children have already thought of it, let’s simulate it, let’s mount a process on the window, is not the moment suddenly realized!! Let’s go down

5. Simulation of the process

For this problem, I initially used the first scheme, introducing cross-env and modifying package.json dev script as follows:

Then print it when mini-viet.js returns HTML with the following code:

Do you think this problem can be solved? Why is that?

The answer is: NO!! The reason is that our code is executed in the browser, the root object of the browser is window, there is no property process, we should add this property on the window

To see the correct solution, add the following code to index.html:

<body> <div id="app"></div> <script> // hash: Circumvent window.process = {env: {NODE_ENV: 'dev', } } </script> <script src="/main.js" type="module"></script> </body>Copy the code

Refresh the browser, and we will not report the error if we find the result.

6. Single file (SFC) component processing

In Vite, the single file processing is compiled using @vue/ Compiler-SFC module, so we also use this module to complete the processing of VUE files. The result of its parsing is something like this:

(1) Script processing

First we create app.vue in the SRC folder

<! -- * @author: Water ice Miao * @Date: 2021-11-01 15:06:48
 * @LastEditTime: 2021-11-01 15:43:51* @filepath: \mini-vite\ SRC \ app.vue --><template>
  <div id="app">
    {{title}}
  </div>
</template>

<script>
export default {
  data () {
    return {
      title: "hello Vite"}}}</script>

<style>
  #app {
    color: red;
    font-weight: 400;
  }
</style>
Copy the code

Then change the main.js code to the following:

/* * @author: @date: 2021-10-22 20:58:14 * @lasteditTime: 2021-11-01 15:18:34 * @lasteditors: Please set LastEditors * @description: main.js, simulation vue project entry file * @filepath: \mini-vite\main.js */
import { createApp } from "vue";
import App from "./src/App.vue"
createApp(App).mount('#app')
Copy the code

Then add the following code to mini-Vite:

// ...
else if (url.includes(".vue")) {
    // Get absolute strength, url.slice(1) remove the first '/'
    const filePath = path.resolve(__dirname, url.slice(1));
    // console.log(filePath, url,'path')
    const { descriptor } = compilerSfc.parse(
      fs.readFileSync(filePath, "utf-8"));/ / processing script
    if(! query.type) {/ / get the script
      const scriptContent = descriptor.script.content
      // export default {... } --------> const __script = {... }
      const script = scriptContent.replace('export default '.'const __script = ')
      // Returns the result of app.vue parsing
      ctx.type = 'text/javascript'
      ctx.body = `
        ${rewirteImport(script)}// If there is a style, send a request to get the style part${descriptor.styles.length ? `import "${url}? type=style"` : ' '}Import {render as __render} from 'import {render as __render} from'${url}? type=template' __script.render = __render export default __script `}}// ...
Copy the code

We refresh the browser and f12 cuts to Network to see the result:

Now that we can see the request style and template, let’s move on to template and style

(2) Process template

In vue, we use @vue/compiler-dom to compile the template. Since we return the Runtime version of vue, there is no compiler, we should return the compiled template. Let’s return the render function. Continue adding code to mini-viet.js:

/ /... To deal with the template
else if(query.type === 'template') {
      const templateContent = descriptor.template.content
      const render = compilerDom.compile(templateContent, {
        mode: 'module'
      }).code
      ctx.type = "application/javascript"
      ctx.body = rewirteImport(render);
    }
// ... template
Copy the code

We refreshed the browser and found the following:

Now let’s deal with style

(3)

Vite’s style processing is special, in the hot update module, because we did not implement hot update, let’s simulate the implementation here, return the Style content, in the client side to implement the method.

New code in mini-viet.js

// ...
/ / processing style
else if (query.type === "style") {
      const styleBlock = descriptor.styles[0];
      ctx.type = "application/javascript";
      ctx.body = `
        const css = The ${JSON.stringify(styleBlock.content)};
        updateStyle(css);
        export default css;
      `;
    }
// ...
Copy the code

Add updateStyle code to index.html:

/ /...<body>
    <div id="app"></div>
    <script>
      // hash: To avoid environment judgment by process.env.node_env
      window.process = {
        env: {
          NODE_ENV: 'dev',}};function updateStyle(content) {
       const isExist = typeofCSSStyleSheet ! = =undefined
       if(isExist) {
          // Method 1, use a constructible style sheet
        let cssStyleSheet = new CSSStyleSheet()
        cssStyleSheet.replaceSync(content)
        document.adoptedStyleSheets = [
          ...document.adoptedStyleSheets,
          cssStyleSheet
        ]
       } else {
         2 / / method
        let style = document.createElement('style')
        style.setAttribute('type'.'text/css')
        style.innerHTML = content
        document.head.appendChild(style)
       }
      }
    </script>
    <script src="/main.js" type="module"></script>
</body>/ /...Copy the code

Method 1: with constructible stylesheets, method 2 is a no-brait

Refresh the browser and see the result:

We can see from the figure that the SFC component has been successfully parsed.The core principle of hand-tearing Mini-ViteThat’s it.

7. Optimized point

Some students have found that the speed of our refresh is very slow, we actually said in the above principle has been said, Vite will rely on the use of strong cache, the source code using negotiated cache to speed up the response, we here to simulate the operation. Core ideas:

Cache-control: max-age=31536000,immutable; cache-control: no-cache; If etag is present, ifNoneMatch (eTAG) will be sent to the server. We compare the value with the unique hash value of the source code. If it is the same, 304 will be returned. If ifNoneMatch is absent or different, 200 and the new resource are returned and a new eTAG is set in the response header. If ifNoneMatch does not exist in the request header but ifModifiedSince(value: last-modified) is used to compare ifModifiedSince with the Last modified time of the source code, if the same, 304 is returned; If ifModifiedSince is not the same or does not exist, 200 and the new resource are returned and a new last-Modified is set in the response header. The condition for returning 304 to read from the cache is that there is a cache, and we all use HTTP header Expires caching for source code for a period of time.

The caching process can be referred to the following figure:

A bit different from the diagram, the source code file is requested directly from the negotiation cache, and does not judge the local cache. Instead, it makes a request directly and lets the server decide.

The code looks like this:

// mini-vite.js
// ...

/** Get the last modification time of the file */
const getFileUpdatedDate = (path) = > {
  const stats = fs.statSync(path);
  return stats.mtime;
};

/** Negotiates whether to return 304 or 200 */
const ifUseCache = (ctx, url, ifNoneMatch, ifModifiedSince) = > {
  let flag = false
  // Use negotiation cache
  ctx.set('Cache-Control'.'no-cache')
  // Set the expiration time to 30000 milliseconds, i.e. 30 seconds later
  ctx.set("Expires".new Date(Date.now() + 30000));
  let filePath = url.includes(".vue")? url : path.join(__dirname, url);if (url === "/") {
    filePath = path.join(__dirname, "./index.html");
  }
  // Get the last modification time of the file
  let fileLastModifiedTime = getFileUpdatedDate(filePath);
  console.log(fileLastModifiedTime, "lastTime");
  const buffer = fs.readFileSync(filePath, "utf-8");
  // Calculates the MD5 value of the requested file
  const hash = crypto.createHash("md5");
  hash.update(buffer, "utf-8");
  / / get the etag
  const etag = `${hash.digest("hex")}`;
  if (ifNoneMatch === etag) {
    ctx.status = 304;
    ctx.body = "";
    flag = true
  } else {
    // Etag inconsistent update the tag value, return a new resource
    ctx.set("etag", etag);
    flag = false
  }

  if(! ifNoneMatch && ifModifiedSince === fileLastModifiedTime) { ctx.status =304;
    ctx.body = "";
    flag = true
  } else {
    // The last modified time is inconsistent. Update the last modified time and return a new resource
    ctx.set("Last-Modified", fileLastModifiedTime);
    flag = false
  }
  return flag
};

app.use(async (ctx) => {
  const { url, query } = ctx.request;
  const { "if-none-match": ifNoneMatch, "if-modified-since": ifModifiedSince } =
    ctx.request.headers;
  const home = fs.readFileSync("./index.html"."utf-8");
  // 1. Return HTML
  if (url === "/") {
    ctx.type = "text/html";
    ctx.body = home;
  } else if (url.endsWith(".js")) {
    ctx.set("cache-control"."no-cache");
    // Determine whether to read the cache
    const used = ifUseCache(ctx, url, ifNoneMatch, ifModifiedSince);
    if (used) {
      ctx.status = 304
      ctx.body = null
      return;
    }
    / /...
  } else if (url.startsWith("/@modules/")) {
    // ...
    // Dependencies use strong caching
    ctx.set("cache-control"."max-age=31536000,immutable");
    // ...
  } else if (url.includes(".vue")) {
    // ...
    const usedCache = ifUseCache(
      ctx,
      url.slice(1).split("?") [0],
      ifNoneMatch,
      ifModifiedSince
    );
    if (usedCache) {
      ctx.status = 304
      ctx.body = null
      return;
    }
    // ...}});Copy the code

The first request results in the following, we can see that the source code has met the requirements, and the dependency has met the requirements:

On the second request we can find,Rely onStrong caching has been used for slavememoryordiskRead the source code and go to the negotiation is returned304or200.

🐳 9. First Vite project

1. Install

Compatibility Note Vite requires node.js versions >= 12.0.0.

Use NPM:

npm init @vitejs/app
Copy the code

The use of YARN

yarn create @vitejs/app
Copy the code

You can also run the following command:

# npm 6.x
npm init @vitejs/app my-vue-app --template vue

# NPM 7+ requires additional double lines:
npm init @vitejs/app my-vue-app -- --template vue

# yarn
yarn create @vitejs/app my-vue-app --template vue
Copy the code

Supported template presets include:

  • vanilla
  • vue
  • vue-ts
  • react
  • react-ts
  • preact
  • preact-ts
  • lit-element
  • lit-element-ts

See @vitejs/create-app for more details on each template.

Let’s look at the page request: the page entry returns index.html, which uses script type=”module” to introduce the entry file main.js, which will be requested when SRC or import is encountered:

When the browser requests the main.js file, Vite returns the following

Here a bare-mod quick substitution occurs, replacing import {createApp} from ‘vue’ with a relative path. Because browsers only have relative or absolute paths. Behind and launched a request to the App. Vue, vue. Js, HelloWorld. Vue

Type =style is used to process CSS and return it. CSS is handled in a special way. As you can see, updateStyle() is called in the return and vite puts it in the hot module update.

2. The command line

In projects with Vite installed, you can use the Vite executable in NPM Scripts or run it directly with NPX Vite. Here are the default NPM scripts for Vite projects created through scaffolding:

{
  "scripts": {
    "dev": "vite".// Start the development server
    "build": "vite build".// Build artifacts for production environments
    "serve": "vite preview" // Preview production builds locally}}Copy the code

You can use –port to specify the port to boot from, — HTTPS to use HTTPS, NPX vite –help to get more, a follow-up article on this takes you from 0 to lift a scaffolding tool

🐋 x. Custom Vite

1. Configuration file

(1) Configuration file parsing

When running vite from the command line, the default configuration file read is the vite.config.js file in the root directory. The default configuration generated by scaffolding looks like this:

You can also use vite –config filePath to specify configuration files, which default is based on the current project root directory.

(2) Configure intelligent prompt

Since Vite itself supports TS, you can use IDE and JSDOC to do this

/ * * * *@type {import('vite').UserConfig}* /
const config = {
  // ...
}

export default config
Copy the code

Or use the helper function defineConfig to get an intelligent hint that doesn’t apply to JSDoc:

import { defineConfig } from 'vite'

export default defineConfig({
  // ...
})
Copy the code

Define the configuration based on the environment

We can output different configurations based on environment (development, production) or command (server,build), as follows:

export default ({ command, Mode}) => {if (command === 'serve') {return {// serve unique configuration}} else {return {// build unique configuration}}}Copy the code

🦄 11. Conclusion

The code is rough, not too much encapsulation, just do the idea of transfer, in fact, there are still a lot of places can be optimized. Static resource hosting, resolution of less, SASS, Stylus, etc., can be integrated with ESBuilder to do more things, this is not mini-Vite, we only implement the core principles and ideas, interested children can continue to research to achieve their ideal.

🦓 twelve. Complete code

Mini-vite complete code

🦝 13. Reference

  • Vite – Chinese
  • Node practices thoroughly understanding strong and negotiated caches