or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-bundling.mdindex.mdplugin-system.mdutilities.mdwatch-mode.md

utilities.mddocs/

0

# Utilities

1

2

AST parsing, logging, and debugging utilities for advanced use cases and tool development. Rollup provides several utility functions as separate entry points for specialized scenarios.

3

4

## Capabilities

5

6

### AST Parsing

7

8

Standalone AST parsing utilities that use Rollup's internal parser, available for external tooling and plugin development.

9

10

```typescript { .api }

11

/**

12

* Synchronous AST parsing utility

13

* @param input - JavaScript/TypeScript code to parse

14

* @param options - Parser configuration options

15

* @returns Parsed AST program node

16

*/

17

function parseAst(

18

input: string,

19

options?: {

20

/** Allow return statements outside functions */

21

allowReturnOutsideFunction?: boolean;

22

/** Enable JSX parsing */

23

jsx?: boolean;

24

}

25

): ProgramNode;

26

27

/**

28

* Asynchronous AST parsing utility with cancellation support

29

* @param input - JavaScript/TypeScript code to parse

30

* @param options - Parser configuration options with abort signal

31

* @returns Promise resolving to parsed AST program node

32

*/

33

function parseAstAsync(

34

input: string,

35

options?: {

36

/** Allow return statements outside functions */

37

allowReturnOutsideFunction?: boolean;

38

/** Enable JSX parsing */

39

jsx?: boolean;

40

/** Abort signal for cancellation */

41

signal?: AbortSignal;

42

}

43

): Promise<ProgramNode>;

44

```

45

46

**Usage Examples:**

47

48

```typescript

49

import { parseAst, parseAstAsync } from "rollup/parseAst";

50

51

// Synchronous parsing

52

const code = `

53

import { foo } from './bar.js';

54

export default function main() {

55

return foo();

56

}

57

`;

58

59

const ast = parseAst(code);

60

console.log(ast.type); // 'Program'

61

console.log(ast.body.length); // 2 (import + export)

62

63

// JSX parsing

64

const jsxCode = `

65

function Component() {

66

return <div>Hello World</div>;

67

}

68

`;

69

70

const jsxAst = parseAst(jsxCode, { jsx: true });

71

72

// Asynchronous parsing with cancellation

73

const controller = new AbortController();

74

75

const asyncAst = await parseAstAsync(code, {

76

allowReturnOutsideFunction: true,

77

signal: controller.signal

78

});

79

80

// Cancel parsing if needed

81

// controller.abort();

82

```

83

84

### Log Filtering

85

86

Utility for creating log filtering functions based on filter expressions, useful for custom logging implementations and debugging.

87

88

```typescript { .api }

89

/**

90

* Creates a log filtering function based on filter expressions

91

* @param filters - Array of filter strings

92

* @returns Function that tests whether a log should be included

93

*/

94

function getLogFilter(filters: string[]): (log: RollupLog) => boolean;

95

```

96

97

**Usage Examples:**

98

99

```typescript

100

import { getLogFilter } from "rollup/getLogFilter";

101

102

// Create filter for warnings only

103

const warningsOnly = getLogFilter(['level:warn']);

104

105

// Create filter excluding specific plugins

106

const excludePlugin = getLogFilter(['!plugin:my-plugin']);

107

108

// Complex filtering with multiple conditions

109

const complexFilter = getLogFilter([

110

'level:warn&!code:UNUSED_EXTERNAL_IMPORT',

111

'level:error'

112

]);

113

114

// Usage with custom logging

115

const customLogger = (level, log) => {

116

const filter = getLogFilter(['!plugin:verbose-plugin']);

117

118

if (filter(log)) {

119

console.log(`[${level}] ${log.message}`);

120

}

121

};

122

123

// Filter pattern examples:

124

// 'level:warn' - Only warnings

125

// 'plugin:typescript' - Only from typescript plugin

126

// 'code:CIRCULAR_DEPENDENCY' - Only circular dependency warnings

127

// '!plugin:commonjs' - Exclude commonjs plugin logs

128

// 'level:warn&plugin:typescript' - Warnings from typescript plugin only

129

// 'message:*deprecat*' - Messages containing 'deprecat'

130

```

131

132

### Version Information

133

134

Current version constant for runtime version checking and compatibility verification.

135

136

```typescript { .api }

137

/**

138

* Current Rollup version string

139

*/

140

const VERSION: string;

141

```

142

143

**Usage Examples:**

144

145

```typescript

146

import { VERSION } from "rollup";

147

148

console.log(`Using Rollup ${VERSION}`);

149

150

// Version compatibility checking

151

const requiredVersion = '4.0.0';

152

const currentMajor = parseInt(VERSION.split('.')[0]);

153

const requiredMajor = parseInt(requiredVersion.split('.')[0]);

154

155

if (currentMajor < requiredMajor) {

156

throw new Error(`Requires Rollup ${requiredVersion}+, got ${VERSION}`);

157

}

158

159

// Plugin compatibility

160

const myPlugin = () => ({

161

name: 'my-plugin',

162

buildStart() {

163

console.log(`Plugin initialized with Rollup ${VERSION}`);

164

}

165

});

166

```

167

168

## Advanced Utility Usage

169

170

### Custom AST Processing

171

172

```typescript

173

import { parseAst } from "rollup/parseAst";

174

175

function analyzeImports(code) {

176

const ast = parseAst(code);

177

const imports = [];

178

179

for (const node of ast.body) {

180

if (node.type === 'ImportDeclaration') {

181

imports.push({

182

source: node.source.value,

183

specifiers: node.specifiers.map(spec => ({

184

type: spec.type,

185

imported: spec.imported?.name,

186

local: spec.local.name

187

}))

188

});

189

}

190

}

191

192

return imports;

193

}

194

195

// Usage

196

const code = `

197

import React from 'react';

198

import { useState, useEffect } from 'react';

199

import * as utils from './utils.js';

200

`;

201

202

const imports = analyzeImports(code);

203

console.log(imports);

204

// [

205

// { source: 'react', specifiers: [{ type: 'ImportDefaultSpecifier', local: 'React' }] },

206

// { source: 'react', specifiers: [

207

// { type: 'ImportSpecifier', imported: 'useState', local: 'useState' },

208

// { type: 'ImportSpecifier', imported: 'useEffect', local: 'useEffect' }

209

// ]},

210

// { source: './utils.js', specifiers: [{ type: 'ImportNamespaceSpecifier', local: 'utils' }]}

211

// ]

212

```

213

214

### Sophisticated Log Filtering

215

216

```typescript

217

import { getLogFilter } from "rollup/getLogFilter";

218

219

class LogManager {

220

constructor(filterExpressions = []) {

221

this.filter = getLogFilter(filterExpressions);

222

this.logs = [];

223

}

224

225

handleLog(level, log) {

226

if (this.filter(log)) {

227

const entry = {

228

timestamp: Date.now(),

229

level,

230

...log

231

};

232

233

this.logs.push(entry);

234

this.outputLog(level, entry);

235

}

236

}

237

238

outputLog(level, log) {

239

const color = {

240

warn: '\x1b[33m', // Yellow

241

error: '\x1b[31m', // Red

242

info: '\x1b[36m', // Cyan

243

debug: '\x1b[37m' // White

244

}[level] || '\x1b[0m';

245

246

console.log(`${color}[${level.toUpperCase()}] ${log.message}\x1b[0m`);

247

248

if (log.frame) {

249

console.log(log.frame);

250

}

251

}

252

253

getFilteredLogs(additionalFilters = []) {

254

const filter = getLogFilter(additionalFilters);

255

return this.logs.filter(filter);

256

}

257

258

exportLogs(format = 'json') {

259

switch (format) {

260

case 'json':

261

return JSON.stringify(this.logs, null, 2);

262

case 'csv':

263

return this.logs.map(log =>

264

`${log.timestamp},${log.level},"${log.message}",${log.plugin || ''}"`

265

).join('\n');

266

default:

267

return this.logs;

268

}

269

}

270

}

271

272

// Usage

273

const logManager = new LogManager([

274

'!code:UNUSED_EXTERNAL_IMPORT', // Ignore unused external import warnings

275

'level:warn|level:error' // Only warnings and errors

276

]);

277

278

// In rollup config

279

export default {

280

input: 'src/main.js',

281

output: { file: 'dist/bundle.js', format: 'esm' },

282

onLog: (level, log, defaultHandler) => {

283

logManager.handleLog(level, log);

284

}

285

};

286

```

287

288

### Development Tools Integration

289

290

```typescript

291

import { parseAst, getLogFilter, VERSION } from "rollup";

292

293

class RollupDevTools {

294

constructor() {

295

this.logFilter = getLogFilter(['level:debug']);

296

this.buildStats = {

297

version: VERSION,

298

builds: [],

299

errors: []

300

};

301

}

302

303

analyzeBundleStructure(code) {

304

try {

305

const ast = parseAst(code);

306

return {

307

imports: this.extractImports(ast),

308

exports: this.extractExports(ast),

309

functions: this.extractFunctions(ast),

310

complexity: this.calculateComplexity(ast)

311

};

312

} catch (error) {

313

console.error('AST analysis failed:', error);

314

return null;

315

}

316

}

317

318

extractImports(ast) {

319

return ast.body

320

.filter(node => node.type === 'ImportDeclaration')

321

.map(node => ({

322

source: node.source.value,

323

specifiers: node.specifiers.length,

324

dynamic: false

325

}));

326

}

327

328

extractExports(ast) {

329

return ast.body

330

.filter(node =>

331

node.type === 'ExportDefaultDeclaration' ||

332

node.type === 'ExportNamedDeclaration'

333

)

334

.map(node => ({

335

type: node.type,

336

name: this.getExportName(node)

337

}));

338

}

339

340

extractFunctions(ast) {

341

const functions = [];

342

343

const walk = (node) => {

344

if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') {

345

functions.push({

346

name: node.id?.name || 'anonymous',

347

params: node.params.length,

348

async: node.async,

349

generator: node.generator

350

});

351

}

352

353

// Recursively walk child nodes

354

for (const key in node) {

355

const child = node[key];

356

if (Array.isArray(child)) {

357

child.forEach(walk);

358

} else if (child && typeof child === 'object' && child.type) {

359

walk(child);

360

}

361

}

362

};

363

364

walk(ast);

365

return functions;

366

}

367

368

calculateComplexity(ast) {

369

// Simple complexity calculation based on node types

370

let complexity = 0;

371

372

const walk = (node) => {

373

if (['IfStatement', 'ForStatement', 'WhileStatement', 'SwitchCase'].includes(node.type)) {

374

complexity++;

375

}

376

377

for (const key in node) {

378

const child = node[key];

379

if (Array.isArray(child)) {

380

child.forEach(walk);

381

} else if (child && typeof child === 'object' && child.type) {

382

walk(child);

383

}

384

}

385

};

386

387

walk(ast);

388

return complexity;

389

}

390

391

recordBuild(inputOptions, outputOptions, result) {

392

this.buildStats.builds.push({

393

timestamp: Date.now(),

394

input: inputOptions.input,

395

output: outputOptions.file || outputOptions.dir,

396

format: outputOptions.format,

397

duration: result.duration,

398

size: result.output[0]?.code?.length || 0

399

});

400

}

401

402

generateReport() {

403

return {

404

...this.buildStats,

405

summary: {

406

totalBuilds: this.buildStats.builds.length,

407

totalErrors: this.buildStats.errors.length,

408

averageBuildTime: this.buildStats.builds.reduce((sum, build) =>

409

sum + (build.duration || 0), 0) / this.buildStats.builds.length,

410

formats: [...new Set(this.buildStats.builds.map(b => b.format))]

411

}

412

};

413

}

414

}

415

416

// Usage

417

const devTools = new RollupDevTools();

418

419

export default {

420

input: 'src/main.js',

421

output: { file: 'dist/bundle.js', format: 'esm' },

422

plugins: [{

423

name: 'dev-tools',

424

buildStart(options) {

425

console.log(`Build starting with Rollup ${VERSION}`);

426

},

427

generateBundle(options, bundle) {

428

const mainChunk = Object.values(bundle).find(chunk => chunk.type === 'chunk');

429

if (mainChunk) {

430

const analysis = devTools.analyzeBundleStructure(mainChunk.code);

431

console.log('Bundle analysis:', analysis);

432

}

433

}

434

}]

435

};

436

```

437

438

## Core Types

439

440

```typescript { .api }

441

/**

442

* AST Program node type

443

*/

444

type ProgramNode = RollupAstNode<estree.Program>;

445

446

interface RollupAstNode<T> extends Omit<T, 'loc' | 'range' | 'leadingComments' | 'trailingComments' | 'innerComments' | 'comments'> {

447

start: number;

448

end: number;

449

}

450

451

/**

452

* Error interface extending RollupLog

453

*/

454

interface RollupError extends RollupLog {

455

/** Error name */

456

name?: string;

457

/** Stack trace */

458

stack?: string;

459

/** Files being watched when error occurred */

460

watchFiles?: string[];

461

}

462

463

/**

464

* Log entry interface

465

*/

466

interface RollupLog {

467

/** Log message */

468

message: string;

469

/** Log code identifier */

470

code?: string;

471

/** Related file ID */

472

id?: string;

473

/** Source location */

474

loc?: {

475

column: number;

476

file?: string;

477

line: number;

478

};

479

/** Code frame showing context */

480

frame?: string;

481

/** Related plugin name */

482

plugin?: string;

483

/** Additional metadata */

484

meta?: any;

485

/** Source position */

486

pos?: number;

487

/** URL reference */

488

url?: string;

489

/** Error binding */

490

binding?: string;

491

/** Error cause */

492

cause?: unknown;

493

/** Module exporter */

494

exporter?: string;

495

/** Related module IDs */

496

ids?: string[];

497

/** Export names */

498

names?: string[];

499

/** Plugin-specific code */

500

pluginCode?: unknown;

501

/** Re-exporter module */

502

reexporter?: string;

503

/** Stack trace */

504

stack?: string;

505

}

506

507

/**

508

* Logging function type

509

*/

510

type LoggingFunction = (log: RollupLog | string | (() => RollupLog | string)) => void;

511

512

/**

513

* Log levels

514

*/

515

type LogLevel = 'warn' | 'info' | 'debug';

516

```