-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Co-authored-by: bluwy <bjornlu.dev@gmail.com>
- Loading branch information
1 parent
7a0758c
commit e5f5301
Showing
4 changed files
with
148 additions
and
1 deletion.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
packages/vite/src/node/ssr/runtime/__tests__/fixtures/worker.invoke.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// @ts-check | ||
|
||
import { BroadcastChannel, parentPort } from 'node:worker_threads' | ||
import { fileURLToPath } from 'node:url' | ||
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner' | ||
import { createBirpc } from 'birpc' | ||
|
||
if (!parentPort) { | ||
throw new Error('File "worker.js" must be run in a worker thread') | ||
} | ||
|
||
/** @type {import('worker_threads').MessagePort} */ | ||
const pPort = parentPort | ||
|
||
/** @type {import('birpc').BirpcReturn<{ invoke: (data: any) => any }>} */ | ||
const rpc = createBirpc({}, { | ||
post: (data) => pPort.postMessage(data), | ||
on: (data) => pPort.on('message', data), | ||
}) | ||
|
||
const runner = new ModuleRunner( | ||
{ | ||
root: fileURLToPath(new URL('./', import.meta.url)), | ||
transport: { | ||
invoke(data) { return rpc.invoke(data) } | ||
}, | ||
hmr: false, | ||
}, | ||
new ESModulesEvaluator(), | ||
) | ||
|
||
const channel = new BroadcastChannel('vite-worker:invoke') | ||
channel.onmessage = async (message) => { | ||
try { | ||
const mod = await runner.import(message.data.id) | ||
channel.postMessage({ result: mod.default }) | ||
} catch (e) { | ||
channel.postMessage({ error: e.stack }) | ||
} | ||
} | ||
parentPort.postMessage('ready') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
packages/vite/src/node/ssr/runtime/__tests__/server-worker-runner.invoke.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { BroadcastChannel, Worker } from 'node:worker_threads' | ||
import { afterAll, beforeAll, describe, expect, it } from 'vitest' | ||
import type { BirpcReturn } from 'birpc' | ||
import { createBirpc } from 'birpc' | ||
import { DevEnvironment } from '../../..' | ||
import { type ViteDevServer, createServer } from '../../../server' | ||
|
||
describe('running module runner inside a worker and using the ModuleRunnerTransport#invoke API', () => { | ||
let worker: Worker | ||
let server: ViteDevServer | ||
let rpc: BirpcReturn< | ||
unknown, | ||
{ invoke: (data: any) => Promise<{ result: any } | { error: any }> } | ||
> | ||
let handleInvoke: (data: any) => Promise<{ result: any } | { error: any }> | ||
|
||
beforeAll(async () => { | ||
worker = new Worker( | ||
new URL('./fixtures/worker.invoke.mjs', import.meta.url), | ||
{ | ||
stdout: true, | ||
}, | ||
) | ||
await new Promise<void>((resolve, reject) => { | ||
worker.on('message', () => resolve()) | ||
worker.on('error', reject) | ||
}) | ||
server = await createServer({ | ||
root: __dirname, | ||
logLevel: 'error', | ||
server: { | ||
middlewareMode: true, | ||
watch: null, | ||
hmr: { | ||
port: 9610, | ||
}, | ||
}, | ||
environments: { | ||
worker: { | ||
dev: { | ||
createEnvironment: (name, config) => { | ||
return new DevEnvironment(name, config, { | ||
hot: false, | ||
}) | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
handleInvoke = (data: any) => server.environments.ssr.hot.handleInvoke(data) | ||
rpc = createBirpc( | ||
{ | ||
invoke: (data: any) => handleInvoke(data), | ||
}, | ||
{ | ||
post: (data) => worker.postMessage(data), | ||
on: (data) => worker.on('message', data), | ||
}, | ||
) | ||
}) | ||
|
||
afterAll(() => { | ||
server.close() | ||
worker.terminate() | ||
rpc.$close() | ||
}) | ||
|
||
async function run(id: string) { | ||
const channel = new BroadcastChannel('vite-worker:invoke') | ||
return new Promise<any>((resolve, reject) => { | ||
channel.onmessage = (event) => { | ||
try { | ||
resolve((event as MessageEvent).data) | ||
} catch (e) { | ||
reject(e) | ||
} | ||
} | ||
channel.postMessage({ id }) | ||
}) | ||
} | ||
|
||
it('correctly runs ssr code', async () => { | ||
const output = await run('./fixtures/default-string.ts') | ||
expect(output).toStrictEqual({ | ||
result: 'hello world', | ||
}) | ||
}) | ||
|
||
it('triggers an error', async () => { | ||
handleInvoke = async () => ({ error: new Error('This is an Invoke Error') }) | ||
const output = await run('dummy') | ||
expect(output).not.toHaveProperty('result') | ||
expect(output.error).toContain('Error: This is an Invoke Error') | ||
}) | ||
|
||
it('triggers an unknown error', async () => { | ||
handleInvoke = async () => ({ error: 'a string instead of an error' }) | ||
const output = await run('dummy') | ||
expect(output).not.toHaveProperty('result') | ||
expect(output.error).toContain('Error: Unknown invoke error') | ||
}) | ||
}) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.