Skip to content

Commit

Permalink
chore: rename ?worker-runner to ?worker-env (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Sep 30, 2024
1 parent 34262fe commit 2ebef6f
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 20 deletions.
2 changes: 1 addition & 1 deletion examples/web-worker-rsc/src/app.tsx
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
2 changes: 1 addition & 1 deletion examples/web-worker-rsc/src/lib/ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare module "*?worker-runner" {
declare module "*?worker-env" {
const src: string;
export default src;
}
Expand Down
8 changes: 6 additions & 2 deletions examples/web-worker-rsc/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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: {
Expand Down
51 changes: 49 additions & 2 deletions examples/web-worker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion examples/web-worker/src/app.tsx
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
2 changes: 1 addition & 1 deletion examples/web-worker/src/lib/ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare module "*?worker-runner" {
declare module "*?worker-env" {
const src: string;
export default src;
}
2 changes: 1 addition & 1 deletion examples/web-worker/src/worker/entry.tsx
Original file line number Diff line number Diff line change
@@ -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") {
Expand Down
26 changes: 15 additions & 11 deletions examples/web-worker/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -76,15 +80,15 @@ const manager = new (class PluginStateManager {
workerMap: Record<string, { referenceId?: string; fileName?: string }> = {};
})();

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("<id>?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("<id>?worker-env-file")`
if (this.environment.mode === "dev") {
return {
code: `export default ${JSON.stringify(workerUrl)}`,
Expand All @@ -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)
Expand All @@ -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)});
Expand All @@ -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() {
Expand Down

0 comments on commit 2ebef6f

Please sign in to comment.