Apple M1(Big Sur)下node-gyp编译metrohash原生插件报错
问题根因
这个报错完全和M1芯片的架构适配缺失相关,和你之前做的Xcode重装、brew升级操作没有关联,核心问题有三个:
- 你安装的
metrohash是需要本地编译C++代码的原生Node扩展,这个包的发布版本从2020年停更后,就从未做过Apple Silicon适配,代码里硬编码了仅x86架构支持的SSE4.2指令集,M1对应的arm64架构根本无法识别这些x86专属的内置函数,所以才会出现大量undeclared identifier类的编译错误 - 编译日志中调用的还是3.8.0版本的老旧
node-gyp,这个版本发布时M1芯片尚未上市,对arm64 Mac的编译支持存在缺失,就算代码本身适配,也会出现流程报错 - 你之前尝试用Rosetta模式运行终端安装却没生效,是因为仅给终端开启Rosetta转译并没有作用——只要你安装的Node本身是arm64原生版本,编译流程就依然会走arm64的目标路径,根本不会触发x86转译层,自然无法识别x86专属的指令集。
可落地的解决方案
方案1(最省事,优先推荐):升级asset-hash版本,直接规避有问题的依赖
现在新版的asset-hash早已移除了对这个停更metrohash的依赖,改用纯JavaScript实现的哈希逻辑,不需要本地编译C++代码,可从根源上解决问题:
- 把项目内的
asset-hash升级到2.0.0以上版本,该版本开始就不会拉取存在兼容问题的metrohash - 删掉项目里的
node_modules文件夹和yarn.lock锁文件,重新执行yarn install即可
如果你的项目受版本限制无法直接升级
asset-hash,可以在项目根目录的package.json内添加一段依赖替换配置,强制把有问题的metrohash替换成社区维护的、已经适配M1的版本,配置格式如下:"overrides": { "metrohash": "npm:@metrohash-dev/node-metrohash@^2.0.0" }配置添加完成后重新安装依赖即可,替换后的包已经完成arm64架构适配,不需要手动调整编译参数。
方案2(适配锁死老版本的项目,不强制换依赖):手动调整编译参数跳过不兼容的指令
要是你既不能升级asset-hash,也不想替换metrohash包,就手动给编译流程添加参数,把那些arm64不支持的x86指令剔除:
- 先全局安装最新版的node-gyp,老旧版本的node-gyp根本不支持arm64的编译流程:
yarn global add node-gyp@latest - 在项目
package.json的scripts字段里添加一段安装后自动执行的编译脚本,剔除metrohash编译时硬加的不兼容参数:"scripts": { "postinstall": "node-gyp rebuild --directory=node_modules/metrohash --ignore-flags=-msse4.2" } - 删掉旧的
node_modules文件夹,重新执行yarn install,安装流程结束后会自动触发postinstall脚本,用新版本的node-gyp重新编译metrohash,去掉不兼容的x86参数,即可顺利完成编译。
方案3(兜底方案):完全走x86转译路径完成编译
这才是开启Rosetta安装能生效的正确操作,之前未生效是因为步骤不完整:
- 打开访达的应用程序目录,找到终端.app,右键选择「显示简介」,勾选「使用Rosetta打开」
- 关掉所有已经打开的终端窗口,重新启动开启Rosetta的终端,通过nvm安装x64版本的Node(不要用默认的arm64版本):
arch -x86_64 nvm install 16 arch -x86_64 nvm use 16 - 删掉项目里的
node_modules和yarn.lock,重新执行yarn install,此时整个编译流程都在x86转译环境下运行,x86专属的SSE4.2指令可以正常识别,就不会再出现之前找不到内置函数的报错。
内容的提问来源于stack exchange,提问作者Axel Meier
相关产品推荐
相关产品推荐

