likes
comments
collection
share

Vite 插件指南Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象,在 Vite 不同的运行阶段进行

作者站长头像
站长
· 阅读数 9

Vite 插件是什么

Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象, Vite 不同的运行阶段进行调用。

通常的惯例是创建一个 Vite/Rollup 插件作为一个返回实际插件对象的工厂函数。该函数可以接受允许用户自定义插件行为的选项。

简单示例

转换自定义文件类型

const fileRegex = /\.(my-file-ext)$/

export default function myPlugin() {
  return {
    name: 'transform-file',
    transform(src, id) {
      if (fileRegex.test(id)) {
        return {
          code: compileFileToJS(src),
          map: null // 如果可行将提供 source map
        }
      }
    },
  }
}

用户将插件添加到项目的 devDependencies 中,使用数组形式的 plugins 选项配置它们。

// vite.config.js
import vitePlugin from 'vite-plugin-feature'
import rollupPlugin from 'rollup-plugin-feature'

export default defineConfig({
  plugins: [vitePlugin(), rollupPlugin()],
})

Vite 插件的作用

  • 将各种类型文件转换为 ES 模块
  • 编译 Less,Sass,Stylus 等文件
  • 编译各种前端框架的组件
  • 编译模板语言
  • ......

编写 Vite 插件

通常一个 Vite 插件使用 vite-plugin- 前缀,在 package.json 中包含 vite-plugin 关键字。

开发之前需要了解插件将在哪个阶段被调用

通用钩子

以下钩子在服务器启动时被调用:

以下钩子会在每个传入模块请求时被调用:

以下钩子在服务器关闭时被调用:

Vite 独有钩子

Vite 插件也可以提供钩子来服务于特定的 Vite 目标。这些钩子会被 Rollup 忽略。

添加测试环境提示

通过 transformindexhtml 钩子在页面上添加一个只在测试环境会出现的提示

function addTestMark(opts = {}) {
  return {
    apply: "build", // 或 'serve'
    name: "add-test-mark",
    transformIndexHtml(html) {
      const mark = `
        <style>
        .test-mark-parent {
          overflow: hidden; /* required */
          width: 150px; /* for demo only */
          height: 150px /* some non-zero number */;
          position: fixed; /* required  for demo*/
          top: 0;
          right: 0;
        }
        
        .test-mark-ribbon {
          margin: 0;
          padding: 0;
          background: greenyellow;
          color:white;
          padding:1em 0;
          position: absolute;
          top:0;
          right:0;
          transform: translateX(30%) translateY(0%) rotate(45deg);
          transform-origin: top left;
        }

        .test-mark-ribbon:before,
        .test-mark-ribbon:after {
          content: '';
          position: absolute;
          top:0;
          margin: 0 -1px; /* tweak */
          width: 100%;
          height: 100%;
          background: greenyellow;
        }

        .test-mark-ribbon:before {
          right:100%;
        }
        .test-mark-ribbon:after {
          left:100%;
        }
        </style>
        <div class="test-mark-parent">
          <h4 class="test-mark-ribbon">Test Mode</h4>
        <div>
      `
      return html + mark
    },
  }
}

export { addTestMark as default }

Vite 插件指南Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象,在 Vite 不同的运行阶段进行

去除生产 console 语句

通过解析代码 AST 将的 console 语句去掉。

Vite 插件指南Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象,在 Vite 不同的运行阶段进行

Vite 插件指南Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象,在 Vite 不同的运行阶段进行

可以使用 AST explorer 查看代码的抽象语法树。

首先在 transform 阶段获取到传入的代码源码,排除非项目代码,然后通过 babel 的 transformSync方法解析代码的抽象语法树,最后通过 visitor 访问器查询 console 语句的调用,将其删除即可。

import { transformSync } from "@babel/core"

function removeASTConsole(api) {
  const { types } = api

  return {
    visitor: {
      CallExpression(path) {
        if (
          types.isMemberExpression(path.node.callee) &&
          types.isIdentifier(path.node.callee.object, {
            name: "console",
          })
        ) {
          path.remove()
        }
      },
    },
  }
}

function removeConsole(opts = {}) {
  return {
    name: "remove-console",
    apply: "build",
    transform(src, id) {
      const exclude = [/node_modules\//]
      const include = [/\.(js|ts|jsx|tsx)/]

      const check =
        !exclude.some(item => new RegExp(item).test(id)) &&
        include.some(item => new RegExp(item).test(id))

      if (check) {
        const transformedCode = transformSync(src, {
          ast: true,
          plugins: [removeASTConsole],
        }).code

        return {
          code: transformedCode,
          map: null,
        }
      }
    },
  }
}

export { removeConsole as default }

Vite 插件指南Vite 插件是一个函数,返回一个具有属性,构建钩子,生成钩子的对象,在 Vite 不同的运行阶段进行

参考

插件 API | Vite 官方中文文档 (vitejs.dev)

插件开发 | Rollup 中文文档 (rollupjs.org)

转载自:https://juejin.cn/post/7302347058069405723
评论
请登录