This is a tool for tracing the execution of javascript code. It does not require you to make changes to your source code; instrumentation is automated. The instrumented code will report the value of every expression it evaluates, and other execution details such as the tree of function calls.
This can be used in a few ways:
- The UI lets you run code directly in the browser and explore the trace. It's deployed to https://brokensandals.github.io/blunt-instrument/ and the source code is in packages/blunt-instrument-ui.
- The libraries can help you build interactive explanations of algorithms. You can evaluate arbitrary code at runtime and get programmatic access to the full trace. Jump to the blunt-instrument-eval README to get started, or see https://brokensandals.github.io/blunt-instrument/fib-call-tree.html for a simple example of usage in the browser.
- The Babel plugin can instrument your code for troubleshooting purposes. See example-plugin-config to see how.
Contents:
- Currently the UI naively loads the entire trace into memory, so it can't handle large traces yet. (Any fully-instrumented real-world software is going to produce large traces, so I'd like to fix this.)
- Support for
for await
loop syntax is not yet implemented. - As mentioned in Enabling and Disabling Tracing, turning the instrumenter on/off for individual lines currently has some gotchas.
- When tracing assignments such as
x.prop = z
orx[index] = z
, the trace will include the initial value ofx
and the results ofindex
andz
, but not the final value ofx
after modification. In the future an additional trace event type may be added to track the final value ofx
. - When tracing method calls such as
x.y()
, the trace will include the value ofx
and the result ofx.y()
, along with the trace of they
method (if it was instrumented). But it will not include thex.y
function object itself. (This might be fixed in the future, but it seems to be cumbersome to do without changing program semantics.) - When tracing postfix increment/decrement operators
x++
orx--
only the expression result (which is equal tox
) is traced, not the new value after assignment. In the future a trace event type may be added to track the effect of the assignment. - When it encounters a
Proxy
object the tracer will log/display it as if it were the target object. (I think it's impossible by design to universally detect when an object is a Proxy, but it seems possible via monkey-patching to track proxies that are created after the tracer initializes. So this may be partially addressed in the future.)
Clone this repo and run npm install
to install dependencies, then run npx lerna bootstrap
to link the packages together.
This is a multi-package project managed using lerna.
Each package is in a subdirectory of the packages
folder.
Jest and Babel config are at the root and apply to all packages except blunt-instrument-ui
, whose babel/webpack/jest config are managed by create-react-app.
Build and test commands can be run from the root directory.
Run npm run build:cjs
or npm run build:cjs:watch
to build the library packages.
You must do this before running tests, and you must rebuild a package before changes to it will affect other packages' tests.
Run npm test
or npm run test:watch
to run the unit tests.
Note: test:watch
in the root directory will not run the UI's tests.
You can run npm test
in packages/blunt-instrument-ui
to watch the UI tests.
Some of the snapshot tests are a bit sensitive to the version of Node you're running - for example, in 12.16.0 the name
property is present on some functions for which it is missing in 12.13.1.
I need a better strategy for dealing with this, but my current aim is to check in the results corresponding to the latest version of Node 12.
Run npm start
to run the UI locally.
Run npm run build
to build all packages, including the UI and ESM builds of the libraries.
Bug reports and pull requests are welcome on GitHub at https://github.com/brokensandals/blunt-instrument.
This is available as open source under the terms of the MIT License.