82
Packager support resolve.alias ala webpack
Activity
Newest
Oldest
Gabirieli Lalasava
Currently both 'browser' and 'react-native' are used to defined module aliases in package.json.
That prevents you from aliasing any modules only for browser since the 'browser' alias will be used by react-native as well.
Fran Guijarro
Hi! I want to leave this documentation of an instance of this problem:
Trying to use mqtt.js https://github.com/mqttjs is not possible in React Native.
Why?
- mqtt requires node.js native modules and the browser versions are shimmed via browserify package.json.browser attribute.
- browserify builds of mqtt lib are rejected by Packager because, it looks like, the analysis it does on the UMD file of the requirestatements are not satisfied i.e.:require('./Store')fails because the bundled UMD file has not that directory relationship to the Store.js file, but the UMD file already provides an implementation of that package, and implementation ofrequirefor that matter, the problem is that Packager wont play well with prebuilt bundles.
I also tried ReactNativify but it fails with obscure, browser crashing, error reports.
Mark Vayngrib
@Fran Guijarro: have you tried https://github.com/mvayngrib/rn-nodeify ?
Fran Guijarro
@Mark Vayngrib: nope, but it looks promising!
Gabirieli Lalasava
@Fran Guijarro: Very late reply here but for anyone trying to use MQTT.js in react-native:
mqtt.js has a browser version. You can use that directly:
require('mqtt/lib/connect/index.js')
or by aliasing via the browser field.Before the require you need to set some globals:
global.Buffer = require('buffer').Buffer
global.process = require('process')
const mqtt = require('mqtt/lib/connect/index.js')
Philipp von Weitershausen
After putting too much effort into maintaining react-native-webpack-server, I've decided to divert that energy into a solution that would let me use the React Native packager while having the similar benefits: using node.js standard libraries and having module alias. I've documented my solution here: https://github.com/philikon/ReactNativify. Feedback very welcome, ideally in the form of Pull Requests :)
Koen Schmeets
Hi! I am the creator of that issue, and of the (working) pull request that adds support for "global-react-native" require replacements in node-haste over here: https://github.com/facebook/node-haste/pull/46
Unfortunately, writing a test case for it is really hard (I wasted a couple of nights on it)
If anyone wants to help over there to update the PR to the latest node-haste version, or to writing the test case would be very welcome!
Hilke Heremans
We are also having this issue while attempting to use socket.io with React Native. Socket.io depends on Engine.io, which conditionally loads the 'ws' npm module, which in turn depends on 'http'. While engine.io's package.json clearly attempts to shim the ws dependency (into "false"), the packager does not pick this up and attempts to load anyway. The only semi-practical way to circumvent this is to eliminate the require() call altogether (read: fork engine.io).
Jacob Rosenthal
Another more in depth explanation:
Its common to use the browser field in package.json to select a package to shim. The packager will whenever(globally) it sees a require for this package, swap it out for another. In webpack its called resolve.alias in browserify its called transforms. Its used (amongst other things) whenever an existing package uses some platform specific code (crypto, serialport, ble) to move that to another platform like chrome/w3c/react native. You can use the entire ecosystem of modules that exist on top of existing packages without editing them manually.
React native's packager only alias's 1 deep for some reason. So in my index.ios.js I can indeed use the browser field and require('noble') and it will figure out to instead require('react-native-ble). However when I require('ble-bean) which does a require('noble') it dies trying to bring in the actual noble.
Philipp von Weitershausen
Yes, the React Native packager will read the 'browser' and since lately also the 'react-native' field of a package.json. But that won't help when you want to redirect a third-party's import of some package, e.g. say node's 'crypto'.
Jacob Rosenthal
So it turns out this is supported 1 level deep with the browser field in package.json, but not globally, which is what is required for any use case I can think of. The current issue Im tracking is here https://github.com/facebook/react-native/issues/6253
Philipp von Weitershausen
Hi, current de-facto maintainer of react-native-webpack-server here. I very much second the need for module aliasing. It'd be very elegant if we could do this as a Babel transform. Unfortunately, the way that the RN packager currently resolves module dependencies, way before modules are actually handed off to Babel for transformation, makes this impossible.