| 390 | } |
| 391 | |
| 392 | export function webWorkerPlugin(config: ResolvedConfig): Plugin { |
| 393 | const isBuild = config.command === 'build' |
| 394 | const isWorker = config.isWorker |
| 395 | |
| 396 | workerOutputCaches.set(config, new WorkerOutputCache()) |
| 397 | const emittedAssets = new Set<string>() |
| 398 | |
| 399 | return { |
| 400 | name: 'vite:worker', |
| 401 | |
| 402 | buildStart() { |
| 403 | if (isWorker) return |
| 404 | emittedAssets.clear() |
| 405 | }, |
| 406 | |
| 407 | load: { |
| 408 | filter: { id: workerOrSharedWorkerRE }, |
| 409 | async handler(id) { |
| 410 | const workerMatch = workerOrSharedWorkerRE.exec(id) |
| 411 | if (!workerMatch) return |
| 412 | |
| 413 | const { format } = config.worker |
| 414 | const workerConstructor = |
| 415 | workerMatch[1] === 'sharedworker' ? 'SharedWorker' : 'Worker' |
| 416 | const isBundled = this.environment.config.isBundled |
| 417 | const workerType = isBundled |
| 418 | ? format === 'es' |
| 419 | ? 'module' |
| 420 | : 'classic' |
| 421 | : 'module' |
| 422 | const workerTypeOption = `{ |
| 423 | ${workerType === 'module' ? `type: "module",` : ''} |
| 424 | name: options?.name |
| 425 | }` |
| 426 | |
| 427 | let urlCode: string |
| 428 | if (isBundled) { |
| 429 | if (isWorker && config.bundleChain.at(-1) === cleanUrl(id)) { |
| 430 | urlCode = 'self.location.href' |
| 431 | } else if (inlineRE.test(id)) { |
| 432 | const result = await bundleWorkerEntry(config, id) |
| 433 | for (const file of result.watchedFiles) { |
| 434 | this.addWatchFile(file) |
| 435 | } |
| 436 | |
| 437 | const jsContent = `const jsContent = ${JSON.stringify(result.entryCode)};` |
| 438 | |
| 439 | const code = |
| 440 | // Using blob URL for SharedWorker results in multiple instances of a same worker |
| 441 | workerConstructor === 'Worker' |
| 442 | ? `${jsContent} |
| 443 | const blob = typeof self !== "undefined" && self.Blob && new Blob([${ |
| 444 | // NOTE: Revoke the objURL after creating the worker, otherwise it breaks WebKit-based browsers |
| 445 | workerType === 'classic' |
| 446 | ? `'(self.URL || self.webkitURL).revokeObjectURL(self.location.href);',` |
| 447 | : // `URL` is always available, in `Worker[type="module"]` |
| 448 | `'URL.revokeObjectURL(import.meta.url);',` |
| 449 | }jsContent], { type: "text/javascript;charset=utf-8" }); |