From dbe765b092fc6cc97616e83869e8db8ef483c175 Mon Sep 17 00:00:00 2001
From: fi3ework
Date: Wed, 8 Mar 2023 01:31:39 +0800
Subject: [PATCH] fix: correct shared worker test
---
docs/config/worker-options.md | 2 +-
packages/vite/src/node/config.ts | 4 +--
packages/vite/src/node/plugins/worker.ts | 23 ++++++++++++++--
.../worker/__tests__/es/es-worker.spec.ts | 2 +-
.../inline-url/inline-url-worker.spec.ts | 9 +++++--
.../__tests__/inline-url/vite.config.js | 2 +-
playground/worker/index.html | 6 +++++
playground/worker/my-shared-worker.ts | 11 +++-----
playground/worker/vite.config-es.js | 2 ++
playground/worker/vite.config-inline-url.js | 16 ++++++++----
playground/worker/worker/main-module.js | 26 +++++++++++++++----
11 files changed, 77 insertions(+), 26 deletions(-)
diff --git a/docs/config/worker-options.md b/docs/config/worker-options.md
index b0896cb10aa507..04c3d60c5ce746 100644
--- a/docs/config/worker-options.md
+++ b/docs/config/worker-options.md
@@ -14,7 +14,7 @@ Output format for worker bundle.
- **Type:** `'blob' | 'base64'`
- **Default:** `'blob'`
-URL type for inline worker, when setting to `'blob'`, the worker will be loaded as a blob URL with a fallback to data URL. Set to `'base64'` to load the worker as a data URL.
+URL type for inline worker, when setting to `'blob'`, the worker will be loaded as a blob URL with a fallback to data URL. Set to `'base64'` to load the worker as a data URL. When not set, `inlineUrl` will be `'blob'` for Worker and `'base64'` for SharedWorker as blob URL not works with a shared worker.
## worker.plugins
diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts
index 0df29b7e348cf9..3f1176fb8cb2df 100644
--- a/packages/vite/src/node/config.ts
+++ b/packages/vite/src/node/config.ts
@@ -320,9 +320,9 @@ export interface LegacyOptions {
export interface ResolveWorkerOptions extends PluginHookUtils {
format: 'es' | 'iife'
- inlineUrl: 'blob' | 'base64'
plugins: Plugin[]
rollupOptions: RollupOptions
+ inlineUrl?: 'blob' | 'base64'
}
export interface InlineConfig extends UserConfig {
@@ -637,7 +637,7 @@ export async function resolveConfig(
workerConfig = await runConfigHook(workerConfig, workerUserPlugins, configEnv)
const resolvedWorkerOptions: ResolveWorkerOptions = {
format: workerConfig.worker?.format || 'iife',
- inlineUrl: workerConfig.worker?.inlineUrl || 'blob',
+ inlineUrl: workerConfig.worker?.inlineUrl,
plugins: [],
rollupOptions: workerConfig.worker?.rollupOptions || {},
getSortedPlugins: undefined!,
diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts
index 18ac599890ef84..c09e9d08526736 100644
--- a/packages/vite/src/node/plugins/worker.ts
+++ b/packages/vite/src/node/plugins/worker.ts
@@ -1,4 +1,5 @@
import path from 'node:path'
+import colors from 'picocolors'
import MagicString from 'magic-string'
import type { EmittedAsset, OutputChunk } from 'rollup'
import type { ResolvedConfig } from '../config'
@@ -281,6 +282,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
const encodedJs = `const encodedJs = "${Buffer.from(
chunk.code,
).toString('base64')}";`
+
const blobCode = `${encodedJs}
const blob = typeof window !== "undefined" && window.Blob && new Blob([atob(encodedJs)], { type: "text/javascript;charset=utf-8" });
export default function WorkerWrapper() {
@@ -298,9 +300,26 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}
`
- // inline as blob data url
+ // If inlineUrl is not specified, use base64 for SharedWorker and blob for Worker
+ const resolvedInlineUrl = inlineUrl
+ ? inlineUrl
+ : workerConstructor === 'SharedWorker'
+ ? 'base64'
+ : 'blob'
+
+ if (
+ workerConstructor === 'SharedWorker' &&
+ resolvedInlineUrl === 'blob'
+ ) {
+ config.logger.warn(
+ colors.yellow(
+ `\nThe inlined SharedWorker: ${id} does not work with blob URL, considering set 'worker.inlineUrl' to 'base64'. \n`,
+ ),
+ )
+ }
+
return {
- code: inlineUrl === 'blob' ? blobCode : base64Code,
+ code: resolvedInlineUrl === 'blob' ? blobCode : base64Code,
// Empty sourcemap to suppress Rollup warning
map: { mappings: '' },
}
diff --git a/playground/worker/__tests__/es/es-worker.spec.ts b/playground/worker/__tests__/es/es-worker.spec.ts
index 754aa4584b48e2..d9c00892d8f862 100644
--- a/playground/worker/__tests__/es/es-worker.spec.ts
+++ b/playground/worker/__tests__/es/es-worker.spec.ts
@@ -76,7 +76,7 @@ describe.runIf(isBuild)('build', () => {
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`)
expect(content).toMatch(`window.Blob`)
expect(content).toMatch(
- /try\{return e\?new Worker\(.+\):new Worker\("data:application\/javascript;base64,"\+/,
+ /try\{return .*\?new Worker\(.+\):new Worker\("data:application\/javascript;base64,"\+/,
)
})
diff --git a/playground/worker/__tests__/inline-url/inline-url-worker.spec.ts b/playground/worker/__tests__/inline-url/inline-url-worker.spec.ts
index de66ee5d1a3d3c..d59832a5325faf 100644
--- a/playground/worker/__tests__/inline-url/inline-url-worker.spec.ts
+++ b/playground/worker/__tests__/inline-url/inline-url-worker.spec.ts
@@ -11,9 +11,14 @@ describe.runIf(isBuild)('build', () => {
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
- // inlined
+ // inline worker
expect(content).toMatch(
- `return new Worker("data:application/javascript;base64,"+`,
+ /try\{return .*\?new Worker\(.+\):new Worker\("data:application\/javascript;base64,"\+/,
+ )
+
+ // inline sharedworker
+ expect(content).toMatch(
+ `return new SharedWorker("data:application/javascript;base64,"+`,
)
})
})
diff --git a/playground/worker/__tests__/inline-url/vite.config.js b/playground/worker/__tests__/inline-url/vite.config.js
index 8676577f7bce4b..c6c9d32e918015 100644
--- a/playground/worker/__tests__/inline-url/vite.config.js
+++ b/playground/worker/__tests__/inline-url/vite.config.js
@@ -1 +1 @@
-module.exports = require('../../vite.config-inline-url')
+export { default } from '../../vite.config-inline-url'
diff --git a/playground/worker/index.html b/playground/worker/index.html
index 5c9c85b4799fd5..ed7079ae8dd38c 100644
--- a/playground/worker/index.html
+++ b/playground/worker/index.html
@@ -26,6 +26,12 @@
+
+ import InlineSharedWorker from '../my-shared-worker?sharedworker&inline'
+ .pong-shared-inline
+
+
+
import TSOutputWorker from '../possible-ts-output-worker?worker'
.pong-ts-output
diff --git a/playground/worker/my-shared-worker.ts b/playground/worker/my-shared-worker.ts
index 552c3e20f57853..0062ec2636089f 100644
--- a/playground/worker/my-shared-worker.ts
+++ b/playground/worker/my-shared-worker.ts
@@ -1,14 +1,11 @@
-const ports = new Set()
+let sharedWorkerCount = 0
// @ts-expect-error onconnect exists in worker
self.onconnect = (event) => {
+ sharedWorkerCount++
const port = event.ports[0]
- ports.add(port)
- port.postMessage('pong')
- port.onmessage = () => {
- ports.forEach((p: any) => {
- p.postMessage('pong')
- })
+ if (sharedWorkerCount === 2) {
+ port.postMessage('pong')
}
}
diff --git a/playground/worker/vite.config-es.js b/playground/worker/vite.config-es.js
index 329377ee37732a..3adb2b157f671d 100644
--- a/playground/worker/vite.config-es.js
+++ b/playground/worker/vite.config-es.js
@@ -1,6 +1,8 @@
import vite from 'vite'
import workerPluginTestPlugin from './worker-plugin-test-plugin'
+/** @type {import('vite').UserConfig} */
+// @ts-expect-error typecast
export default vite.defineConfig({
base: '/es/',
resolve: {
diff --git a/playground/worker/vite.config-inline-url.js b/playground/worker/vite.config-inline-url.js
index cf68bf6499d653..b6592d9ae7fe4f 100644
--- a/playground/worker/vite.config-inline-url.js
+++ b/playground/worker/vite.config-inline-url.js
@@ -1,5 +1,11 @@
-const config = require('./vite.config-es')
-config.worker.inlineUrl = 'base64'
-config.base = '/inline-url/'
-config.build.outDir = 'dist/inline-url'
-module.exports = config
+import { defineConfig } from 'vite'
+import config from './vite.config-es'
+
+export default defineConfig({
+ ...config,
+ base: '/inline-url/',
+ build: {
+ ...config.build,
+ outDir: 'dist/inline-url',
+ },
+})
diff --git a/playground/worker/worker/main-module.js b/playground/worker/worker/main-module.js
index 1e5242935cdbb8..effad0c33d7ce3 100644
--- a/playground/worker/worker/main-module.js
+++ b/playground/worker/worker/main-module.js
@@ -1,5 +1,6 @@
import myWorker from '../my-worker.ts?worker'
import InlineWorker from '../my-worker.ts?worker&inline'
+import InlineSharedWorker from '../my-shared-worker?sharedworker&inline'
import mySharedWorker from '../my-shared-worker?sharedworker&name=shared'
import TSOutputWorker from '../possible-ts-output-worker?worker'
import NestedWorker from '../worker-nested-worker?worker'
@@ -26,11 +27,26 @@ inlineWorker.addEventListener('message', (e) => {
text('.pong-inline', e.data.msg)
})
-const sharedWorker = new mySharedWorker()
-sharedWorker.port.addEventListener('message', (event) => {
- text('.tick-count', event.data)
-})
-sharedWorker.port.start()
+const startSharedWorker = () => {
+ const sharedWorker = new mySharedWorker()
+ sharedWorker.port.addEventListener('message', (event) => {
+ text('.tick-count', event.data)
+ })
+ sharedWorker.port.start()
+}
+startSharedWorker()
+startSharedWorker()
+
+const startInlineSharedWorker = () => {
+ const inlineSharedWorker = new InlineSharedWorker()
+ inlineSharedWorker.port.addEventListener('message', (event) => {
+ text('.pong-shared-inline', event.data)
+ })
+ inlineSharedWorker.port.start()
+}
+
+startInlineSharedWorker()
+startInlineSharedWorker()
const tsOutputWorker = new TSOutputWorker()
tsOutputWorker.postMessage('ping')