Skip to content

Commit 8f322fe

Browse files
committed
perf: simplify worker re-export code
1 parent 1ae1e23 commit 8f322fe

5 files changed

Lines changed: 55 additions & 49 deletions

File tree

src/plugins/unplugin.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,46 +83,43 @@ export const WorkerPlugin = (opts: WorkerPluginOptions) => createUnplugin(() =>
8383
let source = ''
8484
if (opts.mode === 'client') {
8585
source += `
86-
const counts = {}
8786
const map = {}
87+
let count = 0
88+
let _nuxt_worker
8889
89-
function initWorker (worker, name) {
90-
map[name] = {}
91-
counts[name] = 0
90+
function initWorker (worker) {
91+
const worker = new Worker(new URL(${JSON.stringify(file)}, import.meta.url))
9292
worker.onmessage = (e) => {
93-
const [resolve, reject] = map[name][e.data.id]
93+
const [resolve, reject] = map[e.data.id]
9494
if ('error' in e.data) {
9595
reject(new Error(e.data.error))
9696
} else {
9797
resolve(e.data.result)
9898
}
9999
}
100100
return worker
101-
}`
101+
}
102+
`
102103
}
103104

104105
for (const name of exports) {
105-
source += `\nvar _nuxt_worker_${name};`
106-
107-
source += `\nasync function ${name} (...args) {\n`
106+
source += `\nexport async function ${name} (...args) {`
108107
if (opts.mode === 'server') {
109-
source += `\n const { ${name}: fn } = await import(${JSON.stringify(opts.context.workerExports[name])})\n`
110-
source += `\n return fn(...args)\n`
108+
source += `\n const { ${name}: fn } = await import(${JSON.stringify(opts.context.workerExports[name])})`
109+
source += `\n return fn(...args)`
111110
}
112111
else {
113-
source += `\n _nuxt_worker_${name} ||= initWorker(new Worker(new URL(${JSON.stringify(opts.context.workerExports[name])}, import.meta.url)), ${JSON.stringify(name)})\n`
114-
source += `\n const id = counts[${JSON.stringify(name)}]++`
112+
source += `\n _nuxt_worker ||= initWorker()\n`
113+
source += `\n const id = count++`
115114
source += `\n return new Promise((resolve, reject) => {`
116-
source += `\n map[${JSON.stringify(name)}][id] = [resolve, reject]`,
117-
source += `\n _nuxt_worker_${name}.postMessage({ name: ${JSON.stringify(name)}, args, id })`
115+
source += `\n map[id] = [resolve, reject]`,
116+
source += `\n _nuxt_worker.postMessage({ name: ${JSON.stringify(name)}, args, id })`
118117
source += `\n })`
119118
}
120119

121120
source += `\n}\n`
122121
}
123122

124-
source += `\nexport { ${exports.join(', ')} }\n`
125-
126123
return {
127124
code: source,
128125
map: null,
Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

2-
const counts = {}
32
const map = {}
3+
let count = 0
4+
let _nuxt_worker
45

5-
function initWorker (worker, name) {
6-
map[name] = {}
7-
counts[name] = 0
6+
function initWorker (worker) {
7+
const worker = new Worker(new URL("somefile.ts", import.meta.url))
88
worker.onmessage = (e) => {
9-
const [resolve, reject] = map[name][e.data.id]
9+
const [resolve, reject] = map[e.data.id]
1010
if ('error' in e.data) {
1111
reject(new Error(e.data.error))
1212
} else {
@@ -15,16 +15,23 @@ function initWorker (worker, name) {
1515
}
1616
return worker
1717
}
18-
var _nuxt_worker_bob;
19-
async function bob (...args) {
2018

21-
_nuxt_worker_bob ||= initWorker(new Worker(new URL("somefile.ts", import.meta.url)), "bob")
19+
export async function foo (...args) {
20+
_nuxt_worker ||= initWorker()
2221

23-
const id = counts["bob"]++
22+
const id = count++
2423
return new Promise((resolve, reject) => {
25-
map["bob"][id] = [resolve, reject]
26-
_nuxt_worker_bob.postMessage({ name: "bob", args, id })
24+
map[id] = [resolve, reject]
25+
_nuxt_worker.postMessage({ name: "foo", args, id })
2726
})
2827
}
2928

30-
export { bob }
29+
export async function bar (...args) {
30+
_nuxt_worker ||= initWorker()
31+
32+
const id = count++
33+
return new Promise((resolve, reject) => {
34+
map[id] = [resolve, reject]
35+
_nuxt_worker.postMessage({ name: "bar", args, id })
36+
})
37+
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11

2-
var _nuxt_worker_bob;
3-
async function bob (...args) {
4-
5-
const { bob: fn } = await import("somefile.ts")
6-
2+
export async function foo (...args) {
3+
const { foo: fn } = await import("somefile.ts")
74
return fn(...args)
8-
95
}
106

11-
export { bob }
7+
export async function bar (...args) {
8+
const { bar: fn } = await import("somefile.ts")
9+
return fn(...args)
10+
}

test/__snapshots__/worker.client.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const bob = () => 42; const foo = () => "thing"
2-
const __worker_exports__ = { bob: bob }
1+
const foo = () => 42; const bar = async () => "thing"; const baz = function () { }
2+
const __worker_exports__ = { foo: foo, bar: bar }
33
self.onmessage = async (e) => {
44
const { name, args, id } = e.data
55
const fn = __worker_exports__[name]

test/transform.spec.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,17 @@ import { describe, it, expect } from 'vitest'
33
import { WorkerTransformPlugin, WorkerPlugin, VIRTUAL_ID } from '../src/plugins/unplugin.js'
44

55
describe('worker transform', () => {
6+
const workerSource = 'export const foo = () => 42; export const bar = async () => "thing"; export const baz = function () { }'
67
it('should not transform code on the server', async () => {
7-
const code = await transform('server', 'export const bob = () => 42; export const foo = () => "thing"')
8+
const code = await transform('server', workerSource)
89
expect(code).toBeUndefined()
910
})
1011
it('should transform code on the client', async () => {
11-
const code = await transform('client', 'export const bob = () => 42; export const foo = () => "thing"')
12+
const code = await transform('client', workerSource)
1213
expect(code).toMatchFileSnapshot('__snapshots__/worker.client.js')
1314
})
1415
})
1516

16-
async function transform(mode: 'server' | 'client', code: string) {
17-
const context = { workerExports: {}, reverseMap: { 'somefile.ts': ['bob'] } }
18-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19-
const plugin = WorkerTransformPlugin({ mode, context }).raw({}, {} as any)
20-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21-
return (plugin as any).transform(code, 'somefile.ts')?.code
22-
}
23-
2417
describe('worker loader', () => {
2518
it('should load worker on server', async () => {
2619
const code = await load('server')
@@ -32,8 +25,18 @@ describe('worker loader', () => {
3225
})
3326
})
3427

28+
// Helper utils
29+
30+
const context = { workerExports: { foo: 'somefile.ts', bar: 'somefile.ts' }, reverseMap: { 'somefile.ts': ['foo', 'bar'] } }
31+
32+
async function transform(mode: 'server' | 'client', code: string) {
33+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
34+
const plugin = WorkerTransformPlugin({ mode, context }).raw({}, {} as any)
35+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
36+
return (plugin as any).transform(code, 'somefile.ts')?.code
37+
}
38+
3539
async function load(mode: 'server' | 'client') {
36-
const context = { workerExports: { bob: 'somefile.ts' }, reverseMap: { 'somefile.ts': ['bob'] } }
3740
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3841
const plugin = WorkerPlugin({ mode, context }).raw({}, {} as any)
3942
// eslint-disable-next-line @typescript-eslint/no-explicit-any

0 commit comments

Comments
 (0)