解决“ DevTools已从页面断开连接”的提示,Electron Helper消失

Sha*_*non 8 debugging hang electron

我在Electron的应用程序出现空白时遇到了问题。即它变成白屏。如果我打开开发工具,它将显示以下消息。

在此处输入图片说明

在ActivityMonitor中,发生这种情况时,我可以看到Electron Helper进程的数量从3个减少到2个。另外,似乎我不是唯一遇到它的人。例如

但是我还没有找到一个有帮助的答案。在电子崩溃的情况下,有什么好的方法可以识别问题?

对于上下文,我正在将SDK加载到Electron中。最初,我是使用browserify对其进行打包的,效果很好。但是我想转到SDK的npm版本。这个版本似乎已经引入了问题(尽管代码应该相同)。

Sha*_*non 16

自从我最初发布这个问题以来已经过去了一段时间。如果我的错误可以帮助任何人,我会自己回答。

我从来没有得到原始问题的“解决方案”。在很久以后,我切换到 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
Run Code Online (Sandbox Code Playgroud)

然后在 index.html 我首先加载这个脚本

<script src="js/logger.js"></script>
<script>switchConsoleToLogger()</script>
Run Code Online (Sandbox Code Playgroud)