Skip to content
Created: July 20, 2024

Write a Vite plug-in that actually works

Function: Automatically remove console.log in the code when compiling ​

For example:

js
console.log("hello")

After building it becomes:

js
// 被移除

You will learn:

  • Plug-in structure
  • Vite plug-in life cycle
  • transform hook
  • Process file ID
  • Hot update behavior

Then gradually upgrade the plug-in.

📌 Step 1: Basic structure of the plug-in ​

A Vite plugin is essentially a function returns an object :

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

This is the most basic plugin structure for Vite.

📌 Step 2: Understand the plug-in life cycle ​

Vite plug-in API = Rollup plug-in + Vite's own extension.

The hooks you will use most often are these:

hookfunction
configModify Vite configuration
configureServerdev server middleware
resolveIdpath resolution
loadcustom content return
transformModify the core hook of the source code
handleHotUpdateHMR

We just need transform now.

📌 Step 3: Implement transform() processing code ​

Our goal: remove console.log(...).

The transform hook will accept two parameters:

ts
transform(code, id) { ... }
  • code: source code of the current file
  • id: including path, query, style suffix, etc., for example:
/src/main.js?import

✔ Implement plug-in function (first version) ​

Create plugins/remove-console.js at the project root:

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: Use plugins in Vite ​

vite.config.js:

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

export default {
  plugins: [
    removeConsole()
  ]
}

Start the project:

npm run dev

Open the console and you will see that all console.log has been removed during the compilation phase.

📢 You now know how to write a basic Vite plugin ​

Let's continue upgrading and let you enter the real "plug-in developer" level.

⭐ Step 5: Support multiple console methods (more professional) ​

For example:

  • console.info
  • console.debug
  • console.warn
  • console.error (optional)

Use regular expressions:

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

Modify the plugin:

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

⭐ Step 6: Remove console only in production environment ​

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: Support user-defined configuration (required for professional plug-ins) ​

Make plugins more flexible:

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, '')
    }
  }
}

Users use this:

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

⭐ Step 8: Support sourcemap (advanced) ​

Return:

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

⭐ Step 9: Support HMR (optional) ​

If you remove the console in dev mode too, HMR needs to be consistent.

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

🧱 A complete, professional and publishable plug-in structure ​

Complete plugin file (full version):

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,
      }
    }
  }
}