问题描述
使用 pnpm 全局安装 OpenClaw 时,安装过程中出现警告或错误,提示 postinstall 脚本未执行:
$ pnpm add -g openclaw
WARN Lifecycle script `postinstall` of package `[email protected]` was blocked by pnpm.
WARN Lifecycle script `postinstall` of package `[email protected]` was blocked by pnpm.
WARN To allow scripts from packages, run:
WARN pnpm approve-builds -g
安装看似完成了,但运行 openclaw start 时报错:
Error: Cannot find module '../build/Release/sharp-linux-x64.node'
或者:
Error: Could not locate the bindings file. Tried:
→ /path/to/better-sqlite3/build/better_sqlite3.node
这是因为 pnpm 从 v9 开始默认阻止了包的 lifecycle 脚本(如 postinstall),以提升安全性。某些包(如 sharp、better-sqlite3)需要在 postinstall 阶段下载预编译的原生二进制文件或进行本地编译,脚本被阻止后这些包无法正常工作。
原因分析
pnpm 的这一安全策略是为了防止恶意包在安装时执行危险的脚本。但 OpenClaw 依赖的一些合法包确实需要运行 postinstall 脚本:
- sharp:在 postinstall 阶段下载对应平台的 libvips 预编译二进制文件
- better-sqlite3:在 postinstall 阶段编译或下载 SQLite 的原生绑定
- @napi-rs 系列包:在 postinstall 阶段下载 Rust 编译的原生模块
如果这些脚本不执行,对应的原生模块就不会被正确安装,运行时会出现找不到二进制文件的错误。
解决方案
方案一:使用 pnpm approve-builds(推荐)
pnpm 提供了 approve-builds 命令,用于显式批准特定包的构建脚本。对于全局安装:
pnpm approve-builds -g
运行后,pnpm 会列出所有被阻止的包及其脚本内容,让你逐一确认是否允许执行:
? Allow build scripts for the following packages?
[email protected] (postinstall: node install/sharp)
[email protected] (postinstall: prebuild-install -r napi || node-gyp rebuild)
✔ [email protected]
✔ [email protected]
选择需要批准的包后,pnpm 会重新执行这些包的 postinstall 脚本。
批准后重新安装 OpenClaw 以确保所有原生模块正确构建:
pnpm add -g openclaw
方案二:在安装时允许脚本执行
如果你信任 OpenClaw 及其依赖,可以在安装时使用 --unsafe-perm 标志允许脚本执行:
pnpm add -g openclaw --unsafe-perm
或者设置 pnpm 的配置来全局允许特定包的构建脚本:
pnpm config set approve-builds-automatically true -g
注意:approve-builds-automatically 会自动批准所有包的构建脚本,这降低了安全性。仅在你信任所有安装的包时使用。
方案三:使用 .pnpmfile.cjs 配置
创建一个全局的 pnpm 配置来预先批准 OpenClaw 相关包的构建脚本。
首先找到 pnpm 的全局配置目录:
pnpm config get global-dir
在该目录下创建或编辑 .pnpmfile.cjs:
module.exports = {
hooks: {
readPackage(pkg) {
// 允许这些包运行构建脚本
const allowedPackages = ['sharp', 'better-sqlite3', '@napi-rs'];
if (allowedPackages.some(name => pkg.name.includes(name))) {
pkg.allowBuild = true;
}
return pkg;
}
}
};
方案四:切换到 npm 安装
如果 pnpm 的构建脚本管理给你带来了持续的困扰,可以考虑使用 npm 进行全局安装。npm 默认允许 postinstall 脚本执行:
npm install -g openclaw
你仍然可以在项目中使用 pnpm,只是 OpenClaw 这个全局工具使用 npm 安装。两者不冲突。
方案五:手动触发构建
如果已经安装了 OpenClaw 但原生模块未构建,可以手动触发 rebuild:
pnpm rebuild -g
这会重新执行所有全局包的构建脚本。如果某些包仍然被阻止,先运行 pnpm approve-builds -g 再 rebuild。
也可以针对特定包 rebuild:
pnpm rebuild -g sharp
pnpm rebuild -g better-sqlite3
验证修复
确认原生模块已正确构建:
# 验证 sharp
node -e "require('sharp')" && echo "sharp OK" || echo "sharp FAILED"
# 验证 better-sqlite3
node -e "require('better-sqlite3')" && echo "sqlite OK" || echo "sqlite FAILED"
运行 OpenClaw 的环境检查:
openclaw doctor
如果所有检查通过,启动服务:
openclaw start
预防建议
为了在后续更新 OpenClaw 时避免同样的问题,建议在第一次解决后将批准记录持久化。pnpm 会将批准的包列表存储在全局配置中,后续安装或更新时会自动允许已批准的包运行构建脚本。
查看当前已批准的构建列表:
pnpm audit --fix -g
pnpm approve-builds -g --list
定期更新 pnpm 到最新版本,新版本可能改进了构建脚本的管理机制:
pnpm self-update