Generates and consumes source maps for debugging tools that map minified code back to original source code
npx @tessl/cli install tessl/npm-source-map@0.7.00
# Source Map
1
2
Source Map is a comprehensive JavaScript library for generating and consuming source maps, which are essential debugging tools that map minified or compiled code back to original source code. It provides both high-level APIs for building source maps incrementally during code generation and low-level APIs for direct manipulation and consumption of source map data.
3
4
## Package Information
5
6
- **Package Name**: source-map
7
- **Package Type**: npm
8
- **Language**: JavaScript with TypeScript definitions
9
- **Installation**: `npm install source-map`
10
- **Browser Support**: Yes (with WASM initialization)
11
- **Node.js Support**: >= 12
12
13
## Core Imports
14
15
ES Modules:
16
```typescript
17
import { SourceMapGenerator, SourceMapConsumer, SourceNode } from "source-map";
18
```
19
20
CommonJS:
21
```javascript
22
const { SourceMapGenerator, SourceMapConsumer, SourceNode } = require("source-map");
23
```
24
25
## Basic Usage
26
27
### Consuming a Source Map
28
29
```javascript
30
import { SourceMapConsumer } from "source-map";
31
32
const rawSourceMap = {
33
version: 3,
34
file: "min.js",
35
names: ["bar", "baz", "n"],
36
sources: ["one.js", "two.js"],
37
sourceRoot: "http://example.com/www/js/",
38
mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUGE,GAClB,OAAOA"
39
};
40
41
// Use the auto-cleanup wrapper (recommended)
42
const result = await SourceMapConsumer.with(rawSourceMap, null, consumer => {
43
// Find original position for generated code
44
const originalPos = consumer.originalPositionFor({
45
line: 2,
46
column: 28
47
});
48
// Returns: { source: 'http://example.com/www/js/two.js', line: 2, column: 10, name: 'n' }
49
50
return originalPos;
51
});
52
```
53
54
### Generating a Source Map
55
56
```javascript
57
import { SourceMapGenerator } from "source-map";
58
59
const map = new SourceMapGenerator({
60
file: "source-mapped.js"
61
});
62
63
map.addMapping({
64
generated: { line: 10, column: 35 },
65
source: "foo.js",
66
original: { line: 33, column: 2 },
67
name: "christopher"
68
});
69
70
console.log(map.toString());
71
// Outputs complete source map JSON
72
```
73
74
### Building with SourceNode
75
76
```javascript
77
import { SourceNode } from "source-map";
78
79
const node = new SourceNode(1, 0, "math.js", [
80
"function add(a, b) {\n",
81
new SourceNode(2, 2, "math.js", "return a + b;\n"),
82
"}"
83
]);
84
85
const result = node.toStringWithSourceMap({
86
file: "compiled.js"
87
});
88
89
console.log(result.code); // Generated JavaScript
90
console.log(result.map.toString()); // Source map JSON
91
```
92
93
### Google Chrome DevTools Integration
94
95
Source maps support an optional `x_google_ignoreList` field for marking third-party sources:
96
97
```javascript
98
const sourceMapWithIgnoreList = {
99
version: 3,
100
sources: ["app.js", "vendor.js", "node_modules/lib.js"],
101
names: [],
102
mappings: "...",
103
x_google_ignoreList: [1, 2] // Mark vendor.js and lib.js as third-party
104
};
105
```
106
107
## Architecture
108
109
Source Map is built around three main components:
110
111
- **SourceMapGenerator**: Creates source maps incrementally during code generation, ideal for build tools and transpilers
112
- **SourceMapConsumer**: Reads and queries existing source maps, perfect for debuggers and development tools
113
- **SourceNode**: High-level API for building source maps through code concatenation and manipulation
114
115
The library supports both regular source maps and indexed source maps for large applications, with WASM-accelerated performance for fast position lookups in browser environments.
116
117
## Browser Initialization
118
119
When using in browsers, initialize WASM before creating consumers:
120
121
```javascript
122
import { SourceMapConsumer } from "source-map";
123
124
// Required for browser usage
125
SourceMapConsumer.initialize({
126
"lib/mappings.wasm": "https://unpkg.com/source-map@0.7.6/lib/mappings.wasm"
127
});
128
129
// Now safe to use SourceMapConsumer
130
```
131
132
## Error Handling
133
134
Source map operations can fail for various reasons. Handle errors appropriately:
135
136
```javascript
137
try {
138
const consumer = await new SourceMapConsumer(rawSourceMap);
139
// Use consumer safely
140
consumer.destroy();
141
} catch (error) {
142
if (error.message.includes("Unsupported version")) {
143
console.error("Source map version not supported (only v3 supported)");
144
} else if (error.message.includes("lib/mappings.wasm")) {
145
console.error("WASM not initialized for browser usage");
146
} else if (error.message.includes("Invalid mapping")) {
147
console.error("Source map contains invalid mapping data");
148
} else {
149
console.error("Failed to parse source map:", error.message);
150
}
151
}
152
```
153
154
Common error scenarios:
155
- **Unsupported version**: Only version 3 source maps are supported
156
- **WASM not initialized**: Browser usage requires `SourceMapConsumer.initialize()`
157
- **Invalid format**: Malformed JSON or missing required fields
158
- **Source not found**: Requested source file not present in source map
159
- **Invalid positions**: Line/column values outside valid ranges
160
161
## Performance Considerations
162
163
Source map operations can be expensive for large files. Consider these optimizations:
164
165
- **Use `SourceMapConsumer.with()`** for automatic resource cleanup
166
- **Enable column spans** only when needed (increases memory usage)
167
- **Cache consumers** for frequently accessed source maps
168
- **Batch position lookups** instead of many individual calls
169
- **Use WASM in browsers** for faster parsing and position lookups
170
171
```javascript
172
// Good: Batch operations within consumer lifecycle
173
const results = await SourceMapConsumer.with(sourceMap, null, (consumer) => {
174
return sourcePositions.map(pos => consumer.originalPositionFor(pos));
175
});
176
177
// Avoid: Creating multiple consumers for the same map
178
// This creates unnecessary overhead
179
```
180
181
## Capabilities
182
183
### Source Map Generation
184
185
Create source maps incrementally during code generation with full control over mappings and source content.
186
187
```typescript { .api }
188
class SourceMapGenerator {
189
constructor(args?: StartOfSourceMap);
190
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
191
addMapping(mapping: Mapping): void;
192
setSourceContent(sourceFile: string, sourceContent: string): void;
193
applySourceMap(
194
sourceMapConsumer: SourceMapConsumer,
195
sourceFile?: string,
196
sourceMapPath?: string
197
): void;
198
toString(): string;
199
toJSON(): RawSourceMap;
200
}
201
202
interface StartOfSourceMap {
203
file?: string;
204
sourceRoot?: string;
205
skipValidation?: boolean;
206
}
207
208
interface Mapping {
209
generated: Position;
210
original: Position;
211
source: string;
212
name?: string;
213
}
214
```
215
216
[Source Map Generation](./source-map-generation.md)
217
218
### Source Map Consumption
219
220
Read and query existing source maps with bidirectional position mapping and source content access.
221
222
```typescript { .api }
223
interface SourceMapConsumerConstructor {
224
new (
225
rawSourceMap: RawSourceMap | RawIndexMap | string,
226
sourceMapUrl?: SourceMapUrl
227
): Promise<BasicSourceMapConsumer | IndexedSourceMapConsumer>;
228
229
// Static constants
230
readonly GENERATED_ORDER: 1;
231
readonly ORIGINAL_ORDER: 2;
232
readonly GREATEST_LOWER_BOUND: 1;
233
readonly LEAST_UPPER_BOUND: 2;
234
235
initialize(mappings: SourceMappings): void;
236
fromSourceMap(
237
sourceMap: SourceMapGenerator,
238
sourceMapUrl?: SourceMapUrl
239
): Promise<BasicSourceMapConsumer>;
240
with<T>(
241
rawSourceMap: RawSourceMap | RawIndexMap | string,
242
sourceMapUrl: SourceMapUrl | null | undefined,
243
callback: (consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer) => Promise<T> | T
244
): Promise<T>;
245
}
246
247
interface SourceMapConsumer {
248
computeColumnSpans(): void;
249
originalPositionFor(
250
generatedPosition: Position & { bias?: number }
251
): NullableMappedPosition;
252
generatedPositionFor(
253
originalPosition: MappedPosition & { bias?: number }
254
): NullablePosition;
255
allGeneratedPositionsFor(
256
originalPosition: MappedPosition
257
): NullablePosition[];
258
hasContentsOfAllSources(): boolean;
259
sourceContentFor(source: string, returnNullOnMissing?: boolean): string | null;
260
eachMapping(
261
callback: (mapping: MappingItem) => void,
262
context?: any,
263
order?: number
264
): void;
265
destroy(): void;
266
}
267
```
268
269
[Source Map Consumption](./source-map-consumption.md)
270
271
### Source Node Building
272
273
Build source maps through code concatenation and manipulation with a high-level fluent API.
274
275
```typescript { .api }
276
class SourceNode {
277
constructor(
278
line?: number | null,
279
column?: number | null,
280
source?: string | null,
281
chunks?: Array<string | SourceNode> | SourceNode | string,
282
name?: string
283
);
284
285
static fromStringWithSourceMap(
286
code: string,
287
sourceMapConsumer: SourceMapConsumer,
288
relativePath?: string
289
): SourceNode;
290
291
add(chunk: Array<string | SourceNode> | SourceNode | string): SourceNode;
292
prepend(chunk: Array<string | SourceNode> | SourceNode | string): SourceNode;
293
setSourceContent(sourceFile: string, sourceContent: string): void;
294
walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
295
walkSourceContents(fn: (file: string, content: string) => void): void;
296
join(sep: string): SourceNode;
297
replaceRight(pattern: string, replacement: string): SourceNode;
298
toString(): string;
299
toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
300
}
301
```
302
303
[Source Node Building](./source-node-building.md)
304
305
## Core Types
306
307
```typescript { .api }
308
type SourceMapUrl = string;
309
310
interface Position {
311
line: number;
312
column: number;
313
}
314
315
interface NullablePosition {
316
line: number | null;
317
column: number | null;
318
lastColumn: number | null;
319
}
320
321
interface MappedPosition {
322
source: string;
323
line: number;
324
column: number;
325
name?: string;
326
}
327
328
interface NullableMappedPosition {
329
source: string | null;
330
line: number | null;
331
column: number | null;
332
name: string | null;
333
}
334
335
interface RawSourceMap {
336
version: number;
337
sources: string[];
338
names: string[];
339
sourceRoot?: string;
340
sourcesContent?: string[];
341
mappings: string;
342
file: string;
343
x_google_ignoreList?: number[];
344
}
345
346
interface RawIndexMap extends StartOfSourceMap {
347
version: number;
348
sections: RawSection[];
349
}
350
351
interface RawSection {
352
offset: Position;
353
map: RawSourceMap;
354
}
355
356
interface MappingItem {
357
source: string;
358
generatedLine: number;
359
generatedColumn: number;
360
lastGeneratedColumn: number | null;
361
originalLine: number;
362
originalColumn: number;
363
name: string;
364
}
365
366
interface CodeWithSourceMap {
367
code: string;
368
map: SourceMapGenerator;
369
}
370
371
interface SourceMappings {
372
"lib/mappings.wasm": SourceMapUrl | ArrayBuffer;
373
}
374
```