Apollo-client-devtools: React Native implementation

Created on 15 Dec 2016  Ā·  46Comments  Ā·  Source: apollographql/apollo-client-devtools

Could you provide a tutorial how could I use it with React Native?

šŸŖ feature-request

Most helpful comment

Hey everyone,
Amazing news, I just managed to include apollo client devtools inside react-native-debugger. And I've included it without running websockets.

That means we have full functionality support, including graphiql, explorer, running queries and everything.

I will publish my forks tomorrow and try to talk with @jhen0409 on how I should do it properly.

I am really happy to see it working!!

Once again, a low quality gif! https://media.giphy.com/media/47J99DEuzDolu7zKR0/giphy.gif

Edit: Seems like I didn't add the update here, so here it is: https://twitter.com/GytisVinclovas/status/1072646494518423553

All 46 comments

Have you tried it yet?

I thought it have to work with something likes remote-redux-devtools.

Yes but I use mocked version of my application using graphql-server

I do not see also the Apollo store at Redux dev tools. It is my mistake?

This tool needs window.__APOLLO_CLIENT__ to work, maybe we just didn't trans our apolloCLient to remote dev page?

@linonetwo this doesn't use redux devtools at all, it's a custom thing. So right now I don't think it's possible to use with React Native.

It works by evaling some code inside the page, so if there is an easy bridge to eval that code inside React Native it should work just as well. Is there some tool that can do that? (like a chrome console for RN?)

There is a feature in React Native that runs the application code in the google chrome engine and you can use the chrome devtools to debug it (including Pause On Caught Exceptions).

There is currently a bug that prevents React Devtools to work with React Native but I don't know if the same problem applies to apollo-client-devtools.

@JohannesKaufmann react-native-debugger does it: https://github.com/jhen0409/react-native-debugger

And storybook-react-native is doing something by using websocket https://github.com/storybooks/react-native-storybook/blob/master/src/preview/index.js#L63

Has anyone tried the React Native Chrome DevTools thing yet? Perhaps it just works out of the box?

Does React DevTools work with RN? We are using an identical approach so if that works the Apollo tools should work as well.

@stubailo I've tried that , do you mean 'remote-redux-devtool' ? It add socket to RN chrome dev tool's html and use socket inside a redux middleware to send serialized store to Chrome. It works, I guess Apollo's devtool can try to read unserialized store in Chrome side to work.

React DevTools ? I don't think any react information will be send to Chrome, what will be sent was only the serialized store.

I'm talking about React devtools - not Redux. Is it possible to use React dev tools with React Native? https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en

@stubailo this is the solution people seem to be using besides Nuclide: https://github.com/jhen0409/react-native-debugger

@stubailo any word on this? I wonder if the best place for the apollo devtools is just along with the redux devtools in react-native-debugger.

That's the only place that the React devtools is working for RN besides Nuclide, which last time I tried was not worth using because performance was so bad.

Enhancing + promoting react-native-debugger may be something apollo may want to get behind if you find it solid enough. I think there is a need in the React Native community for the defacto React devtools. Not many people are aware of this. There's whole issue comment walls with people complaining about how to get React devtools working for RN (https://github.com/facebook/react-devtools/issues/229). In addition, getting redux devtools working on RN isn't as easy as as the chrome plugin for browser apps (which automatically just works). So packaging it all up--while of course giving Apollo first class placement in the mix--and using apollo's--essentially--promotional clout could go a long way to establishing a standard debugging solution for RN.

I haven't gotten a chance to use this as I'm currently focused elsewhere in the stack, but if I saw a professional all-around debugging solution came out for RN, I'd most definitely jump on it.

Yeah that's not a bad idea! I wonder if this is something the Exponent people are interested in, since they know a lot more about React Native and are looking into Apollo.

@stubailo can you paste links to the relevant code/lines that makes the Apollo devtools plugin work in the browser? I mean this can't be that hard. It just requires knowing how both the apollo devtools work and react-native-debugger.

It's pretty much just this: https://github.com/apollostack/apollo-client-devtools/blob/master/app/evalInPage.js

The code is already designed to run equally well as a React component in a page, and as a Chrome extension. The only functionality required is to eval stuff.

After looking into this. The Devtools don’t work out of the box for the same reason the React devtools don’t work out of the box. React Native runs your JavaScript in a web worker with the debugger, and because web workers were designed with a share nothing principle we can’t get to the global object that Apollo Client sets __APOLLO_CLIENT__ on. There is an API in the Chrome dev channel for chrome.processes which would let us see what web worker processes there are, but it doesn’t appear to give us access to workers’ global scope and even if it did the API is in the dev channel so we couldn’t practically use it.

It’s worth noting that the React Devtools has the same problem and only works in react-native-debugger thanks to the remote React Devtools API (see https://github.com/facebook/react-devtools/issues/229 which is still unresolved).

The way Redux devtools and react-native-storybook solve this is by providing a standalone app that communicates to your JavaScript thread through a web socket. This is something we may want to consider in the future for the Apollo developer tools, but it would be non-trivial to implement.

react-native-debugger is, unfortunately, a dead end as well. All react-native-debugger does is use the remote versions of Redux Devtools and React Devtools instead of handing the global context to these tools like Apollo needs.

So unless I’m missing a stable Chrome API that allows extensions to access the global context of a worker (here’s the JavaScript API reference) we can’t get the Chrome devtool to work.

The next option is then getting the devtools to support a remote API communicated over web sockets. This would not be frictionless to use, however, as users would then need to install an Electron app, reference the URL of the remote server in their code, and jump through hoops with adb and XCode respectively to get access to the remote server when running the app on a real device.


An interesting solution would be to create bespoke devtools that run in React Native, however. We would probably need to lose GraphiQL (or allow users to open a browser window with GraphiQL) both because it is hard to type on mobile and we couldn’t use the actual GraphiQL UI as it was built for the web. We could, however, provide a custom store UI and the query UI.

Both options seem prohibitively expensive, so we may not have a good React Native debugging story for some time. It’s incredibly frustrating because React Native remote debugging opens up your code in Chrome, but the fact that the code runs in a web worker blocks us from getting access to the Apollo Client 😣

I initially wrote of the https://developer.chrome.com/extensions/debugger APIs, but I’m going to look at it one more time given it’s the only other Chrome extensions API that mentions web workers (https://duckduckgo.com/?q=site%3Ahttps%3A%2F%2Fdeveloper.chrome.com%2Fextensions+worker&atb=v1&ia=web). I’ll report back with my findings šŸ‘

Ok, so I might have a way to make this work. Using the Chrome debugging protocol we should be able to evaluate arbitrary JavaScript in a worker thread that we get from the chrome.debugger API as long as we expect a JSON object to be returned. Which is good because chrome.devtools.inspectedWindow.eval also expects JSON objects to be returned which we currently use. So the code was already written with this assumption in mind. I’m going to spend some time to see if I can hook this together. I’ll let you know how it goes šŸ‘

Unfortunately, the Chrome debugging protocol will not work either, for two reasons:

  1. In order to debug a process and inject code through that route into a web worker, our extension needs to take over the entire debugging procedure. What this means is that the user would see something like the image below, and the native Chrome debugging tools would not work.
  2. Web workers that are simply used as another thread are not returned by chrome.debugger.getTargets. Only service workers are returned (the workers that continue to run even after the browser window is closed). This means that even if sending commands using the Chrome debugging protocol didn’t require a browser take over there is no way to get the target id for the worker that React Native is running in.

screen shot 2017-01-26 at 10 08 09 am

See the yellow bar at the top? That’s what people would see whenever Apollo Devtools would be running in React Native using the debugging protocol. This also means that the Chrome debugger tools would not work while we had a debugger attached.

There is still some hope, though! We could do some hacks with chrome.webRequest to intercept the http://localhost:*/debuggerWorker.js file the React Native packager serves and inject some code. Then we could override window.Worker in the browser thread to inject some more code that routes certain messages from the worker to the devtools. However, this approach would be a total hack and incredibly fragile. Not to mention it would take some time to string it all together.

The best solution is to get some worker related APIs added to the Chrome Extensions APIs that allow us to evaluate code in a worker. I don’t see that happening anytime soon, however, as the release process for Google Chrome is very slow, and web workers are still a young technology.

The second best solution is to get React Native to not run the JavaScript code in a worker, and instead run it directly in the browser. However, this will likely _never_ happen as this used to be the case and the RN team reverted it for good reasons. React Native shouldn’t have DOM APIs, and running the code in the browser is the best way to introduce DOM APIs into React Native.

The third best solution is to explore alternative devtools environments for React Native and Apollo Client that may not be Chrome. Mozilla, Edge, or Node.js may all behave differently than Chrome.

IMO, the best solution here is to have an electron app which would interact with Apollo client via websockets. Same as React and Redux DevTools do. It could be used exactly like for React.

However, I predict having a "DevTools fatigue", as you have to lunch dozens of apps in order to debug your code 😬. That is the issue which react-native-debugger is solving. Another advantage of having all devtools in one app, is that you'll not have lots of websocket connections for each of them.

I can add the ability to include it in remotedev-app (which is the core lib for both react-native-debugger and redux-devtools-extension). It would be similarly to Atom packages or VSCode extensions, and actually you could adapt it later for them as well. I guess we could eval the code on the client side (as we do for dispatching Redux actions) or identify the commands with specific types (as we do for Redux monitor actions).

Let me know if you find this as a reasonable option.

Not sure if this helped, but @gaearon just responded with a note to use the "Standalone React Devtools" package:

https://github.com/facebook/react-devtools/issues/229#issuecomment-280081973

https://github.com/facebook/react-devtools/blob/master/packages/react-devtools/README.md

Any progress on this?

This just came out:

https://blog.expo.io/using-react-devtools-with-react-native-6c59e636a03b

Maybe that provides another way this can be implemented.

That tool works fine so it would be very interesting to see if those 2 could integrate!

Sorry if I'm incorrect since I haven't dived very deep into any of these projects, but doesn't react-devtools (npm) use eval which is what this seems to require?
ws://localhost:8097, messages starting with eval:.

EDIT: eval: is legacy for Nuclide, but the WS info stands.
Also, RNDebuggerWorker does have access to window.__APOLLO_CLIENT__, this might be part of what we need?
Can someone with better knowledge of react devtools standalone can chime in, it seems that are hooks for react and relay, and listeners there that can be added to achieve this?

@stubailo @jhen0409 you guys really should work together to get this into

react-native-debugger

I personally only use React Native Debugger now, and it is top notch. @jhen0409 has done a whole lot to incorporate everything in a seamless/frictionless manner. Basically, when using it, it's finally like us developers are using the sort of GUI-based tools video editors and 3D guys are using.

@stubailo essentially Apollo would be lucky/blessed to get into that Devtools Environment. It would be great for marketing. That said @jhen0409 is the guy to make it happen. He runs a very tight shift over there in all the related packages. Have MDG send him some cash and make it happen. That's my recommendation. The longer this hangs on the vine it becomes a missed opportunity. Despite previous research, I think it will take the creator of the Apollo Devtools + @jhen0409 to really determine the feasibility. As is common with development, you may very well find a workaround that makes it not so bad.

Here's the related issue in @jhen0409 's package:

https://github.com/jhen0409/react-native-debugger/issues/61

I'm migrating to GraphQL on the road, Apollo devtools might be my one of goal for improving our workflow, but I have more high priority works to do, so I haven't yet try to do this. 😢

Just saw the disscussions, I think it need to explain, currently the redux-devtools implementation of react-native-debugger isn't used websocket as bridge, it built on top of WebWorker message, here is the implementation. @zalmoxisus exported the components / utils so we can use!

Compared to websocket, I think that would be more easier implement Apollo devtools into RNDebugger, and we don't need a client package for connect via websocket (Keep using apollo-client, no any changes for user). Ideally it just replaced evalInPage function.

Also, react-native-debugger still keeping react-devtools use websocket, because the client connection have been built in react-native, it starts with [email protected].

I understand. I wasn't implying that redux-devtools uses websockets but
react-devtools does. I was suggesting to leverage that. It'd probably
require:

  1. A custom hook in react-devtools, the ability to add hooks, or leveraging
    an existing eval message (either would do). I see hooks for react inspector
    and relay, but that's as far as I went.
  2. Env detection in Apollo Client dev tools, the simple check for
    window.__APOLLO_CLIENT__ won't cut it. This hides the extension.
  3. Assuming the above hook is in place, conditionally switch away from
    postMessage in apollo devtools to pass messages via websocket.

I think if we follow that path we could make it work, am I right?

—
Best Regards,

Adrian Perez
https://adrianperez.codes

On June 3, 2017 at 4:40:25 AM, Jhen-Jie Hong ([email protected])
wrote:

I'm migrating to GraphQL on the road, Apollo devtools might be my one of
goal for improving our workflow, but I have more high priority works to do,
so I haven't yet try to do this. 😢

Just saw the disscussions, I think it need to explain, currently the
redux-devtools implementation of react-native-debugger isn't used
websocket as bridge, it built on top of WebWorker message, here is the
implementation
https://github.com/jhen0409/react-native-debugger/blob/master/app/worker/index.js#L21-L33.
@zalmoxisus https://github.com/zalmoxisus exported the components /
utils so we can use!

Compared to websocket, I think that would be more easier implement Apollo
devtools into RNDebugger, and we don't need a client package for connect
via websocket (Keep using apollo-client, no any changes for user).
Ideally it just replaced evalInPage
https://github.com/apollographql/apollo-client-devtools/blob/master/app/evalInPage.js
function.

Also, react-native-debugger still keeping react-devtools use websocket,
because the client connection have been built in react-native
https://github.com/facebook/react-native/blob/master/Libraries/Core/Devtools/setupDevtools.js,
it starts with [email protected]
https://github.com/facebook/react-native/commit/9e4af68d91b3c5a321627bd393e4a3991bf94db1
.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/apollographql/apollo-client-devtools/issues/6#issuecomment-305945348,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIIvNsxcvVRNItpzDfntRbiVLjCY9wtks5sAMeZgaJpZM4LN8tX
.

I understand. I wasn't implying that redux-devtools uses websockets

I'm meaning the earlier comments.

I was suggesting to leverage that. It'd probably require:

It's also a one of the possible way, but it's mean we will implement it in react-devtools repo. If we have to use websocket, I think make it as a standalone app will be a better choice.

@jhen0409 thanks so much for responding! Your thoughts on how to do this is exactly what's needed to take this to the next stage. @stubailo any thoughts from the Apollo team?

Unlike other extensions, Apollo DevTools doesn't rely on the background page script (it uses it only to show the icon). It could be possible to include it in React Debugger, without any changes on apollo-client-devtools side, by just redefining chrome.devtools.inspectedWindow.eval to use websockets or WebWorker message.

Any traction on this?

I understand react-native-debugger plans to add support for this tool, but the apollo client devtools do not yet work remotely (a la redux, react) so is blocked. Does that sound right @calebmer ? Is there another issue in this repo re: remote debugging

@peggyrayzis - happy to try and help out here and submit a PR, any points you can give me?

It sounds like the Apollo Dev Tools team has been unblocked - https://github.com/jhen0409/react-native-debugger/issues/177#issuecomment-408453332

I'd love to work on solving this issue, but need someone more familiar with Apollo and debuggers to accompany me.

I believe this is something a lot of people would love using.

Anyone out there who wants to take a look at it? :)

Hey, I've been looking out if anyone is going to work on apollo dev tools to support react native. As far as I know nobody yet worked on it.

I took a honor to spend few hours trying to hack some kind of solution. By using websockets I managed to achieve some of the functionality.

By saying some I mean I only cannot think of the way to support apollo link through websockets (not familiar with links).

But I can see query history, mutations, cache data.

Would anyone be interested in helping me out with link functionality?

Here is the proof of functionality:

https://media.giphy.com/media/WvkTgooNKpJN8Azd6r/giphy.gif

Hey, I've been looking out if anyone is going to work on apollo dev tools to support react native. As far as I know nobody yet worked on it.

I took a honor to spend few hours trying to hack some kind of solution. By using websockets I managed to achieve some of the functionality.

By saying some I mean I only cannot think of the way to support apollo link through websockets (not familiar with links).

But I can see query history, mutations, cache data.

Would anyone be interested in helping me out with link functionality?

Here is the proof of functionality:

https://media.giphy.com/media/WvkTgooNKpJN8Azd6r/giphy.gif

@Gongreg Any chance u upload your fork? i really need something.

I was literally trying it inside node_modules.
Now I am trying other solution, that is to inject apollo devtools code inside the react native code, so there would be no need for websockets and we could only use post messages. I will return with my findings later.

Hey everyone,
Amazing news, I just managed to include apollo client devtools inside react-native-debugger. And I've included it without running websockets.

That means we have full functionality support, including graphiql, explorer, running queries and everything.

I will publish my forks tomorrow and try to talk with @jhen0409 on how I should do it properly.

I am really happy to see it working!!

Once again, a low quality gif! https://media.giphy.com/media/47J99DEuzDolu7zKR0/giphy.gif

Edit: Seems like I didn't add the update here, so here it is: https://twitter.com/GytisVinclovas/status/1072646494518423553

@Gongreg Can you share any news? :)

Sure @benseitz,
Work from my side is done. I am waiting for Apollo team to finish their part (I just got notified that they should finally be able to do that).

These are relevant issues and PR's.

publish apollo dev tools to npm: apollographql/apollo-client-devtools#160

PR Update for apollo dev tools: apollographql/apollo-client-devtools#165

PR To include dev tools in React Native Debugger: #298

Thanks for the update and your amazing work @Gongreg!

I believe this can be closed off - thanks all!

Was this page helpful?
0 / 5 - 0 ratings