I'm trying to use node modules in my react-native app, and I'm taking the ReactNativify approach here.
I'm all set up now, and I got the crypto package to load in fine. However when I added in eth-lightwallet things have been getting weird.
Every since I added that package in, npm hasn't been installing dependancies of anything. Meaning I've had to add them in manually. And everytime I install a dependency somehow related to eth-lightwallet, that module is uninstalled. Although tedious and annoying, I'm hoping it can shed light onto my current problem.
Right now I'm running into a Can't find variable: Buffer
which is being thrown in a util folder in the standard library. I've taken a look at the code and it's accessing Buffer from a global namespace. Thing is, I'm importing Buffer into the global namespace. Here's a look at my global.js
// Inject node globals into React Native global scope.
global.Buffer = require('buffer').Buffer;
global.process = require('process');
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
// Needed so that 'stream-http' chooses the right default protocol.
global.location = {
protocol: 'file:',
};
// Don't do this in production. You're going to want to patch in
// https://github.com/mvayngrib/react-native-randombytes or similar.
global.crypto = {
getRandomValues(byteArray) {
for (let i = 0; i < byteArray.length; i++) {
byteArray[i] = Math.floor(256 * Math.random());
}
},
};
My guess is the standard library is being evaluated before this global is being loaded in, and thus the error is thrown.
Coming back to this to leave a solution in case anyone is stuck on this. The solution was to essentially try to shim in different packages in different times to change the load order.
We tried going back to a different version when TYPED_ARRAY_SUPPORT was being treated differently and Buffer was more dependent on it. While on the older version we tried a lot of different things and eventually gave up and backtracked by updating buffer to the most recent version and finally everything worked.
What I mean to say is we're not sure how we fixed it, but it was by randomly changing the load order until we got lucky. Not a good answer, I'm aware, but the best I can provide for this issue.
Here's what our global.js looked like at the end
// Inject node globals into React Native global scope.
// Required for crypto functionality for bitcoinjs-lib, web3, etc.
global.Buffer = require('buffer').Buffer;
//global.Buffer.TYPED_ARRAY_SUPPORT = false;
global.process = require('process');
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
var getRandomValues = function(byteArray) {
var bytes = crypto.rng.randomBytes(byteArray.length);
for (let i = 0; i < byteArray.length; i++) {
byteArray[i] = bytes[i];
}
};
// "But Zach, aren't you just doing the same thing twice?"
// Yes. Initializing the crypto-browserify module eventually requires
// crypto.getRandomValues to exist, so we must add it here once.
// However, crypto-browserify does not support getRandomValues, so we
// must re-add it after loading the module.
global.crypto = { getRandomValues };
global.crypto.rng = require('react-native-randombytes');
global.crypto = require('crypto');
global.crypto.getRandomValues = getRandomValues;
global.crypto.rng = require('react-native-randombytes');
crypto.rng.seedSJCL();
// Needed so that 'stream-http' chooses the right default protocol.
global.location = {
protocol: 'file:'
};