Files
Brian Vaughn 2eb3f4e9b8 README typofix
2019-08-06 10:45:16 -07:00

146 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `react-devtools-inline`
React DevTools implementation for embedding within a browser-based IDE (e.g. [CodeSandbox](https://codesandbox.io/), [StackBlitz](https://stackblitz.com/)).
This is a low-level package. If you're looking for the standalone DevTools app, **use the `react-devtools` package instead.**
## Usage
This package exports two entry points: a frontend (to be run in the main `window`) and a backend (to be installed and run within an `iframe`<sup>1</sup>).
The frontend and backend can be initialized in any order, but **the backend must not be activated until after the frontend has been initialized**. Because of this, the simplest sequence is:
1. Frontend (DevTools interface) initialized in the main `window`.
1. Backend initialized in an `iframe`.
1. Backend activated.
<sup>1</sup> Sandboxed iframes are supported.
## API
### `react-devtools-inline/backend`
* **`initialize(contentWindow)`** -
Installs the global hook on the window. This hook is how React and DevTools communicate. **This method must be called before React is loaded.** (This means before any `import` or `require` statements!)
* **`activate(contentWindow)`** -
Lets the backend know when the frontend is ready. It should not be called until after the frontend has been initialized, else the frontend might miss important tree-initialization events.
```js
import { activate, initialize } from 'react-devtools-inline/backend';
// Call this before importing React (or any other packages that might import React).
initialize();
// Call this only once the frontend has been initialized.
activate();
```
### `react-devtools-inline/frontend`
* **`initialize(contentWindow)`** -
Configures the DevTools interface to listen to the `window` the backend was injected into. This method returns a React component that can be rendered directly<sup>2</sup>.
```js
import { initialize } from 'react-devtools-inline/frontend';
// This should be the iframe the backend hook has been installed in.
const iframe = document.getElementById(frameID);
const contentWindow = iframe.contentWindow;
// This returns a React component that can be rendered into your app.
// <DevTools {...props} />
const DevTools = initialize(contentWindow);
```
<sup>2</sup> Because the DevTools interface makes use of several new React APIs (e.g. suspense, concurrent mode) it should be rendered using either `ReactDOM.unstable_createRoot` or `ReactDOM.unstable_createSyncRoot`. It should not be rendered with `ReactDOM.render`.
## Examples
### Configuring a same-origin `iframe`
The simplest way to use this package is to install the hook from the parent `window`. This is possible if the `iframe` is not sandboxed and there are no cross-origin restrictions.
```js
import {
activate as activateBackend,
initialize as initializeBackend
} from 'react-devtools-inline/backend';
import { initialize as initializeFrontend } from 'react-devtools-inline/frontend';
// The React app you want to inspect with DevTools is running within this iframe:
const iframe = document.getElementById('target');
const { contentWindow } = iframe;
// Installs the global hook into the iframe.
// This must be called before React is loaded into that frame.
initializeBackend(contentWindow);
// React application can be injected into <iframe> at any time now...
// Note that this would need to be done via <script> tag injection,
// as setting the src of the <iframe> would load a new page (withou the injected backend).
// Initialize DevTools UI to listen to the hook we just installed.
// This returns a React component we can render anywhere in the parent window.
const DevTools = initializeFrontend(contentWindow);
// <DevTools /> interface can be rendered in the parent window at any time now...
// Be sure to use either ReactDOM.unstable_createRoot()
// or ReactDOM.unstable_createSyncRoot() to render this component.
// Let the backend know the frontend is ready and listening.
activateBackend(contentWindow);
```
### Configuring a sandboxed `iframe`
Sandboxed `iframe`s are also supported but require more complex initialization.
**`iframe.html`**
```js
import { activate, initialize } from "react-devtools-inline/backend";
// The DevTooks hook needs to be installed before React is even required!
// The safest way to do this is probably to install it in a separate script tag.
initialize(window);
// Wait for the frontend to let us know that it's ready.
function onMessage({ data }) {
switch (data.type) {
case "activate-backend":
window.removeEventListener("message", onMessage);
activate(window);
break;
default:
break;
}
}
window.addEventListener("message", onMessage);
```
**`main-window.html`**
```js
import { initialize } from "react-devtools-inline/frontend";
const iframe = document.getElementById("target");
const { contentWindow } = iframe;
// Initialize DevTools UI to listen to the iframe.
// This returns a React component we can render anywhere in the main window.
// Be sure to use either ReactDOM.unstable_createRoot()
// or ReactDOM.unstable_createSyncRoot() to render this component.
const DevTools = initialize(contentWindow);
// Let the backend know to initialize itself.
// We can't do this directly because the iframe is sandboxed.
// Only initialize the backend once the DevTools frontend has been initialized.
iframe.onload = () => {
contentWindow.postMessage(
{
type: "activate-backend"
},
"*"
);
};
```