7

stream cannot be used with expo, as it is a Node.js standard package. However, the package stream-browserify can be used as an alternative in those scenarios.

In order to make modules resolve this instead of the native Node package, I am trying to make babel-plugin-require-rewrite work with expo.

I am adding this to babel.config.js:

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      ["rewrite-require", { aliases: {
        "stream": "stream-browserify"
      }}]
    ]
  };
};

Unfortunately, it is not respected by the bundler. I get this error when trying:

The package at "node_modules\qr-image\lib\qr.js" attempted to import the Node standard library module "stream". It failed because React Native does not include the Node standard library. Read more at https://docs.expo.io/versions/latest/introduction/faq.html#can-i-use-nodejs-packages-with-expo

Is it possible to make this work in Expo?

Harold Smith
  • 882
  • 3
  • 12
  • 21
  • Have you tried using `rn-nodeify`? (https://github.com/tradle/rn-nodeify) Seems like people use it with the lib you want to use https://github.com/tradle/rn-nodeify/issues/32 – Bruno Eduardo Feb 08 '19 at 12:31
  • Didn't really work. I am not sure why, exactly. I created an issue with details: https://github.com/tradle/rn-nodeify/issues/77 – Harold Smith Feb 11 '19 at 10:59
  • If you're explicitly trying to use `stream`, newer versions of Expo already come with a ported `stream` version. Just go ahead and `var stream = require('stream');`. I'm using Expo version 2.6.14. – diogenesgg Feb 13 '19 at 02:01
  • What Expo version are you using? Did you try to `require('stream')`? You don't even need to add it to package.json. Not all packages are ported. `crypto` won't work, for example. – diogenesgg Feb 14 '19 at 13:26

3 Answers3

2

You dont need to modify babel config to use stream-browserify in your source. You can import stream-browserify in your App.js. I have created a simple example on GitHub.

App.js

const Stream = require('stream-browserify');

Package.json

  "dependencies": {
    "buffer": "^5.2.1",
    "events": "^3.0.0",
    "stream-browserify": "^2.0.2",
    "readable-stream": {
      "version": "2.3.6",
      "dependencies": {
        "core-util-is": "github:mjmasn/core-util-is"
      }
    }
    ...
  }

stream-browserify has dependency readable-stream which has its own dependency and use node environment. To resolve it you have to add these node packages. You can read about core-util-is fork here.

Stanislav Mayorov
  • 4,298
  • 5
  • 21
  • 44
  • 1
    Problem is, any module in my dependency tree that requires `stream` will still try to find the native `stream`, and not `stream-browserify`. I want to change all attempts to require the native module. – Harold Smith Feb 11 '19 at 10:19
  • Yes. In this case It wont work. `rewrite-require` wont work for node modules too. Like workaround you can create `qr-image` fork and change several `require`. – Stanislav Mayorov Feb 11 '19 at 20:44
1

This answer rn-nodeify install that i have posted should work. Except Step 1 & Step 5 follow all steps. Step 3 is used for adding node packages you are specifically looking to install, in this case specify stream. Please do modifications in Step 4 based on your requirement in Step 3.

Please do comment if you want me to elaborate.

Ron Astle Lobo
  • 1,284
  • 2
  • 14
  • 34
1

What ended up working for me was creating a metro.config.js file with the following content (I used readable-stream instead of stream-browserify, but I think either should work):

module.exports = {
    resolver: {
        extraNodeModules: {
            stream: require.resolve('readable-stream'),
        },
    },
};

And then I just used yarn add readable-stream and this allows dependencies to use readable-stream as if it were stream.

This was based on the info I found here: https://gist.github.com/parshap/e3063d9bf6058041b34b26b7166fd6bd#file-node-modules-in-react-native-md

Daniel Centore
  • 3,220
  • 1
  • 18
  • 39