mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Devtools disable log dimming strict mode setting (#35207)
<!-- 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn test --debug --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). --> ## Summary Currently, every second console log is dimmed, receiving a special style that indicates to user that it was raising because of [React Strict Mode](https://react.dev/reference/react/StrictMode) second rendering. This introduces a setting to disable this. ## How did you test this change? Test in console-test.js https://github.com/user-attachments/assets/af6663ac-f79b-4824-95c0-d46b0c8dec12 Browser extension react devtools https://github.com/user-attachments/assets/7e2ecb7a-fbdf-4c72-ab45-7e3a1c6e5e44 React native dev tools: https://github.com/user-attachments/assets/d875b3ac-1f27-43f8-8d9d-12b2d65fa6e6 --------- Co-authored-by: Ruslan Lesiutin <28902667+hoxyq@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,7 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
#### `Settings`
|
||||
| Spec | Default value |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| <pre>{<br> appendComponentStack: boolean,<br> breakOnConsoleErrors: boolean,<br> showInlineWarningsAndErrors: boolean,<br> hideConsoleLogsInStrictMode: boolean<br>}</pre> | <pre>{<br> appendComponentStack: true,<br> breakOnConsoleErrors: false,<br> showInlineWarningsAndErrors: true,<br> hideConsoleLogsInStrictMode: false<br>}</pre> |
|
||||
| <pre>{<br> appendComponentStack: boolean,<br> breakOnConsoleErrors: boolean,<br> showInlineWarningsAndErrors: boolean,<br> hideConsoleLogsInStrictMode: boolean,<br> disableSecondConsoleLogDimmingInStrictMode: boolean<br>}</pre> | <pre>{<br> appendComponentStack: true,<br> breakOnConsoleErrors: false,<br> showInlineWarningsAndErrors: true,<br> hideConsoleLogsInStrictMode: false,<br> disableSecondConsoleLogDimmingInStrictMode: false<br>}</pre> |
|
||||
|
||||
### `connectToDevTools` options
|
||||
| Prop | Default | Description |
|
||||
@@ -53,7 +53,7 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
| `onSubscribe` | Function, which receives listener (function, with a single argument) as an argument. Called when backend subscribes to messages from the other end (frontend). |
|
||||
| `onUnsubscribe` | Function, which receives listener (function) as an argument. Called when backend unsubscribes to messages from the other end (frontend). |
|
||||
| `onMessage` | Function, which receives 2 arguments: event (string) and payload (any). Called when backend emits a message, which should be sent to the frontend. |
|
||||
| `onSettingsUpdated` | A callback that will be called when the user updates the settings in the UI. You can use it for persisting user settings. |
|
||||
| `onSettingsUpdated` | A callback that will be called when the user updates the settings in the UI. You can use it for persisting user settings. |
|
||||
|
||||
Unlike `connectToDevTools`, `connectWithCustomMessagingProtocol` returns a callback, which can be used for unsubscribing the backend from the global DevTools hook.
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ async function messageListener(event: MessageEvent) {
|
||||
if (typeof settings.hideConsoleLogsInStrictMode !== 'boolean') {
|
||||
settings.hideConsoleLogsInStrictMode = false;
|
||||
}
|
||||
if (
|
||||
typeof settings.disableSecondConsoleLogDimmingInStrictMode !== 'boolean'
|
||||
) {
|
||||
settings.disableSecondConsoleLogDimmingInStrictMode = false;
|
||||
}
|
||||
|
||||
window.postMessage({
|
||||
source: 'react-devtools-hook-settings-injector',
|
||||
|
||||
@@ -27,6 +27,7 @@ function startActivation(contentWindow: any, bridge: BackendBridge) {
|
||||
componentFilters,
|
||||
showInlineWarningsAndErrors,
|
||||
hideConsoleLogsInStrictMode,
|
||||
disableSecondConsoleLogDimmingInStrictMode,
|
||||
} = data;
|
||||
|
||||
contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ =
|
||||
@@ -38,6 +39,8 @@ function startActivation(contentWindow: any, bridge: BackendBridge) {
|
||||
showInlineWarningsAndErrors;
|
||||
contentWindow.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ =
|
||||
hideConsoleLogsInStrictMode;
|
||||
contentWindow.__REACT_DEVTOOLS_DISABLE_SECOND_CONSOLE_LOG_DIMMING_IN_STRICT_MODE__ =
|
||||
disableSecondConsoleLogDimmingInStrictMode;
|
||||
|
||||
// TRICKY
|
||||
// The backend entry point may be required in the context of an iframe or the parent window.
|
||||
@@ -53,6 +56,8 @@ function startActivation(contentWindow: any, bridge: BackendBridge) {
|
||||
showInlineWarningsAndErrors;
|
||||
window.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ =
|
||||
hideConsoleLogsInStrictMode;
|
||||
window.__REACT_DEVTOOLS_DISABLE_SECOND_CONSOLE_LOG_DIMMING_IN_STRICT_MODE__ =
|
||||
disableSecondConsoleLogDimmingInStrictMode;
|
||||
}
|
||||
|
||||
finishActivation(contentWindow, bridge);
|
||||
|
||||
@@ -733,4 +733,85 @@ describe('console', () => {
|
||||
: 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not dim console logs if disableSecondConsoleLogDimmingInStrictMode is enabled', () => {
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
|
||||
false;
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.disableSecondConsoleLogDimmingInStrictMode =
|
||||
true;
|
||||
|
||||
const container = document.createElement('div');
|
||||
const root = ReactDOMClient.createRoot(container);
|
||||
|
||||
function App() {
|
||||
console.log('log');
|
||||
console.warn('warn');
|
||||
console.error('error');
|
||||
return <div />;
|
||||
}
|
||||
|
||||
act(() =>
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
),
|
||||
);
|
||||
|
||||
// Both logs should be called (double logging)
|
||||
expect(global.consoleLogMock).toHaveBeenCalledTimes(2);
|
||||
expect(global.consoleWarnMock).toHaveBeenCalledTimes(2);
|
||||
expect(global.consoleErrorMock).toHaveBeenCalledTimes(2);
|
||||
|
||||
// The second log should NOT have dimming (no ANSI codes)
|
||||
expect(global.consoleLogMock.mock.calls[1]).toEqual(['log']);
|
||||
expect(global.consoleWarnMock.mock.calls[1]).toEqual(['warn']);
|
||||
expect(global.consoleErrorMock.mock.calls[1]).toEqual(['error']);
|
||||
});
|
||||
|
||||
it('should dim console logs if disableSecondConsoleLogDimmingInStrictMode is disabled', () => {
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
|
||||
false;
|
||||
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.disableSecondConsoleLogDimmingInStrictMode =
|
||||
false;
|
||||
|
||||
const container = document.createElement('div');
|
||||
const root = ReactDOMClient.createRoot(container);
|
||||
|
||||
function App() {
|
||||
console.log('log');
|
||||
console.warn('warn');
|
||||
console.error('error');
|
||||
return <div />;
|
||||
}
|
||||
|
||||
act(() =>
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
),
|
||||
);
|
||||
|
||||
// Both logs should be called (double logging)
|
||||
expect(global.consoleLogMock).toHaveBeenCalledTimes(2);
|
||||
expect(global.consoleWarnMock).toHaveBeenCalledTimes(2);
|
||||
expect(global.consoleErrorMock).toHaveBeenCalledTimes(2);
|
||||
|
||||
// The second log should have dimming (ANSI codes present)
|
||||
expect(global.consoleLogMock.mock.calls[1]).toEqual([
|
||||
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
|
||||
'log',
|
||||
]);
|
||||
expect(global.consoleWarnMock.mock.calls[1]).toEqual([
|
||||
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
|
||||
'warn',
|
||||
]);
|
||||
expect(global.consoleErrorMock.mock.calls[1]).toEqual([
|
||||
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
|
||||
'error',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -248,6 +248,7 @@ beforeEach(() => {
|
||||
breakOnConsoleErrors: false,
|
||||
showInlineWarningsAndErrors: true,
|
||||
hideConsoleLogsInStrictMode: false,
|
||||
disableSecondConsoleLogDimmingInStrictMode: false,
|
||||
});
|
||||
|
||||
const bridgeListeners = [];
|
||||
|
||||
@@ -597,4 +597,5 @@ export type DevToolsHookSettings = {
|
||||
breakOnConsoleErrors: boolean,
|
||||
showInlineWarningsAndErrors: boolean,
|
||||
hideConsoleLogsInStrictMode: boolean,
|
||||
disableSecondConsoleLogDimmingInStrictMode: boolean,
|
||||
};
|
||||
|
||||
@@ -36,6 +36,10 @@ export default function DebuggingSettings({
|
||||
useState(usedHookSettings.hideConsoleLogsInStrictMode);
|
||||
const [showInlineWarningsAndErrors, setShowInlineWarningsAndErrors] =
|
||||
useState(usedHookSettings.showInlineWarningsAndErrors);
|
||||
const [
|
||||
disableSecondConsoleLogDimmingInStrictMode,
|
||||
setDisableSecondConsoleLogDimmingInStrictMode,
|
||||
] = useState(usedHookSettings.disableSecondConsoleLogDimmingInStrictMode);
|
||||
|
||||
useEffect(() => {
|
||||
store.setShouldShowWarningsAndErrors(showInlineWarningsAndErrors);
|
||||
@@ -47,6 +51,7 @@ export default function DebuggingSettings({
|
||||
breakOnConsoleErrors,
|
||||
showInlineWarningsAndErrors,
|
||||
hideConsoleLogsInStrictMode,
|
||||
disableSecondConsoleLogDimmingInStrictMode,
|
||||
});
|
||||
}, [
|
||||
store,
|
||||
@@ -54,6 +59,7 @@ export default function DebuggingSettings({
|
||||
breakOnConsoleErrors,
|
||||
showInlineWarningsAndErrors,
|
||||
hideConsoleLogsInStrictMode,
|
||||
disableSecondConsoleLogDimmingInStrictMode,
|
||||
]);
|
||||
|
||||
return (
|
||||
@@ -105,9 +111,12 @@ export default function DebuggingSettings({
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={hideConsoleLogsInStrictMode}
|
||||
onChange={({currentTarget}) =>
|
||||
setHideConsoleLogsInStrictMode(currentTarget.checked)
|
||||
}
|
||||
onChange={({currentTarget}) => {
|
||||
setHideConsoleLogsInStrictMode(currentTarget.checked);
|
||||
if (currentTarget.checked) {
|
||||
setDisableSecondConsoleLogDimmingInStrictMode(false);
|
||||
}
|
||||
}}
|
||||
className={styles.SettingRowCheckbox}
|
||||
/>
|
||||
Hide logs during additional invocations in
|
||||
@@ -120,6 +129,40 @@ export default function DebuggingSettings({
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
hideConsoleLogsInStrictMode
|
||||
? `${styles.SettingDisabled} ${styles.SettingWrapper}`
|
||||
: styles.SettingWrapper
|
||||
}>
|
||||
<label
|
||||
className={
|
||||
hideConsoleLogsInStrictMode
|
||||
? `${styles.SettingDisabled} ${styles.SettingRow}`
|
||||
: styles.SettingRow
|
||||
}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={disableSecondConsoleLogDimmingInStrictMode}
|
||||
disabled={hideConsoleLogsInStrictMode}
|
||||
onChange={({currentTarget}) =>
|
||||
setDisableSecondConsoleLogDimmingInStrictMode(
|
||||
currentTarget.checked,
|
||||
)
|
||||
}
|
||||
className={styles.SettingRowCheckbox}
|
||||
/>
|
||||
Disable log dimming during additional invocations in
|
||||
<a
|
||||
className={styles.StrictModeLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://react.dev/reference/react/StrictMode">
|
||||
Strict Mode
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
margin: 0.125rem 0.25rem 0.125rem 0;
|
||||
}
|
||||
|
||||
.SettingDisabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.OptionGroup {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
|
||||
31
packages/react-devtools-shared/src/hook.js
vendored
31
packages/react-devtools-shared/src/hook.js
vendored
@@ -367,17 +367,22 @@ export function installHook(
|
||||
return;
|
||||
}
|
||||
|
||||
// Dim the text color of the double logs if we're not hiding them.
|
||||
// Firefox doesn't support ANSI escape sequences
|
||||
if (__IS_FIREFOX__) {
|
||||
originalMethod(
|
||||
...formatWithStyles(args, FIREFOX_CONSOLE_DIMMING_COLOR),
|
||||
);
|
||||
if (settings.disableSecondConsoleLogDimmingInStrictMode) {
|
||||
// Don't dim the console logs
|
||||
originalMethod(...args);
|
||||
} else {
|
||||
originalMethod(
|
||||
ANSI_STYLE_DIMMING_TEMPLATE,
|
||||
...formatConsoleArguments(...args),
|
||||
);
|
||||
// Dim the text color of the double logs if we're not hiding them.
|
||||
// Firefox doesn't support ANSI escape sequences
|
||||
if (__IS_FIREFOX__) {
|
||||
originalMethod(
|
||||
...formatWithStyles(args, FIREFOX_CONSOLE_DIMMING_COLOR),
|
||||
);
|
||||
} else {
|
||||
originalMethod(
|
||||
ANSI_STYLE_DIMMING_TEMPLATE,
|
||||
...formatConsoleArguments(...args),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -579,7 +584,10 @@ export function installHook(
|
||||
debugger;
|
||||
}
|
||||
|
||||
if (isRunningDuringStrictModeInvocation) {
|
||||
if (
|
||||
isRunningDuringStrictModeInvocation &&
|
||||
!settings.disableSecondConsoleLogDimmingInStrictMode
|
||||
) {
|
||||
// Dim the text color of the double logs if we're not hiding them.
|
||||
// Firefox doesn't support ANSI escape sequences
|
||||
if (__IS_FIREFOX__) {
|
||||
@@ -667,6 +675,7 @@ export function installHook(
|
||||
breakOnConsoleErrors: false,
|
||||
showInlineWarningsAndErrors: true,
|
||||
hideConsoleLogsInStrictMode: false,
|
||||
disableSecondConsoleLogDimmingInStrictMode: false,
|
||||
};
|
||||
patchConsoleForErrorsAndWarnings();
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user