fioprotocol / fiojs

General purpose utility/helper SDK used by the FIO TypeScript SDK.
http://fio.foundation
MIT License
2 stars 8 forks source link

Importing NPM library into React Native app breaks the app. #8

Open eluzgin opened 4 years ago

eluzgin commented 4 years ago

Step to reproduce:

  1. Import "@fioprotocol/fiojs" library into a React Native application.

  2. When running - the following error is thrown on app startup: error: Error: Unable to resolve module events from node_modules/hash-base/node_modules/readable-stream/lib/_stream_readable.js: events could not be found within the project. Stacktrace: at ModuleResolver.resolveDependency (/Users/eugeneluzgin/Blockchain/kryptowallet/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:186:15) at ResolutionRequest.resolveDependency (/Users/eugeneluzgin/Blockchain/kryptowallet/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18) at DependencyGraph.resolveDependency (/Users/eugeneluzgin/Blockchain/kryptowallet/node_modules/metro/src/node-haste/DependencyGraph.js:287:16) at Object.resolve (/Users/eugeneluzgin/Blockchain/kryptowallet/node_modules/metro/src/lib/transformHelpers.js:26

  3. After performing recommended reset commands: $ watchman watch-del-all $ rm -rf node_modules $ yarn install $ react-native start Then restarting application in iOS Simulator

Getting same error: "error: Error: Unable to resolve module events from node_modules/hash-base/node_modules/readable-stream/lib/_stream_readable.js: events could not be found within the project."

The file listed above exists under node_modules.

I have done some research and found a similar issue reported here for AWS library: https://github.com/aws-amplify/amplify-js/issues/153

The common root cause are these dependencies: fiojs has under it's dependencies create-hash and create-hmac: "dependencies": { "ajv": "^6.10.2", "babel-runtime": "6.26.0", "bigi": "^1.4.2", "browserify-aes": "^1.2.0", "bs58": "^4.0.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "ecurve": "^1.0.6", "long": "^4.0.0", "randombytes": "^2.1.0", "text-encoding": "0.7.0" }, Background: create-hmac and create-hash use a hash-base module. That does a "var Transform = require('stream').Transform". That was defined in node.js core (NOT a standard JS function, see https://nodejs.org/api/stream.html#stream_new_stream_transform_options)

eluzgin commented 4 years ago

Versions and environment: node -v : v14.2.0 npm -v : 6.14.4 macOS Mojave

eluzgin commented 4 years ago

Full package.json:

{ "name": "KWallet", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", "test": "jest", "lint": "eslint ." }, "dependencies": { "@fioprotocol/fiojs": "^1.0.1", "@haskkor/react-native-pincode": "^1.22.2", "@react-native-community/async-storage": "^1.9.0", "@react-native-community/masked-view": "^0.1.9", "@react-navigation/bottom-tabs": "^5.2.7", "@react-navigation/drawer": "^5.5.0", "@react-navigation/native": "^5.1.6", "@react-navigation/stack": "^5.2.18", "eosjs-ecc-rn": "^4.0.6-rn", "eosjs-rn": "^20.0.0", "moment": "^2.25.3", "react": "16.11.0", "react-native": "0.62.2", "react-native-chart-kit": "^5.6.0", "react-native-check-box": "^2.1.7", "react-native-gesture-handler": "^1.6.1", "react-native-keyboard-aware-scroll-view": "^0.9.1", "react-native-keychain": "^5.0.1", "react-native-linear-gradient": "^2.5.6", "react-native-picker-select": "^7.0.0", "react-native-reanimated": "^1.8.0", "react-native-safe-area-context": "^0.7.3", "react-native-screens": "^2.5.0", "react-native-sensitive-info": "^5.5.5", "react-native-spinkit": "^1.5.0", "react-native-svg": "^12.1.0", "react-redux": "^7.1.3", "recompose": "^0.30.0", "redux": "^4.0.5", "redux-actions": "^2.6.5", "redux-logger": "^3.0.6", "redux-persist": "^6.0.0", "redux-persist-sensitive-storage": "^1.0.0", "redux-saga": "^1.1.3", "redux-thunk": "^2.3.0", "remote-redux-devtools": "^0.5.16", "yarn": "^1.22.4" }, "devDependencies": { "@babel/core": "^7.6.2", "@babel/runtime": "^7.6.2", "@react-native-community/eslint-config": "^0.0.5", "babel-jest": "^24.9.0", "eslint": "^6.5.1", "jest": "^24.9.0", "metro-react-native-babel-preset": "^0.58.0", "react-test-renderer": "16.11.0" }, "jest": { "preset": "react-native" } }

ericbutz commented 4 years ago

Temporary solution is to use rn-nodeify package(https://github.com/tradle/rn-nodeify). You can follow these steps to install:

npm i --save react-native-crypto
# install peer deps
npm i --save react-native-randombytes
react-native link react-native-randombytes
# install latest rn-nodeify
npm i --save-dev rn-nodeify@latest
# install node core shims and recursively hack package.json files
# in ./node_modules to add/update the "browser"/"react-native" field with relevant mappings
npx rn-nodeify --install --hack

In your app:

import './shim.js'
// ...the rest of your code
import { Fio } from '@fioprotocol/fiojs'
// use lib
console.log(Fio.accountHash('FIO7pdE1qgKiynthV4cvHf1DG3ASt3r5zSHdYgMrE4dExcJupc4Gp'));

There is one current issue with RN 0.62.0 and higher. react-native-tcp and react-native-udp would cause the duplicate symbol issue on build: https://github.com/tradle/rn-nodeify/issues/94

So, you can remove these packages or try the workaround described in issue.

ericbutz commented 4 years ago

@eluzgin, let me know if this makes sense and helps.