Let's make node inspect better on the command line! I'm used to amazing CLI debugging tools like ipython, iex, and pry. I want to bring some of that magic to node.
This isn't going to all be possible, but here's my wishlist:
- Returning a object in the REPL prints the whole object, rather than a truncated version of the object with
... - Easily copy content (JSON representation of a object, large strings, etc) into the clipboard
- Optionally support printing long output to a pager
- Ability to execute typescript in the repl, ignoring any typing errors (transpilation only)
- Colorized output.
- Ability to use
awaitin a debugger session (SyntaxError: await can not be used when evaluating code while paused in the debugger) - Automatically pause on an exception and keep all state
- Ability to reload code, even if it's already been loaded. With ESM and a custom loader (possibly built on top of esbuild's ESM loader), this should be possible.
- Ability to define a function dynamically with
function name() {} - Ability to paste in a multiline command
- Tab completion for locally defined variables
- Ability to print without leading
>in debug mode - Show stack trace in debugger when it's seems to be doing nothing
- I don't want my imports rewritten from
logintologlevel_1 - Shortcut to open my editor at the
file:line:column - Ability to define custom debugger shortcuts (i.e.
cvscont) _does not work in a debugger repl, I want to get the last result using that shortcut- Drop into a repl immediately instead of a
debug>session, or execute certain types of code within the inner repl automatically. - Custom backtrace filters using a middleware-like interface
_ex_exception reference when an exception is raisedupanddownstacktrace navigation- If there's an exception, but the original source is not present, jump to the source in github
- File location follows
next,up, etc. By default, this does not seem to happen. - Sourcemap-aware file and line locations. If you use
tsx, or any other transpilation tool, the source and line + column numbers are based on the transpiled code, not the original source. - Avoid
process.stdoutbreaking when certain content is passed to it. When the debugger is active, the event loop is paused, and thedrainevent is not processed causingprocess.stdout.writeto stop working entirely. - Works with test runners like jest and vitest
- Automatically start a debugger session when an exception is thrown in a test
-
upanddownstacktrace navigation -
frame(n)to jump to a specific stack frame - colorized output
- pretty print objects using
pp - list local variables with
locals - list current file location with context using
ls - get current file location using
location - set default exception state via
--pause-on-exception-state - don't pause at the beginning of execution via
--inspect-resume-on-start - set
node inspectspecific CLI arguments usingNODE_INSPECT_OPTIONSenv var (exportNODE_INSPECT_OPTIONS="--inspect-resume-on-start true --pause-on-exception-state uncaught")
One of my biggest gripes with the nodejs ecosystem is how fragmented it is. My goal is to get all of the changes here upstreamed:
Install:
npm install better-node-inspect --save-devIn order to use the improved inspector:
better-node-inspect the-file.jsTo use the repl utilities make sure you import the module:
import "better-node-inspect"If you are running into issues running the script, check to make sure NODE_OPTIONS doesn't contain any additional config. Sometimes VS Code
can inject NODE_OPTIONS into the environment, which can cause issues. Here's the error I got when NODE_OPTIONS was set by VS Code.
node:internal/assert:14
throw new ERR_INTERNAL_ASSERTION(message);
^
Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues
at new NodeError (node:internal/errors:405:5)
at assert (node:internal/assert:14:11)
at setupUserModules (node:internal/process/pre_execution:126:3)
at prepareExecution (node:internal/process/pre_execution:118:5)
at prepareMainThreadExecution (node:internal/process/pre_execution:42:3)
at Object.<anonymous> (/Users/mike/Projects/javascript/better-node-inspect/main/inspect.js:10:1)
at Module._compile (node:internal/modules/cjs/loader:1257:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1311:10)
at Module.load (node:internal/modules/cjs/loader:1115:32)
at Module._load (node:internal/modules/cjs/loader:962:12) {
code: 'ERR_INTERNAL_ASSERTION'
}
It's always helpful to understand how things are wired together when you are hacking:
node inspectentrypoint- Where
node:require paths are processed - Debugger.on events
- Visual/prettier debugger protocol documentation
- Where
node inspectis run from - Where expectation errors are throw in jest. If you jump two frames up from here, you'll end up in your test code.
There's been a lot of attempts to improve the node REPL over the years:
- nbd is dead and hasn't been updated in years
- node-help is dead as well and just made it slightly easier to view documentation.
- node-inspector is now included in node and basically enables you to use Chrome devtools
- local-repl some great concepts around importing aspects of your project right into the repl. Hasn't been updated in years.
- The updated repl project wouldn't load for me on v16.
- https://github.com/NicolasPetton/Indium
- https://github.com/danielgtaylor/nesh
- https://github.com/wesgarland/niim lots of good ideas here, but was abandoned years ago.
- https://github.com/11ways/janeway still actively developed, great object inspection
- longjohn has some useful code around sourcemap support and async stack trace support