feat: add Vite 8 support

Vite 8 replaces Rollup with Rolldown, which removes the
`resolveImportMeta` hook. Add a `renderChunk` fallback in the
importMeta plugin so `import.meta.url/filename/dirname` are still
rewritten to CJS equivalents. The existing `resolveImportMeta` hook
is kept for Vite 5-7 backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Steve Zhu 2026-04-04 17:05:17 -04:00
parent a9a496dc1a
commit 8660e7ac5e
No known key found for this signature in database
2 changed files with 36 additions and 1 deletions

View File

@ -61,7 +61,7 @@
},
"peerDependencies": {
"@swc/core": "^1.0.0",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"@swc/core": {

View File

@ -1,10 +1,17 @@
import MagicString from 'magic-string'
import type { SourceMapInput } from 'rollup'
import type { Plugin } from 'vite'
const importMetaUrlRE = /\bimport\.meta\.url\b/g
const importMetaFilenameRE = /\bimport\.meta\.filename\b/g
const importMetaDirnameRE = /\bimport\.meta\.dirname\b/g
export default function importMetaPlugin(): Plugin {
return {
name: 'vite:import-meta',
apply: 'build',
enforce: 'pre',
// For Vite 5-7 (Rollup) - this hook is removed in Vite 8
resolveImportMeta(property, { format }): string | null {
if (property === 'url' && format === 'cjs') {
return `require("url").pathToFileURL(__filename).href`
@ -16,6 +23,34 @@ export default function importMetaPlugin(): Plugin {
return `__dirname`
}
return null
},
// Fallback for Vite 8+ (Rolldown) where resolveImportMeta is removed
renderChunk(code, _chunk, { format, sourcemap }): { code: string; map?: SourceMapInput } | null {
if (format !== 'cjs') return null
if (!code.includes('import.meta.')) return null
const s = new MagicString(code)
let hasReplacements = false
for (const match of code.matchAll(importMetaUrlRE)) {
s.overwrite(match.index, match.index + match[0].length, 'require("url").pathToFileURL(__filename).href')
hasReplacements = true
}
for (const match of code.matchAll(importMetaFilenameRE)) {
s.overwrite(match.index, match.index + match[0].length, '__filename')
hasReplacements = true
}
for (const match of code.matchAll(importMetaDirnameRE)) {
s.overwrite(match.index, match.index + match[0].length, '__dirname')
hasReplacements = true
}
if (!hasReplacements) return null
return {
code: s.toString(),
map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
}
}
}
}