or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-service.mdconfiguration.mdindex.mdplugin-system.mdtesting.md

plugin-system.mddocs/

0

# Plugin System

1

2

Comprehensive plugin system supporting both server-side and client-side plugins with hook management, plugin registration, and execution control.

3

4

## Capabilities

5

6

### Plugin Application Types

7

8

Enumeration defining how plugins are applied and executed.

9

10

```typescript { .api }

11

/**

12

* Plugin application types for different execution patterns

13

*/

14

enum ApplyPluginsType {

15

compose = "compose", // Function composition pattern

16

modify = "modify", // Value modification pattern

17

event = "event" // Event-driven pattern

18

}

19

```

20

21

### Plugin Manager

22

23

Client-side plugin manager for registering and executing plugins with type safety and validation.

24

25

```typescript { .api }

26

/**

27

* Client-side plugin manager for hook registration and execution

28

*/

29

class PluginManager {

30

/**

31

* Creates a new plugin manager instance

32

* @param opts - Configuration with valid hook keys

33

*/

34

constructor(opts: PluginManagerOpts);

35

36

/**

37

* Register a plugin with the manager

38

* @param plugin - Plugin definition with apply methods

39

*/

40

register(plugin: IPlugin): void;

41

42

/**

43

* Get hooks for a specific key, supporting dot notation

44

* @param keyWithDot - Hook key, optionally with member access (e.g., "key.member")

45

* @returns Array of registered hooks for the key

46

*/

47

getHooks(keyWithDot: string): any[];

48

49

/**

50

* Apply plugins for a specific hook key

51

* @param opts - Plugin application options

52

* @returns Result based on application type

53

*/

54

applyPlugins(opts: ApplyPluginsOpts): any;

55

56

/**

57

* Create and initialize a plugin manager with plugins

58

* @param opts - Manager configuration with plugins

59

* @returns Configured plugin manager instance

60

*/

61

static create(opts: CreatePluginManagerOpts): PluginManager;

62

}

63

64

interface PluginManagerOpts {

65

validKeys: string[]; // Array of valid hook keys

66

}

67

68

interface IPlugin {

69

path?: string; // Plugin file path for debugging

70

apply: Record<string, any>; // Hook implementations

71

}

72

73

interface ApplyPluginsOpts {

74

key: string; // Hook key to apply

75

type: ApplyPluginsType; // Application type

76

initialValue?: any; // Initial value for modify type

77

args?: object; // Arguments passed to hooks

78

async?: boolean; // Whether to use async execution

79

}

80

81

interface CreatePluginManagerOpts {

82

validKeys: string[];

83

plugins: IPlugin[];

84

}

85

```

86

87

**Usage Examples:**

88

89

```typescript

90

import { PluginManager, ApplyPluginsType } from "umi/client";

91

92

// Create plugin manager

93

const pluginManager = new PluginManager({

94

validKeys: ["modifyRoutes", "onRouteChange", "render"],

95

});

96

97

// Register a plugin

98

pluginManager.register({

99

path: "./my-plugin.js",

100

apply: {

101

modifyRoutes: (routes) => {

102

return routes.concat([

103

{ path: "/custom", component: "CustomPage" }

104

]);

105

},

106

onRouteChange: ({ location }) => {

107

console.log("Route changed to:", location.pathname);

108

},

109

},

110

});

111

112

// Apply plugins with modify pattern

113

const modifiedRoutes = pluginManager.applyPlugins({

114

key: "modifyRoutes",

115

type: ApplyPluginsType.modify,

116

initialValue: baseRoutes,

117

});

118

119

// Apply plugins with event pattern

120

await pluginManager.applyPlugins({

121

key: "onRouteChange",

122

type: ApplyPluginsType.event,

123

args: { location: { pathname: "/new-route" } },

124

});

125

126

// Create manager with plugins in one step

127

const manager = PluginManager.create({

128

validKeys: ["beforeRender", "afterRender"],

129

plugins: [

130

{

131

apply: {

132

beforeRender: () => console.log("Before render"),

133

afterRender: () => console.log("After render"),

134

},

135

},

136

],

137

});

138

```

139

140

### Plugin Utilities

141

142

Utility functions and exports for plugin development and server-side functionality.

143

144

```typescript { .api }

145

/**

146

* Create server routes for API handling

147

* Re-exported from @umijs/server

148

*/

149

function createServerRoutes(...args: any[]): any;

150

151

/**

152

* Express server instance

153

* Re-exported from @umijs/bundler-utils

154

*/

155

const express: any;

156

157

/**

158

* HTTP proxy middleware for development

159

* Re-exported from @umijs/bundler-utils

160

*/

161

const httpProxyMiddleware: any;

162

163

// All utility functions from @umijs/utils are also available

164

// Including file system utilities, logger, validation, etc.

165

```

166

167

**Usage Examples:**

168

169

```typescript

170

import {

171

createServerRoutes,

172

express,

173

httpProxyMiddleware,

174

logger

175

} from "umi/plugin-utils";

176

177

// Create API routes

178

const routes = createServerRoutes({

179

"/api/users": "./api/users",

180

"/api/auth": "./api/auth",

181

});

182

183

// Use express for custom server setup

184

const app = express();

185

app.use("/api", routes);

186

187

// Add proxy middleware

188

app.use(

189

"/proxy",

190

httpProxyMiddleware({

191

target: "http://localhost:8080",

192

changeOrigin: true,

193

})

194

);

195

196

// Use logger utility

197

logger.info("Plugin initialized successfully");

198

```

199

200

### Client Utilities

201

202

Low-level utilities for client-side plugin functionality.

203

204

```typescript { .api }

205

/**

206

* Assertion utility for runtime validation

207

* @param value - Value to test

208

* @param message - Error message if assertion fails

209

*/

210

function assert(value: any, message: string): void;

211

212

/**

213

* Function composition utility for creating complex operations

214

* @param opts - Composition options with functions and arguments

215

* @returns Composed function

216

*/

217

function compose(opts: ComposeOpts): Function;

218

219

/**

220

* Promise detection utility

221

* @param obj - Object to test for promise-like behavior

222

* @returns True if object has then method

223

*/

224

function isPromiseLike(obj: any): boolean;

225

226

interface ComposeOpts {

227

fns: Function[]; // Functions to compose

228

args?: any; // Arguments to pass through

229

}

230

```

231

232

**Usage Examples:**

233

234

```typescript

235

import { assert, compose, isPromiseLike } from "umi/client";

236

237

// Runtime validation

238

assert(config.routes, "Routes configuration is required");

239

240

// Function composition

241

const pipeline = compose({

242

fns: [validateData, transformData, saveData],

243

args: { strict: true },

244

});

245

246

// Promise detection

247

if (isPromiseLike(result)) {

248

const data = await result;

249

} else {

250

const data = result;

251

}

252

```

253

254

## Plugin Application Patterns

255

256

### Modify Pattern

257

258

Used for transforming values through a chain of plugins:

259

260

```typescript

261

// Synchronous modification

262

const result = pluginManager.applyPlugins({

263

key: "modifyConfig",

264

type: ApplyPluginsType.modify,

265

initialValue: baseConfig,

266

});

267

268

// Asynchronous modification

269

const result = await pluginManager.applyPlugins({

270

key: "modifyConfig",

271

type: ApplyPluginsType.modify,

272

initialValue: baseConfig,

273

async: true,

274

});

275

```

276

277

### Event Pattern

278

279

Used for triggering side effects without return values:

280

281

```typescript

282

// Event execution (all hooks called)

283

await pluginManager.applyPlugins({

284

key: "onBuildComplete",

285

type: ApplyPluginsType.event,

286

args: { buildStats },

287

});

288

```

289

290

### Compose Pattern

291

292

Used for function composition and middleware patterns:

293

294

```typescript

295

// Function composition

296

const composedFn = pluginManager.applyPlugins({

297

key: "middleware",

298

type: ApplyPluginsType.compose,

299

initialValue: baseFn,

300

});

301

302

// Execute composed function

303

const result = composedFn();

304

```

305

306

## Type Definitions

307

308

```typescript { .api }

309

// Plugin application types

310

enum ApplyPluginsType {

311

compose = "compose",

312

modify = "modify",

313

event = "event"

314

}

315

316

// Plugin definition interface

317

interface IPlugin {

318

path?: string;

319

apply: Record<string, any>;

320

}

321

322

// Plugin manager configuration

323

interface PluginManagerOpts {

324

validKeys: string[];

325

}

326

327

// Plugin application options

328

interface ApplyPluginsOpts {

329

key: string;

330

type: ApplyPluginsType;

331

initialValue?: any;

332

args?: object;

333

async?: boolean;

334

}

335

336

// Plugin manager creation options

337

interface CreatePluginManagerOpts {

338

validKeys: string[];

339

plugins: IPlugin[];

340

}

341

342

// Function composition options

343

interface ComposeOpts {

344

fns: Function[];

345

args?: any;

346

}

347

```