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)

相关推荐
下雪天的夏风10 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom21 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan25 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
Hello-Mr.Wang38 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步7 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js