I want to port a number of packages written for NodeJS to React Native.
For this purpose I created a RN project using the popular Ignite boilerplate, then used the ReactNativify method and shim Node API objects mostly reusing existing browserify shims.
(For details and some useful tips see Can we use nodejs code inside react native application?)
Some Node objects are still replaced with empty mocks after transpilation, such as fs
. Done in .babelrc
as follows:
["module-resolver", {
"alias": {
"fs": "./config/mock",
"sodium-universal": "libsodium"
// etcetera
}
}]
The packages to port contain a number of calls to fs.readFileSync
in its transitive dependencies.
For instance in one of them, hypercore-protocol
, there is this line of code:
module.exports = protobuf(fs.readFileSync(path.join(__dirname, 'schema.proto'), 'utf-8'))
And here is a problem, because Android and iOS do not support synchronous file transfer. That line looks like it is un-shim-able
to me
Now, while there exists a shims for fs
: react-native-level-fs it does not implement the synchronous filesystem methods.
Then there are browserify transforms, like brfs
, the 'browserify fs.readFileSync() static asset inliner' (and its alternatives bfrs-babel
and babel-plugin-static-fs
).
But I don't know how to include them, and if they will even work in RN?
So I see four approaches going forward:
react-native-level-fs
and brfs
into a usable shim replacementfs
shim, that has all the methodsI am hoping for 1. and alternatively 3. to be working solutions. Can anyone advise?
For sake of completeness. I am in this stage of life:
System
platform linux
arch x64
cpu 4 cores Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
JavaScript
node 7.10.1 /usr/local/bin/node
npm 4.2.0 /usr/local/bin/npm
yarn 0.24.6 /usr/bin/yarn
React Native
react-native-cli 2.0.1
app rn version 0.45.1
Ignite
ignite 2.0.0 /usr/local/bin/ignite
Android
java 1.8.0_111 /usr/bin/java
android home - undefined
No. There is no reasonable alternative for Node's fs.readFileSync
.
Though technically it is possible to write a readFileSync
shim that blocks on an asynchronous file operation, it is inadvisable to force synchronous behavior in an asynchronous system (but you may be able to get away with it, when only having few synchronous methods in one-time initialization code).
So option 3 or 4 are the only viable alternatives.
In my case there were too many Node dependencies, so I ditched browserifying / shimming and opted for 4. But ...
That does not mean all is necessarily lost. I am now investigating Compiling NodeJS as native library in Android
(And Realm.io to bridge native NodeJS + React Native in Android fat client app (CQRS-style)).