UNPKG

15.3 kBMarkdownView Raw
1# Source Map
2
3This is a library to generate and consume the source map format
4[described here][format].
5
6This library is written in the Asynchronous Module Definition format, and works
7in the following environments:
8
9* Modern Browsers supporting ECMAScript 5 (either after the build, or with an
10 AMD loader such as RequireJS)
11
12* Inside Firefox (as a JSM file, after the build)
13
14* With NodeJS versions 0.8.X and higher
15
16## Node
17
18 $ npm install source-map
19
20## Building from Source (for everywhere else)
21
22Install Node and then run
23
24 $ git clone https://fitzgen@github.com/mozilla/source-map.git
25 $ cd source-map
26 $ npm link .
27
28Next, run
29
30 $ node Makefile.dryice.js
31
32This should spew a bunch of stuff to stdout, and create the following files:
33
34* `dist/source-map.js` - The unminified browser version.
35
36* `dist/source-map.min.js` - The minified browser version.
37
38* `dist/SourceMap.jsm` - The JavaScript Module for inclusion in Firefox source.
39
40## Examples
41
42### Consuming a source map
43
44```js
45var rawSourceMap = {
46 version: 3,
47 file: 'min.js',
48 names: ['bar', 'baz', 'n'],
49 sources: ['one.js', 'two.js'],
50 sourceRoot: 'http://example.com/www/js/',
51 mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
52};
53
54var smc = new SourceMapConsumer(rawSourceMap);
55
56console.log(smc.sources);
57// [ 'http://example.com/www/js/one.js',
58// 'http://example.com/www/js/two.js' ]
59
60console.log(smc.originalPositionFor({
61 line: 2,
62 column: 28
63}));
64// { source: 'http://example.com/www/js/two.js',
65// line: 2,
66// column: 10,
67// name: 'n' }
68
69console.log(smc.generatedPositionFor({
70 source: 'http://example.com/www/js/two.js',
71 line: 2,
72 column: 10
73}));
74// { line: 2, column: 28 }
75
76smc.eachMapping(function (m) {
77 // ...
78});
79```
80
81### Generating a source map
82
83In depth guide:
84[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
85
86#### With SourceNode (high level API)
87
88```js
89function compile(ast) {
90 switch (ast.type) {
91 case 'BinaryExpression':
92 return new SourceNode(
93 ast.location.line,
94 ast.location.column,
95 ast.location.source,
96 [compile(ast.left), " + ", compile(ast.right)]
97 );
98 case 'Literal':
99 return new SourceNode(
100 ast.location.line,
101 ast.location.column,
102 ast.location.source,
103 String(ast.value)
104 );
105 // ...
106 default:
107 throw new Error("Bad AST");
108 }
109}
110
111var ast = parse("40 + 2", "add.js");
112console.log(compile(ast).toStringWithSourceMap({
113 file: 'add.js'
114}));
115// { code: '40 + 2',
116// map: [object SourceMapGenerator] }
117```
118
119#### With SourceMapGenerator (low level API)
120
121```js
122var map = new SourceMapGenerator({
123 file: "source-mapped.js"
124});
125
126map.addMapping({
127 generated: {
128 line: 10,
129 column: 35
130 },
131 source: "foo.js",
132 original: {
133 line: 33,
134 column: 2
135 },
136 name: "christopher"
137});
138
139console.log(map.toString());
140// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
141```
142
143## API
144
145Get a reference to the module:
146
147```js
148// NodeJS
149var sourceMap = require('source-map');
150
151// Browser builds
152var sourceMap = window.sourceMap;
153
154// Inside Firefox
155let sourceMap = {};
156Components.utils.import('resource:///modules/devtools/SourceMap.jsm', sourceMap);
157```
158
159### SourceMapConsumer
160
161A SourceMapConsumer instance represents a parsed source map which we can query
162for information about the original file positions by giving it a file position
163in the generated source.
164
165#### new SourceMapConsumer(rawSourceMap)
166
167The only parameter is the raw source map (either as a string which can be
168`JSON.parse`'d, or an object). According to the spec, source maps have the
169following attributes:
170
171* `version`: Which version of the source map spec this map is following.
172
173* `sources`: An array of URLs to the original source files.
174
175* `names`: An array of identifiers which can be referrenced by individual
176 mappings.
177
178* `sourceRoot`: Optional. The URL root from which all sources are relative.
179
180* `sourcesContent`: Optional. An array of contents of the original source files.
181
182* `mappings`: A string of base64 VLQs which contain the actual mappings.
183
184* `file`: Optional. The generated filename this source map is associated with.
185
186#### SourceMapConsumer.prototype.computeColumnSpans()
187
188Compute the last column for each generated mapping. The last column is
189inclusive.
190
191#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
192
193Returns the original source, line, and column information for the generated
194source's line and column positions provided. The only argument is an object with
195the following properties:
196
197* `line`: The line number in the generated source.
198
199* `column`: The column number in the generated source.
200
201* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
202 `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
203 element that is smaller than or greater than the one we are searching for,
204 respectively, if the exact element cannot be found. Defaults to
205 `SourceMapConsumer.GREATEST_LOWER_BOUND`.
206
207and an object is returned with the following properties:
208
209* `source`: The original source file, or null if this information is not
210 available.
211
212* `line`: The line number in the original source, or null if this information is
213 not available.
214
215* `column`: The column number in the original source, or null or null if this
216 information is not available.
217
218* `name`: The original identifier, or null if this information is not available.
219
220#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
221
222Returns the generated line and column information for the original source,
223line, and column positions provided. The only argument is an object with
224the following properties:
225
226* `source`: The filename of the original source.
227
228* `line`: The line number in the original source.
229
230* `column`: The column number in the original source.
231
232and an object is returned with the following properties:
233
234* `line`: The line number in the generated source, or null.
235
236* `column`: The column number in the generated source, or null.
237
238#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
239
240Returns all generated line and column information for the original source
241and line provided. The only argument is an object with the following
242properties:
243
244* `source`: The filename of the original source.
245
246* `line`: The line number in the original source.
247
248and an array of objects is returned, each with the following properties:
249
250* `line`: The line number in the generated source, or null.
251
252* `column`: The column number in the generated source, or null.
253
254#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
255
256Returns the original source content for the source provided. The only
257argument is the URL of the original source file.
258
259If the source content for the given source is not found, then an error is
260thrown. Optionally, pass `true` as the second param to have `null` returned
261instead.
262
263#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
264
265Iterate over each mapping between an original source/line/column and a
266generated line/column in this source map.
267
268* `callback`: The function that is called with each mapping. Mappings have the
269 form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
270 name }`
271
272* `context`: Optional. If specified, this object will be the value of `this`
273 every time that `callback` is called.
274
275* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
276 `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
277 the mappings sorted by the generated file's line/column order or the
278 original's source/line/column order, respectively. Defaults to
279 `SourceMapConsumer.GENERATED_ORDER`.
280
281### SourceMapGenerator
282
283An instance of the SourceMapGenerator represents a source map which is being
284built incrementally.
285
286#### new SourceMapGenerator([startOfSourceMap])
287
288You may pass an object with the following properties:
289
290* `file`: The filename of the generated source that this source map is
291 associated with.
292
293* `sourceRoot`: A root for all relative URLs in this source map.
294
295* `skipValidation`: Optional. When `true`, disables validation of mappings as
296 they are added. This can improve performance but should be used with
297 discretion, as a last resort. Even then, one should avoid using this flag when
298 running tests, if possible.
299
300#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
301
302Creates a new SourceMapGenerator based on a SourceMapConsumer
303
304* `sourceMapConsumer` The SourceMap.
305
306#### SourceMapGenerator.prototype.addMapping(mapping)
307
308Add a single mapping from original source line and column to the generated
309source's line and column for this source map being created. The mapping object
310should have the following properties:
311
312* `generated`: An object with the generated line and column positions.
313
314* `original`: An object with the original line and column positions.
315
316* `source`: The original source file (relative to the sourceRoot).
317
318* `name`: An optional original token name for this mapping.
319
320#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
321
322Set the source content for an original source file.
323
324* `sourceFile` the URL of the original source file.
325
326* `sourceContent` the content of the source file.
327
328#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
329
330Applies a SourceMap for a source file to the SourceMap.
331Each mapping to the supplied source file is rewritten using the
332supplied SourceMap. Note: The resolution for the resulting mappings
333is the minimium of this map and the supplied map.
334
335* `sourceMapConsumer`: The SourceMap to be applied.
336
337* `sourceFile`: Optional. The filename of the source file.
338 If omitted, sourceMapConsumer.file will be used, if it exists.
339 Otherwise an error will be thrown.
340
341* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
342 to be applied. If relative, it is relative to the SourceMap.
343
344 This parameter is needed when the two SourceMaps aren't in the same
345 directory, and the SourceMap to be applied contains relative source
346 paths. If so, those relative source paths need to be rewritten
347 relative to the SourceMap.
348
349 If omitted, it is assumed that both SourceMaps are in the same directory,
350 thus not needing any rewriting. (Supplying `'.'` has the same effect.)
351
352#### SourceMapGenerator.prototype.toString()
353
354Renders the source map being generated to a string.
355
356### SourceNode
357
358SourceNodes provide a way to abstract over interpolating and/or concatenating
359snippets of generated JavaScript source code, while maintaining the line and
360column information associated between those snippets and the original source
361code. This is useful as the final intermediate representation a compiler might
362use before outputting the generated JS and source map.
363
364#### new SourceNode([line, column, source[, chunk[, name]]])
365
366* `line`: The original line number associated with this source node, or null if
367 it isn't associated with an original line.
368
369* `column`: The original column number associated with this source node, or null
370 if it isn't associated with an original column.
371
372* `source`: The original source's filename; null if no filename is provided.
373
374* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
375 below.
376
377* `name`: Optional. The original identifier.
378
379#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
380
381Creates a SourceNode from generated code and a SourceMapConsumer.
382
383* `code`: The generated code
384
385* `sourceMapConsumer` The SourceMap for the generated code
386
387* `relativePath` The optional path that relative sources in `sourceMapConsumer`
388 should be relative to.
389
390#### SourceNode.prototype.add(chunk)
391
392Add a chunk of generated JS to this source node.
393
394* `chunk`: A string snippet of generated JS code, another instance of
395 `SourceNode`, or an array where each member is one of those things.
396
397#### SourceNode.prototype.prepend(chunk)
398
399Prepend a chunk of generated JS to this source node.
400
401* `chunk`: A string snippet of generated JS code, another instance of
402 `SourceNode`, or an array where each member is one of those things.
403
404#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
405
406Set the source content for a source file. This will be added to the
407`SourceMap` in the `sourcesContent` field.
408
409* `sourceFile`: The filename of the source file
410
411* `sourceContent`: The content of the source file
412
413#### SourceNode.prototype.walk(fn)
414
415Walk over the tree of JS snippets in this node and its children. The walking
416function is called once for each snippet of JS and is passed that snippet and
417the its original associated source's line/column location.
418
419* `fn`: The traversal function.
420
421#### SourceNode.prototype.walkSourceContents(fn)
422
423Walk over the tree of SourceNodes. The walking function is called for each
424source file content and is passed the filename and source content.
425
426* `fn`: The traversal function.
427
428#### SourceNode.prototype.join(sep)
429
430Like `Array.prototype.join` except for SourceNodes. Inserts the separator
431between each of this source node's children.
432
433* `sep`: The separator.
434
435#### SourceNode.prototype.replaceRight(pattern, replacement)
436
437Call `String.prototype.replace` on the very right-most source snippet. Useful
438for trimming whitespace from the end of a source node, etc.
439
440* `pattern`: The pattern to replace.
441
442* `replacement`: The thing to replace the pattern with.
443
444#### SourceNode.prototype.toString()
445
446Return the string representation of this source node. Walks over the tree and
447concatenates all the various snippets together to one string.
448
449#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
450
451Returns the string representation of this tree of source nodes, plus a
452SourceMapGenerator which contains all the mappings between the generated and
453original sources.
454
455The arguments are the same as those to `new SourceMapGenerator`.
456
457## Tests
458
459[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
460
461Install NodeJS version 0.8.0 or greater, then run `node test/run-tests.js`.
462
463To add new tests, create a new file named `test/test-<your new test name>.js`
464and export your test functions with names that start with "test", for example
465
466```js
467exports["test doing the foo bar"] = function (assert, util) {
468 ...
469};
470```
471
472The new test will be located automatically when you run the suite.
473
474The `util` argument is the test utility module located at `test/source-map/util`.
475
476The `assert` argument is a cut down version of node's assert module. You have
477access to the following assertion functions:
478
479* `doesNotThrow`
480
481* `equal`
482
483* `ok`
484
485* `strictEqual`
486
487* `throws`
488
489(The reason for the restricted set of test functions is because we need the
490tests to run inside Firefox's test suite as well and so the assert module is
491shimmed in that environment. See `build/assert-shim.js`.)
492
493[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
494[feature]: https://wiki.mozilla.org/DevTools/Features/SourceMap
495[Dryice]: https://github.com/mozilla/dryice