vitejs/vite · error · Error
import.meta.resolve is not supported in CJS config files
Error message
import.meta.resolve is not supported in CJS config files
What it means
Injected into the bundled config source when the config file is CommonJS but its code references `import.meta.resolve`. Vite shims `import.meta` variables in CJS configs, and since `import.meta.resolve` is an ESM-only runtime feature with no CJS equivalent, it injects a thunk that throws this message at call time. It is produced by the `inject-file-scope-variables` transform (config.ts:2626) only on the `!isESM` branch.
Source
Thrown at packages/vite/src/node/config.ts:2626
name: 'inject-file-scope-variables',
transform: {
filter: { id: /\.[cm]?[jt]s$/ },
handler(code, id) {
let injectValues =
`const ${dirnameVarName} = ${JSON.stringify(path.dirname(id))};` +
`const ${filenameVarName} = ${JSON.stringify(id)};` +
`const ${importMetaUrlVarName} = ${JSON.stringify(
pathToFileURL(id).href,
)};`
if (importMetaResolveRegex.test(code)) {
if (isESM) {
if (!importMetaResolverRegistered) {
importMetaResolverRegistered = true
createImportMetaResolver()
}
injectValues += `const ${importMetaResolveVarName} = (specifier, importer = ${importMetaUrlVarName}) => (${importMetaResolveWithCustomHookString})(specifier, importer);`
} else {
injectValues += `const ${importMetaResolveVarName} = (specifier, importer = ${importMetaUrlVarName}) => { throw new Error('import.meta.resolve is not supported in CJS config files') };`
}
}
let injectedContents: string
if (code.startsWith('#!')) {
const fileStartIndex = getFileStartIndex(code)
const hashbang = code.slice(0, fileStartIndex)
injectedContents =
hashbang +
(lineTerminatorRE.test(hashbang) ? '' : '\n') +
injectValues +
code.slice(fileStartIndex)
} else {
injectedContents = injectValues + code
}
return {
code: injectedContents,View on GitHub (pinned to 89620f09af)
Solutions
- Convert the config to ESM (rename to `vite.config.mjs` or set `"type": "module"`) so the real `import.meta.resolve` shim is wired up.
- Replace `import.meta.resolve(spec)` with `require.resolve(spec)` (and a `pathToFileURL`/`fileURLToPath` dance) while staying in CJS.
- Use `createRequire(import.meta.url).resolve(...)` only after moving to ESM — it is not available in pure CJS either.
Example fix
// before (vite.config.cjs)
const resolved = import.meta.resolve('./src/entry') // throws
// after (vite.config.mjs)
const resolved = import.meta.resolve('./src/entry') Defensive patterns
Strategy: validation
Validate before calling
// Reject import.meta.resolve usage in CJS configs before bundling
const isCjs = configPath.endsWith('.cjs') || (configPath.endsWith('.js') && pkg.type !== 'module')
if (isCjs && /import\.meta\.resolve/.test(fs.readFileSync(configPath, 'utf8'))) {
throw new Error('import.meta.resolve is unavailable in CJS configs; use .mjs')
} Type guard
function isEsmConfig(p: string): boolean {
return p.endsWith('.mjs') || (p.endsWith('.js') && require('./package.json').type === 'module')
} Prevention
- Keep all Vite configs in ESM (.mjs or "type": "module").
- Use require.resolve() as the CJS equivalent when you must stay CJS.
When it happens
Trigger: Authoring a `vite.config.cjs` (or any config bundled to CJS) that calls `import.meta.resolve(...)`. At runtime, when that call executes, the injected stub throws.
Common situations: Copy-pasting config snippets from ESM examples into a CJS config; using `import.meta.resolve` to locate a path in a project that hasn't enabled `"type": "module"`; migrating partially to ESM tooling.
Related errors
- Failed to resolve ${JSON.stringify(id)}. This package is ESM
- { runtime: "${result.runtime}" } is not supported for assets
- `renderLegacyChunks` and `renderModernChunks` cannot be both
- @vitejs/plugin-legacy does not support library mode.
- HMR is not supported by this runner transport, but `hmr` opt
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/305a624024ff5c73.json.
Report an issue: GitHub.