Resolve the source map and/or sources for a generated file.
const sourceMapResolve = require("source-map-resolve")
const sourceMap = require("source-map")
const readFile = util.promisify(fs.readFile)
const code = [
"!function(){...}();",
"/*# sourceMappingURL=foo.js.map */"
].join("\n")
(async () => {
try {
const result = await sourceMapResolve.resolveSourceMap(code, "/js/foo.js", readFile)
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map"
// }
const result = await sourceMapResolve.resolveSources(result.map, result.sourcesRelativeTo, readFile)
result
// {
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
const result = await sourceMapResolve.resolve(code, "/js/foo.js", readFile)
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map",
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
result.map.sourcesContent = result.sourcesContent
const map = new sourceMap.sourceMapConsumer(result.map)
map.sourceContentFor("/coffee/foo.coffee")
// "<contents of /coffee/foo.coffee>"
} catch (error) {
notifyFailure(error)
}
}())npm install source-map-resolve
codeis a string of code that may or may not contain a sourceMappingURL comment. Such a comment is used to resolve the source map.codeUrlis the url to the file containingcode. If the sourceMappingURL is relative, it is resolved againstcodeUrl.read(url, callback)is a function that readsurland responds usingcallback(error, content). In Node.js you might want to usefs.readFile, while in the browser you might want to use an asynchronusXMLHttpRequest.callback(error, result)is a function that is invoked with either an error ornulland the result.
The result is an object with the following properties:
map: The source map forcode, as an object (not a string).url: The url to the source map. If the source map came from a data uri, this property isnull, since then there is no url to it.sourcesRelativeTo: The url that the sources of the source map are relative to. Since the sources are relative to the source map, and the url to the source map is provided as theurlproperty, this property might seem superfluos. However, remember that theurlproperty can benullif the source map came from a data uri. If so, the sources are relative to the file containing the data uri—codeUrl. This property will be identical to theurlproperty orcodeUrl, whichever is appropriate. This way you can conveniently resolve the sources without having to think about where the source map came from.sourceMappingURL: The url of the sourceMappingURL comment incode.
If code contains no sourceMappingURL, the result is null.
mapis a source map, as an object (not a string).mapUrlis the url to the file containingmap. Relative sources in the source map, if any, are resolved againstmapUrl.read(url, callback)is a function that readsurland responds usingcallback(error, content). In Node.js you might want to usefs.readFile, while in the browser you might want to use an asynchronusXMLHttpRequest.optionsis an optional object with any of the following properties:sourceRoot: Override thesourceRootproperty of the source map, which might only be relevant when resolving sources in the browser. This lets you bypass it when using the module outside of a browser, if needed. Pass a string to replace thesourceRootproperty with, orfalseto ignore it. Defaults toundefined.
callback(error, result)is a function that is invoked with either an error ornulland the result.
The result is an object with the following properties:
sourcesResolved: The same asmap.sources, except all the sources are fully resolved.sourcesContent: An array with the contents of all sources inmap.sources, in the same order asmap.sources. If getting the contents of a source fails, an error object is put into the array instead.
The arguments are identical to sourceMapResolve.resolveSourceMap, except that
you may also provide the same options as in sourceMapResolve.resolveSources.
This is a convenience method that first resolves the source map and then its
sources. You could also do this by first calling
sourceMapResolve.resolveSourceMap and then sourceMapResolve.resolveSources.
The result is identical to sourceMapResolve.resolveSourceMap, with the
properties from sourceMapResolve.resolveSources merged into it.
There is one extra feature available, though. If code is null, codeUrl is
treated as a url to the source map instead of to code, and will be read. This
is handy if you sometimes get the source map url from the SourceMap: <url>
header (see the Notes section). In this case, the sourceMappingURL property
of the result is null.
The spec says that if a source map (as a string) starts with )]}', it should
be stripped off. This is to prevent XSSI attacks. This function does that and
returns the result of JSON.parseing what’s left.
If this function throws error, error.sourceMapData === data.
All errors passed to callbacks or thrown by this module have a sourceMapData
property that contain as much as possible of the intended result of the function
up until the error occurred.
Note that while the map property of result objects always is an object,
error.sourceMapData.map will be a string if parsing that string fails.
This module resolves the source map for a given generated file by looking for a
sourceMappingURL comment. The spec defines yet a way to provide the URL to the
source map: By sending the SourceMap: <url> header along with the generated
file. Since this module doesn’t retrive the generated code for you (instead
you give the generated code to the module), it’s up to you to look for such a
header when you retrieve the file (should the need arise).
MIT.