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

Update react-devtools-inline, react, and react-dom dependencies #6075

Merged
merged 7 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@
"parse-script-tags": "^0.1.7",
"prop-types": "^15.8.1",
"properties-parser": "^0.3.1",
"react": "^0.0.0-experimental-edfe50510-20210823",
"react": "^0.0.0-experimental-e7d0053e6-20220325",
"react-canvas-confetti": "^1.3.0",
"react-circular-progressbar": "^2.0.4",
"react-codemirror2": "^7.2.1",
"react-devtools-inline": "^4.17.0",
"react-dom": "^0.0.0-experimental-edfe50510-20210823",
"react-devtools-inline_4_17_0": "npm:react-devtools-inline@4.17.0",
"react-devtools-inline": "^4.24.3",
"react-dom": "^0.0.0-experimental-e7d0053e6-20220325",
"react-dom-factories": "^1.0.2",
"react-json-view": "^1.21.3",
"react-lazyload": "^3.2.0",
Expand Down
46 changes: 45 additions & 1 deletion src/ui/components/SecondaryToolbox/ReactDevTools.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { useEffect, useState } from "react";
import { connect, ConnectedProps, useSelector } from "react-redux";
import { createBridge, createStore, initialize, Store, Wall } from "react-devtools-inline/frontend";
import { ExecutionPoint, ObjectId } from "@recordreplay/protocol";
import { ThreadFront } from "protocol/thread";
import { compareNumericStrings } from "protocol/utils";
Expand All @@ -18,6 +18,10 @@ import Highlighter from "highlighter/highlighter";
import NodePicker, { NodePickerOpts } from "ui/utils/nodePicker";
import { sendTelemetryEvent, trackEvent } from "ui/utils/telemetry";

import type { Store, Wall } from "react-devtools-inline/frontend";

type ReactDevToolsInlineModule = typeof import("react-devtools-inline/frontend");

const getDOMNodes = `((rendererID, id) => __REACT_DEVTOOLS_GLOBAL_HOOK__.rendererInterfaces.get(rendererID).findNativeNodesForFiberID(id))`;

// used by the frontend to communicate with the backend
Expand Down Expand Up @@ -207,12 +211,15 @@ class ReplayWall implements Wall {
}

function createReactDevTools(
reactDevToolsInlineModule: ReactDevToolsInlineModule,
annotations: Annotation[],
currentPoint: ExecutionPoint,
enablePicker: (opts: NodePickerOpts) => void,
disablePicker: () => void,
onShutdown: () => void
) {
const { createBridge, createStore, initialize } = reactDevToolsInlineModule;

const target = { postMessage() {} };
const wall = new ReplayWall(enablePicker, disablePicker, onShutdown);
const bridge = createBridge(target, wall);
Expand All @@ -229,6 +236,28 @@ function createReactDevTools(
return ReactDevTools;
}

// React DevTools (RD) changed its internal data structure slightly in a minor update.
// The result is that Replay sessions recorded with older versions of RD don't play well in newer versions.
// We can work around this by checking RD's "bridge protocol" version (which we also store)
// and loading the appropriate frontend version to match.
// For more information see https://github.com/facebook/react/issues/24219
async function loadReactDevToolsInlineModuleFromProtocol(stateUpdaterCallback: Function) {
const response = await ThreadFront.evaluate({
asyncIndex: 0,
text: ` __RECORD_REPLAY_REACT_DEVTOOLS_SEND_MESSAGE__("getBridgeProtocol", undefined)`,
});
const json: any = await response?.returned?.getJSON();
const version = json?.data?.version;

// We should only load the DevTools module once we know which protocol version it requires.
// If we don't have a version yet, it probably means we're too early in the Replay session.
if (version >= 2) {
stateUpdaterCallback(await import("react-devtools-inline/frontend"));
} else if (version === 1) {
stateUpdaterCallback(await import("react-devtools-inline_4_17_0/frontend"));
}
}

function ReactDevtoolsPanel({
annotations,
currentPoint,
Expand All @@ -239,6 +268,19 @@ function ReactDevtoolsPanel({
}: PropsFromRedux) {
const theme = useSelector(getTheme);

// Once we've obtained the protocol version, we'll dynamically load the correct module/version.
const [reactDevToolsInlineModule, setReactDevToolsInlineModule] =
useState<ReactDevToolsInlineModule | null>(null);

// Try to load the DevTools module whenever the current point changes.
// Eventually we'll reach a point that has the DevTools protocol embedded.
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => {
if (reactDevToolsInlineModule === null) {
loadReactDevToolsInlineModuleFromProtocol(setReactDevToolsInlineModule);
}
});

if (currentPoint === null) {
return null;
}
Expand Down Expand Up @@ -270,6 +312,7 @@ function ReactDevtoolsPanel({
}

const isReady =
reactDevToolsInlineModule !== null &&
reactInitPoint !== null &&
currentPoint !== null &&
compareNumericStrings(reactInitPoint, currentPoint) <= 0;
Expand All @@ -284,6 +327,7 @@ function ReactDevtoolsPanel({
}

const ReactDevTools = createReactDevTools(
reactDevToolsInlineModule,
annotations,
currentPoint,
enablePicker,
Expand Down
4 changes: 4 additions & 0 deletions src/ui/components/SecondaryToolbox/react-devtools-inline.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,7 @@ https: declare module "react-devtools-inline/frontend" {
bridgeAndStore: { bridge?: FrontentBridge; store?: Store }
): typeof ReactDevTools;
}

https: declare module "react-devtools-inline_4_17_0/frontend" {
export * from "@types/react-devtools-inline/frontend";
bvaughn marked this conversation as resolved.
Show resolved Hide resolved
}