Vite 构建报错 `Rollup failed to resolve import` 排查全记录

主题: vite-build-rollup-failed-to-resolve-import更新于: 2026/6/24作者:AgentFactory 技术团队

如果你正在使用 Vite 构建前端项目,大概率遇到过这个令人头疼的错误:[vite]: Rollup failed to resolve import "xxx" from "src/main.js"。开发模式下一切正常,一跑 vite build 就崩。这篇文章直接拆解这个错误的根因、四种典型场景的解决方案,以及如何避免在生产 CI/CD 环境中再次踩坑。

它解决什么问题 / 适用场景

这个错误并非某个独立工具或服务,而是 Vite 构建流程中 Rollup 无法解析 import 语句时的通用报错。任何使用 Vite 作为构建工具的前端项目(Vue、React、Svelte 等)都可能遇到。最常出现的场景:

  • 引入了一个未在 package.json 中声明的依赖
  • 使用了路径别名(如 @/components)但未在 Vite 配置中正确映射
  • 依赖了仅支持 CommonJS(CJS)格式的库,而 Vite/Rollup 期望 ES Module(ESM)格式
  • 依赖包本身缺少 mainmodule 字段,导致入口文件无法定位
  • Monorepo 环境下子包依赖未正确声明

核心配置 / 参数说明

Vite 的构建行为主要通过 vite.config.js 控制。以下是解决 Rollup failed to resolve import 错误最关键的配置项:

配置项类型作用典型值
resolve.aliasObject定义路径别名,让 Rollup 能正确解析简写路径{ '@': path.resolve(__dirname, './src') }
optimizeDeps.includeArray<string>强制 Vite 预构建指定的依赖(常用于 CJS 转 ESM)['lodash', 'some-cjs-lib']
optimizeDeps.excludeArray<string>排除某些依赖不进行预构建(用于有问题的 ESM 包)['some-esm-only-package']
resolve.dedupeArray<string>强制 Vite 解析到同一个版本的依赖(Monorepo 场景)['react', 'react-dom']

注意optimizeDeps.exclude 配置过多依赖会显著增加冷启动和构建时间,因为 Vite 会跳过对这些依赖的预构建,直接让 Rollup 处理原始源码。

四种典型场景的解决方案

场景一:依赖未安装或未声明

报错信息

[vite]: Rollup failed to resolve import "lodash" from "src/main.js".

根因lodash 包未在 package.jsondependenciesdevDependencies 中声明,或者 node_modules 目录不完整。

解决方案

BASH
# 安装并保存到 dependencies
npm install lodash
# 或
yarn add lodash
# 或
pnpm add lodash

确保 package.jsonnode_modules 目录同步。必须提交锁文件package-lock.jsonyarn.lockpnpm-lock.yaml)到版本控制,避免不同环境安装到不同版本的依赖。

场景二:路径别名未配置

报错信息

[vite]: Rollup failed to resolve import "@/components/Header" from "src/App.vue".

根因:项目中使用了 @ 作为 src/ 目录的别名,但未在 vite.config.js 中配置 resolve.alias

解决方案

JAVASCRIPT
// vite.config.js
import { defineConfig } from 'vite';
import path from 'path';

export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});

关键点

  • 别名路径必须是绝对路径(使用 path.resolve
  • 不要同时使用 @rollup/plugin-alias 插件,Vite 内置的 resolve.alias 已经足够,两者可能冲突
  • 确保别名配置在 defineConfig 内部正确导出

场景三:CJS/ESM 格式不兼容

报错信息

[vite]: Rollup failed to resolve import "some-esm-only-package" from "src/utils.js".

根因:引入了一个仅支持 ESM 的包,但项目配置或 Node.js 版本不支持 ESM,或者该包在 package.json 中缺少 exportsmodule 字段。

解决方案(按优先级尝试):

  1. 确保项目支持 ESM:在 package.json 中设置 "type": "module"

  2. 强制预构建 CJS 包:如果包是 CJS 格式,在 vite.config.js 中添加:

    JAVASCRIPT
    export default defineConfig({
      optimizeDeps: {
        include: ['some-cjs-lib'],
      },
    });
    
  3. 排除有问题的 ESM 包:如果包是 ESM 格式但解析失败,尝试排除预构建:

    JAVASCRIPT
    export default defineConfig({
      optimizeDeps: {
        exclude: ['some-esm-only-package'],
      },
    });
    

场景四:Monorepo 环境下的依赖解析失败

报错信息

[vite]: Rollup failed to resolve import "react" from "src/App.jsx".

根因:在 Monorepo(如 pnpm workspace)中,子包可能没有正确声明对 react 的依赖,或者 hoist 行为导致 react 被提升到了根 node_modules,但子包的构建环境无法访问。

解决方案

  1. 显式声明依赖:在子包的 package.json 中添加 react 作为 peerDependenciesdependencies

  2. 检查 pnpm hoist 配置:在 .npmrc 中配置:

    shamefully-hoist=true
    
  3. 强制去重:在 vite.config.js 中使用 resolve.dedupe

    JAVASCRIPT
    export default defineConfig({
      resolve: {
        dedupe: ['react', 'react-dom'],
      },
    });
    

常见报错与排查

错误 1:开发正常,构建报错

问题npm run dev 正常,npm run buildRollup failed to resolve import

根因:Vite 在开发模式下使用 esbuild 进行预构建,esbuild 对模块解析的处理比 Rollup 更宽松。例如,esbuild 可以自动处理 CJS 到 ESM 的转换,而 Rollup 在构建生产包时要求所有导入的模块必须是严格的 ESM 格式。此外,开发模式下 Vite 会缓存预构建结果,而构建时是全新解析。

排查步骤

  1. 检查报错中提到的依赖包格式(CJS 还是 ESM)
  2. 查看 node_modules 中该包的 package.json,确认 mainmoduleexports 字段
  3. 尝试在 optimizeDeps.include 中添加该包名

错误 2:私有 npm 包解析失败

问题:私有包 npm install 成功,但构建时报 Rollup failed to resolve import

根因:私有包在 package.json 中缺少 mainmodule 字段,或者 exports 字段配置不正确。Vite/Rollup 在解析包入口时,会按照 exportsmodulemain 的优先级查找。

解决方案

  1. 检查私有包的 package.json,确保 main 字段指向正确的入口文件(如 dist/index.js
  2. 如果包是 ESM 格式,添加 "type": "module""module": "dist/index.esm.js"
  3. 如果使用了 exports 字段,确保包含完整的映射:
    JSON
    {
      "exports": {
        ".": "./dist/index.js",
        "./package.json": "./package.json"
      }
    }
    

常见问题 FAQ

Q: 为什么我的 Vite 项目在 npm run dev 时正常,但 npm run build 时却报 Rollup failed to resolve import 错误?

A: 这是因为 Vite 在开发模式下使用 esbuild 进行预构建和模块转换,esbuild 对模块解析的处理比 Rollup 更宽松。例如,esbuild 可以自动处理 CJS 到 ESM 的转换,而 Rollup 在构建生产包时要求所有导入的模块必须是严格的 ESM 格式。此外,开发模式下 Vite 会缓存预构建结果,而构建时是全新解析。常见原因包括:依赖包是 CJS 格式且未正确配置 optimizeDeps,或者路径别名在构建时未被正确解析。

Q: 我使用了 @rollup/plugin-alias 来配置别名,为什么还是报错?

A: Vite 本身已经内置了别名解析功能,通过 resolve.alias 配置即可,通常不需要额外安装 @rollup/plugin-alias。如果同时使用两者,可能会产生冲突。建议:1) 移除 @rollup/plugin-alias 插件。2) 直接在 vite.config.js 中使用 resolve.alias 配置。3) 确保别名路径是绝对路径(使用 path.resolve)。4) 检查别名是否被正确导出,例如 export default defineConfig({ resolve: { alias: { ... } } })

Q: 我的依赖包是从一个私有的 npm 仓库安装的,构建时提示 Rollup failed to resolve import,但 npm install 成功了,这是为什么?

A: 这通常是因为私有包在 package.json 中缺少 mainmodule 字段,或者 exports 字段配置不正确。Vite/Rollup 在解析包入口时,会按照 exportsmodulemain 的优先级查找。如果 exports 字段存在但未包含正确的导出路径,Rollup 会解析失败。解决方案:1) 检查私有包的 package.json,确保 main 字段指向正确的入口文件(如 dist/index.js)。2) 如果包是 ESM 格式,添加 "type": "module""module": "dist/index.esm.js"。3) 如果使用了 exports 字段,确保包含 "./package.json": "./package.json"".": "./dist/index.js" 这样的映射。

生产环境实践与注意事项

构建环境一致性

确保 CI/CD 环境与本地开发环境的 Node.js 版本、包管理器(npm/yarn/pnpm)版本一致。锁文件解析差异可能导致不同环境安装到不同版本的依赖,从而触发此错误。

依赖锁定

必须提交锁文件到版本控制。没有锁文件,不同环境可能安装到依赖的不同次版本,而某些次版本可能改变了导出格式或入口文件路径。

安全性

  • 避免在构建脚本中动态执行用户输入,防止注入攻击
  • 对于私有 npm 仓库,配置好 .npmrc 文件并确保凭证安全(使用 CI/CD 的 secrets 管理)

性能限制

optimizeDeps.exclude 配置过多依赖会显著增加冷启动和构建时间,因为 Vite 会跳过对这些依赖的预构建。仅在确实需要时使用此配置,并定期检查是否可以移除。

相关深度解决方案

在配置当前服务时,如果您遇到了数据库锁死或需要更高并发的读写控制,建议配合参考我们整理的 SQLite MCP 服务的高级缓存配置指南 来提升响应速度。