In the last few articles, I wrote about the exploration of Vite2 in engineering and project practice, which was loved by my friends. One of them suggested that I would like to see how to write the vite plug-in. I looked at the documentation, viet-plugin-mock and viet-plugin-vue-i18n source code. Here to share, the content of this article is as follows:

  • Vite2 plug-in development guide
    • What is the Vite plug-in
    • Vite plugin form
    • The plugin hooks
    • Plug-in order
    • Plug-in writing practice
    • Accompanying video Tutorial
    • Form a complete set of source code
    • Follow-up Creation Plan
    • To support our

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.

Vite plugin form

The Vite plugin extends the Rollup plugin interface with additional Vite specific options.

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

If a plug-in needs to be configured, it should take the form of a function that takes the plug-in options and returns the plug-in object.

Example: Load a non-existent virtual module

Create vite – plugin – my – example. Js

export default function myExample () {
  return {
    name: 'my-example'.// The name is used for warnings and error presentations
    resolveId ( source ) {
      if (source === 'virtual-module') {
        return source; // Returning source indicates a hit, and Vite no longer asks other plug-ins to handle the ID request
      }
      return null; // Return null to indicate that it is another ID to continue processing
    },
    load ( id ) {
      if (id === 'virtual-module') {
        return 'export default "This is virtual!" '; // Return the source code of the "virtual-module" module
      }
      return null; // Other ids continue processing}}; }Copy the code

The plugin hooks

General hook

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 server starts:

  • optionsReplacement or manipulationrollupoptions
  • BuildStart starts building

The following hooks are called every time there is a module request:

  • ResolveId creates a custom validation function, commonly used to locate third-party dependencies
  • Load creates a custom load function that can be used to return custom content
  • Transform can be used to transform the loaded module content

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

  • buildEnd
  • closeBundle

Vite has unique hooks

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

Example: Hook calls sequential tests

export default function myExample () {
  // The plugin object is returned
  return {
    name: 'hooks-order'.// Initialize hooks, only once
    options(opts) {
      console.log('options', opts);
    },
    buildStart() {
      console.log('buildStart');
    },
    // Vite has unique hooks
    config(config) {
      console.log('config', 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 replaced! `
      // )
    },
    // Generic hook
    resolveId ( source ) {
      if (source === 'virtual-module') {
        console.log('resolvedId', source);
        return source; 
      }
      return null; 
    },
    load ( id ) {
      if (id === 'virtual-module') {
        console.log('load');
        return 'export default "This is virtual!" ';
      }
      return null;
    },
    transform(code, id) {
      if (id === 'virtual-module') {
        console.log('transform');
      }
      return code
    },
  };
}
Copy the code

Hook call order

Plug-in order

  • 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)

Plug-in writing practice

Implement a mock server vite-plugin-mock

The implementation idea is to configure a middleware for the development server instance (CONNECT), which can store the user configuration interface mapping information and process the input request in advance. If the URL of the request matches the routing table, it will take over and return the result according to the user configuration handler.

Creating plugins/vite – plugin – mock. Js

import path from 'path'

let mockRouteMap = {};

function matchRoute(req) {
  let url = req.url;
  let method = req.method.toLowerCase();
  let routeList = mockRouteMap[method];

  return routeList && routeList.find((item) = > item.path === url);
}

function createRoute(mockConfList) {
  mockConfList.forEach((mockConf) = > {
    let method = mockConf.type || 'get';
    let path = mockConf.url;
    let handler = mockConf.response;
    let route = { path, method: method.toLowerCase(), handler };
    if(! mockRouteMap[method]) { mockRouteMap[method] = []; }console.log('create mock api: ', route.method, route.path);
    mockRouteMap[method].push(route);
  });
}

function send(body) {
  let chunk = JSON.stringify(body);
  // Content-Length
  if (chunk) {
    chunk = Buffer.from(chunk, 'utf-8');
    this.setHeader('Content-Length', chunk.length);
  }
  // content-type
  this.setHeader('Content-Type'.'application/json');
  // status
  this.statusCode = 200;
  // respond
  this.end(chunk, 'utf8');
}
export default function (options = {}) {
  options.entry = options.entry || './mock/index.js';


  if(! path.isAbsolute(options.entry)) { options.entry = path.resolve(process.cwd(), options.entry); }return {
    configureServer: function ({ app }) {
      const mockObj = require(options.entry);
      createRoute(mockObj);

      const middleware = (req, res, next) = > {
        let route = matchRoute(req);

        if (route) {
          console.log('mock request', route.method, route.path);
          res.send = send;
          route.handler(req, res);
        } else{ next(); }}; app.use(middleware); }}; }Copy the code

Video tutorial

In addition to the above basic content, I also recorded the vite-plugin-VUE-i18N source code learning video, including the international plug-in installation, use, principle and handwriting implementation, wonderful, welcome friends to support: [prepare for 2021] Vite2 plug-in development guide “continuous update.”

Original is not easy, you are welcome to three small partners + attention, your encouragement is the biggest power I insist on ❤️

Form a complete set of source code

Welcome to pay attention to the public number village head to learn from the front

Follow-up Creation Plan

Why is Vite so fast, and can it take webpack’s place on the front end? I think friends and I must have such a question, I plan to do a Vite analysis of the principle, and finally write our own Vite. Please like 👍 and follow it for further study.