Skip to content

Instantly share code, notes, and snippets.

@bcoe
Last active September 12, 2019 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcoe/6baf9393eb914003391795bb1fe9f9bf to your computer and use it in GitHub Desktop.
Save bcoe/6baf9393eb914003391795bb1fe9f9bf to your computer and use it in GitHub Desktop.
Source Map Support in Node.js

Programatic Access of Source Maps

To begin collecting source-maps, node must be run with --enable-source-maps (or with NODE_V8_COVERAGE set).

At which point, the new built-in module source_map can be used to interact with the source-map cache:

// tooling has one interface into the source-map cache, URIs, any type of module that we
// wish to attach source-maps to (ESM, CJS, evals, data-urls) needs to have a methodlogy
// for setting a URI; Two different source-maps cannot be stored at the same URI.
const {cache} = require('source_map');
const sm1 = cache.sourceMapFromURI(`file://${require.resolve('./my-module')}`);

These methods return the same data-structure that is written to disk when executing with NODE_V8_COVERAGE:

{
  "url": "data:abc123", // original source-map URL.
  "data": {} // parsed source-map or null.
}

Stack Traces When Source Maps are Enabled

When executing with --enable-source-maps, stack traces will be rewritten if source-maps are found corresponding to files represented in the stack-trace.

The hope is to intitially engage folks rom the https://github.com/evanw/node-source-map-support project, to support stack-trace rewritting in Node.js. And, in the future, work with the V8 team to move more of this behavior into V8 itself.

@ljharb
Copy link

ljharb commented Sep 12, 2019

Why not a single function, like require, that takes a path, resolves it, and then returns a Buffer to the source map contents (cached, of course) - regardless of whether it's inline or a file on disk. If there's concerns about fetching a URL, an alternative could be that it returns some kind of object that indicates the source, and lets you get the contents yourself if it's not inline or on disk. (a different function with the same semantics could apply for esm)

@bcoe
Copy link
Author

bcoe commented Sep 12, 2019

@ljharb are you picturing an API more like this:

const {fetchSourceMap} = require('source_map');
const sm1 = fetchSourceMap(require.resolve('./my-script'));
  1. if the source-map is already in the cache, return the object:

    {
      "url": "file://original-source-map-url",
       "data": {} // maybe loaded Source Map V3.
    }
  2. if the Source Map was not yet loaded, we read the file from disk and look for a source map potentially; returning the same format.

What's your reasoning for a Buffer rather than returning the object, as suggested above?

@benjamingr
Copy link

This is fantastic and a real pain for a lot of Node.js developers - thank you for working on it.

Making source maps work out of the box in stack traces would be great and it's mostly blocked on someone actually doing the work on making it happen.

@ljharb
Copy link

ljharb commented Sep 12, 2019

@bcoe yes, the object would work fine. I'd initially thought of a Buffer so it would directly return the content (the source being irrelevant), but I'd forgotten about remote URLs (which would not be good for node to implicitly request).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment