.claude/skills/vite/vite-errors/vite-errors-build/SKILL.md
Use when encountering Vite build failures, chunk size warnings, or version-specific build errors. Prevents the common mistake of using deprecated rollupOptions in v8 or misconfiguring build targets and minifiers. Covers Rolldown/Rollup bundling failures, CSS minification errors, sourcemap problems, library mode build failures, BundleError handling, and asset processing errors. Keywords: build error, Rolldown, chunk size, sourcemap, library mode, minify, BundleError, rollupOptions, build.target.
npx skillsauth add OpenAEC-Foundation/OpenAEC-Workspace-Composer vite-errors-buildInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Symptom | Cause | Fix |
|---------|-------|-----|
| Could not resolve './module' | Unresolved import path | Check file exists, verify resolve.alias config, ensure extensions match resolve.extensions |
| Circular dependency detected | Modules import each other | Refactor shared logic into a third module; use dynamic import() to break the cycle |
| [vite]: Rollup failed to resolve import | Bare import not in node_modules | Run npm install, verify package name spelling, check optimizeDeps.include |
| Warning: Some chunks are larger than 500 KiB | Chunk exceeds build.chunkSizeWarningLimit | Code-split with dynamic imports, increase limit, or use build.rolldownOptions.output.manualChunks |
| build.target: Unexpected token | Syntax too modern for target browsers | Lower build.target (e.g., 'es2020') or add @vitejs/plugin-legacy |
| CSS minification error (v8) | Lightning CSS cannot parse CSS | Set build.cssMinify: 'esbuild' as fallback; fix invalid CSS syntax |
| Sourcemap is likely to be incorrect | Plugin transforms without sourcemap | Set build.sourcemap: false or fix plugin to emit sourcemaps |
| Missing "name" option for UMD export | Library mode UMD without name | Add build.lib.name: 'MyLib' for UMD/IIFE formats |
| build.rollupOptions is deprecated (v8) | Using Rollup config key in v8 | Rename to build.rolldownOptions |
| BundleError thrown (v8) | Build API throws structured error | Catch with e.errors array iteration (see v8 Error Handling) |
| terser not found | Terser not installed | Run npm install -D terser; or switch to build.minify: 'oxc' (v8 default) |
| esbuild not found (v8) | esbuild no longer bundled in v8 | Run npm install -D esbuild; or migrate to oxc config |
| Could not load content for ... (sourcemap) | Sourcemap references missing source | Set build.sourcemap: 'hidden' or ensure sources exist |
| vite:preloadError in browser | Dynamic import chunk missing after deploy | Listen for vite:preloadError event, trigger page reload |
| emptyOutDir: outDir is not inside root | Safety check prevents deletion | Pass build.emptyOutDir: true explicitly to override |
| assetsDir is ignored in lib mode | Library mode ignores build.assetsDir | ALWAYS use flat output or build.rolldownOptions.output.assetFileNames in lib mode |
| moduleType not set (v8 plugin) | Plugin transforms non-JS without declaring type | Add moduleType: 'js' in plugin load/transform hook return |
NEVER ignore chunk size warnings in production -- they indicate bundles that degrade page load performance. ALWAYS code-split large vendor dependencies with dynamic imports.
NEVER set build.sourcemap: true in production without understanding the security implications -- sourcemaps expose original source code. Use 'hidden' to generate maps without embedding references.
NEVER use build.rollupOptions in Vite 8 -- it is deprecated and will be removed. ALWAYS use build.rolldownOptions instead.
ALWAYS install terser separately when using build.minify: 'terser' -- Vite does NOT bundle terser. In v8, esbuild is also not bundled.
ALWAYS handle vite:preloadError in SPAs to gracefully recover from stale chunk references after deployment.
Build fails?
|
+-- Error message contains "resolve"?
| +-- Bare import? --> Check node_modules, run npm install
| +-- Relative import? --> Verify file path, check resolve.alias
| +-- TypeScript path? --> Enable resolve.tsconfigPaths or add alias
|
+-- Error message contains "chunk" or "size"?
| +-- Warning only? --> Split code or raise build.chunkSizeWarningLimit
| +-- Build fails? --> Check build.rolldownOptions.output config
|
+-- Error message contains "CSS"?
| +-- Lightning CSS error (v8)? --> Fallback to build.cssMinify: 'esbuild'
| +-- Preprocessor error? --> Check sass/less/stylus installed
| +-- PostCSS error? --> Verify postcss config, check plugin versions
|
+-- Error message contains "minify"?
| +-- terser not found? --> npm install -D terser
| +-- esbuild not found (v8)? --> npm install -D esbuild or use oxc
| +-- oxc error? --> Check oxc config syntax, report upstream if bug
|
+-- Error message contains "target"?
| +-- Syntax error in output? --> Lower build.target
| +-- CSS feature unsupported? --> Set build.cssTarget separately
|
+-- Library mode error?
| +-- Missing name? --> Add build.lib.name for UMD/IIFE
| +-- Missing externals? --> Add to build.rolldownOptions.external
| +-- CSS filename? --> Use build.lib.cssFileName
|
+-- v8 migration error?
+-- rollupOptions? --> Rename to rolldownOptions
+-- esbuild config? --> Rename to oxc config
+-- moduleType error? --> Add moduleType: 'js' in plugin
+-- BundleError? --> Catch e.errors array
Vite 8 throws a BundleError from the build() API instead of raw errors. ALWAYS use structured error handling:
import { build } from 'vite'
try {
await build()
} catch (e) {
if (e.errors) {
// BundleError: iterate structured error array
for (const error of e.errors) {
console.error(`[${error.code}] ${error.message}`)
if (error.frame) console.error(error.frame)
if (error.loc) {
console.error(` at ${error.loc.file}:${error.loc.line}:${error.loc.column}`)
}
}
} else {
// Fallback for non-BundleError
throw e
}
}
Default warning limit: 500 KiB (uncompressed). To fix large chunks:
// Option 1: Dynamic imports for route-level code splitting
const AdminPanel = () => import('./views/AdminPanel.vue')
// Option 2: Manual chunk splitting (v8 with Rolldown)
export default defineConfig({
build: {
rolldownOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('lodash')) return 'vendor-lodash'
if (id.includes('chart.js')) return 'vendor-charts'
return 'vendor'
}
},
},
},
},
})
// Option 3: Raise the limit (last resort)
export default defineConfig({
build: {
chunkSizeWarningLimit: 1000, // KiB
},
})
NEVER raise chunkSizeWarningLimit without first attempting code splitting -- the warning exists to protect user experience.
After deployment, users with cached pages may request chunks that no longer exist. ALWAYS add this handler to SPA entry points:
// main.ts -- add BEFORE app initialization
window.addEventListener('vite:preloadError', (event) => {
event.preventDefault()
// Reload to fetch updated HTML with new chunk references
window.location.reload()
})
Vite refuses to empty outDir if it is outside the project root:
// outDir outside root triggers safety warning
export default defineConfig({
build: {
outDir: '../dist', // Outside root -- Vite warns and skips
emptyOutDir: true, // Explicit override required
},
})
ALWAYS set build.emptyOutDir: true explicitly when outDir is outside root. Vite adds this safety check to prevent accidental deletion of unrelated directories.
| Error Pattern | Vite 6 | Vite 7 | Vite 8 |
|--------------|--------|--------|--------|
| Bundler config key | build.rollupOptions | build.rollupOptions | build.rolldownOptions |
| Transform config | esbuild | esbuild | oxc |
| Default minifier | esbuild | esbuild | oxc |
| CSS minifier default | esbuild | esbuild | Lightning CSS |
| build.target default | 'modules' | 'baseline-widely-available' | 'baseline-widely-available' |
| Build error type | Raw error | Raw error | BundleError |
| Plugin moduleType | Not required | Not required | Required for non-JS |
| Node.js minimum | 18+ | 20.19+ / 22.12+ | 20.19+ / 22.12+ |
development
Use when integrating Vite with a backend framework, rendering Vite assets from server-side templates, or setting up dev/production HTML serving. Prevents incorrect manifest.json traversal and missing CSS chunk resolution in production. Covers build.manifest configuration, .vite/manifest.json structure, ManifestChunk properties, dev mode HTML setup, production rendering, CSS/JS chunk resolution, and modulepreload polyfill. Keywords: backend integration, manifest.json, ManifestChunk, Django, Laravel, Rails, modulepreload.
development
Use when encountering dev server startup failures, HMR issues, proxy errors, CORS blocks, or module not found errors during development. Prevents misconfiguring server.hmr behind reverse proxies and forgetting appType: 'custom' in middleware mode. Covers HMR full-reload debugging, proxy configuration, CORS setup, HTTPS certificates, server.fs.strict violations, port conflicts, WebSocket failures, file watcher issues, and middleware mode. Keywords: dev server, HMR, proxy, CORS, HTTPS, WebSocket, port conflict, server.fs.strict, middleware mode, file watcher.
development
Use when encountering pre-bundling errors, dependency resolution failures, stale cache issues, or slow development server startup. Prevents excluding CJS dependencies from pre-bundling (which breaks runtime module resolution) and misconfiguring optimizeDeps. Covers CJS/ESM conversion failures, missing dependency auto-discovery, optimizeDeps configuration, monorepo linked dependencies, cache invalidation, browser cache staleness, and large dependency tree performance. Keywords: pre-bundling, optimizeDeps, CJS, ESM, cache, dependency resolution, monorepo, node_modules/.vite.
tools
Use when configuring SSR environments, edge workers, custom environments, or migrating to the Vite 6+ environment model. Prevents using the Environment API on Vite 5 (where it does not exist) and misconfiguring per-environment vs shared plugin scoping. Covers per-environment build and dev settings, EnvironmentOptions interface, custom environment providers, shared vs per-environment plugins, configuration inheritance, and migration from Vite 5 implicit environments. Keywords: vite, environment api, vite 6, SSR, edge workers, per-environment config, providers.