or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-vitest--web-worker

Web Worker support for testing in Vitest without requiring JSDom

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@vitest/web-worker@3.2.x

To install, run

npx @tessl/cli install tessl/npm-vitest--web-worker@3.2.0

0

# @vitest/web-worker

1

2

@vitest/web-worker provides Web Worker support for Vitest testing without requiring JSDom. It simulates Web Worker functionality in the same thread, enabling developers to test web worker code in unit tests while maintaining full compatibility with the Web Worker API.

3

4

## Package Information

5

6

- **Package Name**: @vitest/web-worker

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install -D @vitest/web-worker`

10

11

## Core Imports

12

13

**Main entry (side-effect only, no exports):**

14

```typescript

15

import '@vitest/web-worker';

16

```

17

18

**Pure entry for manual setup:**

19

```typescript

20

import { defineWebWorkers } from '@vitest/web-worker/pure';

21

```

22

23

CommonJS (pure entry only):

24

```javascript

25

const { defineWebWorkers } = require('@vitest/web-worker/pure');

26

```

27

28

## Basic Usage

29

30

### Global Setup

31

32

Add to your Vitest configuration for global Web Worker support:

33

34

```typescript

35

import { defineConfig } from 'vitest/node';

36

37

export default defineConfig({

38

test: {

39

setupFiles: ['@vitest/web-worker'],

40

},

41

});

42

```

43

44

### Test Usage

45

46

```typescript

47

import '@vitest/web-worker';

48

import MyWorker from './worker?worker';

49

50

const worker = new MyWorker();

51

worker.postMessage('hello');

52

worker.onmessage = (e) => {

53

console.log(e.data); // 'hello world'

54

};

55

56

// Or with URL-based workers

57

const worker2 = new Worker(new URL('./worker.ts', import.meta.url));

58

```

59

60

## Architecture

61

62

@vitest/web-worker is built around these key components:

63

64

- **Automatic Setup**: Main entry point automatically configures global Worker/SharedWorker

65

- **Pure Setup**: Manual configuration through `defineWebWorkers` function

66

- **Same-thread Simulation**: Workers run in the same thread as tests for synchronous testing

67

- **Message Cloning**: Configurable message cloning strategies (native, ponyfill, none)

68

- **Inline Execution**: Uses VitestExecutor to run worker code in isolated contexts

69

70

## Capabilities

71

72

### Worker Configuration

73

74

Configure Web Worker behavior and message cloning strategies.

75

76

```typescript { .api }

77

/**

78

* Defines Worker and SharedWorker constructors on globalThis

79

* @param options - Optional configuration for worker behavior

80

*/

81

function defineWebWorkers(options?: DefineWorkerOptions): void;

82

83

interface DefineWorkerOptions {

84

/** Cloning strategy for message passing in Worker communication */

85

clone: CloneOption;

86

}

87

88

type CloneOption = 'native' | 'ponyfill' | 'none';

89

```

90

91

### Worker Constructor

92

93

Create simulated Web Workers for testing.

94

95

```typescript { .api }

96

/**

97

* Web Worker constructor that simulates worker behavior in same thread

98

* Available globally after importing '@vitest/web-worker' or calling defineWebWorkers()

99

*/

100

declare class Worker extends EventTarget {

101

/** Message event handler */

102

onmessage: ((event: MessageEvent) => void) | null;

103

/** Message error event handler */

104

onmessageerror: ((event: MessageEvent) => void) | null;

105

/** Error event handler */

106

onerror: ((event: ErrorEvent) => void) | null;

107

108

/**

109

* Create a new Worker instance

110

* @param url - Worker script URL or path

111

* @param options - Worker options including name

112

*/

113

constructor(url: URL | string, options?: WorkerOptions);

114

115

/**

116

* Send a message to the worker

117

* @param data - Data to send

118

* @param transferOrOptions - Transfer options or transferable objects

119

*/

120

postMessage(

121

data: any,

122

transferOrOptions?: StructuredSerializeOptions | Transferable[]

123

): void;

124

125

/** Terminate the worker and clean up resources */

126

terminate(): void;

127

}

128

129

interface WorkerOptions {

130

/** Optional name for the worker */

131

name?: string;

132

}

133

```

134

135

### SharedWorker Constructor

136

137

Create simulated Shared Web Workers for testing.

138

139

```typescript { .api }

140

/**

141

* SharedWorker constructor that simulates shared worker behavior

142

* Available globally after importing '@vitest/web-worker' or calling defineWebWorkers()

143

*/

144

declare class SharedWorker extends EventTarget {

145

/** Communication port for the shared worker */

146

readonly port: MessagePort;

147

/** Error event handler */

148

onerror: ((event: ErrorEvent) => void) | null;

149

150

/**

151

* Create a new SharedWorker instance

152

* @param url - SharedWorker script URL or path

153

* @param options - SharedWorker options or name string

154

*/

155

constructor(url: URL | string, options?: WorkerOptions | string);

156

}

157

```

158

159

### Worker Context API

160

161

API available within worker execution context.

162

163

```typescript { .api }

164

/**

165

* Dedicated Worker Global Scope - available as 'self' within worker context

166

* Compatible with standard DedicatedWorkerGlobalScope interface

167

*/

168

interface DedicatedWorkerGlobalScope {

169

/** Message event handler from main thread */

170

onmessage: ((event: MessageEvent) => void) | null;

171

/** Message error event handler */

172

onmessageerror: ((event: MessageEvent) => void) | null;

173

/** Error event handler */

174

onerror: ((event: ErrorEvent) => void) | null;

175

/** Worker origin */

176

readonly origin: string;

177

/** Worker name */

178

readonly name: string;

179

/** Cross-origin isolation status */

180

readonly crossOriginIsolated: boolean;

181

182

/**

183

* Post message to main thread

184

* @param data - Data to send

185

* @param transferOrOptions - Transfer options or transferable objects

186

*/

187

postMessage(

188

data: any,

189

transferOrOptions?: StructuredSerializeOptions | Transferable[]

190

): void;

191

192

/** Close/terminate the worker */

193

close(): void;

194

195

/** Import scripts (not supported in Vite - throws error) */

196

importScripts(): never;

197

198

/** Reference to worker global scope */

199

readonly self: DedicatedWorkerGlobalScope;

200

}

201

202

/**

203

* Shared Worker Global Scope - available as 'self' within shared worker context

204

* Compatible with standard SharedWorkerGlobalScope interface

205

*/

206

interface SharedWorkerGlobalScope {

207

/** Connect event handler when new clients connect */

208

onconnect: ((event: MessageEvent) => void) | null;

209

/** Worker name */

210

readonly name: string;

211

/** Worker origin */

212

readonly origin: string;

213

/** Cross-origin isolation status */

214

readonly crossOriginIsolated: boolean;

215

216

/** Close the worker port */

217

close(): void;

218

219

/** Import scripts (not supported in Vite - throws error) */

220

importScripts(): never;

221

222

/** Reference to shared worker global scope */

223

readonly self: SharedWorkerGlobalScope;

224

}

225

```

226

227

### Supporting Types

228

229

Types used by the defineWebWorkers function.

230

231

```typescript { .api }

232

/** Message cloning strategy options */

233

type CloneOption = 'native' | 'ponyfill' | 'none';

234

235

/** Configuration options for defining web workers */

236

interface DefineWorkerOptions {

237

/** Message cloning strategy for Worker communication */

238

clone: CloneOption;

239

}

240

```

241

242

## Configuration

243

244

### Environment Variables

245

246

Configure worker behavior through environment variables:

247

248

- `VITEST_WEB_WORKER_CLONE`: Set default cloning strategy (`'native' | 'ponyfill' | 'none'`)

249

250

### Debug Logging

251

252

Enable debug logging with the environment variable:

253

254

```bash

255

DEBUG=vitest:web-worker

256

```

257

258

## Import Patterns

259

260

The package supports various worker import patterns:

261

262

```typescript

263

// Vite worker imports with ?worker suffix

264

import MyWorker from './worker?worker';

265

const worker = new MyWorker();

266

267

// Vite shared worker imports with ?sharedworker suffix

268

import MySharedWorker from './worker?sharedworker';

269

const sharedWorker = new MySharedWorker();

270

271

// URL-based worker creation

272

const worker = new Worker(new URL('./worker.ts', import.meta.url));

273

const sharedWorker = new SharedWorker(new URL('./worker.ts', import.meta.url));

274

```

275

276

## Error Handling

277

278

- **Worker Initialization Errors**: Dispatched as 'error' events on the worker instance

279

- **Message Errors**: Failed message cloning results in 'messageerror' events

280

- **Import Scripts**: Throws error as `importScripts` is not supported in Vite workers

281

282

## Usage Examples

283

284

### Basic Worker Communication

285

286

```typescript

287

import '@vitest/web-worker';

288

289

// worker.ts

290

self.onmessage = (e) => {

291

self.postMessage(`${e.data} world`);

292

};

293

294

// test file

295

import MyWorker from './worker?worker';

296

297

const worker = new MyWorker();

298

worker.postMessage('hello');

299

worker.onmessage = (e) => {

300

expect(e.data).toBe('hello world');

301

};

302

```

303

304

### SharedWorker Communication

305

306

```typescript

307

import '@vitest/web-worker';

308

309

// shared-worker.ts

310

self.onconnect = (e) => {

311

const port = e.ports[0];

312

port.onmessage = (event) => {

313

port.postMessage(event.data);

314

};

315

};

316

317

// test file

318

import MySharedWorker from './shared-worker?sharedworker';

319

320

const worker = new MySharedWorker();

321

worker.port.postMessage('test');

322

worker.port.onmessage = (e) => {

323

expect(e.data).toBe('test');

324

};

325

```

326

327

### Custom Cloning Configuration

328

329

```typescript

330

import { defineWebWorkers } from '@vitest/web-worker/pure';

331

332

// Configure with no message cloning for performance

333

defineWebWorkers({ clone: 'none' });

334

335

// Configure with ponyfill cloning for compatibility

336

defineWebWorkers({ clone: 'ponyfill' });

337

338

// Configure with native cloning (requires Node 17+)

339

defineWebWorkers({ clone: 'native' });

340

```

341

342

### Conditional Setup

343

344

```typescript

345

import { defineWebWorkers } from '@vitest/web-worker/pure';

346

347

if (process.env.SUPPORT_WORKERS) {

348

defineWebWorkers({ clone: 'none' });

349

}

350

```

351

352

## Notes

353

354

- Worker does not support `onmessage = () => {}`. Use `self.onmessage = () => {}` instead

355

- Shared worker does not support `onconnect = () => {}`. Use `self.onconnect = () => {}` instead

356

- Transferring Buffer will not change its `byteLength`

357

- Workers have access to the same global space as tests

358

- Requires Node 17+ for native `structuredClone`, otherwise falls back to polyfill or no cloning