Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save x-yuri/6ba5946db0a8ec7e9511771fef59fcc9 to your computer and use it in GitHub Desktop.
Save x-yuri/6ba5946db0a8ec7e9511771fef59fcc9 to your computer and use it in GitHub Desktop.
Setting breakpoints using Chrome DevTools Protocol

Setting breakpoints using Chrome DevTools Protocol

a.js:

const waitPort = require('wait-port');
const CDP = require('chrome-remote-interface');
const { spawn } = require('node:child_process');
const path = require('path');
const fs = require('fs');

let script, useScriptId;
process.argv.slice(2).forEach(a => {
    switch (a) {
        case '--use-script-id':
            useScriptId = true;
            break;
        default:
            script = a;
            break;
    }
});
if (!script) {
    process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} [--use-script-id] SCRIPT`);
    process.exit(1)
}
script = fs.realpathSync(script);
const compiled = path.extname(script) == '.ts'
    ? path.join(path.dirname(script), path.basename(script, '.ts') + '.js')
    : script;

const subprocess = spawn('node', ['--inspect-brk=9222', compiled], {
    stdio: 'inherit',
}).on('spawn', debug);

function debug() {
    waitPort({port: 9222}).then(() => {
        return CDP();
    }).then(client => {
        console.log('-- connected');
        process.stdin.on('data', () => {
            client.Debugger.resume();
        });
        client.Debugger.paused(args => {
            console.log('-- paused', args.reason, args.hitBreakpoints);
        });
        client.Debugger.breakpointResolved(args => {
            console.log('-- breakpointResolved', args);
        });
        client.Debugger.scriptParsed(args => {
            if (args.url == 'file://' + compiled) {
                console.log(`-- scriptParsed ${args.scriptId} ${args.url}`);
                if (useScriptId)
                    client.Debugger.setBreakpoint({
                        location: {lineNumber: 2, scriptId: args.scriptId}});
            }
        });
        client.Debugger.enable();
        client.Debugger.setBreakpointByUrl({
            lineNumber: 2,
            url: 'file://' + script});
        client.Runtime.runIfWaitingForDebugger();
    });
}

b.ts:

console.log('a');
console.log('b');
console.log('c');

c.js:

console.log('a');
console.log('b');
console.log('c');
$ npm i chrome-remote-interface@0.33.x typescript@5.x wait-port@1.x
$ npx tsc --sourceMap b.ts
$ node a.js b.ts
Waiting for localhost:9222..Debugger listening on ws://127.0.0.1:9222/e2b743f2-dc2e-4222-9511-17ab2301781d
For help, see: https://nodejs.org/en/docs/inspector
.
Connected!
Debugger attached.
-- connected
-- scriptParsed 73 file:///home/yuri/tmp/control-nodejs3/b.js
-- paused Break on start []

a
b
c
Waiting for the debugger to disconnect...
^C
$ node a.js --use-script-id b.ts
Waiting for localhost:9222..Debugger listening on ws://127.0.0.1:9222/98b601d6-2a2c-4063-9b20-79a0c1dfb450
For help, see: https://nodejs.org/en/docs/inspector
.
Connected!
Debugger attached.
-- connected
-- scriptParsed 73 file:///home/yuri/tmp/control-nodejs3/b.js
-- paused Break on start []

a
b
-- paused other [ '4:2:0:73' ]

c
Waiting for the debugger to disconnect...
^C
$ node a.js c.js
Waiting for localhost:9222..Debugger listening on ws://127.0.0.1:9222/e0a5d38c-0e78-4aef-b25a-bd60c18984e5
For help, see: https://nodejs.org/en/docs/inspector
.
Connected!
Debugger attached.
-- connected
-- scriptParsed 73 file:///home/yuri/tmp/control-nodejs3/c.js
-- breakpointResolved {
  breakpointId: '1:2:0:file:///home/yuri/tmp/control-nodejs3/c.js',
  location: { scriptId: '73', lineNumber: 2, columnNumber: 0 }
}
-- paused Break on start []

a
b
-- paused other [ '1:2:0:file:///home/yuri/tmp/control-nodejs3/c.js' ]

c
Waiting for the debugger to disconnect...
^C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment