Skip to content

Commit

Permalink
feat[devtools]: add package for fusebox integration (facebook#28553)
Browse files Browse the repository at this point in the history
## Summary

Stacked on facebook#28552. Review only the
[last commit at the
top](facebook@c69952f).

These changes add new package `react-devtools-fusebox`, which is the
entrypoint for the RDT Frontend, which will be used in Chrome DevTools
panel. The main differences from other frontend shells (extension,
standalone) are:
1. This package builds scripts in ESM format, this is required by Chrome
DevTools, see webpack config:

https://github.com/facebook/react/blob/c69952f1bf6e23252d47e0f7eb98efbbb2cc2c55/packages/react-devtools-fusebox/webpack.config.frontend.js#L50-L52
2. The build includes styles in a separate `.css` file, which is
required for Chrome DevTools: styles are loaded lazily once panel is
mounted.
  • Loading branch information
hoxyq authored and AndyPengc12 committed Apr 15, 2024
1 parent 06b81eb commit aeec059
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ packages/react-devtools-extensions/firefox/*.xpi
packages/react-devtools-extensions/firefox/*.pem
packages/react-devtools-extensions/shared/build
packages/react-devtools-extensions/.tempUserDataDir
packages/react-devtools-fusebox/dist
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist
packages/react-devtools-timeline/dist
6 changes: 6 additions & 0 deletions packages/react-devtools-fusebox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# react-native-fusebox

This package is private and not expected to become public anytime soon. Consider using [react-devtools-inline](https://github.com/facebook/react/tree/main/packages/react-devtools-inline) or [react-devtools-core](https://github.com/facebook/react/tree/main/packages/react-devtools-core).

## What is Fusebox?
"Fusebox" is the internal codename for the new React Native debugger stack based on Chrome DevTools.
22 changes: 22 additions & 0 deletions packages/react-devtools-fusebox/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "react-devtools-fusebox",
"version": "0.0.0",
"private": "true",
"license": "MIT",
"files": ["dist"],
"scripts": {
"build:frontend:local": "cross-env NODE_ENV=development webpack --config webpack.config.frontend.js",
"build:frontend": "cross-env NODE_ENV=production webpack --config webpack.config.frontend.js",
"build": "yarn build:frontend"
},
"devDependencies": {
"buffer": "^6.0.3",
"cross-env": "^7.0.3",
"css-loader": "^6.9.1",
"mini-css-extract-plugin": "^2.7.7",
"process": "^0.11.10",
"webpack": "^5.82.1",
"webpack-cli": "^5.1.1",
"workerize-loader": "^2.0.2"
}
}
62 changes: 62 additions & 0 deletions packages/react-devtools-fusebox/src/frontend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import * as React from 'react';
import {createRoot} from 'react-dom/client';
import Bridge from 'react-devtools-shared/src/bridge';
import Store from 'react-devtools-shared/src/devtools/store';
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';

import type {Wall} from 'react-devtools-shared/src/frontend/types';
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';

type Config = {
checkBridgeProtocolCompatibility?: boolean,
supportsNativeInspection?: boolean,
supportsProfiling?: boolean,
};

export function createBridge(wall?: Wall): FrontendBridge {
if (wall != null) {
return new Bridge(wall);
}

return new Bridge({listen: () => {}, send: () => {}});
}

export function createStore(bridge: FrontendBridge, config?: Config): Store {
return new Store(bridge, {
checkBridgeProtocolCompatibility: true,
supportsTraceUpdates: true,
supportsNativeInspection: true,
...config,
});
}

type InitializationOptions = {
bridge: FrontendBridge,
store: Store,
};

export function initialize(
contentWindow: Element | Document,
options: InitializationOptions,
): void {
const {bridge, store} = options;
const root = createRoot(contentWindow);

root.render(
<DevTools
bridge={bridge}
store={store}
showTabBar={true}
warnIfLegacyBackendDetected={true}
/>,
);
}
141 changes: 141 additions & 0 deletions packages/react-devtools-fusebox/webpack.config.frontend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
const {resolve} = require('path');
const Webpack = require('webpack');
const {
DARK_MODE_DIMMED_WARNING_COLOR,
DARK_MODE_DIMMED_ERROR_COLOR,
DARK_MODE_DIMMED_LOG_COLOR,
LIGHT_MODE_DIMMED_WARNING_COLOR,
LIGHT_MODE_DIMMED_ERROR_COLOR,
LIGHT_MODE_DIMMED_LOG_COLOR,
GITHUB_URL,
getVersionString,
} = require('react-devtools-extensions/utils');
const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
console.error('NODE_ENV not set');
process.exit(1);
}

const builtModulesDir = resolve(
__dirname,
'..',
'..',
'build',
'oss-experimental',
);

const __DEV__ = NODE_ENV === 'development';

const EDITOR_URL = process.env.EDITOR_URL || null;

const DEVTOOLS_VERSION = getVersionString();

const babelOptions = {
configFile: resolve(
__dirname,
'..',
'react-devtools-shared',
'babel.config.js',
),
};

module.exports = {
mode: __DEV__ ? 'development' : 'production',
entry: {
frontend: './src/frontend.js',
},
experiments: {
outputModule: true,
},
output: {
path: __dirname + '/dist',
publicPath: '/dist/',
filename: '[name].js',
chunkFilename: '[name].chunk.js',
library: {
type: 'module',
},
},
node: {
global: false,
},
resolve: {
alias: {
'react-devtools-feature-flags': resolveFeatureFlags('fusebox'),
react: resolve(builtModulesDir, 'react'),
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
'react-dom/client': resolve(builtModulesDir, 'react-dom/client'),
'react-dom': resolve(builtModulesDir, 'react-dom'),
'react-is': resolve(builtModulesDir, 'react-is'),
scheduler: resolve(builtModulesDir, 'scheduler'),
},
},
optimization: {
minimize: false,
},
plugins: [
new MiniCssExtractPlugin(),
new Webpack.ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer'],
}),
new Webpack.DefinePlugin({
__DEV__,
__EXPERIMENTAL__: true,
__EXTENSION__: false,
__PROFILE__: false,
__TEST__: NODE_ENV === 'test',
'process.env.DEVTOOLS_PACKAGE': `"react-devtools-fusebox"`,
'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
'process.env.EDITOR_URL': EDITOR_URL != null ? `"${EDITOR_URL}"` : null,
'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
'process.env.NODE_ENV': `"${NODE_ENV}"`,
'process.env.DARK_MODE_DIMMED_WARNING_COLOR': `"${DARK_MODE_DIMMED_WARNING_COLOR}"`,
'process.env.DARK_MODE_DIMMED_ERROR_COLOR': `"${DARK_MODE_DIMMED_ERROR_COLOR}"`,
'process.env.DARK_MODE_DIMMED_LOG_COLOR': `"${DARK_MODE_DIMMED_LOG_COLOR}"`,
'process.env.LIGHT_MODE_DIMMED_WARNING_COLOR': `"${LIGHT_MODE_DIMMED_WARNING_COLOR}"`,
'process.env.LIGHT_MODE_DIMMED_ERROR_COLOR': `"${LIGHT_MODE_DIMMED_ERROR_COLOR}"`,
'process.env.LIGHT_MODE_DIMMED_LOG_COLOR': `"${LIGHT_MODE_DIMMED_LOG_COLOR}"`,
}),
],
module: {
rules: [
{
test: /\.worker\.js$/,
use: [
{
loader: 'workerize-loader',
options: {
inline: true,
name: '[name]',
},
},
{
loader: 'babel-loader',
options: babelOptions,
},
],
},
{
test: /\.js$/,
loader: 'babel-loader',
options: babelOptions,
},
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {modules: true},
},
],
},
],
},
};
1 change: 1 addition & 0 deletions packages/react-devtools-shared/buildUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function resolveFeatureFlags(target) {
switch (target) {
case 'inline':
case 'shell':
case 'fusebox':
flagsPath = 'DevToolsFeatureFlags.default';
break;
case 'core/backend-oss':
Expand Down
Loading

0 comments on commit aeec059

Please sign in to comment.