【Bug已解决】openclaw: dependency resolution failed / Module not found — OpenClaw 依赖解析失败解决方案1. 问题描述在使用 OpenClaw 运行或构建项目时系统报出依赖解析失败错误无法找到所需的模块或包# 依赖解析失败 - 模块未找到 $ openclaw 运行项目 Error: dependency resolution failed Cannot find module express Module not found in /project/node_modules/express # 依赖版本冲突 $ openclaw 构建项目 Error: Version conflict detected Package typescript requires typescript^5.0.0 But found typescript4.9.5 in node_modules # 依赖树不完整 $ openclaw 启动服务 Error: Missing dependency Required package anthropic-ai/sdk is not installed Run npm install to install missing dependencies # 循环依赖检测 $ openclaw 分析依赖 Error: Circular dependency detected Module A - Module B - Module C - Module A这个问题在以下场景中特别常见clone 项目后未执行npm install/pip installpackage.json/requirements.txt更新后未同步node_modules 损坏或不完整版本冲突多个包要求不同版本的同名依赖monorepo 中包引用路径错误锁文件lock file与依赖配置不一致2. 原因分析OpenClaw启动项目 ↓ 解析依赖树 ←──── 读取 package.json / requirements.txt ↓ 检查已安装的包 ←──── 扫描 node_modules / site-packages ↓ 发现缺失/冲突 ←──── 版本不匹配或包不存在 ↓ 抛出 dependency resolution failed原因分类具体表现占比未安装依赖node_modules 缺失约 35%版本冲突多个版本要求不兼容约 25%锁文件不一致lock 与 config 不匹配约 15%模块路径错误相对路径解析失败约 10%包名拼写错误找不到模块约 8%循环依赖A→B→C→A约 7%深层原理现代包管理器npm/pip/yarn/pnpm使用依赖树算法来解析项目的所有依赖关系。以 npm 为例它读取package.json中声明的依赖及其版本范围然后检查node_modules中实际安装的版本是否满足要求。如果多个包依赖同一个包的不同大版本npm 会尝试在node_modules中创建嵌套结构来同时满足两个版本需求。当版本范围完全互斥、或锁文件package-lock.json与package.json不同步时解析过程就会失败并报错。3. 解决方案方案一重新安装所有依赖最推荐# Node.js 项目 - 清理并重新安装 rm -rf node_modules package-lock.json npm install # 如果使用 yarn rm -rf node_modules yarn.lock yarn install # 如果使用 pnpm rm -rf node_modules pnpm-lock.yaml pnpm install # Python 项目 - 重新创建虚拟环境 deactivate 2/dev/null rm -rf venv python3 -m venv venv source venv/bin/activate pip install -r requirements.txt # 验证依赖完整性 npm ls --depth0 21 | head -20 # 或 pip list --formattable | head -20 # 重新运行 OpenClaw openclaw 运行项目方案二解决版本冲突# 检查版本冲突详情 npm ls typescript 21 # 查看哪些包依赖冲突的包 npm why typescript 21 # 使用 overrides 强制统一版本 # package.json 中添加 python3 -c import json with open(package.json, r) as f: pkg json.load(f) pkg[overrides] pkg.get(overrides, {}) pkg[overrides][typescript] ^5.0.0 with open(package.json, w) as f: json.dump(pkg, f, indent2) print(已添加 typescript override: ^5.0.0) # 重新安装 rm -rf node_modules package-lock.json npm install # Yarn 的 resolutions 字段 python3 -c import json with open(package.json, r) as f: pkg json.load(f) pkg[resolutions] pkg.get(resolutions, {}) pkg[resolutions][typescript] 5.0.4 with open(package.json, w) as f: json.dump(pkg, f, indent2) print(已添加 yarn resolution) yarn install方案三修复锁文件不一致# 检查 package.json 与 lock 文件是否同步 npm ci --dry-run 21 | head -10 # 如果报错 lock file out of sync需要重新生成 rm package-lock.json npm install # 确保使用 ci 而非 installCI 环境中 # npm ci 严格按照 lock 文件安装不会修改它 npm ci # 验证锁文件一致性 npm ls --all 21 | grep -i ERR\|WARN\|invalid | head -10 # Python 项目 - 生成精确的 requirements.txt pip freeze requirements.lock # 或使用 pip-tools pip install pip-tools pip-compile requirements.in pip-sync requirements.txt方案四处理模块路径解析问题# 检查模块解析路径 node -e console.log(require.resolve.paths(express)) # 修复 NODE_PATH export NODE_PATH$(npm root -g) echo NODE_PATH$NODE_PATH # 在 package.json 中配置模块别名 python3 -c import json with open(package.json, r) as f: pkg json.load(f) # 配置 imports 字段Node.js 子路径导入 pkg[imports] pkg.get(imports, {}) pkg[imports][#utils] ./src/utils/index.js pkg[imports][#config] ./src/config/index.js with open(package.json, w) as f: json.dump(pkg, f, indent2) print(模块别名已配置) # tsconfig.json 中的路径映射 # 确保 paths 配置正确 cat tsconfig.pathcheck.json EOF { compilerOptions: { baseUrl: ., paths: { utils/*: [src/utils/*], config/*: [src/config/*], components/*: [src/components/*] } } } EOF # 验证路径解析 npx tsc --noEmit --project tsconfig.pathcheck.json 21 | head -10方案五monorepo 依赖管理# 检查 workspace 配置 cat package.json | grep -A5 workspaces # 使用 pnpm workspace cat pnpm-workspace.yaml EOF packages: - packages/* - apps/* - tools/* EOF # 安装所有 workspace 依赖 pnpm install --workspace # 在 workspace 内部添加依赖引用 # 例如 packages/webapp 引用 packages/shared cd packages/webapp pnpm add project/shared --workspace # 确保引用的是 workspace 内的包而非从 npm 下载 # 检查 workspace 依赖是否正确链接 pnpm why project/shared 21 # npm workspaces npm install --workspaces npm run build --workspaces方案六自动化依赖检查工具# 创建依赖检查脚本 import subprocess import json import sys import os class DependencyChecker: 项目依赖检查工具 staticmethod def check_nodejs(): 检查 Node.js 依赖 issues [] # 检查 node_modules 是否存在 if not os.path.exists(node_modules): issues.append(❌ node_modules 不存在需要运行 npm install) # 检查 lock 文件 if os.path.exists(package-lock.json): result subprocess.run( [npm, ci, --dry-run], capture_outputTrue, textTrue ) if result.returncode ! 0: issues.append(f❌ lock文件不一致: {result.stderr[:200]}) # 检查依赖完整性 result subprocess.run( [npm, ls, --depth0, --json], capture_outputTrue, textTrue ) if result.returncode ! 0: try: data json.loads(result.stdout) problems data.get(problems, []) for p in problems[:5]: issues.append(f⚠️ {p}) except json.JSONDecodeError: issues.append(⚠️ 依赖树存在问题运行 npm ls 查看详情) # 检查过期的依赖 result subprocess.run( [npm, outdated, --json], capture_outputTrue, textTrue ) try: outdated json.loads(result.stdout) for pkg, info in outdated.items(): issues.append(fℹ️ {pkg}: 当前 {info.get(current, ?)}, f最新 {info.get(latest, ?)}) except json.JSONDecodeError: pass return issues staticmethod def check_python(): 检查 Python 依赖 issues [] if not os.path.exists(requirements.txt): issues.append(⚠️ 未找到 requirements.txt) else: result subprocess.run( [pip, install, --dry-run, -r, requirements.txt], capture_outputTrue, textTrue ) if result.returncode ! 0: issues.append(f❌ 依赖安装检查失败: {result.stderr[:200]}) return issues staticmethod def fix_common_issues(): 自动修复常见问题 fixes [] # 修复 node_modules if os.path.exists(package.json) and not os.path.exists(node_modules): subprocess.run([npm, install], capture_outputTrue) fixes.append(✅ 已执行 npm install) # 修复 lock 文件 if os.path.exists(package.json) and os.path.exists(package-lock.json): result subprocess.run( [npm, ci, --dry-run], capture_outputTrue, textTrue ) if result.returncode ! 0: os.remove(package-lock.json) subprocess.run([npm, install], capture_outputTrue) fixes.append(✅ 已重新生成 lock 文件) return fixes if __name__ __main__: checker DependencyChecker() if os.path.exists(package.json): print( Node.js 依赖检查 ) issues checker.check_nodejs() for issue in issues: print(issue) print(\n 自动修复 ) fixes checker.fix_common_issues() for fix in fixes: print(fix) if os.path.exists(requirements.txt): print(\n Python 依赖检查 ) issues checker.check_python() for issue in issues: print(issue)4. 各方案对比总结方案适用场景推荐指数方案一重新安装通用首选⭐⭐⭐⭐⭐方案二解决版本冲突版本不兼容⭐⭐⭐⭐方案三修复锁文件lock 不一致⭐⭐⭐⭐方案四修复路径解析模块找不到⭐⭐⭐方案五monorepo 管理多包项目⭐⭐⭐方案六自动化检查长期维护⭐⭐⭐⭐5. 常见问题 FAQ5.1 Windows 上路径分隔符导致模块解析失败Windows 使用\而 Node.js 期望/# 检查 package.json 中的路径是否使用了正确的分隔符 # Node.js 在 Windows 上也支持 / 分隔符 # 确保 tsconfig.json 中使用正斜杠 # paths: { utils/*: [src/utils/*] } ← 正确 # paths: { utils/*: [src\utils\*] } ← 错误 # 如果使用 PowerShell注意路径中的反引号转义 $env:NODE_PATH C:\project\node_modules5.2 Docker 构建时依赖安装失败Docker 构建缓存可能导致依赖不完整# 正确的 Dockerfile 依赖安装方式 FROM node:18 WORKDIR /app # 先复制依赖文件利用缓存层 COPY package.json package-lock.json ./ RUN npm ci --production # 再复制源码 COPY . . # 验证依赖 RUN npm ls --depth0 CMD [openclaw, start]# 如果构建失败清除缓存重新构建 docker build --no-cache -t myapp .5.3 CI/CD 中依赖安装超时CI 环境网络可能不稳定# GitHub Actions - 使用 npm ci 并配置重试 steps: - name: Install dependencies run: | npm ci || { echo 第一次安装失败清理重试... rm -rf node_modules package-lock.json npm install } env: CI: true timeout-minutes: 10 - name: Verify dependencies run: npm ls --depth0 21 | grep -v npm ERR || true5.4 全局安装的包在 OpenClaw 中找不到全局安装的包不在项目 node_modules 中# 检查全局安装的包 npm ls -g --depth0 # 将全局包链接到项目 npm link express # 或者在 package.json 中声明为本地依赖 npm install express --save # 设置 NODE_PATH 包含全局模块路径 export NODE_PATH$(npm root -g):$NODE_PATH echo NODE_PATH$NODE_PATH # 验证全局模块是否可解析 node -e console.log(require.resolve(express))5.5 团队成员之间依赖版本不一致不同开发者使用不同版本的包管理器# 统一包管理器版本 # package.json 中添加 engines 字段 python3 -c import json with open(package.json, r) as f: pkg json.load(f) pkg[engines] { node: 18.0.0, npm: 9.0.0 } pkg[packageManager] npm9.6.7 with open(package.json, w) as f: json.dump(pkg, f, indent2) print(已锁定包管理器版本) # 使用 corepack 管理包管理器版本 corepack enable corepack prepare npm9.6.7 --activate # 将 lock 文件纳入版本控制 git add package-lock.json # 不要 .gitignore package-lock.json5.6 使用 private registry 时依赖解析失败私有 npm registry 需要认证# 配置 .npmrc 文件 cat .npmrc EOF company:registryhttps://registry.company.com/ //registry.company.com/:_authToken${NPM_TOKEN} registryhttps://registry.npmjs.org/ EOF # 设置认证 token环境变量 export NPM_TOKENyour-token-here # 验证私有 registry 可用 npm whoami --registryhttps://registry.company.com/ # Docker 中使用 build args 传递 token # docker build --build-arg NPM_TOKEN$NPM_TOKEN .5.7 optionalDependencies 安装失败导致整个安装中断可选依赖失败不应该阻断安装# 检查是否是可选依赖导致的问题 npm install --no-optional # 或者在 package.json 中临时移除 optionalDependencies python3 -c import json with open(package.json, r) as f: pkg json.load(f) if optionalDependencies in pkg: print(可选依赖:) for dep, ver in pkg[optionalDependencies].items(): print(f {dep}: {ver}) print(可使用 npm install --no-optional 跳过) else: print(无可选依赖) # 设置 npm 忽略可选依赖安装失败 npm config set optional false npm install5.8 peerDependencies 冲突导致安装失败npm 7 严格检查 peerDependencies# 查看 peer 依赖冲突 npm install 21 | grep -i peer # 使用 --legacy-peer-deps 忽略 peer 依赖冲突 npm install --legacy-peer-deps # 或使用 --force 强制安装 npm install --force # 永久配置 npm config set legacy-peer-deps true # 找到冲突的 peer 依赖 npm ls 21 | grep -i peer dep # 手动安装缺失的 peer 依赖 npm install react18 react-dom18 --save-peer排查清单速查表□ 1. 确认已执行 npm install / pip install □ 2. 检查 node_modules 是否存在且完整 □ 3. 运行 npm ls 查看依赖树状态 □ 4. 检查 package-lock.json 是否与 package.json 同步 □ 5. 使用 npm ci 在 CI 环境中安装 □ 6. 检查版本冲突npm why package □ 7. 验证模块路径解析node -e require.resolve(...) □ 8. 检查 .npmrc 中的 registry 配置 □ 9. 确认 peer dependencies 是否兼容 □ 10. 使用自动化检查脚本定期验证依赖健康6. 总结最常见原因clone 项目后未安装依赖35%和版本冲突25%首选方案清理node_modules和 lock 文件后重新npm install版本冲突使用overridesnpm或resolutionsyarn强制统一版本CI 环境使用npm ci严格按 lock 文件安装避免意外更新最佳实践建议将 lock 文件纳入版本控制锁定包管理器版本定期使用自动化工具检查依赖健康度故障排查流程图flowchart TD A[依赖解析失败] -- B[检查node_modules] B -- C{node_modules存在?} C --|否| D[npm install] C --|是| E[npm ls 检查依赖树] D -- F[openclaw 测试] E -- G{有冲突?} G --|是| H[npm why 查找冲突] G --|否| I[检查锁文件] H -- J[版本冲突?] J --|是| K[配置 overrides] J --|peer冲突| L[--legacy-peer-deps] K -- M[重新安装] L -- M M -- F I -- N{lock不一致?} N --|是| O[删除lock重新生成] N --|否| P[检查模块路径] O -- F P -- Q[检查NODE_PATH] Q -- R{路径正确?} R --|是| S[检查registry配置] R --|否| T[修复路径/别名] T -- F S -- U[验证.npmrc] U -- F F -- V{成功?} V --|是| W[✅ 问题解决] V --|否| X[使用自动化检查脚本] X -- Y[根据报告修复] Y -- W