From 2ebef6f0e450ff6b73dd89804eb7e520e160fe2e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 30 Sep 2024 10:01:04 +0900 Subject: [PATCH] chore: rename `?worker-runner` to `?worker-env` (#121) --- examples/web-worker-rsc/src/app.tsx | 2 +- examples/web-worker-rsc/src/lib/ambient.d.ts | 2 +- examples/web-worker-rsc/vite.config.ts | 8 ++- examples/web-worker/README.md | 51 +++++++++++++++++++- examples/web-worker/src/app.tsx | 2 +- examples/web-worker/src/lib/ambient.d.ts | 2 +- examples/web-worker/src/worker/entry.tsx | 2 +- examples/web-worker/vite.config.ts | 26 +++++----- 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/examples/web-worker-rsc/src/app.tsx b/examples/web-worker-rsc/src/app.tsx index ea83f33..b477d00 100644 --- a/examples/web-worker-rsc/src/app.tsx +++ b/examples/web-worker-rsc/src/app.tsx @@ -1,6 +1,6 @@ import React from "react"; import ReactClient from "react-server-dom-webpack/client"; -import workerUrl from "./worker/entry?worker-runner"; +import workerUrl from "./worker/entry?worker-env"; export function App() { const [count, setCount] = React.useState(0); diff --git a/examples/web-worker-rsc/src/lib/ambient.d.ts b/examples/web-worker-rsc/src/lib/ambient.d.ts index 82a838a..3686e86 100644 --- a/examples/web-worker-rsc/src/lib/ambient.d.ts +++ b/examples/web-worker-rsc/src/lib/ambient.d.ts @@ -1,4 +1,4 @@ -declare module "*?worker-runner" { +declare module "*?worker-env" { const src: string; export default src; } diff --git a/examples/web-worker-rsc/vite.config.ts b/examples/web-worker-rsc/vite.config.ts index 3004d79..1321b64 100644 --- a/examples/web-worker-rsc/vite.config.ts +++ b/examples/web-worker-rsc/vite.config.ts @@ -1,11 +1,15 @@ import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; -import { vitePluginWorkerRunner } from "../web-worker/vite.config"; +import { vitePluginWorkerEnvironment } from "../web-worker/vite.config"; import { vitePluginFetchModuleServer } from "./src/lib/fetch-module-server"; export default defineConfig((_env) => ({ clearScreen: false, - plugins: [react(), vitePluginWorkerRunner(), vitePluginFetchModuleServer()], + plugins: [ + react(), + vitePluginWorkerEnvironment(), + vitePluginFetchModuleServer(), + ], environments: { client: { dev: { diff --git a/examples/web-worker/README.md b/examples/web-worker/README.md index 32365a8..b55f5d2 100644 --- a/examples/web-worker/README.md +++ b/examples/web-worker/README.md @@ -6,12 +6,59 @@ pnpm build pnpm preview ``` -## tbd +## Why + +This approach can potentially solve following issues: + +- resolve `worker` conditions both during dev and build (cf. https://github.com/vitejs/vite/issues/7439) +- multiple esm workers sharing code split chunks (cf. https://github.com/vitejs/vite/issues/18068) +- [`worker`](https://vitejs.dev/config/worker-options.html#worker-options) options can be integrated into `environments.worker` options and plugins run more consistently during dev and build. + +## How it works + +Example code: + +```ts +import workerUrl from "./worker.ts?worker-env"; +const worker = new Worker(workerUrl, { type: "module" }); +``` + +__transform during dev__ + +```ts +//// transform of /path-to/worker.ts?worker-env +export default "/path-to/worker.ts?worker-env-file"; +``` + +```ts +//// transform of /path-to/worker.ts?worker-env-file +import { createFetchRunner } from "/src/lib/runner"; +const runner = createFetchRunner({ root: "...", environmentName: "worker" }); +runner.import("/path-to/worker.ts"); +``` + +__transform during build__ + +Build pipeline (notably it requires building client twice): + +- 1st client build: discover `./worker.ts?worker-env` imports, +- worker build: `emitFile({ type: "chunk", id: "/path-to/worker.ts" })` for discovered `?worker-env` imports, +- 2nd client build: transform `./worker.ts?worker-env` using worker build chunks, + +```ts +//// transform of /path-to/worker.ts?worker-env +export default "/path-to-emitted-chunk/worker-xxyyzzww.js"; +``` + +## TBD - need parallel client/worker build to avoid extra client build for discovering worker references - only esm supports multi worker entries +- how to optimizeDeps +- resolve conditions bug https://github.com/vitejs/vite/issues/18222 -## related +## Related - https://github.com/vitejs/vite/discussions/18191 - https://github.com/vitejs/vite/issues/7439 +- https://github.com/vitejs/vite/issues/18068 diff --git a/examples/web-worker/src/app.tsx b/examples/web-worker/src/app.tsx index 75d17da..dd716b7 100644 --- a/examples/web-worker/src/app.tsx +++ b/examples/web-worker/src/app.tsx @@ -1,5 +1,5 @@ import React from "react"; -import workerUrl from "./worker/entry?worker-runner"; +import workerUrl from "./worker/entry?worker-env"; export function App() { const [count, setCount] = React.useState(0); diff --git a/examples/web-worker/src/lib/ambient.d.ts b/examples/web-worker/src/lib/ambient.d.ts index 8e14e1e..3df729f 100644 --- a/examples/web-worker/src/lib/ambient.d.ts +++ b/examples/web-worker/src/lib/ambient.d.ts @@ -1,4 +1,4 @@ -declare module "*?worker-runner" { +declare module "*?worker-env" { const src: string; export default src; } diff --git a/examples/web-worker/src/worker/entry.tsx b/examples/web-worker/src/worker/entry.tsx index c0a4067..2cccf64 100644 --- a/examples/web-worker/src/worker/entry.tsx +++ b/examples/web-worker/src/worker/entry.tsx @@ -1,7 +1,7 @@ import ReactDomServer from "react-dom/server"; import dep from "./dep"; import { depThrowError } from "./dep-error"; -import workerInWorkerUrl from "./worker-in-worker?worker-runner"; +import workerInWorkerUrl from "./worker-in-worker?worker-env"; self.addEventListener("message", (e) => { if (e.data.type === "render") { diff --git a/examples/web-worker/vite.config.ts b/examples/web-worker/vite.config.ts index be29579..8a4dd4e 100644 --- a/examples/web-worker/vite.config.ts +++ b/examples/web-worker/vite.config.ts @@ -5,7 +5,11 @@ import { vitePluginFetchModuleServer } from "./src/lib/fetch-module-server"; export default defineConfig((_env) => ({ clearScreen: false, - plugins: [react(), vitePluginWorkerRunner(), vitePluginFetchModuleServer()], + plugins: [ + react(), + vitePluginWorkerEnvironment(), + vitePluginFetchModuleServer(), + ], environments: { client: { dev: { @@ -76,15 +80,15 @@ const manager = new (class PluginStateManager { workerMap: Record = {}; })(); -export function vitePluginWorkerRunner(): Plugin[] { +export function vitePluginWorkerEnvironment(): Plugin[] { const workerImportPlugin: Plugin = { - name: vitePluginWorkerRunner.name + ":import", + name: vitePluginWorkerEnvironment.name + ":import", sharedDuringBuild: true, transform(_code, id) { - // rewrite ?worker-runner import - if (id.endsWith("?worker-runner")) { - const workerUrl = id.replace("?worker-runner", "?worker-runner-file"); - // dev: pass url directly to `new Worker("?worker-runner-file")` + // rewrite ?worker-env import + if (id.endsWith("?worker-env")) { + const workerUrl = id.replace("?worker-env", "?worker-env-file"); + // dev: pass url directly to `new Worker("?worker-env-file")` if (this.environment.mode === "dev") { return { code: `export default ${JSON.stringify(workerUrl)}`, @@ -93,7 +97,7 @@ export function vitePluginWorkerRunner(): Plugin[] { } // build if (this.environment.mode === "build") { - const entry = id.replace("?worker-runner", ""); + const entry = id.replace("?worker-env", ""); let code: string; if (manager.workerScan) { // client -> worker (scan) @@ -119,14 +123,14 @@ export function vitePluginWorkerRunner(): Plugin[] { } // rewrite worker entry to import it from runner - if (id.endsWith("?worker-runner-file")) { + if (id.endsWith("?worker-env-file")) { console.assert(this.environment.name === "client"); console.assert(this.environment.mode === "dev"); const options = { root: this.environment.config.root, environmentName: "worker", }; - const entryId = id.replace("?worker-runner-file", ""); + const entryId = id.replace("?worker-env-file", ""); const output = ` import { createFetchRunner } from "/src/lib/runner"; const runner = createFetchRunner(${JSON.stringify(options)}); @@ -145,7 +149,7 @@ export function vitePluginWorkerRunner(): Plugin[] { }; const workerBuildPlugin: Plugin = { - name: vitePluginWorkerRunner.name + ":build", + name: vitePluginWorkerEnvironment.name + ":build", applyToEnvironment: (env) => env.mode === "build" && env.name === "worker", sharedDuringBuild: true, buildStart() {