Skip to content

Commit

Permalink
fix[devtools]: fixed duplicated backend activation with multiple rend…
Browse files Browse the repository at this point in the history
…erers (facebook#26807)

## Summary
Initially reported in facebook#26797.
Was not able to reproduce the exact same problem, but found this case:

1. Open corresponding codepen from the issue in debug mode
2. Open components tab of the extension
3. Refresh the page

Received multiple errors:
- Warning in the Console tab: Invalid renderer id "2".
- Error in the Components tab: Uncaught Error: Cannot add node "3"
because a node with that id is already in the Store.

This problem has occurred after landing a fix in
facebook#26779. Looks like Chrome is
keeping the injected scripts (the backend in this case) and we start
backend twice.
  • Loading branch information
hoxyq authored and AndyPengc12 committed Apr 15, 2024
1 parent 7a9f01c commit efbe7de
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/react-devtools-extensions/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ function setup(hook: ?DevToolsHook) {
initBackend,
setupNativeStyleEditor,
});

hook.emit('devtools-backend-installed', COMPACT_VERSION_NAME);
}
17 changes: 13 additions & 4 deletions packages/react-devtools-extensions/src/backendManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function setup(hook: ?DevToolsHook) {

// register renderers that have already injected themselves.
hook.renderers.forEach(renderer => {
registerRenderer(renderer);
registerRenderer(renderer, hook);
});

// Activate and remove from required all present backends, registered within the hook
Expand All @@ -71,7 +71,7 @@ function setup(hook: ?DevToolsHook) {

// register renderers that inject themselves later.
hook.sub('renderer', ({renderer}) => {
registerRenderer(renderer);
registerRenderer(renderer, hook);
updateRequiredBackends();
});

Expand All @@ -84,19 +84,24 @@ function setup(hook: ?DevToolsHook) {

const requiredBackends = new Set<string>();

function registerRenderer(renderer: ReactRenderer) {
function registerRenderer(renderer: ReactRenderer, hook: DevToolsHook) {
let version = renderer.reconcilerVersion || renderer.version;
if (!hasAssignedBackend(version)) {
version = COMPACT_VERSION_NAME;
}
requiredBackends.add(version);

// Check if required backend is already activated, no need to require again
if (!hook.backends.has(version)) {
requiredBackends.add(version);
}
}

function activateBackend(version: string, hook: DevToolsHook) {
const backend = hook.backends.get(version);
if (!backend) {
throw new Error(`Could not find backend for version "${version}"`);
}

const {Agent, Bridge, initBackend, setupNativeStyleEditor} = backend;
const bridge = new Bridge({
listen(fn) {
Expand Down Expand Up @@ -157,6 +162,10 @@ function activateBackend(version: string, hook: DevToolsHook) {

// tell the service worker which versions of backends are needed for the current page
function updateRequiredBackends() {
if (requiredBackends.size === 0) {
return;
}

window.postMessage(
{
source: 'react-devtools-backend-manager',
Expand Down

0 comments on commit efbe7de

Please sign in to comment.