or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdindex.mdplatform-abstraction.mdplugin-context.mdplugin-system.md

plugin-context.mddocs/

0

# Plugin Context API

1

2

Complete plugin development API providing access to the service layer's capabilities including comprehensive lifecycle hooks, method registration, build customization, and validation support.

3

4

## Capabilities

5

6

### Plugin Context Interface

7

8

The primary API interface available to all plugins providing access to the kernel's capabilities and state.

9

10

```typescript { .api }

11

/**

12

* Plugin context interface defining the complete API available to plugins

13

*/

14

interface IPluginContext {

15

/** Map of all registered plugins */

16

plugins: Map<string, IPlugin>;

17

/** Map of all registered platforms */

18

platforms: Map<string, IPlatform>;

19

/** Path configuration object */

20

paths: IPaths;

21

/** Runtime options from command execution */

22

runOpts: any;

23

/** Helper utilities from @tarojs/helper package */

24

helper: typeof helper;

25

/** Runner utilities from @tarojs/runner-utils package */

26

runnerUtils: typeof runnerUtils;

27

/** Initial project configuration */

28

initialConfig: IProjectConfig;

29

30

// Registration methods

31

register(hook: IHook): void;

32

registerMethod(arg: string | { name: string; fn?: Func }, fn?: Func): void;

33

registerCommand(command: ICommand): void;

34

registerPlatform(platform: IPlatform): void;

35

36

// Hook execution

37

applyPlugins(args: string | { name: string; initialVal?: any; opts?: any }): Promise<any>;

38

39

// Validation

40

addPluginOptsSchema(fn: (joi: joi.Root) => void): void;

41

}

42

```

43

44

### Hook Registration

45

46

Register hooks to participate in the build process and customize behavior at specific lifecycle points.

47

48

```typescript { .api }

49

/**

50

* Register a hook to be called during the build process

51

* @param hook - Hook configuration object

52

*/

53

register(hook: IHook): void;

54

55

interface IHook {

56

/** Hook name (e.g., 'onBuildStart', 'modifyWebpackChain') */

57

name: string;

58

/** Plugin ID that registered this hook (automatically set) */

59

plugin?: string;

60

/** Hook implementation function */

61

fn: Func;

62

/** Execute this hook before another hook */

63

before?: string;

64

/** Execution stage (lower numbers execute first) */

65

stage?: number;

66

}

67

```

68

69

**Usage Examples:**

70

71

```typescript

72

// Build lifecycle hook

73

ctx.register({

74

name: 'onBuildStart',

75

fn: async (opts) => {

76

console.log('Build starting for platform:', opts.platform);

77

}

78

});

79

80

// Configuration modification hook

81

ctx.register({

82

name: 'modifyWebpackChain',

83

fn: (opts, { chain }) => {

84

chain.plugin('MyPlugin').use(MyWebpackPlugin, [options]);

85

return { chain };

86

}

87

});

88

89

// Hook with execution order control

90

ctx.register({

91

name: 'modifyWebpackChain',

92

stage: 100, // Execute later

93

fn: (opts, { chain }) => {

94

// This runs after hooks with lower stage numbers

95

}

96

});

97

```

98

99

### Build Lifecycle Hooks

100

101

Pre-defined lifecycle hooks available for build process customization.

102

103

```typescript { .api }

104

/**

105

* Hook called when build process starts

106

*/

107

onBuildStart(fn: Func): void;

108

109

/**

110

* Hook called when build process finishes (after each save in watch mode)

111

*/

112

onBuildFinish(fn: Func): void;

113

114

/**

115

* Hook called when build process completes (once after initial build)

116

*/

117

onBuildComplete(fn: Func): void;

118

119

/**

120

* Hook called during compiler.make phase

121

*/

122

onCompilerMake(fn: (args: { compilation: Webpack.Compilation; compiler: Webpack.Compiler; plugin: any }) => void): void;

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

// Build start hook

129

ctx.onBuildStart(async (opts) => {

130

console.log('Starting build...');

131

// Initialize build resources

132

});

133

134

// Build finish hook (called on each rebuild)

135

ctx.onBuildFinish(async (opts) => {

136

console.log('Build finished');

137

// Cleanup or post-processing

138

});

139

140

// Build complete hook (called once)

141

ctx.onBuildComplete(async (opts) => {

142

console.log('Initial build complete, ready for development');

143

// Open browser, start additional services, etc.

144

});

145

```

146

147

### Configuration Modification Hooks

148

149

Hooks for modifying various aspects of the build configuration.

150

151

```typescript { .api }

152

/**

153

* Modify App configuration before compilation

154

*/

155

modifyAppConfig(fn: (args: { appConfig: AppConfig }) => void): void;

156

157

/**

158

* Modify webpack configuration using webpack-chain

159

*/

160

modifyWebpackChain(fn: (args: { chain: Chain; webpack: typeof Webpack; data?: IModifyChainData }) => void): void;

161

162

/**

163

* Modify Vite configuration

164

*/

165

modifyViteConfig(fn: (args: { viteConfig: any; data?: IModifyChainData; viteCompilerContext: any }) => void): void;

166

167

/**

168

* Modify build assets after compilation

169

*/

170

modifyBuildAssets(fn: (args: { assets: any; miniPlugin: any }) => void): void;

171

172

/**

173

* Modify mini-program configuration files

174

*/

175

modifyMiniConfigs(fn: (args: { configMap: IMiniFilesConfig }) => void): void;

176

177

/**

178

* Modify runner options before execution

179

*/

180

modifyRunnerOpts(fn: (args: { opts: any }) => void): void;

181

```

182

183

**Usage Examples:**

184

185

```typescript

186

// Modify webpack configuration

187

ctx.modifyWebpackChain(({ chain, webpack }) => {

188

// Add custom plugin

189

chain.plugin('MyCustomPlugin')

190

.use(MyCustomPlugin, [{ option: 'value' }]);

191

192

// Modify loader

193

chain.module

194

.rule('custom-rule')

195

.test(/\.custom$/)

196

.use('custom-loader')

197

.loader('custom-loader');

198

});

199

200

// Modify app configuration

201

ctx.modifyAppConfig(({ appConfig }) => {

202

appConfig.pages.push('pages/custom/index');

203

appConfig.window.navigationBarTitleText = 'Custom Title';

204

});

205

206

// Modify build assets

207

ctx.modifyBuildAssets(({ assets, miniPlugin }) => {

208

// Add or modify generated files

209

assets['custom-file.json'] = JSON.stringify({ custom: 'data' });

210

});

211

```

212

213

### Command Registration

214

215

Register custom commands that can be executed via the CLI or programmatically.

216

217

```typescript { .api }

218

/**

219

* Register a custom command

220

* @param command - Command configuration object

221

*/

222

registerCommand(command: ICommand): void;

223

224

interface ICommand extends IHook {

225

/** Command alias for CLI */

226

alias?: string;

227

/** CLI options mapping for help display */

228

optionsMap?: Record<string, string>;

229

/** Usage examples for help display */

230

synopsisList?: string[];

231

}

232

```

233

234

**Usage Examples:**

235

236

```typescript

237

// Basic command

238

ctx.registerCommand({

239

name: 'analyze',

240

fn: async (opts) => {

241

console.log('Analyzing project...');

242

// Analysis logic

243

}

244

});

245

246

// Command with CLI options and help

247

ctx.registerCommand({

248

name: 'deploy',

249

alias: 'd',

250

optionsMap: {

251

'--env [env]': 'deployment environment',

252

'--dry-run': 'preview deployment without executing'

253

},

254

synopsisList: [

255

'taro deploy --env production',

256

'taro deploy --dry-run'

257

],

258

fn: async (opts) => {

259

const { env, dryRun } = opts.options;

260

// Deployment logic

261

}

262

});

263

```

264

265

### Platform Registration

266

267

Register custom platforms that can be targeted for builds.

268

269

```typescript { .api }

270

/**

271

* Register a custom platform

272

* @param platform - Platform configuration object

273

*/

274

registerPlatform(platform: IPlatform): void;

275

276

interface IPlatform extends IHook {

277

/** Configuration section name to use for this platform */

278

useConfigName?: string;

279

}

280

```

281

282

**Usage Examples:**

283

284

```typescript

285

// Register custom platform

286

ctx.registerPlatform({

287

name: 'my-platform',

288

useConfigName: 'mini', // Use mini-program config section

289

fn: (opts) => {

290

const platform = new MyCustomPlatform(ctx, opts.config);

291

return platform.start();

292

}

293

});

294

295

// Register platform with custom config

296

ctx.registerPlatform({

297

name: 'electron',

298

useConfigName: 'electron',

299

fn: (opts) => {

300

// Electron platform build logic

301

}

302

});

303

```

304

305

### Method Registration

306

307

Register methods that can be called by other plugins.

308

309

```typescript { .api }

310

/**

311

* Register a method that can be called by other plugins

312

* @param arg - Method name or configuration object

313

* @param fn - Method implementation (if first arg is string)

314

*/

315

registerMethod(arg: string | { name: string; fn?: Func }, fn?: Func): void;

316

```

317

318

**Usage Examples:**

319

320

```typescript

321

// Register utility method

322

ctx.registerMethod('getProjectInfo', () => {

323

return {

324

name: ctx.initialConfig.projectName,

325

framework: ctx.initialConfig.framework

326

};

327

});

328

329

// Register method with object syntax

330

ctx.registerMethod({

331

name: 'customTransform',

332

fn: (data) => {

333

// Custom transformation logic

334

return transformedData;

335

}

336

});

337

338

// Use registered method in another plugin

339

const projectInfo = ctx.getProjectInfo();

340

```

341

342

### Plugin Options Validation

343

344

Add validation schema for plugin options using Joi.

345

346

```typescript { .api }

347

/**

348

* Add validation schema for plugin options

349

* @param fn - Function that receives Joi instance and returns schema

350

*/

351

addPluginOptsSchema(fn: (joi: joi.Root) => void): void;

352

```

353

354

**Usage Examples:**

355

356

```typescript

357

// Add options validation

358

ctx.addPluginOptsSchema((joi) => {

359

return joi.object({

360

outputDir: joi.string().required(),

361

minify: joi.boolean().default(true),

362

target: joi.string().valid('es5', 'es6').default('es5'),

363

plugins: joi.array().items(joi.string())

364

});

365

});

366

367

// Plugin with validated options

368

export default (ctx, opts) => {

369

// opts is now validated and has defaults applied

370

console.log(opts.outputDir); // Required string

371

console.log(opts.minify); // Boolean, defaults to true

372

};

373

```

374

375

### Hook Execution

376

377

Execute registered hooks programmatically within plugins.

378

379

```typescript { .api }

380

/**

381

* Execute registered hooks with optional initial value and options

382

* @param args - Hook name or configuration object

383

* @returns Promise resolving to final transformed value

384

*/

385

applyPlugins(args: string | { name: string; initialVal?: any; opts?: any }): Promise<any>;

386

```

387

388

**Usage Examples:**

389

390

```typescript

391

// Execute simple hook

392

await ctx.applyPlugins('customHook');

393

394

// Execute hook with initial value (modify pattern)

395

const modifiedConfig = await ctx.applyPlugins({

396

name: 'modifyCustomConfig',

397

initialVal: baseConfig,

398

opts: { context: 'build' }

399

});

400

401

// Execute hook and collect results (add pattern)

402

const additionalItems = await ctx.applyPlugins({

403

name: 'addCustomItems',

404

initialVal: [],

405

opts: { filter: 'active' }

406

});

407

```

408

409

## Context Properties

410

411

```typescript { .api }

412

interface IPaths {

413

/** Current command execution directory */

414

appPath: string;

415

/** Project configuration directory */

416

configPath: string;

417

/** Project source code directory */

418

sourcePath: string;

419

/** Build output directory */

420

outputPath: string;

421

/** Node modules directory */

422

nodeModulesPath: string;

423

}

424

425

interface IPlugin {

426

/** Unique plugin identifier */

427

id: string;

428

/** Plugin file path */

429

path: string;

430

/** Plugin configuration options */

431

opts: any;

432

/** Plugin type (Plugin or Preset) */

433

type: PluginType;

434

/** Plugin apply function */

435

apply: Func;

436

}

437

```

438

439

## Plugin Development Best Practices

440

441

### Plugin Structure Template

442

443

```typescript

444

export default (ctx, opts = {}) => {

445

// Add options validation

446

ctx.addPluginOptsSchema((joi) => {

447

return joi.object({

448

// Define your options schema

449

});

450

});

451

452

// Register hooks

453

ctx.onBuildStart(async () => {

454

// Build start logic

455

});

456

457

ctx.modifyWebpackChain(({ chain }) => {

458

// Webpack modifications

459

});

460

461

// Register custom methods

462

ctx.registerMethod('myUtility', () => {

463

// Utility logic

464

});

465

};

466

```

467

468

### Error Handling in Hooks

469

470

```typescript

471

ctx.register({

472

name: 'onBuildStart',

473

fn: async (opts) => {

474

try {

475

// Build logic that might fail

476

await riskyOperation();

477

} catch (error) {

478

ctx.helper.printLog('ERROR', 'Build failed', error.message);

479

throw error; // Re-throw to stop build

480

}

481

}

482

});

483

```