title: Duplicate Vue Plugin Detection impact: MEDIUM impactDescription: fixes cryptic build errors from Vue plugin registered twice type: capability
Impact: MEDIUM - fixes cryptic build errors from Vue plugin registered twice
When using Vite's JavaScript API, if the Vue plugin is loaded in vite.config.js and specified again in inlineConfig, it gets registered twice, causing cryptic build errors.
Vite doesn't deduplicate plugins by name when merging configs. The Vue plugin's internal state gets corrupted when registered twice.
Option 1: Use configFile: false with inline plugins
import vue from '@vitejs/plugin-vue'
import { build } from 'vite'
await build({
configFile: false, // Don't load vite.config.js
plugins: [vue()],
// ... rest of config
})
Option 2: Don't specify plugins in inlineConfig
// vite.config.js already has vue plugin
import { build } from 'vite'
await build({
// Don't add vue plugin here - it's in vite.config.js
root: './src',
build: { outDir: '../dist' }
})
Option 3: Filter out Vue plugin before merging
import vue from '@vitejs/plugin-vue'
import { build, loadConfigFromFile } from 'vite'
const { config } = await loadConfigFromFile({ command: 'build', mode: 'production' })
// Remove existing Vue plugin
const filteredPlugins = config.plugins?.filter(
p => !p || (Array.isArray(p) ? false : p.name !== 'vite:vue')
) || []
await build({
...config,
plugins: [...filteredPlugins, vue({ /* your options */ })]
})
Add this to debug plugin registration:
// vite.config.ts
export default defineConfig({
plugins: [
vue(),
{
name: 'debug-plugins',
configResolved(config) {
const vuePlugins = config.plugins.filter(p => p.name?.includes('vue'))
if (vuePlugins.length > 1) {
console.warn('WARNING: Multiple Vue plugins detected:', vuePlugins.map(p => p.name))
}
}
}
]
})
| Scenario | Solution |
|---|---|
Using vite.createServer() |
Use configFile: false |
| Build script with custom config | Don't duplicate plugins |
| Monorepo with shared config | Check for plugin inheritance |