Open parshap opened 7 years ago
@parshap thanks for cc'ing me, hope to check it out very soon!
Woah! I'll check it out for sure!
And it seems to be working! I had to find this alternative approach because babel-plugin-rewrite-require was failing on a module with a dynamic require: readable-stream does require('st'+'ream').
This is what the throwForNonStringLiteral
option in babel-plugin-rewrite-require is meant for. You want to enable it when you're using browserify modules (e.g. via node-libs-browser
).
Hey @parshap I'm running react-native 0.44.1
here, tried the extraNodeModules approach with node-libs-browser
and I'm getting Unable to resolve net
when trying to require a node package. Any reasons you can think of why that might not be working?
node-libs-browser doesn't include a "polyfill" for net. You'll have to include react-native-tcp.
Also check out https://www.npmjs.com/package/node-libs-react-native
Yo @parshap! react-native-tcp
is giving me this error when I require it in rn-cli.config.js:
.../project/path/node_modules/react-native-tcp/TcpSockets.js:16
exports.createServer = function(connectionListener: (socket: Socket) => void) : Server {
^
SyntaxError: Unexpected token :
at Object.exports.runInThisContext (vm.js:76:16)
I'm not sure, I've also seen modules brought in via rn-cli.config.js trip over import
statements. So confusing! Does rn-cli.config.js get babel transpiles or not? I'm using const and other es6 features, it didn't catch an object rest feature either. So it threw for that on:
{ ...extraNodeModules, net: require('react-native-tcp') }
The only thing that works for me right now is this .babelrc file. I deleted my rn-cli.config.js
!
{
"presets": ["react-native"],
"sourceMaps": true,
"plugins": [
["rewrite-require", {
"aliases": {
"constants": "constants-browserify",
"crypto": "react-native-crypto",
"dns": "node-libs-browser/mock/dns",
"domain": "domain-browser",
"fs": "node-libs-browser/mock/empty",
"http": "stream-http",
"https": "https-browserify",
"net": "node-libs-browser/mock/net",
"os": "os-browserify/browser",
"path": "path-browserify",
"pbkdf2": "react-native-pbkdf2-shim",
"querystring": "querystring-es3",
"stream": "stream-browserify",
"_stream_duplex": "readable-stream/duplex",
"_stream_passthrough": "readable-stream/passthrough",
"_stream_readable": "readable-stream/readable",
"_stream_transform": "readable-stream/transform",
"_stream_writable": "readable-stream/writable",
"sys": "util",
"timers": "timers-browserify",
"tls": "node-libs-browser/mock/tls",
"tty": "tty-browserify",
"vm": "vm-browserify",
"zlib": "browserify-zlib"
},
"throwForNonStringLiteral": true
}]
]
}
and react-native-pbkdf2-shim
looks like this in package.json:
"react-native-pbkdf2-shim": "git+https://git@github.com/wswoodruff/react-native-pbkdf2-shim.git",
@wswoodruff: extraNodeModules
should have paths to packages, not imported packages themselves.
module.exports = {
extraNodeModules: {
...extraNodeModules,
net: require.resolve('react-native-tcp'),
},
};
@parshap I'm having trouble with your approach. Are you doing anything besides adding your rn-cli.config.js
? I'm having trouble trying to load the bitcoin example. It seems like the module loading isn't working. I get:
bscript.compile is not a function. (In 'bscript.compile([OPS.OP_DUP, OPS.OP_HASH160, pubKeyHash, OPS.OP_EQUALVERIFY, OPS.OP_CHECKSIG])', 'bscript.compile' is undefined)
encode
output.js:26:25
toOutputScript
address.js:42:85
addOutput
transaction_builder.js:592:43
example
bitcoin_example.js:13:15
<unknown>
rn.js:16:6
run
browser.js:153:19
drainQueue
browser.js:123:16
callTimer
JSTimersExecution.js:96:8
callTimers
JSTimersExecution.js:138:34
__callFunction
MessageQueue.js:260:47
<unknown>
MessageQueue.js:101:26
__guard
MessageQueue.js:228:6
callFunctionReturnFlushedQueue
MessageQueue.js:100:17
In the original file:
var bscript = require('../../script')
seems to be loading an empty object, instead of the one exported in ../../script
For people arriving in the future:
To use this properly now you should edit your metro.config.js
(not rn-cli.config.js
anymore) and add a resolver
section like so:
module.exports = {
resolver: {
extraNodeModules: {
// Polyfills for node libraries
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify")
}
},
// other metro config, etc
}
extraNodeModules
docs: https://facebook.github.io/metro/docs/en/configuration#extranodemodules
@philikon Do you think this ^ alternative approach is worth documenting in the README
?
@parshap Would you consider updating your gist to say metro.config.js
rather than rn-cli.config.js
and to reflect the info in the comment in this issue that require('st'+'ream')
is possible with babel-plugin-rewrite-require
using the throwForNonStringLiteral
option?
Updated, thanks! Can you clarify what you mean by the throwForNonStringLiteral
option and make a specific suggestion in the gist?
@parshap Thanks!!
The author of ReactNativify
mentioned that that's an option in babel-plugin-rewrite-require
in this comment
Here is the feature itself: https://www.npmjs.com/package/babel-plugin-rewrite-require#non-string-literals
I don't think there's a way to make suggestions in the gist directly other than adding a comment, but my suggestion would be to remove this line:
"not supporting require()
calls with an expression (such as require('cyrp' + 'to')
)."
...since it does support that if you use the throwForNonStringLiteral
setting.
Does this work if crypto is required by a dependency of a dependency? For example, we use yarn workspaces and have a shared library. That library depends on crypto-hash
which requires crypto
. If I set crypto
as an extraNodeModule, will that get triggered for the library's usage of crypto
? If not, what would be a way to get this to work?
getting error for fs: unable to resolve fs
I am using google cloud/logging package for logs
Update
See this library for convenience: https://github.com/parshap/node-libs-react-native
And this gist for more details: https://gist.github.com/parshap/e3063d9bf6058041b34b26b7166fd6bd
Original post
The React Native Packager has a built-in option,
extraNodeModules
, which seems to act as a module alias mapping. I couldn't find much information about this option, but here's the PR where it was added: https://github.com/facebookarchive/node-haste/pull/69. Here's myrn-cli.config.js
:And it seems to be working! I had to find this alternative approach because
babel-plugin-rewrite-require
was failing on a module with a dynamic require: readable-stream doesrequire('st'+'ream')
.This may be a better approach than using
babel-plugin-rewrite-require
because it doesn't need a customtransformer.js
or a static mapping in.babelrc
, and it seems to work on dynamic requires!@davidaurelio: Is this an appropriate use of the
extraNodeModules
option?/cc @mvayngrib