New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Relay work with React Native out of the box #26

Closed
qingfeng opened this Issue Aug 12, 2015 · 199 comments

Comments

Projects
None yet
@qingfeng
Copy link

qingfeng commented Aug 12, 2015

The remaining steps are:

  • Relay/React Native/fbjs versioning
  • Use the appropriate unstableBatchedUpdates depending on React/React Native
  • Version of fetch polyfill for React Native
  • Document the use of babel-relay-plugin with React Native (see discussion at #714 (comment))
  • Create a fresh React Native project, set up Relay, configure the plugin per the documentation added in the previous step, and make sure everything works as expected.

Note: edited by @josephsavona

@yongxu

This comment has been minimized.

Copy link

yongxu commented Aug 12, 2015

have not tried yet, but looks like so.
some examples from docs use react native components
https://facebook.github.io/relay/docs/guides-containers.html#content

@josephsavona

This comment has been minimized.

Copy link
Contributor

josephsavona commented Aug 12, 2015

Relay should work as-is on React Native - if not, feel free to let us know and re-open this!

@amccloud

This comment has been minimized.

Copy link

amccloud commented Aug 17, 2015

@josephsavona even if relay components aren't inheriting react-native's Component?

https://github.com/facebook/relay/blob/master/src/container/RelayContainer.js#L23

I'm getting Can't find variable: document in getActiveElement

@amccloud

This comment has been minimized.

Copy link

amccloud commented Aug 17, 2015

I also needed to include johanneslumpe/react-native-browser-polyfill to get around a similar issue Can't find variable: self in whatwg-fetch

@boourns

This comment has been minimized.

Copy link

boourns commented Aug 25, 2015

@josephsavona Relay cannot work as-is with React Native because Relay includes React web as a hard dependency, and including React web into React Native is not functional.

Here's a commit that shows the minimal changes to build relay against react-native:
e0037c7

The 'dist' step of building relay still fails with that commit, with the error:
image

I'm not sure exactly why that's failing.

The last two things we had to do to get relay working with react native was:

  • Commit relay's /lib directory since building dist failed (above)
  • stub process.env before including Relay in the react-native application, since process doesn't exist in react-native's JS environment. This is only necessary until the dist step of compilation works, since dist will remove all process.env references. I made a pseudo-module called 'relay',, which is a bit silly but functional:
process = {env: {}};

module.exports = require('react-relay');
@boourns

This comment has been minimized.

Copy link

boourns commented Aug 25, 2015

Last thing I forgot to mention regarding relay's compatibility with react-native:

relay assumes self is present. This is true in react-native only when debugging in Chrome. If you are not debugging in Chrome you will get an error self is not defined when including Relay. A solution is to add https://github.com/johanneslumpe/react-native-browser-polyfill to your react-native project.

@amccloud

This comment has been minimized.

Copy link

amccloud commented Aug 29, 2015

@josephsavona can we re-open this?

@josephsavona

This comment has been minimized.

Copy link
Contributor

josephsavona commented Aug 30, 2015

@amccloud thanks for investigating, I'm reopening to give us a place to track this.

@josephsavona josephsavona reopened this Aug 30, 2015

@boourns

This comment has been minimized.

Copy link

boourns commented Aug 30, 2015

The last thing we needed to do to get relay working with react-native was to use react-native's global fetch by deleting the var fetch = require('fbjs/lib/fetch'); line from lib/RelayDefaultNetworkLayer.js.

We've gotten basic requests working following the steps I've outlined above in my comments on this issue, but I'm not 100% certain other things aren't broken yet.

@clintonwoo

This comment has been minimized.

Copy link

clintonwoo commented Aug 31, 2015

@boourns that's great. I also had to delete var fetch = require('fbjs/lib/fetch') from the following library which was declared in lib/RelayDefaultNetworkLayer.js:
var fetchWithRetries = require('fbjs/lib/fetchWithRetries');

@almeynman

This comment has been minimized.

Copy link

almeynman commented Sep 2, 2015

@boourns @clintonwoo Hello guys, followed your step all the way, however i get an error 'can't find variable fetchWithRetries', however when adding it i get 'cannot find variable: self'. Any tips would be greatly appreciated. github repo is https://github.com/almasakchabayev/reactNativeRelayWebpackDemo.

@boourns

This comment has been minimized.

Copy link

boourns commented Sep 2, 2015

@almasakchabayev follow this comment: #26 (comment)

@almeynman

This comment has been minimized.

Copy link

almeynman commented Sep 2, 2015

@boourns It worked when I changed fetchWithRetries in 'function _sendQuery' to just fetch. Great! Thanks a lot!

@lukasreichart

This comment has been minimized.

Copy link

lukasreichart commented Sep 4, 2015

@boourns Maybe a dumb question: What do you mean by: "Commit relay's /lib directory since building dist failed (above)" ?

@boourns

This comment has been minimized.

Copy link

boourns commented Sep 4, 2015

@lukasreichart

Ideally we would build relay against react-native, do a dist build which would result in a single relay.js file, which could be copied into the react-native project. The minimal changes to build relay against react-native are here: e0037c7

With that commit applied, the src to lib transpilation step succeeds, but doing a dist build of relay fails. See the screenshot posted in my original comment. So that commit is not sufficient in the long-term.

The proper solution will be to figure out why the dist build fails and making it not fail, but I don't really know what the problem is there yet.

In the meantime if you want to try relay with react native, the hack solution is to fork relay, apply e0037c7, commit /lib and then add that relay fork to your react-native project as an npm dependency. And then make the other changes I outline.

tmitchel2 added a commit to tmitchel2/relay that referenced this issue Sep 7, 2015

@lukasreichart

This comment has been minimized.

Copy link

lukasreichart commented Sep 10, 2015

@boourns Thanks you've directed me to the right path. But now I have a problem with the babel-relay-plugin. I'am using this script. But keep getting an Error: Invariant Violation: RelayQL: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used varbatim as Relay.QL``

This error occurs when you use Relay.QL ( which should have been replaced by the babel-relay-plugin). The strange thing is, that in index.ios.bundle, all Relay.QLstatements have been replaced correctly.

Any ideas on this one?

@boourns

This comment has been minimized.

Copy link

boourns commented Sep 10, 2015

@lukasreichart in package.json for your project change the start command to be:

"start": "node_modules/react-native/packager/packager.sh --transformer ./lib/babelTransform.js"

And then you need to run your react-native packager via 'npm start' instead of running react-native start or using the packager that xcode boots up.

This is another workaround we had to apply, not sure how to make this just gracefully happen yet.

@lukasreichart

This comment has been minimized.

Copy link

lukasreichart commented Sep 10, 2015

@boourns Would you mind sharing the content of your ./lib/babelTransform.js file?

@boourns

This comment has been minimized.

Copy link

boourns commented Sep 10, 2015

Sorry, discussing with @jahfer now who did this portion of the work. Disclaimer again that this is hacks on hacks on hacks, not a robust solution to getting it working :)

What we did was copy the original react-native babel transformer from https://github.com/facebook/react-native/blob/master/packager/transformer.js into your project, and add the relay plugin:

    plugins: [require('./babelRelayPlugin.js')],

babelRelayPlugin.js comes from https://github.com/relayjs/relay-starter-kit

@lukasreichart

This comment has been minimized.

Copy link

lukasreichart commented Sep 10, 2015

I think my transform is working now. Thank you very much. @boourns
Getting a new Error: fetch is not a function which is very strange, because fetch is globally defined in react native(?).
Did you also encounter this error?

@boourns

This comment has been minimized.

Copy link

boourns commented Sep 10, 2015

@lukasreichart yes, you need to follow this comment:
#26 (comment)

and this comment:
#26 (comment)

let me know how that works

heracek added a commit to heracek/relay that referenced this issue Sep 16, 2015

heracek added a commit to heracek/relay that referenced this issue Sep 16, 2015

@steveluscher steveluscher changed the title react-native can use? Make Relay work with React Native out of the box Sep 17, 2015

@siderakis

This comment has been minimized.

Copy link

siderakis commented Mar 7, 2016

After updating package.json with "react-native": "facebook/react-native" running the command pod install gives the following error:

Fetching podspec for RNVectorIcons from ../node_modules/react-native-vector-icons
Fetching podspec for React from ../node_modules/react-native
Fetching podspec for react-native-fbsdkcore from ../node_modules/react-native-fbsdkcore
Fetching podspec for react-native-fbsdklogin from ../node_modules/react-native-fbsdklogin
Fetching podspec for react-native-fbsdkshare from ../node_modules/react-native-fbsdkshare
[!] Unable to satisfy the following requirements:

  • React/Core (from../node_modules/react-native) required by Podfile
@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 7, 2016

The fbjs issues seem to be resolved now. However, I am still running into issues with react-native and babelRelayPlugin after updating my package.json.

Here is what the code looks like:

package.json:

 "name": "relayNative",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "babel-relay-plugin": "^0.7.3",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "react": "^0.14.7",
    "react-native": "facebook/react-native",
    "react-relay": "^0.7.3"
  },
  "devDependencies": {
    "babel": "^6.5.2"
  }
}

.babelrc:

option A:

{
  "presets": [
    {
      "plugins": ["./scripts/babelRelayPlugin", "react-native"]
    }
   ],
   "passPerPreset": true
}

option B:

{
  "presets": ["./scripts/babelRelayPlugin", "react-native"],
  "passPerPreset": true
}

babelRelayPlugin.js:

const getBabelRelayPlugin = require('babel-relay-plugin');
const schema = require('../data/schema.json');

module.exports = { plugins: [getBabelRelayPlugin(schema.data)] };

NPM Errors
If I run npm start I get the following issue:

.babelrc option A:

/node_modules/react-native/node_modules/babel-core/lib/transformation/plugin.js:127
      throw new Error(messages.get("pluginInvalidProperty", loc, i, key));
      ^
Error: Plugin 0 specified in "foreign" provided an invalid property of "plugins"

.babelrc option B:

/node_modules/react-native/Libraries/react-native/react-native.js:120
  ...require('React'),
  ^^^

SyntaxError: Unexpected token ...

Which option of the .babelrc is correct (A or B)? Also, is the 'start' within the package.json correct? Thanks! JV

@siderakis

This comment has been minimized.

Copy link

siderakis commented Mar 8, 2016

I believe option A shows that error because babelRelayPlugin.js exports { plugins: [getBabelRelayPlugin(schema.data)] }; , so it has two levels of plugins:

{
  "presets": [
    { "plugins": [{ plugins: [getBabelRelayPlugin(schema.data)] }]},
    "react-native"
  ],
  "passPerPreset": true
}

To confirm you could try module.exports = getBabelRelayPlugin(schema.data); with option A.

I'm also stuck with the same error while using option B.

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

Here's the results:

.babelrc using option A:

{
  "presets": [
    {
      "plugins": ["./scripts/babelRelayPlugin", "react-native"]
    }
   ],
   "passPerPreset": true
}

babelRelayPlugin.js updated:

const getBabelRelayPlugin = require('babel-relay-plugin');
const schema = require('../data/schema.json');

module.exports = getBabelRelayPlugin(schema.data);

Running npm start:

/node_modules/react-native/Libraries/react-native/react-native.js:120
  ...require('React'),
  ^^^

SyntaxError: Unexpected token ...

Confirms that using:

module.exports = { plugins: [getBabelRelayPlugin(schema.data)] };

within the babelRelayPlugin.js is incorrect as @siderakis pointed out.

@siderakis

This comment has been minimized.

Copy link

siderakis commented Mar 8, 2016

Has anyone resolved this issue?

/node_modules/react-native/Libraries/react-native/react-native.js:120
  ...require('React'),
  ^^^

SyntaxError: Unexpected token ...

Also, if I remove .babelrc I don't get this error anymore. (but I still get errors further down the process).

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

I've played around with that file by changing the spread operator on line 120 to:
get React() { return require('React'); },

and that leads to the following error:

/node_modules/react-native/Libraries/react-native/react-native.js:122
if (__DEV__) {
    ^

ReferenceError: __DEV__ is not defined

And down the rabbit hole we go. I am not sure why a spread operator is used like that there.

@mrlaessig

This comment has been minimized.

Copy link

mrlaessig commented Mar 8, 2016

Have you tried to install RN 0.22.0-rc? Should work out of the box with Babel configured like this:

{
  "presets": [
    { "plugins": ["./relay/babelRelayPlugin"] },
    "react-native"
  ],
  "passPerPreset": true
}
@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

@l-urence I just tried to use RN 0.22.0-rc and here are my results:

package.json

{
  "name": "testApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "babel-relay-plugin": "^0.7.3",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "react": "^0.14.7",
    "react-native": "0.22.0-rc",
    "react-relay": "^0.7.3"
  },
  "devDependencies": {
    "babel": "^6.5.2"
  }
}

.babelrc

{
  "presets": [
    {
      "plugins": ["./scripts/babelRelayPlugin"]
    },
    "react-native"
   ],
   "passPerPreset": true
}


babelRelayPlugin.js:

const getBabelRelayPlugin = require('babel-relay-plugin');
const schema = require('../data/schema.json');

module.exports = getBabelRelayPlugin(schema.data);

running npm start and receiving the following error:

> node node_modules/react-native/local-cli/cli.js start

module.js:341
    throw err;
    ^

Error: Cannot find module 'slash'
    at Function.Module._resolveFilename (module.js:339:15)
    at Function.Module._load (module.js:290:25)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (/node_modules/babel-core/lib/util.js:45:14)

Does your package.json differ from mine?

@oblador

This comment has been minimized.

Copy link

oblador commented Mar 8, 2016

@jefferyvincent: You are using babel-preset-react in your package.json when you should be using babel-preset-react-native.

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

Thanks @oblador, but I am still seeing the same error above even after deleting my node_modules folder and running npm install and npm clear cache.

package.json updated:

{
  "name": "testApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "babel-relay-plugin": "^0.7.3",
    "babel-preset-react-native": "^1.5.2",
    "react": "^0.14.7",
    "react-native": "0.22.0-rc",
    "react-relay": "^0.7.3"
  },
  "devDependencies": {
    "babel": "^6.5.2"
  }
}

Error:


> testApp@0.0.1 start /projects/testApp
> node node_modules/react-native/local-cli/cli.js start

module.js:341
    throw err;
    ^

Error: Cannot find module 'slash'
    at Function.Module._resolveFilename (module.js:339:15)
    at Function.Module._load (module.js:290:25)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (/node_modules/babel-core/lib/util.js:45:14)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)


@oblador

This comment has been minimized.

Copy link

oblador commented Mar 8, 2016

@jefferyvincent: That should work, try resetting some caches like rm -fr $TMPDIR/react-* and killing watchman with watchman watch-del-all.

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

@oblador: I ran those commands and restarted and I still end up with that same error. No idea what Error: Cannot find module 'slash'?

@oblador

This comment has been minimized.

Copy link

oblador commented Mar 8, 2016

@jefferyvincent: This sounds like NPM 3 troubles, try switching to NPM 2 or just installing slash manually and moving it to the babel-core's node_modules folder.

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

Bingo! Thanks @oblador that did the trick. I ran sudo npm install slash

@taion

This comment has been minimized.

Copy link
Contributor

taion commented Mar 8, 2016

Given the number of subscribers to this issue, it might be best to limit discussion to just issue-related topics, rather than support. This is generating a lot of noise.

@jefferyvincent

This comment has been minimized.

Copy link

jefferyvincent commented Mar 8, 2016

@taion, I was merely trying to properly document the above steps more clearly, since there were some discrepancies as to how the .babelrc file should be written. With that said, my comments above due constitute as issue-related. ;)

@steveluscher

This comment has been minimized.

Copy link
Contributor

steveluscher commented Mar 9, 2016

We shouldn't have to keep this thread open much longer. #929

@steveluscher

This comment has been minimized.

Copy link
Contributor

steveluscher commented Mar 9, 2016

I just checked out a fresh copy of Relay from master, and did the following:

cd examples/TodoMVC/
npm install -g react-native-cli && npm install
react-native run-ios & npm start

A wild React Native and Relay app appeared.

Countless thanks to @skevy, @boourns, @gre, @davidaurelio, @martinbigio, @zpao, @spicyj, and everyone on this thread who helped us tear down the barriers to using Relay with React Native in the open source community. I can't wait to field all of your React Native specific GitHub issues.

We're done here. Open new issues at https://github.com/facebook/relay/issues or https://github.com/facebook/react-native/issues as you discover them!

@martinbigio

This comment has been minimized.

Copy link

martinbigio commented Mar 10, 2016

Awesome work @steveluscher!

@filod

This comment has been minimized.

Copy link

filod commented Mar 10, 2016

🎉

@tychota

This comment has been minimized.

Copy link

tychota commented Mar 10, 2016

(Edited : I will found help on discord)

🎉

@davidaurelio

This comment has been minimized.

Copy link
Contributor

davidaurelio commented Mar 10, 2016

@steveluscher awesome work!

@eugenehp

This comment has been minimized.

Copy link

eugenehp commented Mar 10, 2016

@gmochid

This comment has been minimized.

Copy link

gmochid commented Mar 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment