0
# Source Map Generation
1
2
The SourceMapGenerator class provides functionality for creating source maps incrementally during code generation. This is ideal for build tools, transpilers, and bundlers that need to track the relationship between generated code and original source files.
3
4
## Capabilities
5
6
### SourceMapGenerator Class
7
8
Creates source maps incrementally by adding mappings one at a time.
9
10
```typescript { .api }
11
/**
12
* Creates a new source map generator
13
* @param args - Configuration options for the source map
14
*/
15
class SourceMapGenerator {
16
constructor(args?: StartOfSourceMap);
17
18
/**
19
* Creates a new SourceMapGenerator based on a SourceMapConsumer
20
* @param sourceMapConsumer - The source map to convert
21
*/
22
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
23
24
/**
25
* Add a single mapping from original source line and column to the generated
26
* source's line and column for this source map being created
27
* @param mapping - The mapping object containing position information
28
*/
29
addMapping(mapping: Mapping): void;
30
31
/**
32
* Set the source content for a source file
33
* @param sourceFile - The filename of the original source
34
* @param sourceContent - The content of the original source file
35
*/
36
setSourceContent(sourceFile: string, sourceContent: string): void;
37
38
/**
39
* Applies the mappings of a sub-source-map for a specific source file to the
40
* source map being generated. Each mapping to the supplied source file is
41
* rewritten using the supplied source map.
42
* @param sourceMapConsumer - The source map to be applied
43
* @param sourceFile - Optional filename of the source file
44
* @param sourceMapPath - Optional dirname of the path to the source map
45
*/
46
applySourceMap(
47
sourceMapConsumer: SourceMapConsumer,
48
sourceFile?: string,
49
sourceMapPath?: string
50
): void;
51
52
/**
53
* Render the source map as a JSON string
54
*/
55
toString(): string;
56
57
/**
58
* Export the source map as a raw object
59
*/
60
toJSON(): RawSourceMap;
61
}
62
63
interface StartOfSourceMap {
64
/** The filename of the generated source */
65
file?: string;
66
/** A root for all relative URLs in this source map */
67
sourceRoot?: string;
68
/** Skip validation of mappings */
69
skipValidation?: boolean;
70
}
71
72
interface Mapping {
73
/** An object with the generated line and column positions */
74
generated: Position;
75
/** An object with the original line and column positions */
76
original: Position;
77
/** The original source file (relative to the sourceRoot) */
78
source: string;
79
/** An optional original token name for this mapping */
80
name?: string;
81
}
82
83
interface Position {
84
line: number; // 1-based line number
85
column: number; // 0-based column number
86
}
87
88
interface RawSourceMap {
89
version: number;
90
sources: string[];
91
names: string[];
92
sourceRoot?: string;
93
sourcesContent?: string[];
94
mappings: string;
95
file: string;
96
}
97
```
98
99
**Usage Examples:**
100
101
```typescript
102
import { SourceMapGenerator } from "source-map";
103
104
// Create a new source map
105
const map = new SourceMapGenerator({
106
file: "bundled.js",
107
sourceRoot: "http://example.com/"
108
});
109
110
// Add mappings during code generation
111
map.addMapping({
112
generated: { line: 1, column: 0 },
113
source: "input.js",
114
original: { line: 1, column: 0 }
115
});
116
117
map.addMapping({
118
generated: { line: 1, column: 18 },
119
source: "input.js",
120
original: { line: 1, column: 11 },
121
name: "add"
122
});
123
124
// Set source content
125
map.setSourceContent("input.js", "function add(a,b){return a+b}");
126
127
// Generate the source map
128
const sourceMapJSON = map.toString();
129
console.log(sourceMapJSON);
130
```
131
132
### Constructor Configuration
133
134
The SourceMapGenerator constructor accepts an optional configuration object:
135
136
```typescript { .api }
137
interface StartOfSourceMap {
138
/** The filename of the generated source */
139
file?: string;
140
/** A root for all relative URLs in this source map */
141
sourceRoot?: string;
142
/** Skip validation of mappings */
143
skipValidation?: boolean;
144
}
145
```
146
147
**Usage:**
148
149
```typescript
150
const generator = new SourceMapGenerator({
151
file: "output.js", // Generated file name
152
sourceRoot: "/project/src/", // Base path for source files
153
skipValidation: false // Enable mapping validation (default)
154
});
155
```
156
157
### Adding Mappings
158
159
Add individual mappings between generated and original positions:
160
161
```typescript { .api }
162
/**
163
* Add a single mapping from original source line and column to the generated
164
* source's line and column for this source map being created
165
*/
166
addMapping(mapping: Mapping): void;
167
168
interface Mapping {
169
generated: Position; // Required: position in generated code
170
original: Position; // Required: position in original code
171
source: string; // Required: original source file name
172
name?: string; // Optional: original identifier name
173
}
174
```
175
176
**Usage:**
177
178
```typescript
179
// Basic mapping
180
map.addMapping({
181
generated: { line: 10, column: 5 },
182
original: { line: 20, column: 15 },
183
source: "original.js"
184
});
185
186
// Mapping with identifier name
187
map.addMapping({
188
generated: { line: 15, column: 8 },
189
original: { line: 25, column: 12 },
190
source: "original.js",
191
name: "functionName"
192
});
193
```
194
195
### Source Content Management
196
197
Set the content of original source files:
198
199
```typescript { .api }
200
/**
201
* Set the source content for a source file
202
* @param sourceFile - The filename of the original source
203
* @param sourceContent - The content of the original source file
204
*/
205
setSourceContent(sourceFile: string, sourceContent: string): void;
206
```
207
208
**Usage:**
209
210
```typescript
211
// Set content for debugging
212
map.setSourceContent("math.js", `
213
function add(a, b) {
214
return a + b;
215
}
216
`);
217
218
map.setSourceContent("utils.js", `
219
export function format(value) {
220
return String(value);
221
}
222
`);
223
```
224
225
### Applying Sub-Source Maps
226
227
Combine multiple source maps when dealing with transpilation chains:
228
229
```typescript { .api }
230
/**
231
* Applies the mappings of a sub-source-map for a specific source file
232
* @param sourceMapConsumer - The source map to be applied
233
* @param sourceFile - Optional filename of the source file
234
* @param sourceMapPath - Optional dirname of the path to the source map
235
*/
236
applySourceMap(
237
sourceMapConsumer: SourceMapConsumer,
238
sourceFile?: string,
239
sourceMapPath?: string
240
): void;
241
```
242
243
**Usage:**
244
245
```typescript
246
import { SourceMapConsumer, SourceMapGenerator } from "source-map";
247
248
// Apply TypeScript -> JavaScript source map to JavaScript -> minified map
249
const tsToJsMap = await new SourceMapConsumer(typescriptSourceMap);
250
const jsToMinMap = new SourceMapGenerator({ file: "output.min.js" });
251
252
// This creates a direct TypeScript -> minified mapping
253
jsToMinMap.applySourceMap(tsToJsMap, "intermediate.js");
254
```
255
256
### Creating from Existing Consumer
257
258
Convert a SourceMapConsumer back into a generator:
259
260
```typescript { .api }
261
/**
262
* Creates a new SourceMapGenerator based on a SourceMapConsumer
263
* @param sourceMapConsumer - The source map to convert
264
*/
265
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
266
```
267
268
**Usage:**
269
270
```typescript
271
// Load existing source map
272
const consumer = await new SourceMapConsumer(existingSourceMap);
273
274
// Convert to generator for modification
275
const generator = SourceMapGenerator.fromSourceMap(consumer);
276
277
// Add additional mappings
278
generator.addMapping({
279
generated: { line: 100, column: 0 },
280
original: { line: 50, column: 10 },
281
source: "new-file.js"
282
});
283
284
// Clean up consumer
285
consumer.destroy();
286
```
287
288
### Serialization
289
290
Export the source map in various formats:
291
292
```typescript { .api }
293
/**
294
* Render the source map as a JSON string
295
*/
296
toString(): string;
297
298
/**
299
* Export the source map as a raw object
300
*/
301
toJSON(): RawSourceMap;
302
```
303
304
**Usage:**
305
306
```typescript
307
// Get as JSON string for embedding
308
const jsonString = generator.toString();
309
console.log(jsonString);
310
// Output: {"version":3,"sources":["input.js"],"names":[],"mappings":"AAAA","file":"output.js"}
311
312
// Get as object for manipulation
313
const mapObject = generator.toJSON();
314
console.log(mapObject.sources); // ["input.js"]
315
console.log(mapObject.version); // 3
316
```
317
318
## Error Handling
319
320
The SourceMapGenerator validates mappings and throws errors for invalid inputs:
321
322
- **Line numbers must be >= 1** (1-based indexing)
323
- **Column numbers must be >= 0** (0-based indexing)
324
- **Source file names must be provided** for mappings with original positions
325
- **Invalid mapping structure** will throw TypeError
326
327
Example error handling:
328
329
```typescript
330
try {
331
map.addMapping({
332
generated: { line: 0, column: 5 }, // Invalid: line must be >= 1
333
original: { line: 1, column: 0 },
334
source: "test.js"
335
});
336
} catch (error) {
337
console.error("Invalid mapping:", error.message);
338
}
339
```