Skip to content
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
4 of 5 tasks
qingfeng opened this issue Aug 12, 2015 · 199 comments
Closed
4 of 5 tasks

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

qingfeng opened this issue Aug 12, 2015 · 199 comments

Comments

@qingfeng
Copy link

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 Make babel-relay-plugin run before other transforms #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
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
Copy link
Contributor

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

@amccloud
Copy link

@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
Copy link

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
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
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
Copy link

@josephsavona can we re-open this?

@josephsavona
Copy link
Contributor

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

@josephsavona josephsavona reopened this Aug 30, 2015
@boourns
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
Copy link

@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
Copy link

@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
Copy link

boourns commented Sep 2, 2015

@almasakchabayev follow this comment: #26 (comment)

@almeynman
Copy link

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

@lukasredev
Copy link

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

@boourns
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
@lukasredev
Copy link

@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
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.

@lukasredev
Copy link

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

@boourns
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

@lukasredev
Copy link

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
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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

@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
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
Copy link

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
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
Copy link

@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
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
Copy link

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

@taion
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
Copy link

@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
Copy link
Contributor

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

@steveluscher
Copy link
Contributor

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
Copy link

Awesome work @steveluscher!

@filod
Copy link

filod commented Mar 10, 2016

🎉

@tychota
Copy link

tychota commented Mar 10, 2016

(Edited : I will found help on discord)

🎉

@davidaurelio
Copy link
Contributor

@steveluscher awesome work!

@eugenehp
Copy link

@steveluscher 👍

@gmochid
Copy link

gmochid commented Mar 11, 2016

@steveluscher Great

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

Successfully merging a pull request may close this issue.