Советы по решению «DevTools был отключен от страницы» и Electron Helper умирает - PullRequest
4 голосов
/ 07 марта 2019

У меня проблема с Electron, когда приложение гаснет.т.е. становится белым экраном.Если я открою инструменты разработчика, появится следующее сообщение:

enter image description here

В ActivityMonitor я вижу, что число процессов Electron Helper падает с 3 до 2, когдаБывает.Плюс, кажется, я не единственный, кто сталкивался с этим.например,

Но мне еще предстоит найти ответ, который поможет.В сценариях, где происходит сбой Electron, есть ли хорошие подходы для выявления проблемы?

Для контекста я загружаю SDK в Electron.Первоначально я использовал browserify для упаковки, которая работала нормально.Но я хочу перейти к выпуску SDK npm.Эта версия, кажется, привела к проблеме (хотя код должен быть таким же).

1 Ответ

1 голос
/ 13 мая 2019

Прошло много времени с тех пор, как я впервые разместил этот вопрос.Я сам отвечу, если моя ошибка кому-нибудь поможет.

У меня никогда не было «решения» исходной проблемы.Гораздо позже я переключился на выпуск 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 Iсначала загрузите этот скрипт

<script src="js/logger.js"></script>
<script>switchConsoleToLogger()</script>
...