Vite 插件指南

Vite 插件是什么

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

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

简单示例

转换自定义文件类型

js 复制代码
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 选项配置它们。

js 复制代码
// 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 钩子在页面上添加一个只在测试环境会出现的提示

js 复制代码
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 }

去除生产 console 语句

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

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

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

js 复制代码
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 }

参考

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

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

相关推荐
小墨宝21 分钟前
js 生成pdf 并上传文件
前端·javascript·pdf
HED36 分钟前
用扣子快速手撸人生中第一个AI智能应用!
前端·人工智能
DN金猿40 分钟前
使用npm install或cnpm install报错解决
前端·npm·node.js
丘山子41 分钟前
一些鲜为人知的 IP 地址怪异写法
前端·后端·tcp/ip
志存高远661 小时前
Kotlin 的 suspend 关键字
前端
www_pp_1 小时前
# 构建词汇表:自然语言处理中的关键步骤
前端·javascript·自然语言处理·easyui
天天扭码2 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
一个专注写代码的程序媛2 小时前
为什么vue的key值,不用index?
前端·javascript·vue.js
vvilkim2 小时前
React 与 Vue:两大前端框架的深度对比
vue.js·react.js·前端框架
장숙혜2 小时前
ElementUi的Dropdown下拉菜单的详细介绍及使用
前端·javascript·vue.js