react icon indicating copy to clipboard operation
react copied to clipboard

DevTools: Improve browser extension iframe support

Open dmail opened this issue 4 years ago β€’ 52 comments

When react is inside an iframe, chrome extension for react devtools fails to detect react.

This is because the extension sets __REACT_DEVTOOLS_GLOBAL_HOOK__ only on the top level window. Apparently it's possible to have __REACT_DEVTOOLS_GLOBAL_HOOK__ on iframes too by adding all_frames: true in extension manifest.json. It was done by redux devtools extension in https://github.com/zalmoxisus/redux-devtools-extension/pull/56.

Have you considered adding all_frames: true to chrome extension ?

Steps To Reproduce

  1. Create a file react-main.html
<!DOCTYPE html>
<html>
  <head>
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  </head>
  <body></body>
</html>

  1. Create a file react-iframe.html
<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <iframe src="./react-main.html" />
  </body>
</html>
  1. Open react-iframe.html in chrome

The current behavior

react-devtools-not-detected

The expected behavior

react-devtools-detected

Pull request: https://github.com/facebook/react/pull/18952

dmail avatar May 18 '20 09:05 dmail

The frame limitation is mentioned in the docs, FWIW: https://github.com/facebook/react/tree/master/packages/react-devtools

It's not a bug, just a known limitation. We currently suggest using the standalone version (as linked above) or (if you also control the iframe) passing the hook through from the parent: https://github.com/facebook/react/blob/d897c35ecfb7471b55e41933fd4d993b98dbf600/fixtures/devtools/regression/14.9.html#L9-L11

I don't think that adding the Manifest setting you mentioned would be enough on its own to make the React DevTools extension detect and support versions of React running inside of iframes.

I'd be happy for you to take a shot at implementing it though if you'd like. We have a regression test that you could use to verify this:

./fixtures/devtools/regression/server.js
# Open localhost:3000 and see if DevTools detects React

bvaughn avatar May 18 '20 20:05 bvaughn

Thank you very much for your answer and rewording the issue title, it's more accurate.

In my case the iframe runs in an other domain so window.parent would not be accessible.

I am ready to try to implement it. I'll take a look tomorrow. If you have any more info to share that would greatly help me when I'll start working on it.

Thanks again, I will keep you informed and I hope I will be able to make it work :)

dmail avatar May 18 '20 20:05 dmail

Great! Keep me posted on your progress :smile:

Here's instructions to get you started: https://github.com/facebook/react/tree/master/packages/react-devtools-extensions#build-steps

bvaughn avatar May 18 '20 20:05 bvaughn

I have opened a draft pull request. For now I have only tested to add all_frames: true on chrome extension manifest.json and it looks like it's working -> react is being detected inside a sandboxed iframe πŸŽ‰ .

dmail avatar May 19 '20 08:05 dmail

Working on edge πŸŽ‰

About firefox however I have some trouble. I have changed nothing yet concerning firefox and after doing

  1. yarn build:firefox
  2. yarn run test:firefox

In the firefox browser that is launched the extension does not detect react on reactjs.org.

firefoxko

In Firefox console I see this error (and many more with the same error code):

image

The extension in firefox store is working properly

firefoxok

Firefox fails to load some file (apparently related to Localization) when the extension is loaded locally. Any idea what is going on ?

dmail avatar May 19 '20 09:05 dmail

About firefox I got workarounds depending what happens:

(a) Firefox addon is shown but fails to detect react -> refresh the page and it will work normally

(b) Firefox addon does not even show up -> go to Firefox settings -> disable react devtools addon and enable it right away -> go back to reactjs.org and it will work normally

As I said this happens already on master branch without any change on my side.

Now that I can test firefox extension locally I move on and try to add all_frame: true on Firefox.

dmail avatar May 19 '20 12:05 dmail

I'm putting pull request in ready for review.

dmail avatar May 19 '20 13:05 dmail

What happened to this issue? Is it available for me to try out? @dmail , are you planning on working on it or I may try to figure this out?

ghost avatar Jun 25 '20 06:06 ghost

Hello, the pull request is on hold because I don't know what to tackle first. On my side I was waiting for advice to restart working on it. Go ahead, I'm still interested on the subject so I'll keep an eye on it (and may still help to the extent of my abilities).

dmail avatar Jun 25 '20 07:06 dmail

@dmail thank you!

ghost avatar Jun 25 '20 07:06 ghost

For the record, I was able to make this work with a Next.js app that is providing the iframe, with these changes:

$NEXT_PROJECT/public/js/enableReactDevtoolsIframe.js

// The React DevTools do not normally look inside of iframes, just the outer window.
// We can enable inspection of React components in an iframe by copying this global variable:
// https://github.com/facebook/react/issues/18945#issuecomment-630421386
// This code must be injected before React runs, so we add it as a separate tag
// and show it via Next.js <Head> in _app.tsx.
if (window.parent) {
  window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
}

$NEXT_PROJECT/pages/_app.tsx

import React from 'react';
import Head from 'next/head';

export default function MyApp({ Component, pageProps }: { Component: any; pageProps: any }) {
  // Ensure the React DevTools global variable is injected if this is an iframe
  // to enable inspection of components inside the iframe.
  return (
    <React.Fragment>
      <Head>
        <script src="js/enableReactDevtoolsIframe.js"></script>
      </Head>
      <Component {...pageProps} />
    </React.Fragment>
  );
}

markerikson avatar Jul 02 '20 21:07 markerikson

FYI: We've been using the all_frames: true option in manifest.json for a while now over with preact-devtools and it works like a charm. The only thing one needs to be careful about is to inject the highlighting code into each iframe too! Otherwise the position will be off.

marvinhagemeister avatar Jul 03 '20 10:07 marvinhagemeister

@marvinhagemeister Do you remember doing anything additional (beyond just adding all_frames: true option in manifest.json) to get it to work? I haven't taken the time to dig into this yet but I did test out the linked PR (#18952) and it didn't appear to be working.

@shakhbulatgaz did you ever end up digging into this?

bvaughn avatar Jul 06 '20 14:07 bvaughn

@bvaughn Not much really, only had to ensure that each adapter that's injected into the client doesn't traverse into other iframes. The linked PR looks correct to me, so I'm guessing something isn't ok with the connection logic. Maybe it's the same timing issue we've been talking about a while back that's more of a regression in Chrome?

For reference: The PR that added support for iframes for preact-devtools: https://github.com/preactjs/preact-devtools/pull/209/files

marvinhagemeister avatar Jul 06 '20 16:07 marvinhagemeister

Gotcha! Thanks for elaborating :smile:

Maybe it's the same timing issue we've been talking about a while back that's more of a regression in Chrome?

I think the fix for this issue has made its way into stable (or at least I'm no longer seeing the issue myself).

bvaughn avatar Jul 06 '20 16:07 bvaughn

@bvaughn Nah, I'm sorry, other things came up and I completely forgot about this 😒

ghost avatar Jul 06 '20 17:07 ghost

Fair enough. Maybe someone else will pick it up :)

bvaughn avatar Jul 06 '20 17:07 bvaughn

@bvaughn Can you explain to me the current scenario and what needs to be done? Was reading through the thread but couldn't deduce much. This is my first issue to pick from react repo.

anrao91 avatar Jul 06 '20 17:07 anrao91

@anrao91 Unfortunately, no. Not beyond what's been discussed on this thread and on the linked PR (#18952).

bvaughn avatar Jul 06 '20 18:07 bvaughn

@bvaughn By adding the below code, doesn't enable react to inspect inside an iframe. I tried the regression test, didn't work there either.

__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__; 

I was able to make this work by copying the values of parents __REACT_DEVTOOLS_GLOBAL_HOOK__ one by one, instead of copying it directly. (Maybe this isn't the right approach, but it seems to work)

for (const key in __REACT_DEVTOOLS_GLOBAL_HOOK__) {
      __REACT_DEVTOOLS_GLOBAL_HOOK__[key] = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__[key]
}

I verified it by doing the regression test on Firefox and Chrome. It detected React and also displayed the entire component tree under the Components Panel. (Didn't work for React 0.14.9 though due to incompatibility)

Copying it directly didn't update the iframe's __REACT_DEVTOOLS_GLOBAL_HOOK__ value, I'm not really sure why though. Maybe because it's is not writable. When using defineProperty, writable is false by default. But, In this case, the above working code shouldn't have worked. :smile: https://github.com/facebook/react/blob/9ea0f6752da28a91bdb56382367e2a07390cb733/packages/react-devtools-shared/src/hook.js#L309-L321

Anyways let me know your thoughts on this.

Below is a sceenshot showing the working eg:,

react_dev_tools_issue

Reflex-Gravity avatar Jul 13 '20 23:07 Reflex-Gravity

Can I take this up if no one else is currently working on it? @bvaughn @dmail

sarathps93 avatar Aug 30 '20 13:08 sarathps93

@sarathps93 You're welcome to work on this. Please check out the work and discussion on #19345 before starting though!

bvaughn avatar Aug 31 '20 15:08 bvaughn

@sarathps93 Are you still working on it ?

omarsy avatar Sep 07 '20 06:09 omarsy

@omarsy I was about to start this weekend. Let me know if you want to take it up

sarathps93 avatar Sep 08 '20 06:09 sarathps93

Can I push a PR ?

omarsy avatar Sep 11 '20 18:09 omarsy

@omarsy Yes please go ahead

sarathps93 avatar Sep 13 '20 14:09 sarathps93

Thank you @sarathps93

omarsy avatar Sep 13 '20 20:09 omarsy

Resolved in #19827

bvaughn avatar Sep 14 '20 14:09 bvaughn

Re-opening because this was reverted again.

bvaughn avatar Oct 05 '20 13:10 bvaughn

@bvaughn I have walked through previous discussions. Can I take a look at it as my first issue?

Eric0926 avatar Oct 06 '20 05:10 Eric0926

Feel free, @Eric0926.

I'm a little skeptical about landing this change again though, given we've had to revert it twice. πŸ˜… But if you're willing to do a lot of testing, sure!

bvaughn avatar Oct 06 '20 13:10 bvaughn

It looks like the issue is still relevant. πŸ™

alleksei37 avatar Dec 28 '20 01:12 alleksei37

That's why the issue is still open, @alleksei37.

bvaughn avatar Jan 03 '21 15:01 bvaughn

can you merge the fix with a feature flag? (i.e. enable-able from settings) I'm having the __REACT_DEVTOOLS_GLOBAL_HOOK__ fix and I want to remove it!

KutnerUri avatar Jan 07 '21 10:01 KutnerUri

No. If there was a simple fix that just needed to be merged, it would have been merged already. Both previous attempts to fix this have needed to be reverted because they've caused unexpected problems.

Regardless, the fix is not something that could be enabled/disabled via a setting– because it requires changes to things like the extension manifest JSON.

bvaughn avatar Jan 07 '21 14:01 bvaughn

Hi, I want to work on this issue, can you suggest me ways to get started?

prsmahajan avatar Jun 05 '21 18:06 prsmahajan

@prsmahajan You can find an architecture overview doc about how DevTools works here: https://github.com/facebook/react/blob/master/packages/react-devtools/OVERVIEW.md

And instructions for how to build and test the extension here: https://github.com/facebook/react/tree/master/packages/react-devtools-extensions#local-development

Beyond that, this would likely be an unguided task because we're all spread a little thin at the moment.

bvaughn avatar Jun 05 '21 19:06 bvaughn

What is the main problem you all are facing?

prsmahajan avatar Jun 06 '21 11:06 prsmahajan

Solution above works partly, only with deactivated CORS (for me) Do u have any ideas, how to allow using of devtools with enabled CORS? photo_2021-06-19 14 49 30

flydge avatar Jun 19 '21 12:06 flydge

I believe I have the same problem as @flydge .

image

jplindgren avatar Jul 18 '21 00:07 jplindgren

@bvaughn Can I take a look at it as my first issue?

amorphousDj avatar Sep 23 '21 02:09 amorphousDj

If you'd like to, please do.

bvaughn avatar Sep 23 '21 12:09 bvaughn

Can I Pick this, as its pending from long time back @bvaughn

Mukulbaid63 avatar Oct 26 '21 12:10 Mukulbaid63

Sure.

bvaughn avatar Oct 26 '21 13:10 bvaughn

Hi i'd like to contribute.

luanhcastro avatar Dec 01 '21 02:12 luanhcastro

This seems more urgent with google announcing removing document.domain. This means the parent hook passthrough is only available for same-protocol/subdomain/domain iframes.

Has there been any movement on this?

richiepreece avatar Jun 09 '22 19:06 richiepreece

It looks there are a couple pull requests that try to use the manifest.json approach, setting all_frames: true and getting the global devtools hook from the parent. That hasn't worked for my use case and I'm not confident that I would be able to fix the issue in the repo that way since it looks like that fix has been tried for about 7 years (see react-devtools issue 76).

As a workaround, what I want to do is create a dropdown that will let the user pick a frame and then show the component tree for that frame. Is that a viable solution? Would I have better luck with using the standalone devtools app found here?

awells111 avatar Jul 24 '22 11:07 awells111

For the record all_frames: true was inspired from preact-devtools. It might be interesting to see how preact use it and make things work. Out of my abilities.

dmail avatar Jul 24 '22 12:07 dmail

@omarsy Do you remember why #19854 was reverted? Is it because the changes cause some tests to fail or is it something else? The changes in that PR look like they're meeting the needs of my application.

awells111 avatar Jul 26 '22 12:07 awells111

Hello the issue is reverted because someone says it has an issue with my PR https://github.com/facebook/react/pull/19854#issuecomment-705190614. But I don't think it is related of my PR. It is why I create a new PR to fix the issue of the comment https://github.com/facebook/react/pull/19994 to see if it is caused by my PR or not. If I have time this month I will try to close my two PRs

omarsy avatar Jul 26 '22 12:07 omarsy

Thank you. I am available to help if you need. I am currently comparing the outputs of yarn test and yarn flow dom between the React repo and my fork (updated to 19854) to see what can be resolved.

awells111 avatar Jul 26 '22 13:07 awells111

@awells111 I think the frame selector is ideal if possible. Similar to what chrome does when you have iframes.

There's always the option for the standalone dev tools, but honestly it's not great for when you're trying to find a component because you don't have a selector, and you have to know the component tree to know where to look.

richiepreece avatar Jul 26 '22 17:07 richiepreece