React Native集成ethereumjs-wallet时crypto模块无法解析报错
报错复现
核心报错信息
[Error: undefined Unable to resolve module crypto from /pathToProject/node_modules/ethereumjs-wallet/dist.browser/index.js: crypto could not be found within the project or in these directories: node_modules/ethereumjs-wallet/node_modules node_modules
报错定位代码
71 | Object.defineProperty(exports, "__esModule", { value: true }); 72 | exports.thirdparty = exports.hdkey = void 0; > 73 | var crypto = __importStar(require("crypto")); | ^ 74 | var ethereumjs_util_1 = require("ethereumjs-util"); 75 | var scrypt_js_1 = require("scrypt-js");
现有相关依赖
{ "@ethersproject/shims": "^5.6.0", "@metamask/controllers": "^30.0.0", "crypto-js": "3.3.0", "eth-keyring-controller": "^7.0.2", "ethers": "^5.6.4", "react-native-aes-crypto": "^2.1.0", "react-native-crypto": "2.1.2" }
场景:React Native 项目集成 MetaMask 官方 KeyringController 及其他MetaMask控制器时触发上述模块解析错误。
问题根因
React Native 运行环境不内置Node.js核心模块,crypto是Node原生模块,浏览器/RN环境下需要手动注入polyfill;现有依赖里的react-native-crypto未完成模块路径映射,且缺少react-native-crypto依赖的配套polyfill、全局变量注入,导致依赖链里的ethereumjs-wallet找不到crypto模块。
解决步骤
- 补全所有必需的polyfill依赖,在项目根目录执行安装命令:
# npm 执行 npm install react-native-randombytes stream-browserify buffer events process --save # yarn 执行 yarn add react-native-randombytes stream-browserify buffer events process
注:React Native 0.60以下版本需要手动执行
npx react-native link react-native-randombytes链接原生依赖,0.60及以上版本会自动链接无需额外操作。
- 配置Metro打包工具的模块解析规则,将所有对Node原生模块的引用重定向到RN兼容的polyfill包。在项目根目录修改/新建
metro.config.js文件,写入如下配置:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const customConfig = { resolver: { extraNodeModules: { crypto: require.resolve('react-native-crypto'), stream: require.resolve('stream-browserify'), buffer: require.resolve('buffer'), events: require.resolve('events'), process: require.resolve('process/browser') } } }; module.exports = mergeConfig(getDefaultConfig(__dirname), customConfig);
- 调整项目入口文件(默认是根目录
index.js)的导入顺序,在所有业务代码、第三方依赖导入前注入全局polyfill,参考如下写法:
// 1. 最顶部先导入全局polyfill依赖 import process from 'process'; import { Buffer } from 'buffer'; // 2. 挂载全局变量 global.process = process; global.Buffer = Buffer; // 3. 提前初始化crypto polyfill import 'react-native-crypto'; // 4. 导入已安装的ethers shim import '@ethersproject/shims'; // 5. 原有入口逻辑放在polyfill之后,包括MetaMask相关控制器、App组件的导入 import { AppRegistry } from 'react-native'; import App from './App'; import { name as appName } from './app.json'; AppRegistry.registerComponent(appName, () => App);
- 清除Metro打包缓存后重启服务,避免旧缓存导致配置不生效:
npx react-native start --reset-cache
执行完后重新编译运行安卓/iOS客户端即可正常加载MetaMask相关控制器。
内容的提问来源于stack exchange,提问作者Akshay Bhimani
相关产品推荐
相关产品推荐

