0
# Plugin Management
1
2
Comprehensive plugin management system that handles plugin registration, dependency resolution, lifecycle management, and error handling. The PluginList class manages all aspects of plugin orchestration within Playwright Extra.
3
4
## Capabilities
5
6
### Plugin List Class
7
8
The core plugin management class that handles plugin registration, ordering, dependency resolution, and lifecycle event dispatch.
9
10
```typescript { .api }
11
class PluginList {
12
readonly list: Plugin[];
13
readonly names: string[];
14
15
add(plugin: Plugin): boolean;
16
setDependencyDefaults(dependencyPath: string, opts: any): this;
17
setDependencyResolution(dependencyPath: string, pluginModule: CompatiblePluginModule): this;
18
onPluginError(plugin: Plugin, method: PluginMethodName, err: Error): void;
19
}
20
```
21
22
### Plugin Registration
23
24
Add a new plugin to the list after validating its structure and requirements.
25
26
```typescript { .api }
27
/**
28
* Add a new plugin to the list (after checking if it's well-formed).
29
* @param plugin - Plugin instance to add
30
* @returns true if plugin was added successfully, false otherwise
31
*/
32
add(plugin: Plugin): boolean;
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import { chromium } from "playwright-extra";
39
import StealthPlugin from "puppeteer-extra-plugin-stealth";
40
41
const plugin = StealthPlugin();
42
43
// Plugin is automatically added when using .use()
44
chromium.use(plugin);
45
46
// Direct access to plugin manager
47
const wasAdded = chromium.plugins.add(plugin);
48
console.log(`Plugin added: ${wasAdded}`);
49
```
50
51
### Plugin Inspection
52
53
Access registered plugins and their names.
54
55
```typescript { .api }
56
/**
57
* Get a list of all registered plugins.
58
*/
59
readonly list: Plugin[];
60
61
/**
62
* Get the names of all registered plugins.
63
*/
64
readonly names: string[];
65
```
66
67
**Usage Examples:**
68
69
```typescript
70
import { chromium } from "playwright-extra";
71
72
// Check registered plugins
73
console.log(chromium.plugins.names); // ['stealth', 'recaptcha']
74
75
// Inspect plugin instances
76
chromium.plugins.list.forEach(plugin => {
77
console.log(`Plugin: ${plugin.name}`);
78
console.log(`Requirements: ${Array.from(plugin.requirements || [])}`);
79
});
80
```
81
82
### Dependency Configuration
83
84
Configure default options for plugins that are implicitly required through the dependencies system.
85
86
```typescript { .api }
87
/**
88
* Define default values for plugins implicitly required through the dependencies plugin stanza.
89
* @param dependencyPath - The string by which the dependency is listed (not the plugin name)
90
* @param opts - Default options to apply to the dependency
91
* @returns The PluginList instance for chaining
92
*/
93
setDependencyDefaults(dependencyPath: string, opts: any): this;
94
```
95
96
**Usage Examples:**
97
98
```typescript
99
import { chromium } from "playwright-extra";
100
import StealthPlugin from "puppeteer-extra-plugin-stealth";
101
102
chromium.use(StealthPlugin());
103
104
// Configure stealth sub-plugin defaults
105
chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', {
106
vendor: 'Custom Vendor Name',
107
renderer: 'Custom Renderer Name'
108
});
109
110
// Configure user agent evasion defaults
111
chromium.plugins.setDependencyDefaults('stealth/evasions/user-agent-override', {
112
userAgent: 'Mozilla/5.0 (Custom Browser)'
113
});
114
```
115
116
### Dependency Resolution
117
118
Define custom plugin modules for dependencies to avoid dynamic imports, which is useful for bundlers that have issues with dynamic imports.
119
120
```typescript { .api }
121
/**
122
* Define custom plugin modules for plugins implicitly required through the dependencies plugin stanza.
123
* Using this will prevent dynamic imports from being used, which JS bundlers often have issues with.
124
* @param dependencyPath - The dependency path identifier
125
* @param pluginModule - The plugin module to use for this dependency
126
* @returns The PluginList instance for chaining
127
*/
128
setDependencyResolution(dependencyPath: string, pluginModule: CompatiblePluginModule): this;
129
```
130
131
**Usage Examples:**
132
133
```typescript
134
import { chromium } from "playwright-extra";
135
import StealthPlugin from "puppeteer-extra-plugin-stealth";
136
import WebGLVendorPlugin from "puppeteer-extra-plugin-stealth/evasions/webgl.vendor";
137
138
chromium.use(StealthPlugin());
139
140
// Provide explicit plugin modules to avoid dynamic imports
141
chromium.plugins.setDependencyResolution(
142
'stealth/evasions/webgl.vendor',
143
WebGLVendorPlugin
144
);
145
```
146
147
### Error Handling
148
149
Handle errors that occur during plugin method execution. This method can be overwritten to customize error handling behavior.
150
151
```typescript { .api }
152
/**
153
* Error callback in case calling a plugin method throws an error. Can be overwritten.
154
* @param plugin - The plugin that caused the error
155
* @param method - The method name that was being executed
156
* @param err - The error that occurred
157
*/
158
onPluginError(plugin: Plugin, method: PluginMethodName, err: Error): void;
159
```
160
161
**Usage Examples:**
162
163
```typescript
164
import { chromium } from "playwright-extra";
165
166
// Customize error handling
167
chromium.plugins.onPluginError = (plugin, method, error) => {
168
console.error(`Plugin ${plugin.name} failed during ${method}:`, error);
169
170
// Could implement retry logic, disable plugin, etc.
171
if (error.message.includes('timeout')) {
172
console.log('Timeout error, continuing execution...');
173
} else {
174
throw error; // Re-throw critical errors
175
}
176
};
177
```
178
179
### Plugin Lifecycle Dispatch
180
181
The plugin manager handles dispatching lifecycle events to registered plugins.
182
183
**Non-blocking dispatch** (fires events without waiting):
184
185
```typescript { .api }
186
dispatch<TMethod extends PluginMethodName>(
187
method: TMethod,
188
...args: Parameters<PluginMethodFn<TMethod>>
189
): void;
190
```
191
192
**Blocking dispatch** (waits for all plugins, supports waterfall pattern):
193
194
```typescript { .api }
195
async dispatchBlocking<TMethod extends PluginMethodName>(
196
method: TMethod,
197
...args: Parameters<PluginMethodFn<TMethod>>
198
): Promise<ReturnType<PluginMethodFn<TMethod>>>;
199
```
200
201
**Usage Examples:**
202
203
```typescript
204
// These methods are used internally by PlaywrightExtra
205
// but can be called directly for custom scenarios
206
207
const plugins = chromium.plugins;
208
209
// Dispatch non-blocking event
210
plugins.dispatch('onPageCreated', page);
211
212
// Dispatch blocking event with modification support
213
const modifiedOptions = await plugins.dispatchBlocking('beforeLaunch', options);
214
```
215
216
### Plugin Ordering and Dependencies
217
218
The plugin manager automatically handles plugin ordering based on requirements and resolves plugin dependencies.
219
220
**Plugin ordering** - Plugins with `runLast` requirement are moved to the end:
221
222
```typescript
223
// Plugin with runLast requirement will be executed last
224
const plugin = {
225
name: 'cleanup-plugin',
226
requirements: new Set(['runLast']),
227
// ... other plugin properties
228
};
229
```
230
231
**Dependency resolution** - Plugins can declare dependencies that are automatically loaded:
232
233
```typescript
234
// Plugin declaring dependencies
235
const plugin = {
236
name: 'parent-plugin',
237
dependencies: new Set(['stealth/evasions/webgl.vendor']),
238
// ... other plugin properties
239
};
240
```
241
242
## Core Types
243
244
```typescript { .api }
245
interface Plugin extends PuppeteerExtraPlugin {
246
_isPuppeteerExtraPlugin: boolean;
247
name: string;
248
noPuppeteerShim?: boolean;
249
requirements?: PluginRequirements;
250
dependencies?: PluginDependencies;
251
data?: PluginData[];
252
getDataFromPlugins?(name?: string): void;
253
plugins?: CompatiblePlugin[];
254
}
255
256
type PluginMethodName = keyof PluginLifecycleMethods;
257
258
type PluginMethodFn<TMethod extends PluginMethodName> =
259
TMethod extends keyof PluginLifecycleMethods
260
? PluginLifecycleMethods[TMethod]
261
: never;
262
263
type PluginRequirements = Set<'launch' | 'headful' | 'dataFromPlugins' | 'runLast'>;
264
265
type PluginDependencies = Set<string> | Map<string, any> | string[];
266
267
type CompatiblePluginModule = (...args: any[]) => CompatiblePlugin;
268
269
interface PluginData {
270
name: string | { [key: string]: any };
271
value: { [key: string]: any };
272
}
273
```