@vitejs/plugin-rsc 0.5.10 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -224,11 +224,13 @@ The plugin provides an additional helper for multi environment interaction.
224
224
 
225
225
  #### `import.meta.viteRsc.loadModule`
226
226
 
227
- - Type: `(environmentName: "ssr" | "rsc", entryName: string) => Promise<T>`
227
+ - Type: `(environmentName: "ssr" | "rsc", entryName?: string) => Promise<T>`
228
228
 
229
- This allows importing `ssr` environment module specified by `environments.ssr.build.rollupOptions.input[entryName]` inside `rsc` environment and vice versa.
229
+ This allows importing `ssr` environment module specified by `environments.ssr.build.rollupOptions.input[entryName]` inside `rsc` environment and vice versa. When `entryName` is omitted, the function automatically uses the single entry from the target environment's `rollupOptions.input`.
230
230
 
231
- During development, by default, this API assumes both `rsc` and `ssr` environments execute under the main Vite process. When enabling `rsc({ loadModuleDevProxy: true })` plugin option, the loaded module is implemented as a proxy with `fetch`-based RPC to call in node environment on the main Vite process, which for example, allows `rsc` environment inside cloudflare workers to access `ssr` environment on the main Vite process. This proxy mechanism uses [turbo-stream](https://github.com/jacob-ebey/turbo-stream) for serializing data types beyond JSON, with custom encoders/decoders to additionally support `Request` and `Response` instances.
231
+ During development, by default, this API assumes both `rsc` and `ssr` environments execute under the main Vite process as `RunnableDevEnvironment`. Internally, `loadModule` uses the global `__VITE_ENVIRONMENT_RUNNER_IMPORT__` function to import modules in the target environment (see [`__VITE_ENVIRONMENT_RUNNER_IMPORT__`](#__vite_environment_runner_import__) below).
232
+
233
+ When enabling `rsc({ loadModuleDevProxy: true })` plugin option, the loaded module is implemented as a proxy with `fetch`-based RPC to call in node environment on the main Vite process, which for example, allows `rsc` environment inside cloudflare workers to access `ssr` environment on the main Vite process. This proxy mechanism uses [turbo-stream](https://github.com/jacob-ebey/turbo-stream) for serializing data types beyond JSON, with custom encoders/decoders to additionally support `Request` and `Response` instances.
232
234
 
233
235
  During production build, this API will be rewritten into a static import of the specified entry of other environment build and the modules are executed inside the same runtime.
234
236
 
@@ -327,6 +329,35 @@ import.meta.hot.on('rsc:update', async () => {
327
329
  })
328
330
  ```
329
331
 
332
+ ### Global API
333
+
334
+ #### `__VITE_ENVIRONMENT_RUNNER_IMPORT__`
335
+
336
+ - Type: `(environmentName: string, id: string) => Promise<any>`
337
+
338
+ This global function provides a standardized way to import a module in a given environment during development. It is used internally by `import.meta.viteRsc.loadModule` to execute modules in the target environment.
339
+
340
+ By default, the plugin sets this global to import via the environment's module runner:
341
+
342
+ ```js
343
+ globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__ = async (environmentName, id) => {
344
+ return server.environments[environmentName].runner.import(id)
345
+ }
346
+ ```
347
+
348
+ **Custom Environment Integration:**
349
+
350
+ Frameworks with custom environment setups (e.g., environments running in separate workers or with custom module loading) can override this global to provide their own module import logic.
351
+
352
+ ```js
353
+ // Custom logic to import module between multiple environments inside worker
354
+ globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__ = async (environmentName, id) => {
355
+ return myWorkerRunners[environmentname].import(id)
356
+ }
357
+ ```
358
+
359
+ This allows `import.meta.viteRsc.loadModule` to work seamlessly with different runtime configurations without requiring changes to user code.
360
+
330
361
  ## Plugin API
331
362
 
332
363
  ### `@vitejs/plugin-rsc`
@@ -519,7 +550,7 @@ Types for global API are defined in `@vitejs/plugin-rsc/types`. For example, you
519
550
  ```ts
520
551
  import.meta.viteRsc.loadModule
521
552
  // ^^^^^^^^^^
522
- // <T>(environmentName: string, entryName: string) => Promise<T>
553
+ // <T>(environmentName: string, entryName?: string) => Promise<T>
523
554
  ```
524
555
 
525
556
  See also [Vite documentation](https://vite.dev/guide/api-hmr.html#intellisense-for-typescript) for `vite/client` types.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./transforms-BcLQCXiC.js";
2
2
  import "./rpc-CRpYrgKq.js";
3
- import { r as vitePluginRsc, t as getPluginApi } from "./plugin-DNlyqBiD.js";
3
+ import { r as vitePluginRsc, t as getPluginApi } from "./plugin-BcfVRLx-.js";
4
4
  import "./cjs-DHD_0drE.js";
5
5
 
6
6
  export { vitePluginRsc as default, getPluginApi };
@@ -128,10 +128,27 @@ function normalizeRelativePath(s) {
128
128
  s = normalizePath(s);
129
129
  return s[0] === "." ? s : "./" + s;
130
130
  }
131
- function getEntrySource(config, name = "index") {
131
+ function getEntrySource(config, name) {
132
132
  const input = config.build.rollupOptions.input;
133
- assert(typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string", `[vite-rsc:getEntrySource] expected 'build.rollupOptions.input' to be an object with a '${name}' property that is a string, but got ${JSON.stringify(input)}`);
134
- return input[name];
133
+ if (!name) return getFallbackRollupEntry(input).source;
134
+ if (typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string") return input[name];
135
+ throw new Error(`[vite-rsc:getEntrySource] expected 'build.rollupOptions.input' to be an object with a '${name}' property that is a string, but got ${JSON.stringify(input)}`);
136
+ }
137
+ function getFallbackRollupEntry(input = {}) {
138
+ const inputEntries = Object.entries(normalizeRollupOpitonsInput(input));
139
+ if (inputEntries.length === 1) {
140
+ const [name, source] = inputEntries[0];
141
+ return {
142
+ name,
143
+ source
144
+ };
145
+ }
146
+ throw new Error(`[vite-rsc] cannot determine fallback entry name from multiple entries, please specify the entry name explicitly`);
147
+ }
148
+ function normalizeRollupOpitonsInput(input = {}) {
149
+ if (typeof input === "string") input = [input];
150
+ if (Array.isArray(input)) return Object.fromEntries(input.map((file) => [path.basename(file).slice(0, -path.extname(file).length), file]));
151
+ return input;
135
152
  }
136
153
  function hashString(v) {
137
154
  return createHash("sha256").update(v).digest().toString("hex").slice(0, 12);
@@ -554,7 +571,12 @@ function vitePluginRsc(rscPluginOptions = {}) {
554
571
  if (rscPluginOptions.useBuildAppHook) await buildApp(builder);
555
572
  } },
556
573
  configureServer(server) {
557
- globalThis.__viteRscDevServer = server;
574
+ globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__ = async function(environmentName, id) {
575
+ const environment$1 = server.environments[environmentName];
576
+ if (!environment$1) throw new Error(`[vite-rsc] unknown environment '${environmentName}'`);
577
+ if (!vite.isRunnableDevEnvironment(environment$1)) throw new Error(`[vite-rsc] environment '${environmentName}' is not runnable`);
578
+ return environment$1.runner.import(id);
579
+ };
558
580
  const oldSend = server.environments.client.hot.send;
559
581
  server.environments.client.hot.send = async function(...args) {
560
582
  const e = args[0];
@@ -698,8 +720,16 @@ function vitePluginRsc(rscPluginOptions = {}) {
698
720
  const source = getEntrySource(environment.config, entryName);
699
721
  const resolved = await environment.pluginContainer.resolveId(source);
700
722
  assert(resolved, `[vite-rsc] failed to resolve entry '${source}'`);
701
- replacement = `globalThis.__viteRscDevServer.environments[${JSON.stringify(environmentName)}].runner.import(${JSON.stringify(resolved.id)})`;
702
- } else replacement = JSON.stringify(`__vite_rsc_load_module:${this.environment.name}:${environmentName}:${entryName}`);
723
+ replacement = `globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__(${JSON.stringify(environmentName)}, ${JSON.stringify(resolved.id)})`;
724
+ } else {
725
+ const environment = manager.config.environments[environmentName];
726
+ const targetName = entryName || getFallbackRollupEntry(environment.build.rollupOptions.input).name;
727
+ replacement = JSON.stringify(`__vite_rsc_load_module_start__:` + JSON.stringify({
728
+ fromEnv: this.environment.name,
729
+ toEnv: environmentName,
730
+ targetFileName: `${targetName}.js`
731
+ }) + `:__vite_rsc_load_module_end__`);
732
+ }
703
733
  const [start, end] = match.indices[0];
704
734
  s.overwrite(start, end, replacement);
705
735
  }
@@ -712,9 +742,10 @@ function vitePluginRsc(rscPluginOptions = {}) {
712
742
  if (!code.includes("__vite_rsc_load_module")) return;
713
743
  const { config } = manager;
714
744
  const s = new MagicString(code);
715
- for (const match of code.matchAll(/['"]__vite_rsc_load_module:(\w+):(\w+):(\w+)['"]/dg)) {
716
- const [fromEnv, toEnv, entryName] = match.slice(1);
717
- const importPath = normalizeRelativePath(path.relative(path.join(config.environments[fromEnv].build.outDir, chunk.fileName, ".."), path.join(config.environments[toEnv].build.outDir, `${entryName}.js`)));
745
+ for (const match of code.matchAll(/[`'"]__vite_rsc_load_module_start__:([\s\S]*?):__vite_rsc_load_module_end__[`'"]/dg)) {
746
+ const markerString = evalValue(match[0]);
747
+ const { fromEnv, toEnv, targetFileName } = JSON.parse(markerString.slice(31, -29));
748
+ const importPath = normalizeRelativePath(path.relative(path.join(config.environments[fromEnv].build.outDir, chunk.fileName, ".."), path.join(config.environments[toEnv].build.outDir, targetFileName)));
718
749
  const replacement = `(import(${JSON.stringify(importPath)}))`;
719
750
  const [start, end] = match.indices[0];
720
751
  s.overwrite(start, end, replacement);
@@ -732,7 +763,6 @@ function vitePluginRsc(rscPluginOptions = {}) {
732
763
  async function createHandler(url) {
733
764
  const { environmentName, entryName } = Object.fromEntries(url.searchParams);
734
765
  assert(environmentName);
735
- assert(entryName);
736
766
  const environment = server.environments[environmentName];
737
767
  const source = getEntrySource(environment.config, entryName);
738
768
  const resolvedEntry = await environment.pluginContainer.resolveId(source);
package/dist/plugin.d.ts CHANGED
@@ -112,6 +112,9 @@ type PluginApi = {
112
112
  declare function getPluginApi(config: Pick<ResolvedConfig, "plugins">): PluginApi | undefined;
113
113
  /** @experimental */
114
114
  declare function vitePluginRscMinimal(rscPluginOptions?: RscPluginOptions, manager?: RscPluginManager): Plugin[];
115
+ declare global {
116
+ function __VITE_ENVIRONMENT_RUNNER_IMPORT__(environmentName: string, id: string): Promise<any>;
117
+ }
115
118
  declare function vitePluginRsc(rscPluginOptions?: RscPluginOptions): Plugin[];
116
119
  declare class RuntimeAsset {
117
120
  runtime: string;
package/dist/plugin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./transforms-BcLQCXiC.js";
2
2
  import "./rpc-CRpYrgKq.js";
3
- import { i as vitePluginRscMinimal, n as transformRscCssExport, r as vitePluginRsc, t as getPluginApi } from "./plugin-DNlyqBiD.js";
3
+ import { i as vitePluginRscMinimal, n as transformRscCssExport, r as vitePluginRsc, t as getPluginApi } from "./plugin-BcfVRLx-.js";
4
4
  import "./cjs-DHD_0drE.js";
5
5
 
6
6
  export { vitePluginRsc as default, getPluginApi, transformRscCssExport, vitePluginRscMinimal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitejs/plugin-rsc",
3
- "version": "0.5.10",
3
+ "version": "0.5.11",
4
4
  "description": "React Server Components (RSC) support for Vite.",
5
5
  "keywords": [
6
6
  "vite",
package/types/index.d.ts CHANGED
@@ -2,7 +2,7 @@ declare global {
2
2
  interface ImportMeta {
3
3
  readonly viteRsc: {
4
4
  loadCss: (importer?: string) => import('react').ReactNode
5
- loadModule: <T>(environmentName: string, entryName: string) => Promise<T>
5
+ loadModule: <T>(environmentName: string, entryName?: string) => Promise<T>
6
6
  loadBootstrapScriptContent: (entryName: string) => Promise<string>
7
7
  }
8
8
  }