Fix Vite Build Rollup Failed to Resolve Import
Quick Answer
- Conclusion: This error occurs when Vite's production bundler (Rollup) cannot statically resolve an import statement during
vite build, even if development mode works fine. - First checks: Verify that
vite.config.tsexists in your build context, all dependencies are installed, and path aliases are configured correctly in bothvite.config.tsandtsconfig.json. - Minimal fix: Add missing dependencies with
npm install, or configureresolve.aliasinvite.config.tsusing absolute paths withpath.resolve(). - Environment boundary: This error is specific to Vite projects using Rollup for production builds. It does not apply to development server errors, runtime errors, or non-Vite projects.
When This Error Appears
The "Rollup failed to resolve import" error typically surfaces during vite build in these scenarios:
- Path alias mismatch: You use
@/components/Buttonbutresolve.aliasis missing or misconfigured invite.config.ts. - Missing dependencies: A package referenced in your code is not installed or has incompatible versions.
- Docker/CI builds: The build context lacks
vite.config.tsornode_modulesis not properly installed. - CommonJS module issues: Rollup cannot resolve a CommonJS package that esbuild handled fine in development.
- Dynamic imports: Fully dynamic
import(variable)statements that Rollup cannot statically analyze.
Root Cause Analysis
Vite uses two different bundlers depending on the environment:
| Environment | Bundler | Behavior |
|---|---|---|
Development (vite dev) | esbuild | More forgiving with CommonJS, path resolution, and dynamic imports |
Production (vite build) | Rollup | Stricter module resolution, requires explicit configuration |
This dual-bundler architecture means code that works perfectly in development can fail during production builds. The most common root causes are:
- Alias configuration mismatch:
vite.config.tsuses relative paths or is missing entirely from the build context. - Missing pre-bundling: Dependencies that esbuild automatically pre-bundles in dev mode are not pre-bundled for Rollup.
- Inconsistent path mappings:
tsconfig.jsonpaths exist butvite.config.tsaliases do not, or vice versa.
Common Errors and Fixes
Error: Path alias not resolved
[rollup-plugin-dynamic-import-variables] Could not resolve './components/Button' from 'src/App.tsx'
Fix: Configure resolve.alias in vite.config.ts with absolute paths, and sync with tsconfig.json:
TYPESCRIPT// vite.config.ts import { defineConfig } from 'vite'; import path from 'path'; export default defineConfig({ resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, });
JSON// tsconfig.json { "compilerOptions": { "paths": { "@/*": ["./src/*"] } } }
Error: Dependency not resolved
[vite]: Rollup failed to resolve import "tailwindcss" from "src/index.css"
Fix: Install the dependency and configure the plugin correctly:
BASHnpm install tailwindcss @tailwindcss/vite
TYPESCRIPT// vite.config.ts import { defineConfig } from 'vite'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [tailwindcss()], });
Error: CommonJS package not resolved
[vite]: Rollup failed to resolve import "lodash" from "src/App.tsx"
Fix: Force pre-bundling with optimizeDeps.include, or use subpath imports:
TYPESCRIPT// vite.config.ts export default defineConfig({ optimizeDeps: { include: ['lodash'], }, });
Alternatively, import the specific subpath:
TYPESCRIPTimport debounce from 'lodash/debounce';
Error: Build fails in Docker
[vite]: Rollup failed to resolve import "some-lib" from "src/utils/helper.ts"
Fix: Ensure vite.config.ts is copied into the Docker build context:
DOCKERFILECOPY package.json package-lock.json ./ RUN npm ci COPY vite.config.ts ./ COPY . .
Also verify that .dockerignore does not exclude vite.config.ts.
FAQ
Q: Why does development mode work but production build fails with "Rollup failed to resolve import"?
A: This is caused by Vite's dual-bundler architecture. Development uses esbuild, which is more lenient with CommonJS modules and path resolution. Production uses Rollup, which is stricter. Common causes include:
vite.config.tsmissing from the build context (especially in Docker)- Dependencies that esbuild auto-pre-bundles but Rollup cannot resolve
- Use of
import.meta.envvariables only available in development
Solution: Verify vite.config.ts is present in the build context and add problematic dependencies to optimizeDeps.include.
Q: I configured resolve.alias in vite.config.ts, but the build still fails with "Could not resolve '@/components/Button'"
A: This usually happens when the alias configuration in vite.config.ts does not match tsconfig.json. Vite reads vite.config.ts for builds, but TypeScript and your IDE rely on tsconfig.json for path resolution.
Solution:
- Use absolute paths with
path.resolveinvite.config.ts, not relative paths. - Sync
tsconfig.jsonpaths with your Vite aliases. - In monorepos, verify
__dirnamepoints to the correct project root.
Q: The package is in node_modules, but Rollup still cannot resolve it. Why?
A: Possible reasons include:
- The package is pure CommonJS without proper
exportsormainfields in itspackage.json - Version incompatibility with other dependencies
- Symlink or workspace resolution issues in monorepos
Solution:
- Add the package to
optimizeDeps.includeto force esbuild pre-bundling. - Check the package's
package.jsonfor correctmainormodulefields. - Delete
node_modulesandpackage-lock.json, then reinstall. - Use
resolve.dedupeto force a specific package version if needed.