or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdsource-map-consumption.mdsource-map-generation.mdsource-node-building.md

source-map-generation.mddocs/

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

```