or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-manipulation.mdcli-interface.mdcore-operations.mdindex.mdparser-configuration.mdsource-maps.md

source-maps.mddocs/

0

# Source Maps

1

2

Automatic source map generation for tracking original source locations through transformations with character-level precision.

3

4

## Capabilities

5

6

### Automatic Source Map Generation

7

8

Recast automatically generates high-resolution source maps when reprinting modified ASTs, tracking which parts of the output correspond to which parts of the original source.

9

10

```typescript { .api }

11

/**

12

* Enable source map generation by providing source file information

13

*/

14

interface SourceMapOptions {

15

/** Original source file name */

16

sourceFileName?: string | null;

17

/** Output source map name */

18

sourceMapName?: string | null;

19

/** Root directory for relative source paths */

20

sourceRoot?: string | null;

21

/** Input source map for composition */

22

inputSourceMap?: string | null;

23

}

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

import { parse, print } from "recast";

30

31

// Parse with source file information

32

const ast = parse(sourceCode, {

33

sourceFileName: "input.js"

34

});

35

36

// Transform AST

37

// ... modify ast ...

38

39

// Generate source map during printing

40

const result = print(ast, {

41

sourceMapName: "output.js"

42

});

43

44

console.log(result.code); // Generated code

45

console.log(result.map); // Source map object

46

```

47

48

### Source Map Composition

49

50

Compose multiple source maps when chaining transformations.

51

52

**Usage Example:**

53

54

```typescript

55

import { parse, print } from "recast";

56

57

// First transformation

58

const ast1 = parse(originalCode, {

59

sourceFileName: "original.js"

60

});

61

// ... transform ast1 ...

62

const result1 = print(ast1, {

63

sourceMapName: "intermediate.js"

64

});

65

66

// Second transformation using previous source map

67

const ast2 = parse(result1.code, {

68

sourceFileName: "intermediate.js"

69

});

70

// ... transform ast2 ...

71

const result2 = print(ast2, {

72

sourceMapName: "final.js",

73

inputSourceMap: JSON.stringify(result1.map)

74

});

75

76

// result2.map now contains composed source map from original to final

77

```

78

79

### Print Result with Source Maps

80

81

The result object returned by print operations when source maps are enabled.

82

83

```typescript { .api }

84

interface PrintResultType {

85

/** The generated source code */

86

code: string;

87

/** Source map object (when sourceMapName provided) */

88

map?: SourceMap;

89

/** Deprecated string conversion */

90

toString(): string;

91

}

92

93

interface SourceMap {

94

/** Source map version (always 3) */

95

version: number;

96

/** Generated file name */

97

file: string;

98

/** Root directory for source paths */

99

sourceRoot?: string;

100

/** Array of source file names */

101

sources: string[];

102

/** Array of source content (optional) */

103

sourcesContent?: Array<string | null>;

104

/** Encoded mapping data */

105

mappings: string;

106

/** Array of symbol names */

107

names: string[];

108

}

109

```

110

111

### Source Map Consumer Usage

112

113

Using generated source maps with the Mozilla source-map library.

114

115

**Usage Example:**

116

117

```typescript

118

import { parse, print } from "recast";

119

import { SourceMapConsumer } from "source-map";

120

121

const ast = parse(sourceCode, {

122

sourceFileName: "input.js"

123

});

124

125

// Transform code

126

// ... modify ast ...

127

128

const result = print(ast, {

129

sourceMapName: "output.js"

130

});

131

132

// Use source map to find original positions

133

const consumer = new SourceMapConsumer(result.map);

134

135

// Find original position for generated position

136

const originalPosition = consumer.originalPositionFor({

137

line: 5,

138

column: 10

139

});

140

141

console.log(originalPosition);

142

// {

143

// source: 'input.js',

144

// line: 3,

145

// column: 15,

146

// name: null

147

// }

148

```

149

150

### High-Resolution Mapping

151

152

Recast generates character-by-character mappings for maximum debugging precision.

153

154

**Characteristics:**

155

- **Character-level precision:** Maps individual characters rather than just lines

156

- **Preserve unchanged code:** Original source locations maintained for unmodified code

157

- **Automatic tracking:** No manual mapping required - handled during reprinting

158

- **Multiple source support:** Can track code from multiple source files in one output

159

160

**Example mapping data:**

161

162

```typescript

163

// Original code spans multiple files

164

const file1Code = "function add(a, b) { return a + b; }";

165

const file2Code = "const multiply = (x, y) => x * y;";

166

167

// Parse and combine

168

const ast1 = parse(file1Code, { sourceFileName: "math1.js" });

169

const ast2 = parse(file2Code, { sourceFileName: "math2.js" });

170

171

// Combine ASTs

172

ast1.program.body.push(...ast2.program.body);

173

174

// Generate combined source map

175

const result = print(ast1, {

176

sourceMapName: "combined.js"

177

});

178

179

// result.map.sources = ["math1.js", "math2.js"]

180

// Mappings track which output characters came from which source file

181

```

182

183

## Source Map Configuration

184

185

### File Path Configuration

186

187

Configure how source paths are handled in generated source maps.

188

189

```typescript { .api }

190

interface SourceMapConfig {

191

/** Name of the original source file */

192

sourceFileName?: string | null;

193

/** Name for the generated source map */

194

sourceMapName?: string | null;

195

/** Root directory for resolving relative source paths */

196

sourceRoot?: string | null;

197

}

198

```

199

200

**Usage Examples:**

201

202

```typescript

203

// Absolute paths

204

const result = print(ast, {

205

sourceFileName: "/project/src/input.js",

206

sourceMapName: "/project/dist/output.js",

207

sourceRoot: "/project"

208

});

209

210

// Relative paths (recommended)

211

const result = print(ast, {

212

sourceFileName: "src/input.js",

213

sourceMapName: "dist/output.js",

214

sourceRoot: ".."

215

});

216

```

217

218

### Source Content Embedding

219

220

Source maps can optionally include the original source content.

221

222

```typescript

223

// Source map will include sourcesContent array

224

// with original source code embedded

225

const result = print(ast, {

226

sourceFileName: "input.js",

227

sourceMapName: "output.js"

228

});

229

230

// result.map.sourcesContent[0] contains original source

231

```

232

233

## Integration with Build Tools

234

235

### Webpack Integration

236

237

Using recast-generated source maps with Webpack.

238

239

```typescript

240

// webpack.config.js

241

module.exports = {

242

module: {

243

rules: [

244

{

245

test: /\.js$/,

246

use: {

247

loader: 'recast-loader', // hypothetical loader

248

options: {

249

sourceMap: true,

250

sourceRoot: path.resolve(__dirname, 'src')

251

}

252

}

253

}

254

]

255

},

256

devtool: 'source-map'

257

};

258

```

259

260

### Gulp Integration

261

262

Composing recast transformations with Gulp source maps.

263

264

```typescript

265

const gulp = require('gulp');

266

const sourcemaps = require('gulp-sourcemaps');

267

const through2 = require('through2');

268

const { parse, print } = require('recast');

269

270

function recastTransform() {

271

return through2.obj(function(file, enc, callback) {

272

const ast = parse(file.contents.toString(), {

273

sourceFileName: file.relative

274

});

275

276

// Transform AST

277

// ... modify ast ...

278

279

const result = print(ast, {

280

sourceMapName: file.relative

281

});

282

283

file.contents = Buffer.from(result.code);

284

file.sourceMap = result.map;

285

286

callback(null, file);

287

});

288

}

289

290

gulp.task('transform', () => {

291

return gulp.src('src/*.js')

292

.pipe(sourcemaps.init())

293

.pipe(recastTransform())

294

.pipe(sourcemaps.write('.'))

295

.pipe(gulp.dest('dist'));

296

});

297

```

298

299

## Important Notes

300

301

### Source Map Accuracy

302

303

- **Format preservation:** Source maps accurately reflect preserved original formatting

304

- **Transformation tracking:** Modified code sections get new mappings while preserved sections maintain original mappings

305

- **Multi-file support:** Can track transformations across multiple input files

306

- **Character precision:** Maps individual characters for precise debugging

307

308

### Performance Considerations

309

310

- **Memory usage:** Source maps add memory overhead proportional to source size

311

- **Generation time:** Source map creation adds processing time during printing

312

- **File size:** Generated source maps can be large for heavily transformed code

313

314

### Debugging Benefits

315

316

- **Stack traces:** Error stack traces point to original source locations

317

- **Breakpoints:** Debugger breakpoints work on original source

318

- **Variable names:** Original variable names preserved in debugging info

319

- **Code navigation:** IDE navigation works with original source structure