Skip to content

Commit

Permalink
feat(plugins/worker): support SharedWorker (resolve #2093)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Mar 14, 2021
1 parent 26c46b9 commit 00f4f72
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 6 deletions.
30 changes: 28 additions & 2 deletions packages/playground/worker/__tests__/worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,43 @@ test('inlined', async () => {
await untilUpdated(() => page.textContent('.pong-inline'), 'pong')
})

let resolvedSharedWorkerCount = 0

async function waitSharedWorkerTick(page) {
await untilUpdated(async () => {
const count = await page.textContent('.tick-count')
// ignore the initial 0
return count === '1' ? '1' : ''
}, '1')
resolvedSharedWorkerCount++
// test.concurrent sequential is not guaranteed
// force page to wait to ensure two pages overlap in time
await untilUpdated(() => {
return resolvedSharedWorkerCount === 2 ? '2' : ''
}, '2')
}

test.concurrent('shared worker 1', async () => {
await waitSharedWorkerTick(page)
})

test.concurrent('shared worker 2', async () => {
await page.click('.tick-shared')
await waitSharedWorkerTick(page)
})

if (isBuild) {
// assert correct files
test('inlined code generation', async () => {
const assetsDir = path.resolve(testDir, 'dist/assets')
const files = fs.readdirSync(assetsDir)
// should have only 1 worker chunk
expect(files.length).toBe(2)
// should have 2 worker chunk
expect(files.length).toBe(3)
const index = files.find((f) => f.includes('index'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
// chunk
expect(content).toMatch(`new Worker("/assets`)
expect(content).toMatch(`new SharedWorker("/assets`)
// inlined
expect(content).toMatch(`new Worker("data:application/javascript`)
})
Expand Down
18 changes: 18 additions & 0 deletions packages/playground/worker/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@
<button class="ping-inline">Ping Inline Worker</button>
<div>Response from inline worker: <span class="pong-inline"></span></div>

<button class="tick-shared">Tick Shared Worker</button>
<div>
Tick from shared worker, it syncs between pages:
<span class="tick-count">0</span>
</div>

<script type="module">
import Worker from './my-worker?worker'
import InlineWorker from './my-worker?worker&inline'
import SharedWorker from './my-shared-worker?sharedworker&name=shared'

const worker = new Worker()
worker.addEventListener('message', (e) => {
Expand All @@ -28,4 +35,15 @@
document.querySelector('.ping-inline').addEventListener('click', () => {
inlineWorker.postMessage('ping')
})

const sharedWorker = new SharedWorker()
document.querySelector('.tick-shared').addEventListener('click', () => {
sharedWorker.port.postMessage('tick')
})

sharedWorker.port.addEventListener('message', (event) => {
document.querySelector('.tick-count').textContent = event.data
})

sharedWorker.port.start()
</script>
16 changes: 16 additions & 0 deletions packages/playground/worker/my-shared-worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
let count = 0
const ports = new Set()

onconnect = (event) => {
const port = event.ports[0]
ports.add(port)
port.postMessage(count)
port.onmessage = (message) => {
if (message.data === 'tick') {
count++
ports.forEach((p) => {
p.postMessage(count)
})
}
}
}
2 changes: 1 addition & 1 deletion packages/vite/src/node/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const JS_TYPES_RE = /\.(?:j|t)sx?$|\.mjs$/

export const OPTIMIZABLE_ENTRY_RE = /\.(?:m?js|ts)$/

export const SPECIAL_QUERY_RE = /[\?&](?:worker|raw|url)\b/
export const SPECIAL_QUERY_RE = /[\?&](?:worker|sharedworker|raw|url)\b/

export const DEP_CACHE_DIR = `.vite`

Expand Down
20 changes: 17 additions & 3 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
name: 'vite:worker',

load(id) {
if (isBuild && parseWorkerRequest(id)?.worker != null) {
if (
isBuild &&
(parseWorkerRequest(id)?.worker ??
parseWorkerRequest(id)?.sharedworker) != null
) {
return ''
}
},
Expand All @@ -36,7 +40,10 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
code: `import '${ENV_PUBLIC_PATH}'\n` + _
}
}
if (query == null || (query && query.worker == null)) {
if (
query == null ||
(query && (query.worker ?? query.sharedworker) == null)
) {
return
}

Expand Down Expand Up @@ -73,8 +80,15 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}
}

const workerConstructor =
query.sharedworker != null ? 'SharedWorker' : 'Worker'
const { worker, inline, sharedworker, ...optionsFromQuery } = query
const workerOptions = { ...optionsFromQuery, type: 'module' }

return `export default function WorkerWrapper() {
return new Worker(${JSON.stringify(url)}, { type: 'module' })
return new ${workerConstructor}(${JSON.stringify(
url
)}, ${JSON.stringify(workerOptions, null, 2)})
}`
}
}
Expand Down

0 comments on commit 00f4f72

Please sign in to comment.