Official documentation for a new, faster Web development tool

Introduction of vite

  1. Vite is a lighter, faster Web application development tool for modern browsers
  2. It is implemented based on the ECMAScript standard native module system (ES Modules)
  3. It appears to solve the problem of webpack using webpack-dev-server in the development phase, the cold start time is too long, in addition, the webpack-HMR hot update response is slow (the larger the Webpack project, the slower).

Why vite

  1. Solve the webpack development stage using Webpack-dev-server cold start time is too long, in addition, webpack-HMR hot update response speed is slow
  2. Easy to use
  3. Easy to extend (although a new tool, you can directly use the rollup ecosystem, which is relatively mature and has some packaging advantages over WebPack)

Why is Vite so fast

  1. The underlying implementation of Vite is based on esBuild pre-build dependencies.

    Esbuild is written using GO and is 10-100 times faster than a wrapper written in JS to pre-build dependencies.

    Because JS is so slow compared to Go, js usually operates in milliseconds and GO in nanoseconds.

  1. There is also a difference in how you start compared to WebPack

    Webpack schematic:

Vite schematic diagram:

  • Webpack packs, starts the development server, and gives the package results directly when the server is requested
  • Since Vite doesn’t need to be packaged at startup, which means there’s no need to analyze module dependencies and compile, it’s very fast to start up. When a browser requests a module, the content is compiled as needed. This dynamic compilation on demand greatly reduces the compilation time, and the more complex the project and the more modules, the more obvious the advantages of Vite
  • Since modern browsers naturally support ES Modules, they automatically make requests to dependent modules. Vite takes advantage of this by taking module files from the development environment as files to be executed by the browser, rather than being packaged and merged like WebPack.
  • Vite loads on demand, webPack loads all: In HMR (hot update), when a module is changed, Vite only needs to ask the browser to request the module again, unlike WebPack, which needs to compile all dependencies of the module once, which is more efficient.
  • Vite’s advantages are in the development environment: When it comes to packaging to production, Vite uses traditional rollup (you can also manually install webPack yourself) for packaging, so the main advantages of Vite are in the development phase. In addition, since Vite uses ES Module, you can’t use CommonJS in your code (except in viet.config.js, which is the node execution environment)

Vite principle

Vite takes advantage of the browser’s Native ES Module imports feature to organize code in ES mode. The browser automatically requests the required files and compiles them on the server side as needed, skipping the packaging process entirely. The key change is the way entry files are imported in index.html

This way you can organize your code in main.js using ES6 Modules:

Vite needs to do different parsing depending on the type of resource requested, for exampleApp.vue, returns the following content to the user (returns the JS code, which is returned after SFC parsing) :

Handwriting simple Vite implementation:

Based on this article, I tried to write a simple version of Vite

Vite basic applications

  1. Create a Vite project

    Use NPM:

    npm init vite
    Copy the code

    Using YARN:

    yarn create vite
    Copy the code
  2. Select the generated frame
    • vanilla
    • vue
    • react
    • preact
    • lit
    • svelte

    Note that the vUE chosen here refers to VUe3.0. There is no support for generating vue2 projects directly, but templates are available for download

    Github.com/lstoeferle/…

  3. index.htmlWith the project root directory

    In a Vite project, index. HTML is in the outermost layer of the project instead of in the public folder. This is intentional: Vite is a server during development, and index.html is the entry file for that Vite project.

  4. Configuring a Path Alias
    resolve: {
         alias: {
           "@": "/src",
         },
       },
    
    Copy the code
  5. Vite uses various CSS functions

    @importInlining and rebasing#

    Vite is preconfigured with postCSs-import to support CSs@import inlining. The path alias of Vite also complies with CSs@import. In other words, all CSS URL () references, even if the imported files are in different directories, are always automatically rebased to ensure correctness.

    @import url('/src/styles/test.scss');
    Copy the code

    About configuring global SCSS in a project

    css:{ preprocessorOptions: { scss: { // additionalData: `./src/styles/var.scss"; `, additionalData: [ '@import "@/styles/var.scss";', ] } } }Copy the code
  6. Typescript is used in Vite

    Vite naturally supports the introduction of.ts files

    Vite only performs translation of.ts files and does not perform any type checking. Assume that type checking has been taken over by your IDE or build process (you can either run TSC –noEmit in your build script or install vuE-tsc and run VUE-tsc –noEmit to type check your *.vue files).

    yarn add vue-tsc
    Copy the code

    In the package. The json

    "build": "vue-tsc --noEmit && vite build",
    Copy the code
  7. TSX, JSX are used in the project

    Install the plug-in yarn add @vitejs/plugin-vue-jsx -d vite.config.ts

    import vueJsx from "@vitejs/plugin-vue-jsx";
    export default defineConfig({
      plugins: [vueJsx()]
     })
    Copy the code

Vite advanced applications

  1. Hot update feature (how to implement hot update)

    The official documentation

    Vite provides a set of NATIVE ESM HMR apis. Frameworks with HMR capabilities can leverage this API to provide instant, accurate updates without reloading a page or cleaning up application state.

    Note that you don’t need to set this up manually — when you create the application through create-Vite, the selected template will already have this configured for you.

    Vite exposes the manual HMR API through special import.meta.hot objects. To implement hot updates

    First, be sure to guard all HMR API usage with a conditional statement so that the code can be tree-shaking optimized in production:

    If (import.meta. Hot) {// HMR code}Copy the code

    hot.accept(cb)

    To receive the module itself, use import.meta.hot.accept with the callback function that receives the updated module:

    export const count = 1
    ​
    if (import.meta.hot) {
      import.meta.hot.accept((newModule) => {
        console.log('updated: count is now ', newModule.count)
      })
    }
    Copy the code

    Vite’s HMR does not actually replace the originally imported modules: if the HMR boundary module re-exports its imports from a dependency, it is responsible for updating those re-exported modules (these exports must use lets). In addition, importers up from the boundary module will not receive updates.

    The sample

    Make a clean Vite project (clean Vite project does not include hot update)

    Modify the main.js file as follows

    import './style.css' export function rander() { document.querySelector('#app').innerHTML = ` <h1>Hello Vite! < / h1 > < a href = "https://vitejs.dev/guide/features.html" target = "_blank" > SSSSS < / a > `} rander () / / Vite through the special The import.meta. Hot object exposes the manual HMR API. if(import.meta.hot){ import.meta.hot.accept((newModule) => { newModule.rander() }) }Copy the code

    Open a browser and observe

    Through the above understanding, I know the logic and principle of hot update.

    Vite hot update, mainly through the creation of WebSocket browser and server to establish communication, by listening to the change of the file like the client sent a message, the client corresponding to different files for different operations of the update

  2. Glob-import Batch import function

    Require Context is a module method that is unique to Webpack and is not a language standard, so require Context can no longer be used in Vite. However, if the developer manually imports modules completely, on the one hand, it is easy to miss the import of modules because of the existing code changes. The second is to give up this “flexible” mechanism, the subsequent development model will also have certain changes. Fortunately, Vite2.0 provides module imports in Glob mode. This feature can achieve the above goals. Of course, some code changes will be required:

    Batch introduction in Webpack:

    // globJs = require.context('./globle/', true, /.js$/) console.log(globJs); globJs.keys().forEach(key => { console.log(key) console.log(globJs(key).default) const component = globJs(key).default app.component(component.name, component) })Copy the code

    Batch vite

    Use the glob

    Const globModules = import.meta.glob('./glob/*') // Can take regular expressions such as './glob/*-[0-9].ts' console.log(globModules); Object.entries(globModules).forEach(([k,v])=>{ console.log(k+':', v); / / use import module method of v (). Then (m = > {the console. The log (k + ', '+ m. efault); m.test() }) })Copy the code

    Using globEager

    GlobModules = import.meta. GlobEager ('./glob/*') // Can take regular expressions such as './glob/*-[0-9].ts' console.log(globModules); Object.entries(globModules).forEach(([k,v])=>{ console.log(k+':', v); v.test() })Copy the code

Vite plug-in development

  1. What is the Vite plug-in

    You can use the Vite plug-in to extend Vite capabilities, such as parsing user-defined file input, translating code before packaging it, or finding third-party modules.

    Order of plug-in calls

    • Alias handling Alias
    • User plug-in Settingsenforce: 'pre'
    • Vite core plug-in
    • The user plug-in is not configuredenforce
    • Vite builds plug-ins
    • User plug-in Settingsenforce: 'post'
    • Vite build post-plugins (Minify, Manifest, Reporting)

Example: Create test-plugin.js and write the test code

export default (enforce) => { return { name: 'test', enforce, buildStart() { console.log('buildStart', enforce); }, resolveId() { console.log('resolveId', enforce); }}}Copy the code

Introduce the plug-in in viet.config.js

​
import testPlugin from "./src/plugins/test-plugin";
​
// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),
        testPlugin('post'),
        testPlugin(),
        testPlugin('pre'),
    ]
})
Copy the code

The execution result

! [image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/28894cac327b46cfae8e87d3ff0c34eb~tplv-k3u1fbpfcp-zoom-1.im age)Copy the code
  1. Vite plugin form

    A Vite plug-in is an object that has a name, builds hooks, or outputs generate hooks.

    export default {
      name: 'my-vite-plugin',
      resolveId(id) {},
      load(id) {},
      transform(code) {}
    }
    Copy the code

    How does a plug-in contain configuration functionality, which should be in the form of a function that accepts plug-in options and returns plug-in objects

    Export default function (options) {return {name: 'my-vite-plugin', resolveId(id){}, load(id){}, transform(code){}, } }Copy the code
  2. Plug-in hooks (similar to the VUE lifecycle)

    At development time, Vite Dev Server creates a plug-in container that requests hook functions according to the rules for creating hooks in the Rollup call.

    The following hooks are called once when the service is started (file updates are not called either)

    • Options: Replace or manipulaterollupoptions
    • BuildStart: Starts building

    Vite specific hooks

    • Config: Modifies the Vite configuration
    • ConfigResolved: Confirm the Vite configuration
    • ConfigureServer: Used to configure dev Server and perform middleware operations
    • TransformIndexHtml: Used to transform host pages
    • HandleHotUpdate: called when a custom HMR update is performed

    The following hooks are called every time a module requests them :(core hook)

    • ResolveId: create a custom validation function, often used to locate third-party dependencies (find the corresponding file)
    • Load: Create custom load functions that can be used to return custom content (load file source code)
    • Transform: can be used to transform loaded module content (convert source code to required code)

    The following hooks are called once when the server is shut down:

    • buildEnd:
    • closeBundle
    Example: Hook calls sequential tests
    Export default function myExample () {return {name: 'links-order ', // initialize hooks, only once options(opts) {console.log('options'); }, buildStart() { console.log('buildStart'); }, // vite unique hook config(config) {console.log('config'); return {} }, configResolved(resolvedCofnig) { console.log('configResolved'); }, configureServer(server) { console.log('configureServer'); // server.app.use((req, res, next) => { // // custom handle request... // }) }, transformIndexHtml(html) { console.log('transformIndexHtml'); return html // return html.replace( // /<title>(.*?) </title>/, // `<title>Title replaced! </title>` // ) }, // Generic hook resolveId(source) {console.log(resolveId) if (source === 'virtual-module') {console.log('resolvedId'); return source; } return null; }, load(id) { console.log('load'); if (id === 'virtual-module') { return 'export default "This is virtual!" '; } return null; }, transform(code, id) { console.log('transform'); if (id === 'virtual-module') { } return code }, }; }Copy the code

    The execution result

    config
    configResolved
    options
    configureServer
    buildStart
    transformIndexHtml
    load
    load
    transform
    transform
    Copy the code

Stay tuned for the actual combat part