解决 'DevTools was disconnected from the page' 和 Electron Helper dies 的技巧
Tips on solving 'DevTools was disconnected from the page' and Electron Helper dies
我在使用 Electron 时遇到应用程序空白的问题。即它变成了一个白屏。如果我打开开发工具,它会显示以下消息。
在 ActivityMonitor 中,我可以看到发生这种情况时 Electron Helper 进程的数量从 3 下降到 2。另外,我似乎不是唯一遇到它的人。例如
- Facing "Devtools was disconnected from the page. Once page is reloaded, Devtools will automatically reconnect."
- Electron dying without any information, what now?
但我还没有找到有帮助的答案。在 Electron 崩溃的情况下,有什么好的方法可以识别问题吗?
对于上下文,我正在将 sdk 加载到 Electron 中。最初我使用 browserify 来打包它,效果很好。但我想转到 SDKs npm 版本。这个版本好像引入了这个问题(虽然代码应该是一样的)
自从我最初发布这个问题以来已经过去了很长一段时间。如果我的错误可以帮助到任何人,我会自己回答。
我从来没有 "solution" 解决原始问题。在很久以后,我切换到 sdk 的 npm 版本并且它起作用了。
但在那之前我又遇到了这个问题。幸运的是,到那时,我已经添加了一个记录器,它也将控制台写入文件。有了它,我注意到 JavaScript 语法错误导致了崩溃。例如缺少右括号等
我怀疑这就是导致我原来的问题的原因。但是 Chrome 开发工具最糟糕的做法是在工具崩溃时清空控制台而不是保留它。
我用来设置记录器的代码
/*global window */
const winston = require('winston');
const prettyMs = require('pretty-ms');
/**
* Proxy the standard 'console' object and redirect it toward a logger.
*/
class Logger {
constructor() {
// Retain a reference to the original console
this.originalConsole = window.console;
this.timers = new Map([]);
// Configure a logger
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
})
),
transports: [
new winston.transports.File(
{
filename: `${require('electron').remote.app.getPath('userData')}/logs/downloader.log`, // Note: require('electron').remote is undefined when I include it in the normal imports
handleExceptions: true, // Log unhandled exceptions
maxsize: 1048576, // 10 MB
maxFiles: 10
}
)
]
});
const _this = this;
// Switch out the console with a proxied version
window.console = new Proxy(this.originalConsole, {
// Override the console functions
get(target, property) {
// Leverage the identical logger functions
if (['debug', 'info', 'warn', 'error'].includes(property)) return (...parameters) => {
_this.logger[property](parameters);
// Simple approach to logging to console. Initially considered
// using a custom logger. But this is much easier to implement.
// Downside is that the format differs but I can live with that
_this.originalConsole[property](...parameters);
}
// The log function differs in logger so map it to info
if ('log' === property) return (...parameters) => {
_this.logger.info(parameters);
_this.originalConsole.info(...parameters);
}
// Re-implement the time and timeEnd functions
if ('time' === property) return (label) => _this.timers.set(label, window.performance.now());
if ('timeEnd' === property) return (label) => {
const now = window.performance.now();
if (!_this.timers.has(label)) {
_this.logger.warn(`console.timeEnd('${label}') called without preceding console.time('${label}')! Or console.timeEnd('${label}') has been called more than once.`)
}
const timeTaken = prettyMs(now - _this.timers.get(label));
_this.timers.delete(label);
const message = `${label} ${timeTaken}`;
_this.logger.info(message);
_this.originalConsole.info(message);
}
// Any non-overriden functions are passed to console
return target[property];
}
});
}
}
/**
* Calling this function switches the window.console for a proxied version.
* The proxy allows us to redirect the call to a logger.
*/
function switchConsoleToLogger() { new Logger(); } // eslint-disable-line no-unused-vars
然后在index.html我先加载这个脚本
<script src="js/logger.js"></script>
<script>switchConsoleToLogger()</script>
我遇到了这个问题,无法弄清楚为什么 DevTool 不断断开连接。所以一时兴起,我启动了 Firefox Developer Edition,并将原因确定为字符串长度为 属性.
的未定义变量
if ( args.length > 1 ) {
$( this ).find( "option" ).each(function () {
$( $( this ).attr( "s-group" ) ).hide();
});
$( args ).show();
}
TL;DR Firefox Developer Edition 可以在 Chrome 的 DevTool 失败时识别此类问题。
我安装了 Google Chrome 版本 79.0.3945.130(64 位)。每当我处于调试模式时,我的应用程序都会崩溃。我尝试了我在网上找到的所有解决方案,但没有一个有用。我降级到所有以前的版本:
- 78.x 崩溃
- 77.x 崩溃
- 75.x 未崩溃
我不得不重新安装版本 75.0.3770.80(64 位)。问题已经解决。可以是Chrome新版本的问题。我已将反馈发送给 Chrome 帮助。
您可以下载 Google Chrome Canary。我在 Google Chrome 上遇到过这个问题,DevTools 每次都在同一个地方崩溃。在 Chrome Canary 上,调试器不会崩溃。
调试此类崩溃的技巧是启用日志记录,默认情况下显然是禁用的。这是通过设置环境变量 ELECTRON_ENABLE_LOGGING=1, as mentioned in this GitHub issue.
来完成的
启用该功能后,您应该会在控制台中看到与此类似的内容:
打开您的 google 开发控制台 (Ctrl + shift + i)。 然后按 (fn + F1) 或只需 F1,然后向下滚动并单击 恢复默认值并重新加载。
阅读上面的评论后,我很清楚至少在 Chrome 中存在一个问题,即没有显示任何故障原因的指示。在 Firefox 中,该程序可以运行,但延迟很长。
但是,正如 Shane Gannon 所说,问题的根源当然不在浏览器中,而在代码中:在我的例子中,我打开了一个 while 循环,但没有添加相应的增量,这使得循环无限。如下例所示:
var a = 0;
while (a < 10) {
...
a ++ // this is the part I was missing;
}
更正此问题后,问题就消失了。
我发现升级到
react 17.0.2
react-dom 17.0.2
react-scripts 4.0.3
但也因为 react-scripts start
被用于 运行 electron 也许它只是需要更新的反应脚本。
我的问题是我没有加载 index.html
这样的页面。一旦我加载问题就消失了。
parentWindow = new BrowserWindow({
title: 'parent'
});
parentWindow.loadURL(`file://${__dirname}/index.html`);
parentWindow.webContents.openDevTools();
好吧,我差点疯了,但我意识到电子是主要问题,我注释掉了要获取的代码 (index.html)
// 并加载应用程序的 index.html。
mainWindow.loadFile('index.html');
检查这一面并确保您已包含它。没有这个页面将变黑或无法加载。所以检查你的 index.js 看看是否有东西可以加载你的 index.html 文件 :) 如果你需要额外的帮助,请随时发邮件给 profnird@gmail.com
我也遇到了完全相同的问题
我试图从渲染器端请求 sqlite3 模块
这导致了一个问题,但是一旦我删除了请求,它就可以正常工作了
const {app , BrowserWindow , ipcMain, ipcRenderer } = require('electron')
const { event } = require('jquery')
const sqlite3 = require('sqlite3').verbose(); // <<== problem
我认为解决这个问题的最佳方法(如果您的代码真的很小)只是尝试删除函数并 运行 一遍又一遍,最终您可以将其缩小到核心问题
这是一种非常乏味、愚蠢且不明智的方法,但是嘿,它奏效了
从 Electron 11 降级到 Electron 8.2 对我有用 Angular 11 - Electron - Typeorm -sqlite3 app.
这不是解决方案本身,而是对问题原因的假设。
在 angular 'ngOnInit' 生命周期中,我放置了太多 'for' 和 'while' 循环,一个在另一个循环中,在清理代码并使其更紧凑后,问题消失了,我想想也许是因为它没有在时限内完成流程我希望有人觉得这条评论有帮助。 :)
我在使用 Electron 时遇到应用程序空白的问题。即它变成了一个白屏。如果我打开开发工具,它会显示以下消息。
在 ActivityMonitor 中,我可以看到发生这种情况时 Electron Helper 进程的数量从 3 下降到 2。另外,我似乎不是唯一遇到它的人。例如
- Facing "Devtools was disconnected from the page. Once page is reloaded, Devtools will automatically reconnect."
- Electron dying without any information, what now?
但我还没有找到有帮助的答案。在 Electron 崩溃的情况下,有什么好的方法可以识别问题吗?
对于上下文,我正在将 sdk 加载到 Electron 中。最初我使用 browserify 来打包它,效果很好。但我想转到 SDKs npm 版本。这个版本好像引入了这个问题(虽然代码应该是一样的)
自从我最初发布这个问题以来已经过去了很长一段时间。如果我的错误可以帮助到任何人,我会自己回答。
我从来没有 "solution" 解决原始问题。在很久以后,我切换到 sdk 的 npm 版本并且它起作用了。
但在那之前我又遇到了这个问题。幸运的是,到那时,我已经添加了一个记录器,它也将控制台写入文件。有了它,我注意到 JavaScript 语法错误导致了崩溃。例如缺少右括号等
我怀疑这就是导致我原来的问题的原因。但是 Chrome 开发工具最糟糕的做法是在工具崩溃时清空控制台而不是保留它。
我用来设置记录器的代码
/*global window */
const winston = require('winston');
const prettyMs = require('pretty-ms');
/**
* Proxy the standard 'console' object and redirect it toward a logger.
*/
class Logger {
constructor() {
// Retain a reference to the original console
this.originalConsole = window.console;
this.timers = new Map([]);
// Configure a logger
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
})
),
transports: [
new winston.transports.File(
{
filename: `${require('electron').remote.app.getPath('userData')}/logs/downloader.log`, // Note: require('electron').remote is undefined when I include it in the normal imports
handleExceptions: true, // Log unhandled exceptions
maxsize: 1048576, // 10 MB
maxFiles: 10
}
)
]
});
const _this = this;
// Switch out the console with a proxied version
window.console = new Proxy(this.originalConsole, {
// Override the console functions
get(target, property) {
// Leverage the identical logger functions
if (['debug', 'info', 'warn', 'error'].includes(property)) return (...parameters) => {
_this.logger[property](parameters);
// Simple approach to logging to console. Initially considered
// using a custom logger. But this is much easier to implement.
// Downside is that the format differs but I can live with that
_this.originalConsole[property](...parameters);
}
// The log function differs in logger so map it to info
if ('log' === property) return (...parameters) => {
_this.logger.info(parameters);
_this.originalConsole.info(...parameters);
}
// Re-implement the time and timeEnd functions
if ('time' === property) return (label) => _this.timers.set(label, window.performance.now());
if ('timeEnd' === property) return (label) => {
const now = window.performance.now();
if (!_this.timers.has(label)) {
_this.logger.warn(`console.timeEnd('${label}') called without preceding console.time('${label}')! Or console.timeEnd('${label}') has been called more than once.`)
}
const timeTaken = prettyMs(now - _this.timers.get(label));
_this.timers.delete(label);
const message = `${label} ${timeTaken}`;
_this.logger.info(message);
_this.originalConsole.info(message);
}
// Any non-overriden functions are passed to console
return target[property];
}
});
}
}
/**
* Calling this function switches the window.console for a proxied version.
* The proxy allows us to redirect the call to a logger.
*/
function switchConsoleToLogger() { new Logger(); } // eslint-disable-line no-unused-vars
然后在index.html我先加载这个脚本
<script src="js/logger.js"></script>
<script>switchConsoleToLogger()</script>
我遇到了这个问题,无法弄清楚为什么 DevTool 不断断开连接。所以一时兴起,我启动了 Firefox Developer Edition,并将原因确定为字符串长度为 属性.
的未定义变量if ( args.length > 1 ) {
$( this ).find( "option" ).each(function () {
$( $( this ).attr( "s-group" ) ).hide();
});
$( args ).show();
}
TL;DR Firefox Developer Edition 可以在 Chrome 的 DevTool 失败时识别此类问题。
我安装了 Google Chrome 版本 79.0.3945.130(64 位)。每当我处于调试模式时,我的应用程序都会崩溃。我尝试了我在网上找到的所有解决方案,但没有一个有用。我降级到所有以前的版本:
- 78.x 崩溃
- 77.x 崩溃
- 75.x 未崩溃
我不得不重新安装版本 75.0.3770.80(64 位)。问题已经解决。可以是Chrome新版本的问题。我已将反馈发送给 Chrome 帮助。
您可以下载 Google Chrome Canary。我在 Google Chrome 上遇到过这个问题,DevTools 每次都在同一个地方崩溃。在 Chrome Canary 上,调试器不会崩溃。
调试此类崩溃的技巧是启用日志记录,默认情况下显然是禁用的。这是通过设置环境变量 ELECTRON_ENABLE_LOGGING=1, as mentioned in this GitHub issue.
来完成的启用该功能后,您应该会在控制台中看到与此类似的内容:
打开您的 google 开发控制台 (Ctrl + shift + i)。 然后按 (fn + F1) 或只需 F1,然后向下滚动并单击 恢复默认值并重新加载。
阅读上面的评论后,我很清楚至少在 Chrome 中存在一个问题,即没有显示任何故障原因的指示。在 Firefox 中,该程序可以运行,但延迟很长。
但是,正如 Shane Gannon 所说,问题的根源当然不在浏览器中,而在代码中:在我的例子中,我打开了一个 while 循环,但没有添加相应的增量,这使得循环无限。如下例所示:
var a = 0;
while (a < 10) {
...
a ++ // this is the part I was missing;
}
更正此问题后,问题就消失了。
我发现升级到
react 17.0.2
react-dom 17.0.2
react-scripts 4.0.3
但也因为 react-scripts start
被用于 运行 electron 也许它只是需要更新的反应脚本。
我的问题是我没有加载 index.html
这样的页面。一旦我加载问题就消失了。
parentWindow = new BrowserWindow({
title: 'parent'
});
parentWindow.loadURL(`file://${__dirname}/index.html`);
parentWindow.webContents.openDevTools();
好吧,我差点疯了,但我意识到电子是主要问题,我注释掉了要获取的代码 (index.html)
// 并加载应用程序的 index.html。
mainWindow.loadFile('index.html');
检查这一面并确保您已包含它。没有这个页面将变黑或无法加载。所以检查你的 index.js 看看是否有东西可以加载你的 index.html 文件 :) 如果你需要额外的帮助,请随时发邮件给 profnird@gmail.com
我也遇到了完全相同的问题
我试图从渲染器端请求 sqlite3 模块 这导致了一个问题,但是一旦我删除了请求,它就可以正常工作了
const {app , BrowserWindow , ipcMain, ipcRenderer } = require('electron')
const { event } = require('jquery')
const sqlite3 = require('sqlite3').verbose(); // <<== problem
我认为解决这个问题的最佳方法(如果您的代码真的很小)只是尝试删除函数并 运行 一遍又一遍,最终您可以将其缩小到核心问题
这是一种非常乏味、愚蠢且不明智的方法,但是嘿,它奏效了
从 Electron 11 降级到 Electron 8.2 对我有用 Angular 11 - Electron - Typeorm -sqlite3 app.
这不是解决方案本身,而是对问题原因的假设。 在 angular 'ngOnInit' 生命周期中,我放置了太多 'for' 和 'while' 循环,一个在另一个循环中,在清理代码并使其更紧凑后,问题消失了,我想想也许是因为它没有在时限内完成流程我希望有人觉得这条评论有帮助。 :)