ethers.js
ethers.js copied to clipboard
React-Native Issue
Ethers Version
^6.3.0
Search Terms
No response
Describe the Problem
Hi Team,
I am currently working on react-native project and i followed the guide that was provided here( https://docs.ethers.org/v5/cookbook/react-native/#:~:text=To%20use%20ethers%20in%20React,the%20security%20of%20your%20application.) But still i am getting this error:
Code Snippet
No response
Contract ABI
No response
Errors
error: Error: Unable to resolve module net from C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\ethers\lib.commonjs\providers\provider-ipcsocket.js: net could not be found within the project or in these directories:
node_modules\ethers\node_modules
node_modules
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.IpcSocketProvider = void 0;
> 4 | const net_1 = require("net");
| ^
5 | const provider_socket_js_1 = require("./provider-socket.js");
6 | // @TODO: Is this sufficient? Is this robust? Will newlines occur between
7 | // all payloads and only between payloads?
at ModuleResolver.resolveDependency (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\node-haste\DependencyGraph\ModuleResolution.js:162:15)
at DependencyGraph.resolveDependency (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\node-haste\DependencyGraph.js:260:43)
at Object.resolve (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\lib\transformHelpers.js:177:21)
at Graph._resolveDependencies (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\DeltaBundler\Graph.js:432:35)
at Graph._processModule (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\DeltaBundler\Graph.js:218:38)
at async Graph._addDependency (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\DeltaBundler\Graph.js:314:20)
at async Promise.all (index 19)
at async Graph._processModule (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\DeltaBundler\Graph.js:263:5)
at async Graph._addDependency (C:\Users\ACER\Desktop\carbon-tracker\carbontracker\node_modules\metro\src\DeltaBundler\Graph.js:314:20)
at async Promise.all (index 7)
Environment
No response
Environment (Other)
No response
@SyedImam1998 have you been able to resolve this? I'm having same errors.
I have a fix coming out for this soon. In the mean time, if you npm install @types/node it should resolve this.
@SyedImam1998 have you been able to resolve this? I'm having same errors.
Hey mate I moved to version ethers 5.7 here they have cookbook for react native https://docs.ethers.org/v5/cookbook/
npm install @types/node
@ricmoo doesn't work for me, the error is still there
I have a fix coming out for this soon. In the mean time, if you
npm install @types/nodeit should resolve this.
It doesn't solve the problem
The problem here is a simple. React native (at least version 0.71 current one) do not support "exports" field https://github.com/facebook/metro/issues/670#issuecomment-1434510835 React-native try to grab "browser" field for root import https://facebook.github.io/metro/docs/configuration#resolvermainfields and as browser field do not contain root import it fallback to "main" field that loads the nodejs (commonjs) version.
There are a multiple solutions:
- Instead of ethers import the ethers/lib.esm/index.js (not good as thats internal and can be changed in future)
- Implement on metro.config.js "resolveRequest" the will replace ethers with ethers/lib.esm/index.js
- Help ethers.js developers implement special entry point "react-native" in package.json that used by default on react-native. That also can include special "shim" for react-native or different implementation as we on different entry point. Best one
If someone has resolved the v6 issues, please contact me too, so I can include instructions. I’m considering a dedicated rn package too, if people are interested.
In my setup (expo 48). And it not deep tested (can be a wrong solution)
- Create a metro.config.js
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');
// eslint-disable-next-line no-undef
const config = getDefaultConfig(__dirname);
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (moduleName === 'ethers') {
return context.resolveRequest(context, 'ethers/lib.esm/index.js', platform);
}
return context.resolveRequest(context, moduleName, platform);
};
module.exports = config;
- Prepare environment (shims) https://docs.ethers.org/v5/cookbook/react-native/ (do NOT install get-random-values)
npm i @ethersproject/shims
- As get-random-values v2.1 (latest for now) can't be used on expo 48+ (they are deprecated some module that used by get-random-values and second time of use get-random-values will fail). We should implement it based on latest "expo-crypto"
npx expo install expo-crypto
Create file "crypt-shim.js"
import { getRandomValues as expoCryptoGetRandomValues } from 'expo-crypto';
class Crypto {
getRandomValues = expoCryptoGetRandomValues;
}
const webCrypto = typeof crypto !== 'undefined' ? crypto : new Crypto();
(() => {
if (typeof crypto === 'undefined') {
Object.defineProperty(window, 'crypto', {
configurable: true,
enumerable: true,
get: () => webCrypto,
});
}
})();
- Glue it together.
Inside App.js (or any entry point for you)
import './crypto-shim';
import '@ethersproject/shims';
- In any file use ethers as usual
import { ethers } from 'ethers';
const randomWallet = ethers.Wallet.createRandom();
console.log(randomWallet);
Hope that helps.
Tried it and it worked for an example code but when we tried to get balance from a provider, we couldn't get a response.
If you still have that issue, or if some one else have it.
This happens becouse react native don't use the node core modules, like crypto, net, buffer etc. all this modules will return allways undifined, there are there are several ways to fix this, you can use the package rn-nodefy, as @heroims comments here (https://github.com/heroims)#https://github.com/ethers-io/ethers.js/discussions/3905#discussioncomment-5343065 or you can do this by your self using with the library node-libs-react-native.
-
install the library in your app
npm i node-libs-react-native --safe -
Configure your metro.config.js to use this modules:
module.exports = {
// another configurations
resolver: {
extraNodeModules: require('node-libs-react-native')
}
};
- You have to name the the global variables in your app, like process etc, to do this just add this line in the top of your index.js
import 'node-libs-react-native/globals';
This should make your react--native app compatible with node core modules, another thing to mention is that when I was setting this up, even if I was doing it with rn-nodefy, I had an error with some react hooks and also had the following error in a FlatList:
This happens because react native has conflict with the plugin @babel/plugin-proposal-class-properties so to fix this, go to your babel.config.js, and set it like this:
module.exports = {
plugins: ['react-native-reanimated/plugin'],
presets: ['module:metro-react-native-babel-preset'],
overrides: [
{
test: './node_modules/ethers',
plugins: [
'@babel/plugin-proposal-private-property-in-object',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods'
]
}
]
};
With this configuration you only apply the plugins only for ethers and not for all the modules.
it's solved the issue for me https://github.com/ethers-io/ethers.js/issues/4307#issuecomment-1673620848 Also thank you JorgeLpzGnz
If you still have that issue, or if some one else have it.
This happens becouse react native don't use the node core modules, like crypto, net, buffer etc. all this modules will return allways undifined, there are there are several ways to fix this, you can use the package rn-nodefy, as @heroims comments here (#3905 (comment) or you can do this by your self using with the library node-libs-react-native.
1. install the library in your app `npm i node-libs-react-native --safe` 2. Configure your metro.config.js to use this modules:module.exports = { // another configurations resolver: { extraNodeModules: require('node-libs-react-native') } };3. You have to name the the global variables in your app, like process etc, to do this just add this line in the top of your index.jsimport 'node-libs-react-native/globals';This should make your react--native app compatible with node core modules, another thing to mention is that when I was setting this up, even if I was doing it with rn-nodefy, I had an error with some react hooks and also had the following error in a FlatList:
This happens because react native has conflict with the plugin
@babel/plugin-proposal-class-propertiesso to fix this, go to your babel.config.js, and set it like this:module.exports = { plugins: ['react-native-reanimated/plugin'], presets: ['module:metro-react-native-babel-preset'], overrides: [ { test: './node_modules/ethers', plugins: [ '@babel/plugin-proposal-private-property-in-object', '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-private-methods' ] } ] };With this configuration you only apply the plugins only for ethers and not for all the modules.
Please, how to merge this configuration
resolver: { extraNodeModules: require('node-libs-react-native') }
in metro.config as my file looks like this one?
const config = {}; module.exports = mergeConfig(getDefaultConfig(__dirname), config);
