3 [![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
5 [![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map)
7 This is a library to generate and consume the source map format
8 [described here][format].
10 [format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
14 $ npm install source-map
18 <script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
20 --------------------------------------------------------------------------------
22 <!-- `npm run toc` to regenerate the Table of Contents -->
24 <!-- START doctoc generated TOC please keep comment here to allow auto update -->
25 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
28 - [Examples](#examples)
29 - [Consuming a source map](#consuming-a-source-map)
30 - [Generating a source map](#generating-a-source-map)
31 - [With SourceNode (high level API)](#with-sourcenode-high-level-api)
32 - [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
34 - [SourceMapConsumer](#sourcemapconsumer)
35 - [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
36 - [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
37 - [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
38 - [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
39 - [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
40 - [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
41 - [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
42 - [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
43 - [SourceMapGenerator](#sourcemapgenerator)
44 - [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
45 - [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
46 - [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
47 - [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
48 - [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
49 - [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
50 - [SourceNode](#sourcenode)
51 - [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
52 - [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
53 - [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
54 - [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
55 - [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
56 - [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
57 - [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
58 - [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
59 - [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
60 - [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
61 - [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
63 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
67 ### Consuming a source map
73 names: ['bar', 'baz', 'n'],
74 sources: ['one.js', 'two.js'],
75 sourceRoot: 'http://example.com/www/js/',
76 mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
79 var smc = new SourceMapConsumer(rawSourceMap);
81 console.log(smc.sources);
82 // [ 'http://example.com/www/js/one.js',
83 // 'http://example.com/www/js/two.js' ]
85 console.log(smc.originalPositionFor({
89 // { source: 'http://example.com/www/js/two.js',
94 console.log(smc.generatedPositionFor({
95 source: 'http://example.com/www/js/two.js',
99 // { line: 2, column: 28 }
101 smc.eachMapping(function (m) {
106 ### Generating a source map
109 [**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
111 #### With SourceNode (high level API)
114 function compile(ast) {
116 case 'BinaryExpression':
117 return new SourceNode(
121 [compile(ast.left), " + ", compile(ast.right)]
124 return new SourceNode(
132 throw new Error("Bad AST");
136 var ast = parse("40 + 2", "add.js");
137 console.log(compile(ast).toStringWithSourceMap({
141 // map: [object SourceMapGenerator] }
144 #### With SourceMapGenerator (low level API)
147 var map = new SourceMapGenerator({
148 file: "source-mapped.js"
164 console.log(map.toString());
165 // '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
170 Get a reference to the module:
174 var sourceMap = require('source-map');
177 var sourceMap = window.sourceMap;
180 const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
183 ### SourceMapConsumer
185 A SourceMapConsumer instance represents a parsed source map which we can query
186 for information about the original file positions by giving it a file position
187 in the generated source.
189 #### new SourceMapConsumer(rawSourceMap)
191 The only parameter is the raw source map (either as a string which can be
192 `JSON.parse`'d, or an object). According to the spec, source maps have the
193 following attributes:
195 * `version`: Which version of the source map spec this map is following.
197 * `sources`: An array of URLs to the original source files.
199 * `names`: An array of identifiers which can be referenced by individual
202 * `sourceRoot`: Optional. The URL root from which all sources are relative.
204 * `sourcesContent`: Optional. An array of contents of the original source files.
206 * `mappings`: A string of base64 VLQs which contain the actual mappings.
208 * `file`: Optional. The generated filename this source map is associated with.
211 var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
214 #### SourceMapConsumer.prototype.computeColumnSpans()
216 Compute the last column for each generated mapping. The last column is
221 consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
229 consumer.computeColumnSpans();
232 consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
241 // lastColumn: Infinity } ]
245 #### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
247 Returns the original source, line, and column information for the generated
248 source's line and column positions provided. The only argument is an object with
249 the following properties:
251 * `line`: The line number in the generated source. Line numbers in
252 this library are 1-based (note that the underlying source map
253 specification uses 0-based line numbers -- this library handles the
256 * `column`: The column number in the generated source. Column numbers
257 in this library are 0-based.
259 * `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
260 `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
261 element that is smaller than or greater than the one we are searching for,
262 respectively, if the exact element cannot be found. Defaults to
263 `SourceMapConsumer.GREATEST_LOWER_BOUND`.
265 and an object is returned with the following properties:
267 * `source`: The original source file, or null if this information is not
270 * `line`: The line number in the original source, or null if this information is
271 not available. The line number is 1-based.
273 * `column`: The column number in the original source, or null if this
274 information is not available. The column number is 0-based.
276 * `name`: The original identifier, or null if this information is not available.
279 consumer.originalPositionFor({ line: 2, column: 10 })
280 // { source: 'foo.coffee',
285 consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
292 #### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
294 Returns the generated line and column information for the original source,
295 line, and column positions provided. The only argument is an object with
296 the following properties:
298 * `source`: The filename of the original source.
300 * `line`: The line number in the original source. The line number is
303 * `column`: The column number in the original source. The column
306 and an object is returned with the following properties:
308 * `line`: The line number in the generated source, or null. The line
311 * `column`: The column number in the generated source, or null. The
312 column number is 0-based.
315 consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
320 #### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
322 Returns all generated line and column information for the original source, line,
323 and column provided. If no column is provided, returns all mappings
324 corresponding to a either the line we are searching for or the next closest line
325 that has any mappings. Otherwise, returns all mappings corresponding to the
326 given line and either the column we are searching for or the next closest column
327 that has any offsets.
329 The only argument is an object with the following properties:
331 * `source`: The filename of the original source.
333 * `line`: The line number in the original source. The line number is
336 * `column`: Optional. The column number in the original source. The
337 column number is 0-based.
339 and an array of objects is returned, each with the following properties:
341 * `line`: The line number in the generated source, or null. The line
344 * `column`: The column number in the generated source, or null. The
345 column number is 0-based.
348 consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
357 #### SourceMapConsumer.prototype.hasContentsOfAllSources()
359 Return true if we have the embedded source content for every source listed in
360 the source map, false otherwise.
362 In other words, if this method returns `true`, then
363 `consumer.sourceContentFor(s)` will succeed for every source `s` in
368 if (consumer.hasContentsOfAllSources()) {
369 consumerReadyCallback(consumer);
371 fetchSources(consumer, consumerReadyCallback);
376 #### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
378 Returns the original source content for the source provided. The only
379 argument is the URL of the original source file.
381 If the source content for the given source is not found, then an error is
382 thrown. Optionally, pass `true` as the second param to have `null` returned
387 // [ "my-cool-lib.clj" ]
389 consumer.sourceContentFor("my-cool-lib.clj")
392 consumer.sourceContentFor("this is not in the source map");
393 // Error: "this is not in the source map" is not in the source map
395 consumer.sourceContentFor("this is not in the source map", true);
399 #### SourceMapConsumer.prototype.eachMapping(callback, context, order)
401 Iterate over each mapping between an original source/line/column and a
402 generated line/column in this source map.
404 * `callback`: The function that is called with each mapping. Mappings have the
405 form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
408 * `context`: Optional. If specified, this object will be the value of `this`
409 every time that `callback` is called.
411 * `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
412 `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
413 the mappings sorted by the generated file's line/column order or the
414 original's source/line/column order, respectively. Defaults to
415 `SourceMapConsumer.GENERATED_ORDER`.
418 consumer.eachMapping(function (m) { console.log(m); })
420 // { source: 'illmatic.js',
422 // generatedColumn: 0,
424 // originalColumn: 0,
426 // { source: 'illmatic.js',
428 // generatedColumn: 0,
430 // originalColumn: 0,
434 ### SourceMapGenerator
436 An instance of the SourceMapGenerator represents a source map which is being
439 #### new SourceMapGenerator([startOfSourceMap])
441 You may pass an object with the following properties:
443 * `file`: The filename of the generated source that this source map is
446 * `sourceRoot`: A root for all relative URLs in this source map.
448 * `skipValidation`: Optional. When `true`, disables validation of mappings as
449 they are added. This can improve performance but should be used with
450 discretion, as a last resort. Even then, one should avoid using this flag when
451 running tests, if possible.
454 var generator = new sourceMap.SourceMapGenerator({
455 file: "my-generated-javascript-file.js",
456 sourceRoot: "http://example.com/app/js/"
460 #### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
462 Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
464 * `sourceMapConsumer` The SourceMap.
467 var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
470 #### SourceMapGenerator.prototype.addMapping(mapping)
472 Add a single mapping from original source line and column to the generated
473 source's line and column for this source map being created. The mapping object
474 should have the following properties:
476 * `generated`: An object with the generated line and column positions.
478 * `original`: An object with the original line and column positions.
480 * `source`: The original source file (relative to the sourceRoot).
482 * `name`: An optional original token name for this mapping.
485 generator.addMapping({
486 source: "module-one.scm",
487 original: { line: 128, column: 0 },
488 generated: { line: 3, column: 456 }
492 #### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
494 Set the source content for an original source file.
496 * `sourceFile` the URL of the original source file.
498 * `sourceContent` the content of the source file.
501 generator.setSourceContent("module-one.scm",
502 fs.readFileSync("path/to/module-one.scm"))
505 #### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
507 Applies a SourceMap for a source file to the SourceMap.
508 Each mapping to the supplied source file is rewritten using the
509 supplied SourceMap. Note: The resolution for the resulting mappings
510 is the minimum of this map and the supplied map.
512 * `sourceMapConsumer`: The SourceMap to be applied.
514 * `sourceFile`: Optional. The filename of the source file.
515 If omitted, sourceMapConsumer.file will be used, if it exists.
516 Otherwise an error will be thrown.
518 * `sourceMapPath`: Optional. The dirname of the path to the SourceMap
519 to be applied. If relative, it is relative to the SourceMap.
521 This parameter is needed when the two SourceMaps aren't in the same
522 directory, and the SourceMap to be applied contains relative source
523 paths. If so, those relative source paths need to be rewritten
524 relative to the SourceMap.
526 If omitted, it is assumed that both SourceMaps are in the same directory,
527 thus not needing any rewriting. (Supplying `'.'` has the same effect.)
529 #### SourceMapGenerator.prototype.toString()
531 Renders the source map being generated to a string.
535 // '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
540 SourceNodes provide a way to abstract over interpolating and/or concatenating
541 snippets of generated JavaScript source code, while maintaining the line and
542 column information associated between those snippets and the original source
543 code. This is useful as the final intermediate representation a compiler might
544 use before outputting the generated JS and source map.
546 #### new SourceNode([line, column, source[, chunk[, name]]])
548 * `line`: The original line number associated with this source node, or null if
549 it isn't associated with an original line. The line number is 1-based.
551 * `column`: The original column number associated with this source node, or null
552 if it isn't associated with an original column. The column number
555 * `source`: The original source's filename; null if no filename is provided.
557 * `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
560 * `name`: Optional. The original identifier.
563 var node = new SourceNode(1, 2, "a.cpp", [
564 new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
565 new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
566 new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
570 #### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
572 Creates a SourceNode from generated code and a SourceMapConsumer.
574 * `code`: The generated code
576 * `sourceMapConsumer` The SourceMap for the generated code
578 * `relativePath` The optional path that relative sources in `sourceMapConsumer`
579 should be relative to.
582 var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
583 var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
587 #### SourceNode.prototype.add(chunk)
589 Add a chunk of generated JS to this source node.
591 * `chunk`: A string snippet of generated JS code, another instance of
592 `SourceNode`, or an array where each member is one of those things.
597 node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
600 #### SourceNode.prototype.prepend(chunk)
602 Prepend a chunk of generated JS to this source node.
604 * `chunk`: A string snippet of generated JS code, another instance of
605 `SourceNode`, or an array where each member is one of those things.
608 node.prepend("/** Build Id: f783haef86324gf **/\n\n");
611 #### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
613 Set the source content for a source file. This will be added to the
614 `SourceMap` in the `sourcesContent` field.
616 * `sourceFile`: The filename of the source file
618 * `sourceContent`: The content of the source file
621 node.setSourceContent("module-one.scm",
622 fs.readFileSync("path/to/module-one.scm"))
625 #### SourceNode.prototype.walk(fn)
627 Walk over the tree of JS snippets in this node and its children. The walking
628 function is called once for each snippet of JS and is passed that snippet and
629 the its original associated source's line/column location.
631 * `fn`: The traversal function.
634 var node = new SourceNode(1, 2, "a.js", [
635 new SourceNode(3, 4, "b.js", "uno"),
639 new SourceNode(5, 6, "c.js", "quatro")
643 node.walk(function (code, loc) { console.log("WALK:", code, loc); })
644 // WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
645 // WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
646 // WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
647 // WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
650 #### SourceNode.prototype.walkSourceContents(fn)
652 Walk over the tree of SourceNodes. The walking function is called for each
653 source file content and is passed the filename and source content.
655 * `fn`: The traversal function.
658 var a = new SourceNode(1, 2, "a.js", "generated from a");
659 a.setSourceContent("a.js", "original a");
660 var b = new SourceNode(1, 2, "b.js", "generated from b");
661 b.setSourceContent("b.js", "original b");
662 var c = new SourceNode(1, 2, "c.js", "generated from c");
663 c.setSourceContent("c.js", "original c");
665 var node = new SourceNode(null, null, null, [a, b, c]);
666 node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
667 // WALK: a.js : original a
668 // WALK: b.js : original b
669 // WALK: c.js : original c
672 #### SourceNode.prototype.join(sep)
674 Like `Array.prototype.join` except for SourceNodes. Inserts the separator
675 between each of this source node's children.
677 * `sep`: The separator.
680 var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
681 var operand = new SourceNode(3, 4, "a.rs", "=");
682 var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
684 var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
685 var joinedNode = node.join(" ");
688 #### SourceNode.prototype.replaceRight(pattern, replacement)
690 Call `String.prototype.replace` on the very right-most source snippet. Useful
691 for trimming white space from the end of a source node, etc.
693 * `pattern`: The pattern to replace.
695 * `replacement`: The thing to replace the pattern with.
698 // Trim trailing white space.
699 node.replaceRight(/\s*$/, "");
702 #### SourceNode.prototype.toString()
704 Return the string representation of this source node. Walks over the tree and
705 concatenates all the various snippets together to one string.
708 var node = new SourceNode(1, 2, "a.js", [
709 new SourceNode(3, 4, "b.js", "uno"),
713 new SourceNode(5, 6, "c.js", "quatro")
718 // 'unodostresquatro'
721 #### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
723 Returns the string representation of this tree of source nodes, plus a
724 SourceMapGenerator which contains all the mappings between the generated and
727 The arguments are the same as those to `new SourceMapGenerator`.
730 var node = new SourceNode(1, 2, "a.js", [
731 new SourceNode(3, 4, "b.js", "uno"),
735 new SourceNode(5, 6, "c.js", "quatro")
739 node.toStringWithSourceMap({ file: "my-output-file.js" })
740 // { code: 'unodostresquatro',
741 // map: [object SourceMapGenerator] }