From 60a30cf32e1f974b82f0c7da9d8a03822e5b5208 Mon Sep 17 00:00:00 2001 From: Luna Ruan Date: Wed, 25 Aug 2021 15:35:38 -0700 Subject: [PATCH] Console Logging for StrictMode Double Rendering (#22030) React currently suppress console logs in StrictMode during double rendering. However, this causes a lot of confusion. This PR moves the console suppression logic from React into React Devtools. Now by default, we no longer suppress console logs. Instead, we gray out the logs in console during double render. We also add a setting in React Devtools to allow developers to hide console logs during double render if they choose. --- .../react-devtools-core/src/standalone.js | 4 + .../react-devtools-core/webpack.backend.js | 12 ++ .../react-devtools-core/webpack.standalone.js | 12 ++ .../src/injectGlobalHook.js | 3 + .../react-devtools-extensions/src/main.js | 7 + .../react-devtools-extensions/src/utils.js | 4 +- packages/react-devtools-extensions/utils.js | 13 ++ .../webpack.backend.js | 19 +- .../webpack.config.js | 17 +- packages/react-devtools-inline/README.md | 9 +- packages/react-devtools-inline/src/backend.js | 3 + .../react-devtools-inline/src/frontend.js | 2 + .../react-devtools-inline/webpack.config.js | 12 ++ .../src/__tests__/console-test.js | 91 ++++++++- .../src/__tests__/setupEnv.js | 16 ++ .../src/backend/agent.js | 29 ++- .../src/backend/console.js | 165 ++++++++++----- .../src/backend/renderer.js | 22 +- .../src/backend/types.js | 2 + .../src/backend/utils.js | 1 + packages/react-devtools-shared/src/bridge.js | 3 + .../react-devtools-shared/src/constants.js | 3 + .../views/Settings/DebuggingSettings.js | 15 +- .../views/Settings/SettingsContext.js | 19 ++ .../views/Settings/SettingsShared.css | 3 +- packages/react-devtools-shared/src/hook.js | 188 +++++++++++++++++- packages/react-devtools-shared/src/utils.js | 20 ++ .../react-devtools-shell/src/app/console.js | 4 + .../react-devtools-shell/src/app/index.js | 3 +- packages/react-devtools-shell/src/devtools.js | 14 +- .../react-devtools-shell/webpack.config.js | 12 ++ .../src/ReactFiberBeginWork.new.js | 24 ++- .../src/ReactFiberBeginWork.old.js | 24 ++- .../src/ReactFiberClassComponent.new.js | 14 +- .../src/ReactFiberClassComponent.old.js | 14 +- .../src/ReactFiberHooks.new.js | 7 +- .../src/ReactFiberHooks.old.js | 7 +- .../src/ReactFiberReconciler.js | 11 + .../src/ReactFiberReconciler.new.js | 21 ++ .../src/ReactFiberReconciler.old.js | 21 ++ .../src/ReactUpdateQueue.new.js | 11 +- .../src/ReactUpdateQueue.old.js | 11 +- packages/react-reconciler/src/Scheduler.js | 6 + .../src/__tests__/ReactStrictMode-test.js | 26 +-- packages/scheduler/src/forks/SchedulerMock.js | 11 +- packages/shared/consoleWithStackDev.js | 15 +- packages/shared/forks/Scheduler.umd.js | 7 +- .../shared/forks/consoleWithStackDev.www.js | 15 +- scripts/flow/react-devtools.js | 7 + 49 files changed, 799 insertions(+), 180 deletions(-) diff --git a/packages/react-devtools-core/src/standalone.js b/packages/react-devtools-core/src/standalone.js index 2e9e6a1056bf1..35d21b3a8a2ee 100644 --- a/packages/react-devtools-core/src/standalone.js +++ b/packages/react-devtools-core/src/standalone.js @@ -21,6 +21,7 @@ import { getBreakOnConsoleErrors, getSavedComponentFilters, getShowInlineWarningsAndErrors, + getHideConsoleLogsInStrictMode, } from 'react-devtools-shared/src/utils'; import {Server} from 'ws'; import {join} from 'path'; @@ -310,6 +311,9 @@ function startServer( )}; window.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = ${JSON.stringify( getShowInlineWarningsAndErrors(), + )}; + window.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = ${JSON.stringify( + getHideConsoleLogsInStrictMode(), )};`; response.end( diff --git a/packages/react-devtools-core/webpack.backend.js b/packages/react-devtools-core/webpack.backend.js index 9b09448c55b2e..4a034b33bd67c 100644 --- a/packages/react-devtools-core/webpack.backend.js +++ b/packages/react-devtools-core/webpack.backend.js @@ -1,6 +1,12 @@ const {resolve} = require('path'); const {DefinePlugin} = 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'); @@ -60,6 +66,12 @@ module.exports = { 'process.env.DEVTOOLS_PACKAGE': `"react-devtools-core"`, 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`, 'process.env.GITHUB_URL': `"${GITHUB_URL}"`, + '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}"`, }), ], optimization: { diff --git a/packages/react-devtools-core/webpack.standalone.js b/packages/react-devtools-core/webpack.standalone.js index 4d1f8544047c9..e7d2d3af89777 100644 --- a/packages/react-devtools-core/webpack.standalone.js +++ b/packages/react-devtools-core/webpack.standalone.js @@ -1,6 +1,12 @@ const {resolve} = require('path'); const {DefinePlugin} = 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'); @@ -67,6 +73,12 @@ module.exports = { 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`, '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: { diff --git a/packages/react-devtools-extensions/src/injectGlobalHook.js b/packages/react-devtools-extensions/src/injectGlobalHook.js index 980fe21f96d51..e34197af35499 100644 --- a/packages/react-devtools-extensions/src/injectGlobalHook.js +++ b/packages/react-devtools-extensions/src/injectGlobalHook.js @@ -88,6 +88,9 @@ if (sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true') { // Inject a __REACT_DEVTOOLS_GLOBAL_HOOK__ global for React to interact with. // Only do this for HTML documents though, to avoid e.g. breaking syntax highlighting for XML docs. +// We need to inject this code because content scripts (ie injectGlobalHook.js) don't have access +// to the webpage's window, so in order to access front end settings +// and communicate with React, we must inject this code into the webpage if ('text/html' === document.contentType) { injectCode( ';(' + diff --git a/packages/react-devtools-extensions/src/main.js b/packages/react-devtools-extensions/src/main.js index 7cb92c27b6cb9..06c227d7e4cbe 100644 --- a/packages/react-devtools-extensions/src/main.js +++ b/packages/react-devtools-extensions/src/main.js @@ -11,6 +11,7 @@ import { getBreakOnConsoleErrors, getSavedComponentFilters, getShowInlineWarningsAndErrors, + getHideConsoleLogsInStrictMode, } from 'react-devtools-shared/src/utils'; import { localStorageGetItem, @@ -42,6 +43,12 @@ function syncSavedPreferences() { )}; window.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = ${JSON.stringify( getShowInlineWarningsAndErrors(), + )}; + window.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = ${JSON.stringify( + getHideConsoleLogsInStrictMode(), + )}; + window.__REACT_DEVTOOLS_BROWSER_THEME__ = ${JSON.stringify( + getBrowserTheme(), )};`, ); } diff --git a/packages/react-devtools-extensions/src/utils.js b/packages/react-devtools-extensions/src/utils.js index 4fc27de2ee6a1..2c67e2cf047b4 100644 --- a/packages/react-devtools-extensions/src/utils.js +++ b/packages/react-devtools-extensions/src/utils.js @@ -1,5 +1,7 @@ /* global chrome */ +import type {BrowserTheme} from 'react-devtools-shared/src/devtools/views/DevTools'; + const IS_CHROME = navigator.userAgent.indexOf('Firefox') < 0; export type BrowserName = 'Chrome' | 'Firefox'; @@ -8,8 +10,6 @@ export function getBrowserName(): BrowserName { return IS_CHROME ? 'Chrome' : 'Firefox'; } -export type BrowserTheme = 'dark' | 'light'; - export function getBrowserTheme(): BrowserTheme { if (IS_CHROME) { // chrome.devtools.panels added in Chrome 18. diff --git a/packages/react-devtools-extensions/utils.js b/packages/react-devtools-extensions/utils.js index 1babd93f568ea..a096b39b2283c 100644 --- a/packages/react-devtools-extensions/utils.js +++ b/packages/react-devtools-extensions/utils.js @@ -9,6 +9,13 @@ const {execSync} = require('child_process'); const {readFileSync} = require('fs'); const {resolve} = require('path'); +const DARK_MODE_DIMMED_WARNING_COLOR = 'rgba(250, 180, 50, 0.5)'; +const DARK_MODE_DIMMED_ERROR_COLOR = 'rgba(250, 123, 130, 0.5)'; +const DARK_MODE_DIMMED_LOG_COLOR = 'rgba(125, 125, 125, 0.5)'; +const LIGHT_MODE_DIMMED_WARNING_COLOR = 'rgba(250, 180, 50, 0.75)'; +const LIGHT_MODE_DIMMED_ERROR_COLOR = 'rgba(250, 123, 130, 0.75)'; +const LIGHT_MODE_DIMMED_LOG_COLOR = 'rgba(125, 125, 125, 0.75)'; + const GITHUB_URL = 'https://github.com/facebook/react'; function getGitCommit() { @@ -36,6 +43,12 @@ function getVersionString() { } module.exports = { + 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, getGitCommit, getVersionString, diff --git a/packages/react-devtools-extensions/webpack.backend.js b/packages/react-devtools-extensions/webpack.backend.js index 6f5a1d3860933..1644d0b9843e8 100644 --- a/packages/react-devtools-extensions/webpack.backend.js +++ b/packages/react-devtools-extensions/webpack.backend.js @@ -2,7 +2,16 @@ const {resolve} = require('path'); const {DefinePlugin} = require('webpack'); -const {GITHUB_URL, getVersionString} = require('./utils'); +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('./utils'); const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils'); const NODE_ENV = process.env.NODE_ENV; @@ -54,10 +63,16 @@ module.exports = { new DefinePlugin({ __DEV__: true, __PROFILE__: false, - __EXPERIMENTAL__: true, + __DEV____DEV__: true, 'process.env.DEVTOOLS_PACKAGE': `"react-devtools-extensions"`, 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`, 'process.env.GITHUB_URL': `"${GITHUB_URL}"`, + '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: { diff --git a/packages/react-devtools-extensions/webpack.config.js b/packages/react-devtools-extensions/webpack.config.js index 664ec8267c353..7f9e632ffab19 100644 --- a/packages/react-devtools-extensions/webpack.config.js +++ b/packages/react-devtools-extensions/webpack.config.js @@ -2,7 +2,16 @@ const {resolve} = require('path'); const {DefinePlugin} = require('webpack'); -const {GITHUB_URL, getVersionString} = require('./utils'); +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('./utils'); const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils'); const NODE_ENV = process.env.NODE_ENV; @@ -76,6 +85,12 @@ module.exports = { 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`, '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: { diff --git a/packages/react-devtools-inline/README.md b/packages/react-devtools-inline/README.md index 22cff37fb7500..88b2c93b7cb05 100644 --- a/packages/react-devtools-inline/README.md +++ b/packages/react-devtools-inline/README.md @@ -83,14 +83,15 @@ const { contentWindow } = iframe; // This must be called before React is loaded into that frame. initializeBackend(contentWindow); -// React application can be injected into