【问题标题】:Atom Electron - Detect Dev Tools readyAtom Electron - 检测开发工具已准备就绪
【发布时间】:2015-07-09 01:06:16
【问题描述】:

此问题与基于 Chromium/Node.js(Atom ElectronNode Webkit 等)的应用有关,与基于 Chrome 浏览器的应用无关。

在调试使用 Chromium 和 Node.js 的程序的启动代码时,在调用 Dev Tools 和它实际完全启动之间存在显着延迟,包括执行断点的能力。这意味着为了调试应用程序的启动逻辑,在调用开发工具后立即发生,插入或存储的断点不会为此启动代码触发。

我发现的唯一解决方法是使用 setTimeout(continueBootLogic(), <time>) 添加临时超时,以将启动逻辑的启动推迟一段时间,直到我假设开发工具已完全加载。

当开发工具打开但断点引擎启动之前,Electron MainWindow.on('devtools-opened', function() {...}) 中存在一个现有事件。使用这个事件可以让我更接近实际的就绪时刻,但我仍然需要一个糟糕的超时来等待更多时间。

有没有人找到一种方法来精确而优雅地检测开发工具何时准备好开始检测和执行代码中的断点?

拥有这将极大地帮助调试 Electron 和 nw.js 中的启动代码,这样我就可以花更多的时间来玩弄新的 API。

这是一个示例电子程序:

package.json:

{
  "name"    : "DevToolsWait",
  "version" : "0.2.0",
  "main"    : "main.js"
}

ma​​in.js:

'use strict'
const electron = require('electron')

console.log('Electron version: '+process.versions['electron'])

electron.app.on('ready', ()=>{
  var bw = new electron.BrowserWindow({width: 800, height: 600});

  // Load renderer.html
  bw.loadURL('file://' + __dirname + '/renderer.html');

  // Open the devtools.
  bw.webContents.openDevTools();


  // Handle devtools opened event
  bw.webContents.on('devtools-opened', ()=>{
    console.log("devtools-opened event called!")
    setImmediate(()=>{
        console.log("dev tools is now open (not sure if breakpoints work yet)!")
        // Send IPC call to main process that devtools is open
        bw.webContents.send('devtools-opened');
    });
  });


});

index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>DevToolsWait Test!</title>
  </head>
  <body>

    <script>
        // Set this to 0 to get no timeout. 100ms seems to work on Linux with 1.2.1
        // Had to set as long as 1000ms to get it to work with older versions
        const iWaitTimeout = 100

        const electron = require('electron');


        // listen for Dev Tools opening event
        // Still have to wait a bit for break point engine to run
        electron.ipcRenderer.on('devtools-opened', function(){
            console.log('devtools-opened ipc called')
            // Start main logic

            if(iWaitTimeout==0){
                console.log('booting without timeout')
                bootGUI()

            } else {
                console.log('booting with timeout')
                setTimeout(bootGUI, 100)

            }

        });

        // Renderer process bootstrap logic
        function bootGUI(){
            console.log('bootGUI called')

            // Inserting ad-hoc debugger call. This should fire no matter what
            debugger;

            // ... doing other stuff

            if(iWaitTimeout===0){
                window.document.body.innerHTML+="If you see this message before debugger command line stops the code in the DevTools, then it failed. DevTools loaded event fired before the debugger is ready to handle breakpoints :(<br><br> Otherwise, woohoo!"
            } else {
                window.document.body.innerHTML+="If you see this message before debugger breaks, Then the timeout test failed. Maybe you should tweak the timeout to be a little longer to allow dev tools debugger time to warm up. see line with setTimeout(...) in renderer.html"
            }

        }



    </script>
  </body>
</html> 

将所有文件放在同一个文件夹中并运行,安装电子并在与 package.json 相同的文件夹中运行electron .

为了调整测试,renderer.html 中的 iWaitTimeout。

我在逻辑方面的工作将超时设置为 100 毫秒。这可以在我的系统上压缩,但它可能取决于计算机和负载。相当混乱的解决方案 IMO。

如果能像 devtools-breakpoint-ready 或类似的东西那样触发事件会很棒。上面的逻辑可能会稍微优化一下。我昨晚刚开始使用 Electron。 Node Webkit 也有同样的问题。

【问题讨论】:

  • 重复的重复? stackoverflow.com/questions/16765287/… 如果可行,我会不断调用该方法,直到它为真
  • 我希望有一些更优雅的东西,但这可能会起作用。我会试一试的。
  • 不。在console.profiles.length 上失败,出现“TypeError:无法读取未定义的属性‘长度’”。不过方法是合理的。
  • 我发现我可以在开发工具中设置断点并按 F5 刷新,它会重新加载页面并达到我的调试点。必须嵌入到开发工具中。根据您的应用在启动时执行的操作,这可能对您有用。
  • 对我也不起作用。我的应用程序正在调用函数 pageLoaded() ,没有任何超时或延迟,即使硬刷新也没有断点或调试器调用停止。让断点工作的唯一方法是延迟 pageLoaded() 调用并超时。

标签: javascript node.js google-chrome-devtools chromium electron


【解决方案1】:

您可以使用以下方法检测开发工具何时打开:

mainWindow = new BrowserWindow({ width: 1024, height: 768 });
mainWindow.loadURL('your url');
mainWindow.webContents.openDevTools();
mainWindow.webContents.on('devtools-opened', () => {
    setImmediate(() => {
        // do whatever you want to do after dev tool completely opened here
        mainWindow.focus();
    });
});

【讨论】:

  • 谢谢。暂时没时间测试。您是否确认在调用 setImmediate(...) 中的处理程序时是否处理了 devtools 窗口中的断点。我从来没有尝试过这种方式。
  • 是的,断点处理好了。。我用过没问题
  • 甜蜜!我会尽快进行测试,看看它是否可以记录在 Elecron Docs 中。谢谢。
  • 不幸的是不适合我。我在 linux 上使用 Electron 1.2.1。您使用的是什么版本/操作系统?
  • 嗨,我更新了上面的测试代码以包含您的示例,但仍然无法在我的 linux 上运行。你可以在 OSX 上试试吗?
猜你喜欢
  • 1970-01-01
  • 2017-01-21
  • 2015-07-01
  • 2019-08-09
  • 2018-02-04
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多