-
Notifications
You must be signed in to change notification settings - Fork 45.6k
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
Add reload and profile to react-devtools-inline #27733
base: main
Are you sure you want to change the base?
Conversation
Yes, but only if you do all the necessary steps for reloading and start profiling on the application side. Is there a way for I haven't explored if this is currently blocked by something, but I would prefer this approach over exporting |
yes, I did that by setting sessionStorage.
if react-devtools-inline detects sessionStorage and set attach on the global, it works for me but I'm not sure if it work for others. |
Can you test it with I can help you with double-checking these changes a bit later. |
Sorry if I wasn't clear. Instead of just re-exporting
I think we should have this patch in DevTools, this is the solution I am looking for. If everything is fine, then just update the PR, I can test it later and have it merged. |
hi @hoxyq please take a look! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this. You are on the right track, but the current implementation doesn't solve the existing problem.
Some definitions:
react-devtools-shell
is a local-only package, which hosts a testing shell for DevTools. It uses inline version of the React DevTools.react-devtools-shared
contains all shared code across core / extension / inline versions of the DevTools.
What we want to achieve:
- In inline version of the DevTools user should be able to click on
Reload and profile
button and start profiling.
With just exporting attach
, users won't have this button available to them, it won't be visible, because it relies on supportsReloadAndProfile
flag.
What I expect from changes (essentially, to look the same as on other surfaces):
- User should be able to click on the 'Reload and profile' button.
- The page reloads and profiling button is highlighted in red (profiling in progress).
- User can click on this button to stop profiling and he will get a report.
You can test these changes in react-devtools-shell
, which uses the inline version. I don't expect you to update anything in the shell itself, it is just a testing shell.
Some useful links:
- The place where we create Store for inline version of the DevTools, where you can provide
supportsReloadAndProfile
flag -
react/packages/react-devtools-inline/src/frontend.js
Lines 27 to 34 in 77ec618
return new Store(bridge, { checkBridgeProtocolCompatibility: true, supportsTraceUpdates: true, supportsTimeline: true, supportsNativeInspection: true, ...config, }); } - How we define
__REACT_DEVTOOLS_ATTACH__
for extension version of the DevTools -if ( sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true' && !window.hasOwnProperty('__REACT_DEVTOOLS_ATTACH__') ) { Object.defineProperty( window, '__REACT_DEVTOOLS_ATTACH__', ({ enumerable: false, // This property needs to be configurable to allow third-party integrations // to attach their own renderer. Note that using third-party integrations // is not officially supported. Use at your own risk. configurable: true, get() { return attach; }, }: Object), ); } - The backend should listen to
'reloadAndProfile'
event. This is how its implemented in the extension -react/packages/react-devtools-shared/src/backend/agent.js
Lines 583 to 595 in 77ec618
reloadAndProfile: (recordChangeDescriptions: boolean) => void = recordChangeDescriptions => { sessionStorageSetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY, 'true'); sessionStorageSetItem( SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY, recordChangeDescriptions ? 'true' : 'false', ); // This code path should only be hit if the shell has explicitly told the Store that it supports profiling. // In that case, the shell must also listen for this specific message to know when it needs to reload the app. // The agent can't do this in a way that is renderer agnostic. this._bridge.send('reloadAppForProfiling'); }; - It sends an
'reloadAppForProfiling'
to the frontend to reload the page. You won't need that for inline version, because you probably can just reload the page withcontentWindow.parent.location.reload()
.
- It sends an
That's interesting but contains more changes. I will try to do it later. |
hi @hoxyq please take a look thanks. I believe this package is experimental so I bring some breaking changes to support reload and profile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't need to change anything in react-devtools-shell
, why changing the environment?
You need to do 3 things:
- Provide
supportsReloadAndProfile
flag withtrue
value. (What you almost doing) - Inject
__REACT_DEVTOOLS_ATTACH__
, what you are doing. - Backend should listen for
'reloadAndProfile'
event, after which you need to set all necessary flags to sessions storage and reload the whole document. You don't need to send'reloadAppForProfiling'
to the frontend, because the frontend will be reloaded together with the whole document (frontend is in an iframe inside this document). You need to reload what you are debugging, so backend and frontend of the DevTools will be reloaded with it.
Thanks again for working on this, I can help with implementing these probably next week, if you feeling stuck.
createBridge: customCreateBridge, | ||
createStore: customCreateStore, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need these custom functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our use case, I need to unload and reload the DevTools without refreshing the whole page. What I do in this PR is reloading the app iframe only, and destroy then create a new store, so the main page won't need to refresh.
I changed it according to your review, but it became less fit our use case (I need to manually destroy and create store & dev tools because I cannot refresh the page). |
Why not just reloading the whole page? Backend is injected in the page's context and it should be able to reload it with |
I cannot refresh the front-end (DevTools). Backend (app) is ok |
Can you share more on your setup? Is frontend running in a different context / page? |
Yes. Our setup is a Web Extension, therefore it cannot use the official React Devtools (web extensions cannot debug each other). I have integrated react-devtools-inline and made it work like how react-devtools-extension works. |
Why have you chosen Anyways, with this setup it will require more than what I've mentioned before and yes, you would need to reload the frontend as well or make it resetting the store. The scope of this feature is much bigger now, I can help with reviewing the changes, but can't really spend much time digging into this right now, as I am going on PTO next week. My requirements would be:
|
I'll try that. I cannot recall if I tried the core package before. I'll back to this PR after I try that. |
Hi @hoxyq, I looked at the That package is too opinioned, the backend can only run in NodeJS, not the browser. Here is what I found:
I think my current changes are necessary to let it work in our environment, but I think it would be better to publish |
Thanks for the explanation. I will be back in a few days, hopefully will get you unblocked on this. |
Similar attempt: #27978 |
This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated. |
bump |
Summary
This "attach" function is necessary to support the reload & profile function, but it is not accessible from the
react-devtools-inline
package.How did you test this change?
I patched my node_modules to expose this function. It works for me.