Skip to content

写一个真正能运行的 Vite 插件

功能:自动将代码中的 console.log 编译时移除

例如:

js
console.log("hello")

构建后变成:

js
// 被移除

你将学会:

  • 插件结构
  • Vite 插件生命周期
  • transform 钩子
  • 处理文件 ID
  • 热更新行为

然后再逐步升级插件。

📌 Step 1:插件的基础结构

一个 Vite 插件本质上就是一个 函数返回一个对象

ts
export default function myPlugin() {
  return {
    name: 'my-plugin',
  }
}

这是 Vite 最基本的插件结构。

📌 Step 2:理解插件生命周期

Vite 插件 API = Rollup 插件 + Vite 自己扩展。

你最常用的是这些 hook:

hook作用
config修改 Vite 配置
configureServerdev server 中间件
resolveId路径解析
load自定义内容返回
transform修改源码的核心 hook
handleHotUpdateHMR

我们现在只需要 transform。

📌 Step 3:实现 transform() 处理代码

我们的目标:删掉 console.log(...)

transform hook 会接受两个参数:

ts
transform(code, id) { ... }
  • code:当前文件的源码
  • id:包括路径、query、样式后缀等,例如:
/src/main.js?import

✔ 实现插件功能(初版)

在项目根创建 plugins/remove-console.js

js
export default function removeConsole() {
  return {
    name: 'vite-plugin-remove-console',

    transform(code, id) {
      if (!id.endsWith('.js') && !id.endsWith('.ts')) return;

      // 简单替换逻辑
      const transformed = code.replace(/console\.log\(.*?\);?/g, '')

      return {
        code: transformed,
        map: null, // 可选:不生成 sourcemap
      }
    }
  }
}

📌 Step 4:在 Vite 中使用插件

vite.config.js

js
import removeConsole from './plugins/remove-console.js'

export default {
  plugins: [
    removeConsole()
  ]
}

启动项目:

npm run dev

打开控制台,你会看到所有 console.log 在编译阶段已被移除。

📢 你现在已经会写一个基础 Vite 插件了

下面我们继续升级,让你进入真正的“插件开发者”层级。

⭐ Step 5:支持多种 console 方法(更专业)

比如:

  • console.info
  • console.debug
  • console.warn
  • console.error(可选)

使用正则:

js
const regex = /console\.(log|info|debug)\(.*?\);?/g

修改插件:

js
const transformed = code.replace(
  /console\.(log|info|debug)\(.*?\);?/g,
  ''
)

⭐ Step 6:只在生产环境移除 console

js
export default function removeConsole() {
  return {
    name: 'vite-plugin-remove-console',

    apply: 'build', // 仅在 build 阶段启用

    transform(code, id) {
      if (!id.match(/\.(js|ts)$/)) return

      return code.replace(
        /console\.(log|info|debug)\(.*?\);?/g,
        ''
      )
    }
  }
}

⭐ Step 7:支持用户自定义配置(专业插件必备)

让插件更灵活:

js
export default function removeConsole(options = {}) {
  const methods = options.methods || ['log', 'info', 'debug']

  const reg = new RegExp(`console\\.(${methods.join('|')})\\(.*?\\);?`, 'g')

  return {
    name: 'vite-plugin-remove-console',

    apply: 'build',

    transform(code, id) {
      if (!id.match(/\.(js|ts)$/)) return
      return code.replace(reg, '')
    }
  }
}

用户这样用:

js
removeConsole({
  methods: ['log', 'debug']
})

⭐ Step 8:支持 sourcemap(进阶)

返回:

js
return {
  code: transformed,
  map: this.getCombinedSourcemap()
}

⭐ Step 9:支持 HMR(选学)

如果你要在 dev 模式也移除 console,HMR 要保持一致。

js
handleHotUpdate(ctx) {
  console.log('File changed:', ctx.file)
}

🧱 一个完整、专业、可发布的插件结构

完整插件文件(完整版):

vite-plugin-remove-console/
 ├─ index.js
 ├─ package.json
 ├─ README.md
 └─ LICENSE

index.js

js
export default function removeConsole(options = {}) {
  const methods = options.methods || ['log', 'info', 'debug']

  const reg = new RegExp(
    `console\\.(${methods.join('|')})\\(.*?\\);?`,
    'g'
  )

  return {
    name: 'vite-plugin-remove-console',
    apply: options.apply || 'build',

    transform(code, id) {
      if (!id.match(/\.(js|ts)$/)) return

      const transformed = code.replace(reg, '')

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