This issue relates to Chromium/Node.js (Atom Electron, Node Webkit, etc) based apps and not Chrome browser based apps.
When debugging the boot code of a program that uses Chromium and Node.js, there is a significant delay between the time that Dev Tools is invoked and it actually starts up fully, including the ability to execute break points. This means that in order to debug boot logic of an app, which occurs immediately after Dev Tools is invoked, inserted or stored breakpoints don't fire for this boot code.
The only workaround I have found is to add an adhoc timeout using setTimeout(continueBootLogic(), <time>)
to defer starting of my boot logic for a until after I assume that Dev Tools is fully loaded.
There is an existing event in Electron MainWindow.on('devtools-opened', function() {...})
fires when dev tools opens but before the break point engine has booted. Using this event gets me closer in time to the actual ready moment but I still need a crummy timeout to wait a bit more.
Has anybody found a way to precisely and elegantly detect when dev tools is ready to start detecting and executing break points in the code?
Having this would greatly help efforts to debug boot code in Electron and nw.js so I can spend more time playing around with new APIs.
Here is a sample Electron program:
package.json:
{
"name" : "DevToolsWait",
"version" : "0.2.0",
"main" : "main.js"
}
main.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>
Put all files in the same folder and To run, have electron installed and run electron .
in the same folder as package.json.
To tweak the tests, iWaitTimeout in renderer.html.
My work around logic sets timeout to 100 milliseconds. This can be squeezed on my system but its likely computer and load dependent. Pretty messy solution IMO.
Would be awesome to have an event fire like devtools-breakpoint-ready or something similar. The logic above can likely be optimized a bit. I just started using Electron last night. Same issue is with Node Webkit.