0
# Source Map Generation
1
2
Core functionality for creating source maps from raw mappings with support for Metro's specific requirements, Facebook extensions, and Hermes integration.
3
4
## Capabilities
5
6
### Raw Mappings to Source Map
7
8
Create source maps from raw mappings data, which are arrays of tuples representing the relationship between generated and original code positions.
9
10
```javascript { .api }
11
/**
12
* Creates a source map from modules with raw mappings (synchronous)
13
* @param modules - Array of module objects with mappings and metadata
14
* @param offsetLines - Number of lines to offset in the resulting bundle
15
* @returns Generator instance for creating the final source map
16
*/
17
function fromRawMappings(
18
modules: Array<{
19
map: ?Array<MetroSourceMapSegmentTuple>,
20
functionMap: ?FBSourceFunctionMap,
21
path: string,
22
source: string,
23
code: string,
24
isIgnored: boolean,
25
lineCount?: number
26
}>,
27
offsetLines?: number = 0
28
): Generator;
29
30
/**
31
* Creates a source map from modules with raw mappings (asynchronous, non-blocking)
32
* @param modules - Array of module objects with mappings and metadata
33
* @param offsetLines - Number of lines to offset in the resulting bundle
34
* @returns Promise resolving to Generator instance
35
*/
36
function fromRawMappingsNonBlocking(
37
modules: Array<{
38
map: ?Array<MetroSourceMapSegmentTuple>,
39
functionMap: ?FBSourceFunctionMap,
40
path: string,
41
source: string,
42
code: string,
43
isIgnored: boolean,
44
lineCount?: number
45
}>,
46
offsetLines?: number = 0
47
): Promise<Generator>;
48
```
49
50
**Usage Examples:**
51
52
```javascript
53
const { fromRawMappings, fromRawMappingsNonBlocking } = require("metro-source-map");
54
55
// Synchronous generation
56
const modules = [
57
{
58
map: [
59
[1, 0, 1, 0], // Line 1, Col 0 -> Line 1, Col 0
60
[1, 12, 1, 12, "log"], // Line 1, Col 12 -> Line 1, Col 12, name "log"
61
[2, 0, 2, 0] // Line 2, Col 0 -> Line 2, Col 0
62
],
63
functionMap: null,
64
path: "src/utils.js",
65
source: "console.log('hello');\nmodule.exports = {};",
66
code: "console.log('hello');\nmodule.exports = {};",
67
isIgnored: false,
68
lineCount: 2
69
}
70
];
71
72
const generator = fromRawMappings(modules, 0);
73
const sourceMap = generator.toMap("bundle.js");
74
75
// Asynchronous generation (non-blocking)
76
const generatorAsync = await fromRawMappingsNonBlocking(modules, 0);
77
const sourceMapAsync = generatorAsync.toMap("bundle.js");
78
```
79
80
### Generator Class
81
82
The Generator class is used internally by `fromRawMappings` functions. It is not directly exported but is returned by those functions for building source maps incrementally.
83
84
```javascript { .api }
85
/**
86
* Generator class for creating source maps from raw mappings
87
* (Returned by fromRawMappings functions, not directly constructible)
88
*/
89
class Generator {
90
91
/**
92
* Start processing a new source file
93
* @param file - Path to the source file
94
* @param code - Source code content for the file
95
* @param functionMap - Optional Facebook function map for debugging
96
* @param options - Optional file processing flags
97
*/
98
startFile(
99
file: string,
100
code: string,
101
functionMap?: FBSourceFunctionMap,
102
options?: FileFlags
103
): void;
104
105
/**
106
* End processing of the current source file
107
*/
108
endFile(): void;
109
110
/**
111
* Add a simple mapping (generated position only)
112
* @param line - Generated line number (1-based)
113
* @param column - Generated column number (0-based)
114
*/
115
addSimpleMapping(line: number, column: number): void;
116
117
/**
118
* Add a source mapping (generated to original position)
119
* @param line - Generated line number (1-based)
120
* @param column - Generated column number (0-based)
121
* @param originalLine - Original line number (1-based)
122
* @param originalColumn - Original column number (0-based)
123
*/
124
addSourceMapping(
125
line: number,
126
column: number,
127
originalLine: number,
128
originalColumn: number
129
): void;
130
131
/**
132
* Add a named source mapping (includes symbol name)
133
* @param line - Generated line number (1-based)
134
* @param column - Generated column number (0-based)
135
* @param originalLine - Original line number (1-based)
136
* @param originalColumn - Original column number (0-based)
137
* @param name - Symbol name in original source
138
*/
139
addNamedSourceMapping(
140
line: number,
141
column: number,
142
originalLine: number,
143
originalColumn: number,
144
name: string
145
): void;
146
147
/**
148
* Generate the final source map object
149
* @param file - Optional file name for the generated source map
150
* @param options - Optional generation options
151
* @returns Complete source map object
152
*/
153
toMap(file?: string, options?: {excludeSource?: boolean}): BasicSourceMap;
154
155
/**
156
* Serialize the source map to a JSON string
157
* @param file - Optional file name for the generated source map
158
* @param options - Optional generation options
159
* @returns JSON string representation of the source map
160
*/
161
toString(file?: string, options?: {excludeSource?: boolean}): string;
162
}
163
```
164
165
**Usage Examples:**
166
167
```javascript
168
const { fromRawMappings } = require("metro-source-map");
169
170
// Get Generator instance through fromRawMappings
171
const modules = [/* ... */];
172
const generator = fromRawMappings(modules);
173
174
// Start a file
175
generator.startFile("src/app.js", "console.log('hello');", null, { addToIgnoreList: false });
176
177
// Add mappings
178
generator.addSimpleMapping(1, 0); // Generated only
179
generator.addSourceMapping(1, 8, 1, 8); // Generated -> Original
180
generator.addNamedSourceMapping(1, 12, 1, 12, "console"); // With name
181
182
// End the file
183
generator.endFile();
184
185
// Generate the source map
186
const sourceMap = generator.toMap("dist/bundle.js");
187
console.log(sourceMap.mappings); // Base64 VLQ encoded mappings
188
```
189
190
### Segment Tuple Types
191
192
Raw mapping segments can have 2, 4, or 5 elements representing different levels of mapping detail.
193
194
```javascript { .api }
195
/**
196
* Metro source map segment tuple formats:
197
* - GeneratedCodeMapping: [generatedLine, generatedColumn]
198
* - SourceMapping: [generatedLine, generatedColumn, originalLine, originalColumn]
199
* - SourceMappingWithName: [generatedLine, generatedColumn, originalLine, originalColumn, symbolName]
200
*/
201
type MetroSourceMapSegmentTuple =
202
| [number, number] // Generated position only
203
| [number, number, number, number] // Generated -> Original position
204
| [number, number, number, number, string]; // Generated -> Original position + name
205
206
/**
207
* File processing options
208
*/
209
interface FileFlags {
210
/** Whether to add this file to the ignore list for debugging */
211
addToIgnoreList?: boolean;
212
}
213
```
214
215
## Error Handling
216
217
The generation functions and Generator class methods may throw errors in the following cases:
218
219
- **Invalid mapping format**: When segment tuples don't have 2, 4, or 5 elements
220
- **File processing errors**: When startFile/endFile calls are not properly paired
221
- **Invalid coordinates**: When line/column numbers are negative or invalid
222
223
```javascript
224
try {
225
const generator = fromRawMappings(modules);
226
const sourceMap = generator.toMap();
227
} catch (error) {
228
if (error.message.includes('Invalid mapping')) {
229
console.error('Mapping data is malformed:', error);
230
}
231
}
232
```