or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asset-system.mdbuild-configuration.mdbundle-system.mdenvironment-system.mdfile-system.mdindex.mdplugin-system.md

plugin-system.mddocs/

0

# Plugin System

1

2

Comprehensive plugin interfaces for extending Parcel's build pipeline at every stage, including transformers, resolvers, bundlers, packagers, and more.

3

4

## Capabilities

5

6

### Plugin Base Types

7

8

Core interfaces and utilities shared across all plugin types.

9

10

```typescript { .api }

11

/**

12

* Base plugin configuration provided to all plugins

13

*/

14

interface PluginOptions {

15

/** Input file system */

16

inputFS: FileSystem;

17

/** Output file system */

18

outputFS: FileSystem;

19

/** Build cache */

20

cache: Cache;

21

/** Plugin logger */

22

logger: PluginLogger;

23

/** Package manager */

24

packageManager: PackageManager;

25

/** Worker farm for parallel processing */

26

workerFarm: WorkerFarm;

27

/** Performance tracer */

28

tracer: PluginTracer;

29

/** Build mode */

30

mode: BuildMode;

31

/** Environment variables */

32

env: EnvMap;

33

/** Feature flags */

34

featureFlags: FeatureFlags;

35

/** Hot module replacement port */

36

hmrPort?: number;

37

/** Whether HMR is enabled */

38

hmrOptions?: HMROptions;

39

/** Development server options */

40

serveOptions?: ServerOptions;

41

}

42

43

/**

44

* Plugin logger interface

45

*/

46

interface PluginLogger {

47

/** Log verbose information */

48

verbose(message: string): void;

49

/** Log informational message */

50

info(message: string): void;

51

/** Log general message */

52

log(message: string): void;

53

/** Log warning message */

54

warn(message: string): void;

55

/** Log error message */

56

error(message: string): void;

57

}

58

59

/**

60

* Performance tracing interface

61

*/

62

interface PluginTracer {

63

/** Create a performance measurement */

64

createMeasurement(name: string, category?: string): TraceMeasurement;

65

}

66

67

/**

68

* Performance measurement interface

69

*/

70

interface TraceMeasurement {

71

/** End the measurement */

72

end(): void;

73

}

74

```

75

76

### Transformer Plugin

77

78

Transform assets during the build process (e.g., TypeScript to JavaScript, SCSS to CSS).

79

80

```typescript { .api }

81

/**

82

* Transformer plugin interface

83

*/

84

interface Transformer<ConfigType = any> {

85

/** Load configuration for this transformer */

86

loadConfig?(opts: {

87

config: Config;

88

options: PluginOptions;

89

}): Promise<ConfigType> | ConfigType;

90

91

/** Check if AST can be reused from previous transformation */

92

canReuseAST?(opts: {

93

ast: AST;

94

options: PluginOptions;

95

}): boolean;

96

97

/** Parse source code into AST */

98

parse?(opts: {

99

asset: MutableAsset;

100

config: ConfigType;

101

options: PluginOptions;

102

}): Promise<AST> | AST;

103

104

/** Transform the asset */

105

transform(opts: {

106

asset: MutableAsset;

107

config: ConfigType;

108

options: PluginOptions;

109

}): Promise<Array<TransformerResult>> | Array<TransformerResult>;

110

111

/** Post-process after all transformations */

112

postProcess?(opts: {

113

assets: Array<MutableAsset>;

114

config: ConfigType;

115

options: PluginOptions;

116

}): Promise<Array<TransformerResult>> | Array<TransformerResult>;

117

118

/** Generate final code from AST */

119

generate?(opts: {

120

asset: Asset;

121

ast: AST;

122

options: PluginOptions;

123

}): Promise<GenerateOutput> | GenerateOutput;

124

}

125

126

/**

127

* Transformer result type

128

*/

129

type TransformerResult = MutableAsset | Asset;

130

131

/**

132

* Code generation output

133

*/

134

interface GenerateOutput {

135

/** Generated code */

136

content: string;

137

/** Source map */

138

map?: SourceMap;

139

}

140

```

141

142

### Resolver Plugin

143

144

Resolve import specifiers to absolute file paths.

145

146

```typescript { .api }

147

/**

148

* Resolver plugin interface

149

*/

150

interface Resolver<ConfigType = any> {

151

/** Load configuration for this resolver */

152

loadConfig?(opts: {

153

config: Config;

154

options: PluginOptions;

155

}): Promise<ConfigType> | ConfigType;

156

157

/** Resolve a dependency to a file path */

158

resolve(opts: {

159

dependency: Dependency;

160

options: PluginOptions;

161

config: ConfigType;

162

specifier: DependencySpecifier;

163

pipeline: ?string;

164

}): Promise<?ResolveResult> | ?ResolveResult;

165

}

166

167

/**

168

* Resolution result

169

*/

170

interface ResolveResult {

171

/** Resolved file path */

172

filePath?: FilePath;

173

/** Asset pipeline to use */

174

pipeline?: string;

175

/** Invalidation dependencies */

176

invalidateOnFileChange?: Array<FilePath>;

177

/** Invalidation on file creation */

178

invalidateOnFileCreate?: Array<FileCreateInvalidation>;

179

/** Environment variable invalidations */

180

invalidateOnEnvChange?: Array<string>;

181

/** Side effects information */

182

sideEffects?: boolean;

183

/** Code information */

184

code?: string;

185

/** Query string */

186

query?: URLSearchParams;

187

/** Asset priority */

188

priority?: DependencyPriority;

189

}

190

```

191

192

### Bundler Plugin

193

194

Group assets into bundles for optimal loading performance.

195

196

```typescript { .api }

197

/**

198

* Bundler plugin interface

199

*/

200

interface Bundler<ConfigType = any> {

201

/** Load configuration for this bundler */

202

loadConfig?(opts: {

203

config: Config;

204

options: PluginOptions;

205

}): Promise<ConfigType> | ConfigType;

206

207

/** Create bundles from the asset graph */

208

bundle(opts: {

209

bundleGraph: MutableBundleGraph;

210

config: ConfigType;

211

options: PluginOptions;

212

}): Promise<void> | void;

213

214

/** Optimize bundles after creation */

215

optimize?(opts: {

216

bundleGraph: MutableBundleGraph;

217

config: ConfigType;

218

options: PluginOptions;

219

}): Promise<void> | void;

220

}

221

```

222

223

### Namer Plugin

224

225

Generate names for bundles and assets.

226

227

```typescript { .api }

228

/**

229

* Namer plugin interface

230

*/

231

interface Namer<ConfigType = any> {

232

/** Load configuration for this namer */

233

loadConfig?(opts: {

234

config: Config;

235

options: PluginOptions;

236

}): Promise<ConfigType> | ConfigType;

237

238

/** Generate name for a bundle */

239

name(opts: {

240

bundle: Bundle;

241

bundleGraph: BundleGraph<NamedBundle>;

242

config: ConfigType;

243

options: PluginOptions;

244

}): Promise<?string> | ?string;

245

}

246

```

247

248

### Runtime Plugin

249

250

Inject runtime code into bundles for features like hot module replacement.

251

252

```typescript { .api }

253

/**

254

* Runtime plugin interface

255

*/

256

interface Runtime<ConfigType = any> {

257

/** Load configuration for this runtime */

258

loadConfig?(opts: {

259

config: Config;

260

options: PluginOptions;

261

}): Promise<ConfigType> | ConfigType;

262

263

/** Apply runtime modifications to bundle */

264

apply(opts: {

265

bundle: NamedBundle;

266

bundleGraph: BundleGraph<NamedBundle>;

267

config: ConfigType;

268

options: PluginOptions;

269

}): Promise<void | RuntimeAsset> | void | RuntimeAsset;

270

}

271

272

/**

273

* Runtime asset for injection

274

*/

275

interface RuntimeAsset {

276

/** Runtime code */

277

code: string;

278

/** Asset type */

279

filePath: FilePath;

280

/** Environment */

281

env?: Environment;

282

/** Dependencies */

283

dependency?: Dependency;

284

}

285

```

286

287

### Packager Plugin

288

289

Package bundles into final output files.

290

291

```typescript { .api }

292

/**

293

* Packager plugin interface

294

*/

295

interface Packager<ConfigType = any, BundleConfigType = any> {

296

/** Load configuration for this packager */

297

loadConfig?(opts: {

298

config: Config;

299

options: PluginOptions;

300

}): Promise<ConfigType> | ConfigType;

301

302

/** Load bundle-specific configuration */

303

loadBundleConfig?(opts: {

304

bundle: NamedBundle;

305

bundleGraph: BundleGraph<NamedBundle>;

306

config: ConfigType;

307

options: PluginOptions;

308

}): Promise<BundleConfigType> | BundleConfigType;

309

310

/** Package the bundle */

311

package(opts: {

312

bundle: NamedBundle;

313

bundleGraph: BundleGraph<NamedBundle>;

314

getInlineBundleContents: (bundle: Bundle, bundleGraph: BundleGraph<NamedBundle>) => Promise<{contents: Blob}>;

315

getSourceMapReference: (map: ?SourceMap) => Promise<?string>;

316

config: ConfigType;

317

bundleConfig: BundleConfigType;

318

options: PluginOptions;

319

}): Promise<BundleResult> | BundleResult;

320

}

321

322

/**

323

* Bundle packaging result

324

*/

325

interface BundleResult {

326

/** Bundle contents */

327

contents: Blob;

328

/** Source map */

329

map?: SourceMap;

330

}

331

```

332

333

### Optimizer Plugin

334

335

Optimize packaged bundles (minification, compression, etc.).

336

337

```typescript { .api }

338

/**

339

* Optimizer plugin interface

340

*/

341

interface Optimizer<ConfigType = any, BundleConfigType = any> {

342

/** Load configuration for this optimizer */

343

loadConfig?(opts: {

344

config: Config;

345

options: PluginOptions;

346

}): Promise<ConfigType> | ConfigType;

347

348

/** Load bundle-specific configuration */

349

loadBundleConfig?(opts: {

350

bundle: NamedBundle;

351

bundleGraph: BundleGraph<NamedBundle>;

352

config: ConfigType;

353

options: PluginOptions;

354

}): Promise<BundleConfigType> | BundleConfigType;

355

356

/** Optimize the bundle */

357

optimize(opts: {

358

bundle: NamedBundle;

359

bundleGraph: BundleGraph<NamedBundle>;

360

contents: Blob;

361

map?: SourceMap;

362

config: ConfigType;

363

bundleConfig: BundleConfigType;

364

options: PluginOptions;

365

}): Promise<BundleResult> | BundleResult;

366

}

367

```

368

369

### Compressor Plugin

370

371

Compress optimized bundles for final output.

372

373

```typescript { .api }

374

/**

375

* Compressor plugin interface

376

*/

377

interface Compressor {

378

/** Compress bundle contents */

379

compress(opts: {

380

stream: Readable;

381

options: PluginOptions;

382

}): Promise<Readable> | Readable;

383

}

384

```

385

386

### Validator Plugin

387

388

Validate assets and report errors or warnings.

389

390

```typescript { .api }

391

/**

392

* Single-threaded validator plugin

393

*/

394

interface DedicatedThreadValidator {

395

/** Validate an asset */

396

validate(opts: {

397

asset: Asset;

398

options: PluginOptions;

399

config: any;

400

}): Promise<ValidateResult> | ValidateResult;

401

}

402

403

/**

404

* Multi-threaded validator plugin

405

*/

406

interface MultiThreadValidator {

407

/** Validate multiple assets */

408

validateAll(opts: {

409

assets: Array<Asset>;

410

options: PluginOptions;

411

config: any;

412

}): Promise<Array<ValidateResult>> | Array<ValidateResult>;

413

}

414

415

/**

416

* Validator result

417

*/

418

interface ValidateResult {

419

/** Validation warnings */

420

warnings: Array<Diagnostic>;

421

/** Validation errors */

422

errors: Array<Diagnostic>;

423

}

424

```

425

426

### Reporter Plugin

427

428

Report build events and results.

429

430

```typescript { .api }

431

/**

432

* Reporter plugin interface

433

*/

434

interface Reporter {

435

/** Report a build event */

436

report(opts: {

437

event: ReporterEvent;

438

options: PluginOptions;

439

}): Promise<void> | void;

440

}

441

442

/**

443

* Reporter event types

444

*/

445

type ReporterEvent =

446

| BuildStartEvent

447

| BuildProgressEvent

448

| BuildSuccessEvent

449

| BuildFailureEvent

450

| WatchStartEvent

451

| WatchEndEvent

452

| LogEvent

453

| ValidationEvent

454

| CacheEvent

455

| TraceEvent;

456

```

457

458

**Usage Examples:**

459

460

```typescript

461

import type { Transformer, PluginOptions, MutableAsset } from '@parcel/types';

462

463

// Implement a custom transformer

464

class MyTransformer implements Transformer {

465

async transform({ asset, options }: {

466

asset: MutableAsset;

467

options: PluginOptions;

468

}) {

469

const code = await asset.getCode();

470

471

// Transform the code

472

const transformedCode = `// Transformed by MyTransformer\n${code}`;

473

asset.setCode(transformedCode);

474

475

// Log transformation

476

options.logger.info(`Transformed ${asset.filePath}`);

477

478

return [asset];

479

}

480

}

481

482

// Implement a custom resolver

483

class MyResolver implements Resolver {

484

async resolve({ dependency, options }) {

485

if (dependency.specifier.startsWith('virtual:')) {

486

// Handle virtual modules

487

return {

488

filePath: `/virtual/${dependency.specifier.slice(8)}.js`,

489

code: `export default "Virtual module: ${dependency.specifier}";`

490

};

491

}

492

493

return null; // Let other resolvers handle it

494

}

495

}

496

497

// Implement a custom reporter

498

class MyReporter implements Reporter {

499

async report({ event, options }) {

500

if (event.type === 'buildSuccess') {

501

options.logger.info(`Build completed with ${event.bundleGraph.getBundles().length} bundles`);

502

}

503

}

504

}

505

```