Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Vite from entry to master | plug-in system

introduce

Naming conventions

  • rollup-plugin-xxx
  • vite-plugin-xxx

Vite is compatible with Rollup hooks

  • Service startup (once when the server is started, independent of file updates)
    • options
    • buildStart
  • Module (find the corresponding file,-> Load -> transform object code)
    • resolveId
    • load
    • transform
  • Service shutdown
    • buildEnd
    • closeBundle

ModulePased is not called, preventing Vite from performing AST parsing on code as a whole

The rollup plug-in can be configured in the build

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// Introduce JSX dependencies
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
 
  plugins: [ // Use plugins
    vue(),
    vueJsx(),/ / to use vue - JSX].build: {
    rollupOptions:{
      plugins
    }
  }
})
Copy the code

Conditions: The rollup plug-in meets the vite usage conditions

  • The moduleParsed hook is not used
  • There is no strong coupling between the packaged hook and the output hook

Vite hooks

  • config
  • configResolved
  • configureServer
  • transformIndexHtml
  • handleHotUpdate

Vite plug-in execution time

  • Pre: the first plugin to be executed. Vite uses the Rolluo Alias plugin to execute the plugin in the order defined in the plugin array
  • Normal: After the vite core plug-in is executed and before the Vite build plug-in is executed
  • Post: executed after the vite build plug-in

In field

  • The vite project creates plugins/test-plugin.ts

    // test-plugin.ts
    export default(enforce? :'pre' | 'post') = > {return {
            name: 'test',
            enforce,
    
            buildStart() {
                console.log("buildStart", enforce)
            },
            resolveId(){
                console.log('resolveId',enforce)
            }
        }
    }
    Copy the code
  • Vite. Config. Js configuration

    // vim vite.config.js
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    // Introduce JSX dependencies
    import vueJsx from '@vitejs/plugin-vue-jsx'
    import testPlugin from './plugins/test-plugin'
    // https://vitejs.dev/config/
    export default defineConfig({
     plugins: [
       vue(),
       vueJsx(),
       testPlugin('post'),
       testPlugin(),
       testPlugin('pre')]})Copy the code
  • The output

    $yarn dev yarn run v1.22.4 Warning package.json: No license field $vite buildStart pre buildStart undefined buildStart post vite v2.6.2 dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose readyin 415ms.
    
    > Pre > normal > post
    Copy the code

Vite Plugin API (Hooks)

  • Config: return a new config with viet.config. js deepMerge

    import { Plugin } from "vite";
    export default(enforce? :"pre" | "post") :Plugin= > {
      return {
        name: "test".// userConfig configuration item in vite.config.js
        config(userConfig) {
            // return a new config with viet.config. js deepMerge
            return {
                resolve: {
                    alias: {
                        "@img": '/src/img'}}}},}; };Copy the code
  • configResolved

    import { Plugin } from "vite";
    export default(enforce? :"pre" | "post") :Plugin= > {
      return {
        name: "test".// config: final config
        configResolved(config){
      			// Print the plugins in the final config
            console.log(config.plugins)
        }
      };
    };
    
    Copy the code

    results

    [
      {
        name: 'vite:pre-alias',
      },
      {
        name: 'alias',
      },
      {
        name: 'vite:modulepreload-polyfill',
      },
      {
        name: 'vite:resolve',
      },
      {
        name: 'vite:html',
      },
      {
        name: 'vite:css',
      },
      {
        name: 'vite:esbuild',
      },
      { name: 'vite:json'},
      {
        name: 'vite:wasm',
      },
      {
        name: 'vite:worker',
      },
      {
        name: 'vite:asset',
      },
      {
        name: 'vite:vue',
        handleHotUpdate: [Function: handleHotUpdate],
        config: [Function: config],
        configResolved: [Function: configResolved],
        configureServer: [Function: configureServer],
        resolveId: [AsyncFunction: resolveId],
        load: [Function: load],
        transform: [Function: transform]
      },
      {
        name: 'vite:vue-jsx',
      },
      { name: 'test', },
      { name: 'vite:define',},
      {
        name: 'vite:css-post',
      },
      { name: 'vite:client-inject',},
      {
        name: 'vite:import-analysis',}]Copy the code
  • configureServer

      configureServer(server){
            // Add middleware
            // Will be executed before Vite middleware
            server.middlewares.use((req,res,next) = > {
                if (req.url === "/test") {
                    res.end("Hello Vite Plugin")}else {
                    next()
                }
            })
        }
    Copy the code

  • transformIndexHtml

    transformIndexHtml(html) {
      // Here you can process index.html
      console.log(html)
    }
    
    Copy the code
    <! DOCTYPE html> <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <link rel="icon" href="/favicon.ico" />
        <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
        <title>Vite App</title>
      </head>
      <body>
        <div id="app"> <! --APP_HTML--></div> <scripttype="module" src="/src/main.js"></script>
      </body>
    </html>
    Copy the code
    / / deal with HTML
    transformIndexHtml(html) {
            return html.replace('app'.'root')}Copy the code

  • handleHotUpdate

    handleHotUpdate (ctx) {
      // All information about the updated file
      console.log(ctx)
    }
    Copy the code