UNPKG

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