or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

babel-integration.mdcoverage-reading.mdindex.mdinstrumentation.md
tile.json

babel-integration.mddocs/

0

# Babel Plugin Integration

1

2

Integration functionality for incorporating coverage instrumentation directly into Babel transformation pipelines. This approach is used by babel-plugin-istanbul and enables seamless coverage tracking during existing build processes.

3

4

## Capabilities

5

6

### Program Visitor

7

8

Creates a Babel AST visitor for instrumenting code during Babel transformation. Returns an object with `enter` and `exit` methods for Program-level AST manipulation.

9

10

```javascript { .api }

11

/**

12

* Creates a babel adaptor for instrumentation

13

* @param types - An instance of babel-types (typically from Babel's API)

14

* @param sourceFilePath - The path to source file for coverage tracking

15

* @param opts - Additional instrumentation options

16

* @returns Object with enter and exit functions for Babel Program visitor

17

*/

18

function programVisitor(

19

types: object,

20

sourceFilePath?: string,

21

opts?: ProgramVisitorOptions

22

): ProgramVisitorResult;

23

24

interface ProgramVisitorOptions {

25

/** The global coverage variable name (default: "__coverage__") */

26

coverageVariable?: string;

27

/** Report boolean value of logical expressions (default: false) */

28

reportLogic?: boolean;

29

/** The global coverage variable scope (default: "this") */

30

coverageGlobalScope?: string;

31

/** Use an evaluated function to find coverageGlobalScope (default: true) */

32

coverageGlobalScopeFunc?: boolean;

33

/** Names of methods to ignore by default on classes (default: []) */

34

ignoreClassMethods?: string[];

35

/** The input source map that maps uninstrumented code back to original code */

36

inputSourceMap?: object;

37

}

38

39

interface ProgramVisitorResult {

40

/** Function to call when entering Program AST node */

41

enter(path: object): void;

42

/** Function to call when exiting Program AST node */

43

exit(path: object): ExitResult;

44

}

45

46

interface ExitResult {

47

/** The file coverage object created for the source file */

48

fileCoverage: object;

49

/** Any source mapping URL found when processing the file */

50

sourceMappingURL?: string;

51

}

52

```

53

54

**Usage Examples:**

55

56

```javascript

57

const { programVisitor } = require("istanbul-lib-instrument");

58

const { transformSync } = require("@babel/core");

59

const types = require("@babel/types");

60

61

// Create a simple Babel plugin using programVisitor

62

function createCoveragePlugin() {

63

return function({ types }) {

64

const visitor = programVisitor(types, 'example.js', {

65

coverageVariable: '__coverage__',

66

reportLogic: true

67

});

68

69

return {

70

visitor: {

71

Program: {

72

enter: visitor.enter,

73

exit(path) {

74

const result = visitor.exit(path);

75

console.log('Coverage data:', result.fileCoverage);

76

if (result.sourceMappingURL) {

77

console.log('Source map URL:', result.sourceMappingURL);

78

}

79

}

80

}

81

}

82

};

83

};

84

}

85

86

// Use the plugin with Babel

87

const code = `

88

function greet(name) {

89

if (name) {

90

return "Hello, " + name;

91

}

92

return "Hello, World!";

93

}

94

`;

95

96

const result = transformSync(code, {

97

plugins: [createCoveragePlugin()],

98

filename: 'greet.js'

99

});

100

101

console.log(result.code);

102

```

103

104

### Babel Plugin Integration Pattern

105

106

The programVisitor is designed to integrate with existing Babel pipelines without requiring separate instrumentation steps.

107

108

```javascript { .api }

109

// Typical babel-plugin-istanbul usage pattern

110

function babelPluginIstanbul(babel) {

111

const { types } = babel;

112

113

return {

114

visitor: {

115

Program: {

116

enter(path, state) {

117

const visitor = programVisitor(types, state.filename, state.opts);

118

visitor.enter(path);

119

},

120

exit(path, state) {

121

const visitor = programVisitor(types, state.filename, state.opts);

122

const result = visitor.exit(path);

123

// Store coverage data for later use

124

state.coverageData = result.fileCoverage;

125

}

126

}

127

}

128

};

129

}

130

```

131

132

**Usage Examples:**

133

134

```javascript

135

const { programVisitor } = require("istanbul-lib-instrument");

136

137

// Custom Babel transformation with coverage

138

function transformWithCoverage(code, filename, options = {}) {

139

const { transformSync } = require("@babel/core");

140

141

let coverageData = null;

142

143

const result = transformSync(code, {

144

filename,

145

plugins: [

146

function({ types }) {

147

const visitor = programVisitor(types, filename, options);

148

149

return {

150

visitor: {

151

Program: {

152

enter: visitor.enter,

153

exit(path) {

154

const exitResult = visitor.exit(path);

155

coverageData = exitResult.fileCoverage;

156

}

157

}

158

}

159

};

160

}

161

]

162

});

163

164

return {

165

code: result.code,

166

coverage: coverageData,

167

map: result.map

168

};

169

}

170

171

// Usage

172

const { code, coverage } = transformWithCoverage(

173

'function add(a, b) { return a + b; }',

174

'math.js',

175

{ reportLogic: true }

176

);

177

```

178

179

### Advanced Integration Scenarios

180

181

Integration with complex Babel transformation pipelines and build tools.

182

183

```javascript { .api }

184

// Integration with multiple Babel plugins

185

function createInstrumentationPipeline(options = {}) {

186

return [

187

// Pre-instrumentation plugins (e.g., TypeScript, JSX)

188

'@babel/plugin-transform-typescript',

189

'@babel/plugin-transform-react-jsx',

190

191

// Coverage instrumentation

192

function({ types }) {

193

const visitor = programVisitor(types, options.filename, {

194

coverageVariable: options.coverageVariable,

195

reportLogic: options.reportLogic,

196

inputSourceMap: options.inputSourceMap

197

});

198

199

return {

200

visitor: {

201

Program: {

202

enter: visitor.enter,

203

exit: visitor.exit

204

}

205

}

206

};

207

},

208

209

// Post-instrumentation plugins

210

'@babel/plugin-transform-modules-commonjs'

211

];

212

}

213

```

214

215

**Usage Examples:**

216

217

```javascript

218

const { transformSync } = require("@babel/core");

219

220

// Transform TypeScript with coverage

221

const tsCode = `

222

interface User {

223

name: string;

224

age: number;

225

}

226

227

function createUser(name: string, age: number): User {

228

if (age < 0) {

229

throw new Error("Age cannot be negative");

230

}

231

return { name, age };

232

}

233

`;

234

235

const result = transformSync(tsCode, {

236

filename: 'user.ts',

237

plugins: createInstrumentationPipeline({

238

filename: 'user.ts',

239

reportLogic: true,

240

coverageVariable: '__coverage__'

241

})

242

});

243

```

244

245

### Source Map Integration

246

247

Handling source maps during Babel transformation with coverage instrumentation.

248

249

```javascript { .api }

250

// Source map preservation with instrumentation

251

function instrumentWithSourceMap(code, filename, existingSourceMap) {

252

const { transformSync } = require("@babel/core");

253

const { programVisitor } = require("istanbul-lib-instrument");

254

255

let finalCoverage = null;

256

257

const result = transformSync(code, {

258

filename,

259

inputSourceMap: existingSourceMap,

260

sourceMaps: true,

261

plugins: [

262

function({ types }) {

263

const visitor = programVisitor(types, filename, {

264

inputSourceMap: existingSourceMap

265

});

266

267

return {

268

visitor: {

269

Program: {

270

enter: visitor.enter,

271

exit(path) {

272

const exitResult = visitor.exit(path);

273

finalCoverage = exitResult.fileCoverage;

274

}

275

}

276

}

277

};

278

}

279

]

280

});

281

282

return {

283

code: result.code,

284

map: result.map,

285

coverage: finalCoverage

286

};

287

}

288

```

289

290

## Configuration Options

291

292

### Basic Options

293

294

- **coverageVariable**: Global variable name for storing coverage data

295

- **reportLogic**: Whether to track logical expression evaluation (&&, ||)

296

- **coverageGlobalScope**: Scope attachment for coverage variable

297

298

### Advanced Options

299

300

- **ignoreClassMethods**: Array of class method names to exclude from coverage

301

- **inputSourceMap**: Source map for mapping coverage back to original source

302

- **coverageGlobalScopeFunc**: Use function evaluation for scope determination

303

304

## Integration Best Practices

305

306

### Build Tool Integration

307

308

```javascript

309

// Webpack integration example

310

module.exports = {

311

module: {

312

rules: [{

313

test: /\.js$/,

314

use: {

315

loader: 'babel-loader',

316

options: {

317

plugins: [

318

function({ types }) {

319

return {

320

visitor: {

321

Program: {

322

enter(path, state) {

323

const visitor = programVisitor(types, state.filename);

324

visitor.enter(path);

325

},

326

exit(path, state) {

327

const visitor = programVisitor(types, state.filename);

328

visitor.exit(path);

329

}

330

}

331

}

332

};

333

}

334

]

335

}

336

}

337

}]

338

}

339

};

340

```

341

342

### Development vs Production

343

344

```javascript

345

// Conditional instrumentation based on environment

346

function createConditionalPlugin() {

347

if (process.env.NODE_ENV === 'test') {

348

return function({ types }) {

349

const visitor = programVisitor(types, 'unknown.js', {

350

reportLogic: true,

351

debug: true

352

});

353

354

return {

355

visitor: {

356

Program: {

357

enter: visitor.enter,

358

exit: visitor.exit

359

}

360

}

361

};

362

};

363

}

364

365

// Return no-op plugin for production

366

return function() {

367

return { visitor: {} };

368

};

369

}

370

```

371

372

## Error Handling

373

374

The programVisitor handles errors during AST transformation and provides meaningful error messages.

375

376

```javascript

377

const { programVisitor } = require("istanbul-lib-instrument");

378

379

function safeInstrumentation(types, filename, options) {

380

try {

381

return programVisitor(types, filename, options);

382

} catch (error) {

383

console.error(`Failed to create program visitor for ${filename}:`, error);

384

// Return no-op visitor

385

return {

386

enter() {},

387

exit() {

388

return { fileCoverage: null };

389

}

390

};

391

}

392

}

393

```