diff --git a/app/middlewares/debuggerAPI.js b/app/middlewares/debuggerAPI.js index 4a5da0a7..b1953a85 100644 --- a/app/middlewares/debuggerAPI.js +++ b/app/middlewares/debuggerAPI.js @@ -124,6 +124,27 @@ const flushQueuedMessages = () => { queuedMessages = []; }; +let loadCount = 0; +const checkJSLoadCount = () => { + loadCount++; + if ( + currentWindow.webContents.isDevToolsOpened() && + config.timesJSLoadToRefreshDevTools >= 0 && + loadCount > 0 && + loadCount % config.timesJSLoadToRefreshDevTools === 0 + ) { + currentWindow.webContents.closeDevTools(); + currentWindow.webContents.openDevTools(); + console.warn( + '[RNDebugger]', + `Refreshed the devtools panel as React Native app was reloaded ${loadCount} times.`, + 'If you want to update or disable this,', + 'Open `Debugger` -> `Open Config File` to change `timesJSLoadToRefreshDevTools` field.' + ); + loadCount = 0; + } +}; + const connectToDebuggerProxy = async () => { const ws = new WebSocket(`ws://${host}:${port}/debugger-proxy?role=debugger&name=Chrome`); @@ -168,6 +189,7 @@ const connectToDebuggerProxy = async () => { scriptExecuted = true; worker.postMessage({ ...object, url }); flushQueuedMessages(); + checkJSLoadCount(); return; } } finally { @@ -175,6 +197,7 @@ const connectToDebuggerProxy = async () => { clearLogs(); scriptExecuted = true; } + checkJSLoadCount(); } if (scriptExecuted) { // Otherwise, pass through to the worker provided the diff --git a/docs/config-file-in-home-directory.md b/docs/config-file-in-home-directory.md index b522268f..d0f95eac 100644 --- a/docs/config-file-in-home-directory.md +++ b/docs/config-file-in-home-directory.md @@ -47,6 +47,11 @@ We could configure RNDebugger app in `~/.rndebuggerrc`, the file used [json5](ht // Enable Network Inspect by default // See https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md defaultNetworkInspect: false, + + // Refresh devtools when doing JS reload every N times. (-1 for disabled) + // This can effectively avoid possible memory leaks (Like + // https://github.com/jhen0409/react-native-debugger/issues/405) in devtools. + timesJSLoadToRefreshDevTools: -1, } ``` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index cdfb817c..a89dd03a 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -27,7 +27,7 @@ Before: After: 2017-09-19 5 41 27 pm -To avoid similar problems in the future, there is a way to restart the Chrome devtools (macOS: `CMD+OPTION+I`, Linux/Windows: `CTRL+ALT+I`), the same applies to official remote debugger on Chrome. +To avoid similar problems in the future, there is a way to restart the Chrome devtools (macOS: `CMD+OPTION+I`, Linux/Windows: `CTRL+ALT+I`), the same applies to official remote debugger on Chrome. You can also consider to use [`timesJSLoadToRefreshDevTools` option in Config file in home directory](config-file-in-home-directory.md). ## [iOS] Debugger can't load bundle when I use real device @@ -51,10 +51,6 @@ Also, sometimes it have timer problem between host machine and device (emulator) Or try to restart your device (emulator). -## Console thrown a lot of errors when I use React Inspector on Android - -If you're experiencing the issue like [this comment of #84](https://github.com/jhen0409/react-native-debugger/issues/84#issuecomment-304611817), this issue have been fixed in `react-devtools-core@^2.3.0`, please ensure the version is correct in your React Native project (Note that it's dependency of `react-native`). - ## Other documentations - [Getting Started](getting-started.md) diff --git a/electron/config/__tests__/__snapshots__/index.test.js.snap b/electron/config/__tests__/__snapshots__/index.test.js.snap index 1c29786e..8782aeab 100644 --- a/electron/config/__tests__/__snapshots__/index.test.js.snap +++ b/electron/config/__tests__/__snapshots__/index.test.js.snap @@ -11,6 +11,7 @@ Object { "defaultReactDevToolsPort": 19567, "defaultReactDevToolsTheme": "RNDebugger", "editor": "", + "timesJSLoadToRefreshDevTools": -1, "windowBounds": Object { "frame": true, }, @@ -29,6 +30,7 @@ Object { "defaultReactDevToolsPort": 19567, "defaultReactDevToolsTheme": "RNDebugger", "editor": "", + "timesJSLoadToRefreshDevTools": -1, "windowBounds": Object { "frame": true, }, @@ -55,6 +57,7 @@ Object { "defaultReactDevToolsPort": 19567, "defaultReactDevToolsTheme": "RNDebugger", "editor": "", + "timesJSLoadToRefreshDevTools": -1, "windowBounds": Object { "frame": true, }, diff --git a/electron/config/template.js b/electron/config/template.js index 319ffb04..be043186 100644 --- a/electron/config/template.js +++ b/electron/config/template.js @@ -44,5 +44,10 @@ module.exports = `{ // Enable Network Inspect by default // See https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md defaultNetworkInspect: false, + + // Refresh devtools when doing JS reload every N times. (-1 for disabled) + // This can effectively avoid possible memory leaks (Like + // https://github.com/jhen0409/react-native-debugger/issues/405) in devtools. + timesJSLoadToRefreshDevTools: -1, } `; diff --git a/electron/window.js b/electron/window.js index a27077a8..f1e8b29f 100644 --- a/electron/window.js +++ b/electron/window.js @@ -3,6 +3,7 @@ import { BrowserWindow, Menu, globalShortcut, dialog } from 'electron'; import Store from 'electron-store'; import autoUpdate from './update'; import { catchConsoleLogLink, removeUnecessaryTabs } from './devtools'; +import { selectRNDebuggerWorkerContext } from '../app/utils/devtools'; import { readConfig, filePath as configFile } from './config'; const store = new Store(); @@ -96,6 +97,7 @@ export const createWindow = ({ iconPath, isPortSettingRequired, port }) => { }); const isFirstWindow = BrowserWindow.getAllWindows().length === 1; + const { timesJSLoadToRefreshDevTools = -1 } = config; win.debuggerConfig = { port, editor: config.editor, @@ -104,6 +106,7 @@ export const createWindow = ({ iconPath, isPortSettingRequired, port }) => { defaultReactDevToolsPort: config.defaultReactDevToolsPort, networkInspect: config.defaultNetworkInspect && 1, isPortSettingRequired: isPortSettingRequired && 1, + timesJSLoadToRefreshDevTools, }; win.loadURL(`file://${path.resolve(__dirname)}/app.html`); win.webContents.on('did-finish-load', () => { @@ -124,6 +127,7 @@ export const createWindow = ({ iconPath, isPortSettingRequired, port }) => { if (config.showAllDevToolsTab !== true) { removeUnecessaryTabs(win); } + selectRNDebuggerWorkerContext(win); }); win.on('show', () => { if (!win.isFocused()) return;