@vitejs/plugin-rsc 0.4.19 → 0.4.21
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 +64 -60
- package/dist/{browser-DIa4fISB.js → browser-QU10IP0-.js} +2 -1
- package/dist/browser.js +1 -1
- package/dist/extra/browser.js +1 -1
- package/dist/extra/rsc.js +1 -1
- package/dist/extra/ssr.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{plugin-CYYsF3qY.d.ts → plugin-BQszG7oj.d.ts} +1 -0
- package/dist/{plugin-Cu7_zbmH.js → plugin-CzZCeIwj.js} +91 -28
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +1 -1
- package/dist/{rsc-CGUEQCnf.js → rsc-BwEwbLG4.js} +2 -1
- package/dist/rsc.js +1 -1
- package/dist/{ssr-BuzPa0Go.js → ssr-BMTRhW5g.js} +2 -1
- package/dist/ssr.js +1 -1
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -4,10 +4,10 @@ This package provides [React Server Components](https://react.dev/reference/rsc/
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Framework-
|
|
8
|
-
- **
|
|
7
|
+
- **Framework-agnostic**: The plugin implements [RSC bundler features](https://react.dev/reference/rsc/server-components) and provides low level RSC runtime (`react-server-dom`) API without framework-specific abstractions.
|
|
8
|
+
- **Runtime-agnostic**: Built on [Vite environment API](https://vite.dev/guide/api-environment.html) and works with other runtimes (e.g., [`@cloudflare/vite-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vite-plugin-cloudflare)).
|
|
9
9
|
- **HMR support**: Enables editing both client and server components without full page reloads.
|
|
10
|
-
- **
|
|
10
|
+
- **CSS support**: CSS is automatically code-split both at client and server components and they are injected upon rendering.
|
|
11
11
|
|
|
12
12
|
## Getting Started
|
|
13
13
|
|
|
@@ -19,14 +19,17 @@ npx degit vitejs/vite-plugin-react/packages/plugin-rsc/examples/starter my-app
|
|
|
19
19
|
|
|
20
20
|
## Examples
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- [`./examples/
|
|
29
|
-
-
|
|
22
|
+
**Start here:** [`./examples/starter`](./examples/starter) - Recommended for understanding the plugin
|
|
23
|
+
|
|
24
|
+
- Provides an in-depth overview of API with inline comments to explain how they function within RSC-powered React application.
|
|
25
|
+
|
|
26
|
+
**Integration examples:**
|
|
27
|
+
|
|
28
|
+
- [`./examples/basic`](./examples/basic) - Advanced RSC features and testing
|
|
29
|
+
- This is mainly used for e2e testing and includes various advanced RSC usages (e.g. `"use cache"` example).
|
|
30
|
+
- [`./examples/ssg`](./examples/ssg) - Static site generation with MDX and client components for interactivity.
|
|
31
|
+
- [`./examples/react-router`](./examples/react-router) - React Router RSC integration
|
|
32
|
+
- Demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview). React Router now provides [official RSC support](https://reactrouter.com/how-to/react-server-components), so it's recommended to follow React Router's official documentation for the latest integration.
|
|
30
33
|
|
|
31
34
|
## Basic Concepts
|
|
32
35
|
|
|
@@ -128,11 +131,11 @@ export default defineConfig({
|
|
|
128
131
|
- [`entry.rsc.tsx`](./examples/starter/src/framework/entry.rsc.tsx)
|
|
129
132
|
|
|
130
133
|
```tsx
|
|
131
|
-
import
|
|
134
|
+
import { renderToReadableStream } from '@vitejs/plugin-rsc/rsc'
|
|
132
135
|
|
|
133
136
|
// the plugin assumes `rsc` entry having default export of request handler
|
|
134
137
|
export default async function handler(request: Request): Promise<Response> {
|
|
135
|
-
//
|
|
138
|
+
// serialize React VDOM to RSC stream
|
|
136
139
|
const root = (
|
|
137
140
|
<html>
|
|
138
141
|
<body>
|
|
@@ -140,7 +143,7 @@ export default async function handler(request: Request): Promise<Response> {
|
|
|
140
143
|
</body>
|
|
141
144
|
</html>
|
|
142
145
|
)
|
|
143
|
-
const rscStream =
|
|
146
|
+
const rscStream = renderToReadableStream(root)
|
|
144
147
|
|
|
145
148
|
// respond direct RSC stream request based on framework's convention
|
|
146
149
|
if (request.url.endsWith('.rsc')) {
|
|
@@ -170,19 +173,19 @@ export default async function handler(request: Request): Promise<Response> {
|
|
|
170
173
|
- [`entry.ssr.tsx`](./examples/starter/src/framework/entry.ssr.tsx)
|
|
171
174
|
|
|
172
175
|
```tsx
|
|
173
|
-
import
|
|
174
|
-
import
|
|
176
|
+
import { createFromReadableStream } from '@vitejs/plugin-rsc/ssr'
|
|
177
|
+
import { renderToReadableStream } from 'react-dom/server.edge'
|
|
175
178
|
|
|
176
179
|
export async function handleSsr(rscStream: ReadableStream) {
|
|
177
180
|
// deserialize RSC stream back to React VDOM
|
|
178
|
-
const root = await
|
|
181
|
+
const root = await createFromReadableStream(rscStream)
|
|
179
182
|
|
|
180
183
|
// helper API to allow referencing browser entry content from SSR environment
|
|
181
184
|
const bootstrapScriptContent =
|
|
182
185
|
await import.meta.viteRsc.loadBootstrapScriptContent('index')
|
|
183
186
|
|
|
184
187
|
// render html (traditional SSR)
|
|
185
|
-
const htmlStream =
|
|
188
|
+
const htmlStream = renderToReadableStream(root, {
|
|
186
189
|
bootstrapScriptContent,
|
|
187
190
|
})
|
|
188
191
|
|
|
@@ -193,51 +196,26 @@ export async function handleSsr(rscStream: ReadableStream) {
|
|
|
193
196
|
- [`entry.browser.tsx`](./examples/starter/src/framework/entry.browser.tsx)
|
|
194
197
|
|
|
195
198
|
```tsx
|
|
196
|
-
import
|
|
197
|
-
import
|
|
199
|
+
import { createFromReadableStream } from '@vitejs/plugin-rsc/browser'
|
|
200
|
+
import { hydrateRoot } from 'react-dom/client'
|
|
198
201
|
|
|
199
202
|
async function main() {
|
|
200
203
|
// fetch and deserialize RSC stream back to React VDOM
|
|
201
|
-
const rscResponse = await fetch(window.location.href +
|
|
202
|
-
const root = await
|
|
204
|
+
const rscResponse = await fetch(window.location.href + '.rsc')
|
|
205
|
+
const root = await createFromReadableStream(rscResponse.body)
|
|
203
206
|
|
|
204
207
|
// hydration (traditional CSR)
|
|
205
|
-
|
|
208
|
+
hydrateRoot(document, root)
|
|
206
209
|
}
|
|
207
210
|
|
|
208
|
-
main()
|
|
211
|
+
main()
|
|
209
212
|
```
|
|
210
213
|
|
|
211
|
-
## `react-server-dom` API
|
|
212
|
-
|
|
213
|
-
### `@vitejs/plugin-rsc/rsc`
|
|
214
|
-
|
|
215
|
-
This module re-exports RSC runtime API provided by `react-server-dom/server.edge` and `react-server-dom/client.edge` such as:
|
|
216
|
-
|
|
217
|
-
- `renderToReadableStream`: RSC serialization (React VDOM -> RSC stream)
|
|
218
|
-
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM). This is also available on rsc environment itself. For example, it allows saving serailized RSC and deserializing it for later use.
|
|
219
|
-
- `decodeAction/decodeReply/decodeFormState/loadServerAction/createTemporaryReferenceSet`
|
|
220
|
-
- `encodeReply/createClientTemporaryReferenceSet`
|
|
221
|
-
|
|
222
|
-
### `@vitejs/plugin-rsc/ssr`
|
|
223
|
-
|
|
224
|
-
This module re-exports RSC runtime API provided by `react-server-dom/client.edge`
|
|
225
|
-
|
|
226
|
-
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
|
|
227
|
-
|
|
228
|
-
### `@vitejs/plugin-rsc/browser`
|
|
229
|
-
|
|
230
|
-
This module re-exports RSC runtime API provided by `react-server-dom/client.browser`
|
|
231
|
-
|
|
232
|
-
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
|
|
233
|
-
- `createFromFetch`: a robust way of `createFromReadableStream((await fetch("...")).body)`
|
|
234
|
-
- `encodeReply/setServerCallback`: server function related...
|
|
235
|
-
|
|
236
214
|
## Environment helper API
|
|
237
215
|
|
|
238
216
|
The plugin provides an additional helper for multi environment interaction.
|
|
239
217
|
|
|
240
|
-
###
|
|
218
|
+
### Available on `rsc` or `ssr` environment
|
|
241
219
|
|
|
242
220
|
#### `import.meta.viteRsc.loadModule`
|
|
243
221
|
|
|
@@ -260,7 +238,7 @@ ssrModule.renderHTML(...);
|
|
|
260
238
|
export function renderHTML(...) {}
|
|
261
239
|
```
|
|
262
240
|
|
|
263
|
-
###
|
|
241
|
+
### Available on `rsc` environment
|
|
264
242
|
|
|
265
243
|
#### `import.meta.viteRsc.loadCss`
|
|
266
244
|
|
|
@@ -287,7 +265,7 @@ export function ServerPage() {
|
|
|
287
265
|
}
|
|
288
266
|
```
|
|
289
267
|
|
|
290
|
-
|
|
268
|
+
When specifying `loadCss(<id>)`, it will collect css through the server module resolved by `<id>`.
|
|
291
269
|
|
|
292
270
|
```tsx
|
|
293
271
|
// virtual:my-framework-helper
|
|
@@ -324,7 +302,7 @@ export function Page(props) {
|
|
|
324
302
|
return <div>...</div>
|
|
325
303
|
}
|
|
326
304
|
|
|
327
|
-
// my-route.
|
|
305
|
+
// my-route.tsx?vite-rsc-css-export=Page
|
|
328
306
|
function Page(props) {
|
|
329
307
|
return <div>...</div>
|
|
330
308
|
}
|
|
@@ -341,14 +319,13 @@ function __Page(props) {
|
|
|
341
319
|
export { __Page as Page }
|
|
342
320
|
```
|
|
343
321
|
|
|
344
|
-
###
|
|
322
|
+
### Available on `ssr` environment
|
|
345
323
|
|
|
346
324
|
#### `import.meta.viteRsc.loadBootstrapScriptContent("index")`
|
|
347
325
|
|
|
348
326
|
This provides a raw js code to execute a browser entry file specified by `environments.client.build.rollupOptions.input.index`. This is intended to be used with React DOM SSR API, such as [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream)
|
|
349
327
|
|
|
350
328
|
```js
|
|
351
|
-
import bootstrapScriptContent from 'virtual:vite-rsc/bootstrap-script-content'
|
|
352
329
|
import { renderToReadableStream } from 'react-dom/server.edge'
|
|
353
330
|
|
|
354
331
|
const bootstrapScriptContent =
|
|
@@ -358,20 +335,18 @@ const htmlStream = await renderToReadableStream(reactNode, {
|
|
|
358
335
|
})
|
|
359
336
|
```
|
|
360
337
|
|
|
361
|
-
###
|
|
338
|
+
### Available on `client` environment
|
|
362
339
|
|
|
363
340
|
#### `rsc:update` event
|
|
364
341
|
|
|
365
342
|
This event is fired when server modules are updated, which can be used to trigger re-fetching and re-rendering of RSC components on browser.
|
|
366
343
|
|
|
367
344
|
```js
|
|
368
|
-
import
|
|
345
|
+
import { createFromFetch } from '@vitejs/plugin-rsc/browser'
|
|
369
346
|
|
|
370
347
|
import.meta.hot.on('rsc:update', async () => {
|
|
371
348
|
// re-fetch RSC stream
|
|
372
|
-
const rscPayload = await
|
|
373
|
-
fetch(window.location.href + '.rsc'),
|
|
374
|
-
)
|
|
349
|
+
const rscPayload = await createFromFetch(fetch(window.location.href + '.rsc'))
|
|
375
350
|
// re-render ...
|
|
376
351
|
})
|
|
377
352
|
```
|
|
@@ -420,6 +395,31 @@ export default defineConfig({
|
|
|
420
395
|
})
|
|
421
396
|
```
|
|
422
397
|
|
|
398
|
+
## RSC runtime (react-server-dom) API
|
|
399
|
+
|
|
400
|
+
### `@vitejs/plugin-rsc/rsc`
|
|
401
|
+
|
|
402
|
+
This module re-exports RSC runtime API provided by `react-server-dom/server.edge` and `react-server-dom/client.edge` such as:
|
|
403
|
+
|
|
404
|
+
- `renderToReadableStream`: RSC serialization (React VDOM -> RSC stream)
|
|
405
|
+
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM). This is also available on rsc environment itself. For example, it allows saving serialized RSC and deserializing it for later use.
|
|
406
|
+
- `decodeAction/decodeReply/decodeFormState/loadServerAction/createTemporaryReferenceSet`
|
|
407
|
+
- `encodeReply/createClientTemporaryReferenceSet`
|
|
408
|
+
|
|
409
|
+
### `@vitejs/plugin-rsc/ssr`
|
|
410
|
+
|
|
411
|
+
This module re-exports RSC runtime API provided by `react-server-dom/client.edge`
|
|
412
|
+
|
|
413
|
+
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
|
|
414
|
+
|
|
415
|
+
### `@vitejs/plugin-rsc/browser`
|
|
416
|
+
|
|
417
|
+
This module re-exports RSC runtime API provided by `react-server-dom/client.browser`
|
|
418
|
+
|
|
419
|
+
- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
|
|
420
|
+
- `createFromFetch`: a robust way of `createFromReadableStream((await fetch("...")).body)`
|
|
421
|
+
- `encodeReply/setServerCallback`: server function related...
|
|
422
|
+
|
|
423
423
|
## High level API
|
|
424
424
|
|
|
425
425
|
> [!NOTE]
|
|
@@ -473,6 +473,10 @@ export function Page() {
|
|
|
473
473
|
}
|
|
474
474
|
```
|
|
475
475
|
|
|
476
|
+
## Canary and Experimental channel releases
|
|
477
|
+
|
|
478
|
+
See https://github.com/vitejs/vite-plugin-react/pull/524 for how to install the package for React [canary](https://react.dev/community/versioning-policy#canary-channel) and [experimental](https://react.dev/community/versioning-policy#all-release-channels) usages.
|
|
479
|
+
|
|
476
480
|
## Credits
|
|
477
481
|
|
|
478
482
|
This project builds on fundamental techniques and insights from pioneering Vite RSC implementations.
|
package/dist/browser.js
CHANGED
|
@@ -2,6 +2,6 @@ import "./dist-DiJnRA1C.js";
|
|
|
2
2
|
import "./shared-CEyKoKAb.js";
|
|
3
3
|
import { setRequireModule } from "./browser-BhJd-Orx.js";
|
|
4
4
|
import { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setServerCallback } from "./browser-D8OPzpF5.js";
|
|
5
|
-
import "./browser-
|
|
5
|
+
import "./browser-QU10IP0-.js";
|
|
6
6
|
|
|
7
7
|
export { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setRequireModule, setServerCallback };
|
package/dist/extra/browser.js
CHANGED
|
@@ -2,7 +2,7 @@ import "../dist-DiJnRA1C.js";
|
|
|
2
2
|
import "../shared-CEyKoKAb.js";
|
|
3
3
|
import "../browser-BhJd-Orx.js";
|
|
4
4
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "../browser-D8OPzpF5.js";
|
|
5
|
-
import "../browser-
|
|
5
|
+
import "../browser-QU10IP0-.js";
|
|
6
6
|
import { rscStream } from "../client-C1J4FCf5.js";
|
|
7
7
|
import React from "react";
|
|
8
8
|
import ReactDomClient from "react-dom/client";
|
package/dist/extra/rsc.js
CHANGED
|
@@ -4,7 +4,7 @@ import "../encryption-utils-BDwwcMVT.js";
|
|
|
4
4
|
import { loadServerAction } from "../rsc-BfBPoIV8.js";
|
|
5
5
|
import { createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, renderToReadableStream } from "../rsc-VjVw_i-M.js";
|
|
6
6
|
import "../encryption-runtime-CJUalqt3.js";
|
|
7
|
-
import "../rsc-
|
|
7
|
+
import "../rsc-BwEwbLG4.js";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
|
|
10
10
|
//#region src/extra/rsc.tsx
|
package/dist/extra/ssr.js
CHANGED
|
@@ -2,7 +2,7 @@ import "../dist-DiJnRA1C.js";
|
|
|
2
2
|
import "../shared-CEyKoKAb.js";
|
|
3
3
|
import "../ssr--rFiBtws.js";
|
|
4
4
|
import { createFromReadableStream } from "../ssr-BEKKb_cw.js";
|
|
5
|
-
import "../ssr-
|
|
5
|
+
import "../ssr-BMTRhW5g.js";
|
|
6
6
|
import { injectRSCPayload } from "../server-D0-DavPP.js";
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./dist-DiJnRA1C.js";
|
|
2
2
|
import "./plugin-CZbI4rhS.js";
|
|
3
|
-
import { transformHoistInlineDirective, vitePluginRsc } from "./plugin-
|
|
3
|
+
import { transformHoistInlineDirective, vitePluginRsc } from "./plugin-CzZCeIwj.js";
|
|
4
4
|
import "./encryption-utils-BDwwcMVT.js";
|
|
5
5
|
import "./rpc-tGuLT8PD.js";
|
|
6
6
|
import "./vite-utils-Vzd7cqfv.js";
|
|
@@ -28,6 +28,7 @@ type RscPluginOptions = {
|
|
|
28
28
|
rscCssTransform?: false | {
|
|
29
29
|
filter?: (id: string) => boolean;
|
|
30
30
|
};
|
|
31
|
+
/** @deprecated use "DEBUG=vite-env:*" to see warnings. */
|
|
31
32
|
ignoredPackageWarnings?: (string | RegExp)[];
|
|
32
33
|
/**
|
|
33
34
|
* This option allows customizing how client build copies assets from server build.
|
|
@@ -328,7 +328,8 @@ function parseIdQuery(id) {
|
|
|
328
328
|
function transformCjsToEsm(code, ast) {
|
|
329
329
|
const output = new MagicString(code);
|
|
330
330
|
const analyzed = analyze(ast);
|
|
331
|
-
|
|
331
|
+
const parentNodes = [];
|
|
332
|
+
const hoistedCodes = [];
|
|
332
333
|
let hoistIndex = 0;
|
|
333
334
|
walk(ast, {
|
|
334
335
|
enter(node) {
|
|
@@ -346,7 +347,7 @@ function transformCjsToEsm(code, ast) {
|
|
|
346
347
|
} else {
|
|
347
348
|
const hoisted = `__cjs_to_esm_hoist_${hoistIndex}`;
|
|
348
349
|
const importee = code.slice(node.arguments[0].start, node.arguments[0].end);
|
|
349
|
-
|
|
350
|
+
hoistedCodes.push(`const ${hoisted} = await import(${importee});\n`);
|
|
350
351
|
output.update(node.start, node.end, hoisted);
|
|
351
352
|
hoistIndex++;
|
|
352
353
|
}
|
|
@@ -356,6 +357,7 @@ function transformCjsToEsm(code, ast) {
|
|
|
356
357
|
parentNodes.pop();
|
|
357
358
|
}
|
|
358
359
|
});
|
|
360
|
+
for (const hoisted of hoistedCodes.reverse()) output.prepend(hoisted);
|
|
359
361
|
output.prepend(`const exports = {}; const module = { exports };\n`);
|
|
360
362
|
return { output };
|
|
361
363
|
}
|
|
@@ -415,6 +417,25 @@ function extractPackageKey(id) {
|
|
|
415
417
|
return id;
|
|
416
418
|
}
|
|
417
419
|
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/plugins/scan.ts
|
|
422
|
+
const importGlobRE = /\bimport\.meta\.glob(?:<\w+>)?\s*\(/g;
|
|
423
|
+
async function transformScanBuildStrip(code) {
|
|
424
|
+
const [imports] = esModuleLexer.parse(code);
|
|
425
|
+
let output = imports.map((e) => e.n && `import ${JSON.stringify(e.n)};\n`).filter(Boolean).join("");
|
|
426
|
+
if (importGlobRE.test(code)) {
|
|
427
|
+
const ast = await parseAstAsync(code);
|
|
428
|
+
walk(ast, { enter(node) {
|
|
429
|
+
if (node.type === "CallExpression" && node.callee.type === "MemberExpression" && node.callee.object.type === "MetaProperty" && node.callee.object.meta.type === "Identifier" && node.callee.object.meta.name === "import" && node.callee.object.property.type === "Identifier" && node.callee.object.property.name === "meta" && node.callee.property.type === "Identifier" && node.callee.property.name === "glob") {
|
|
430
|
+
const importMetaGlob = code.slice(node.start, node.end);
|
|
431
|
+
output += `console.log(${importMetaGlob});\n`;
|
|
432
|
+
}
|
|
433
|
+
} });
|
|
434
|
+
output += "";
|
|
435
|
+
}
|
|
436
|
+
return output;
|
|
437
|
+
}
|
|
438
|
+
|
|
418
439
|
//#endregion
|
|
419
440
|
//#region src/plugin.ts
|
|
420
441
|
let serverReferences = {};
|
|
@@ -444,6 +465,7 @@ function vitePluginRscMinimal(rscPluginOptions = {}) {
|
|
|
444
465
|
},
|
|
445
466
|
configResolved(config_) {
|
|
446
467
|
config = config_;
|
|
468
|
+
for (const e of Object.values(config.environments)) e.build.outDir = path.resolve(config.root, e.build.outDir);
|
|
447
469
|
},
|
|
448
470
|
configureServer(server_) {
|
|
449
471
|
server = server_;
|
|
@@ -943,10 +965,9 @@ function scanBuildStripPlugin() {
|
|
|
943
965
|
name: "rsc:scan-strip",
|
|
944
966
|
apply: "build",
|
|
945
967
|
enforce: "post",
|
|
946
|
-
transform(code, _id, _options) {
|
|
968
|
+
async transform(code, _id, _options) {
|
|
947
969
|
if (!isScanBuild) return;
|
|
948
|
-
const
|
|
949
|
-
const output = imports.map((e) => e.n && `import ${JSON.stringify(e.n)};\n`).filter(Boolean).join("");
|
|
970
|
+
const output = await transformScanBuildStrip(code);
|
|
950
971
|
return {
|
|
951
972
|
code: output,
|
|
952
973
|
map: { mappings: "" }
|
|
@@ -971,6 +992,13 @@ function vitePluginUseClient(useClientPluginOptions) {
|
|
|
971
992
|
const bareImportRE = /^(?![a-zA-Z]:)[\w@](?!.*:\/\/)/;
|
|
972
993
|
const serverEnvironmentName = useClientPluginOptions.environment?.rsc ?? "rsc";
|
|
973
994
|
const browserEnvironmentName = useClientPluginOptions.environment?.browser ?? "client";
|
|
995
|
+
function warnInoncistentClientOptimization(ctx, id) {
|
|
996
|
+
const { depsOptimizer } = server.environments.client;
|
|
997
|
+
if (depsOptimizer) {
|
|
998
|
+
for (const dep of Object.values(depsOptimizer.metadata.optimized)) if (dep.src === id) ctx.warn("client component dependency is inconsistently optimized. It's recommended to add the dependency to 'optimizeDeps.exclude'.");
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
const debug$1 = createDebug("vite-rsc:use-client");
|
|
974
1002
|
return [
|
|
975
1003
|
{
|
|
976
1004
|
name: "rsc:use-client",
|
|
@@ -983,9 +1011,10 @@ function vitePluginUseClient(useClientPluginOptions) {
|
|
|
983
1011
|
let referenceKey;
|
|
984
1012
|
const packageSource = packageSources.get(id);
|
|
985
1013
|
if (!packageSource && this.environment.mode === "dev" && id.includes("/node_modules/")) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1014
|
+
debug$1(`internal client reference created through a package imported in '${this.environment.name}' environment: ${id}`);
|
|
1015
|
+
id = cleanUrl(id);
|
|
1016
|
+
warnInoncistentClientOptimization(this, id);
|
|
1017
|
+
importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent(id)}`;
|
|
989
1018
|
referenceKey = importId;
|
|
990
1019
|
} else if (packageSource) if (this.environment.mode === "dev") {
|
|
991
1020
|
importId = `/@id/__x00__virtual:vite-rsc/client-package-proxy/${packageSource}`;
|
|
@@ -1141,6 +1170,7 @@ function vitePluginDefineEncryptionKey(useServerPluginOptions) {
|
|
|
1141
1170
|
function vitePluginUseServer(useServerPluginOptions) {
|
|
1142
1171
|
const serverEnvironmentName = useServerPluginOptions.environment?.rsc ?? "rsc";
|
|
1143
1172
|
const browserEnvironmentName = useServerPluginOptions.environment?.browser ?? "client";
|
|
1173
|
+
const debug$1 = createDebug("vite-rsc:use-server");
|
|
1144
1174
|
return [{
|
|
1145
1175
|
name: "rsc:use-server",
|
|
1146
1176
|
async transform(code, id) {
|
|
@@ -1150,8 +1180,7 @@ function vitePluginUseServer(useServerPluginOptions) {
|
|
|
1150
1180
|
const getNormalizedId = () => {
|
|
1151
1181
|
if (!normalizedId_) {
|
|
1152
1182
|
if (this.environment.mode === "dev" && id.includes("/node_modules/")) {
|
|
1153
|
-
|
|
1154
|
-
if (!ignored) this.warn(`[vite-rsc] detected an internal server function created by a package imported on ${this.environment.name} environment`);
|
|
1183
|
+
debug$1(`internal server reference created through a package imported in ${this.environment.name} environment: ${id}`);
|
|
1155
1184
|
id = cleanUrl(id);
|
|
1156
1185
|
}
|
|
1157
1186
|
if (config.command === "build") normalizedId_ = hashString(path.relative(config.root, id));
|
|
@@ -1386,6 +1415,9 @@ async function findSourceMapURL(server$1, filename, environmentName) {
|
|
|
1386
1415
|
};
|
|
1387
1416
|
}
|
|
1388
1417
|
function vitePluginRscCss(rscCssOptions) {
|
|
1418
|
+
function hasSpecialCssQuery(id) {
|
|
1419
|
+
return /[?&](url|inline|raw)(\b|=|&|$)/.test(id);
|
|
1420
|
+
}
|
|
1389
1421
|
function collectCss(environment, entryId) {
|
|
1390
1422
|
const visited = /* @__PURE__ */ new Set();
|
|
1391
1423
|
const cssIds = /* @__PURE__ */ new Set();
|
|
@@ -1395,8 +1427,10 @@ function vitePluginRscCss(rscCssOptions) {
|
|
|
1395
1427
|
visited.add(id);
|
|
1396
1428
|
const mod = environment.moduleGraph.getModuleById(id);
|
|
1397
1429
|
if (mod?.file) visitedFiles.add(mod.file);
|
|
1398
|
-
for (const next of mod?.importedModules ?? []) if (next.id) if (isCSSRequest(next.id))
|
|
1399
|
-
|
|
1430
|
+
for (const next of mod?.importedModules ?? []) if (next.id) if (isCSSRequest(next.id)) {
|
|
1431
|
+
if (hasSpecialCssQuery(next.id)) continue;
|
|
1432
|
+
cssIds.add(next.id);
|
|
1433
|
+
} else recurse(next.id);
|
|
1400
1434
|
}
|
|
1401
1435
|
recurse(entryId);
|
|
1402
1436
|
const hrefs = [...cssIds].map((id) => normalizeViteImportAnalysisUrl(environment, id));
|
|
@@ -1551,7 +1585,25 @@ function vitePluginRscCss(rscCssOptions) {
|
|
|
1551
1585
|
}
|
|
1552
1586
|
}
|
|
1553
1587
|
}
|
|
1554
|
-
}
|
|
1588
|
+
},
|
|
1589
|
+
createVirtualPlugin("vite-rsc/remove-duplicate-server-css", async function() {
|
|
1590
|
+
assert.equal(this.environment.mode, "dev");
|
|
1591
|
+
function removeFn() {
|
|
1592
|
+
document.querySelectorAll("link[rel='stylesheet']").forEach((node) => {
|
|
1593
|
+
if (node instanceof HTMLElement && node.dataset.precedence?.startsWith("vite-rsc/")) node.remove();
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
return `\
|
|
1597
|
+
"use client"
|
|
1598
|
+
import React from "react";
|
|
1599
|
+
export default function RemoveDuplicateServerCss() {
|
|
1600
|
+
React.useEffect(() => {
|
|
1601
|
+
(${removeFn.toString()})();
|
|
1602
|
+
}, []);
|
|
1603
|
+
return null;
|
|
1604
|
+
}
|
|
1605
|
+
`;
|
|
1606
|
+
})
|
|
1555
1607
|
];
|
|
1556
1608
|
}
|
|
1557
1609
|
function invalidteModuleById(environment, id) {
|
|
@@ -1570,25 +1622,36 @@ function collectModuleDependents(mods) {
|
|
|
1570
1622
|
return [...visited];
|
|
1571
1623
|
}
|
|
1572
1624
|
function generateResourcesCode(depsCode) {
|
|
1573
|
-
const ResourcesFn = (React, deps) => {
|
|
1625
|
+
const ResourcesFn = (React, deps, RemoveDuplicateServerCss) => {
|
|
1574
1626
|
return function Resources() {
|
|
1575
|
-
return React.createElement(React.Fragment, null, [
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1627
|
+
return React.createElement(React.Fragment, null, [
|
|
1628
|
+
...deps.css.map((href) => React.createElement("link", {
|
|
1629
|
+
key: "css:" + href,
|
|
1630
|
+
rel: "stylesheet",
|
|
1631
|
+
precedence: "vite-rsc/importer-resources",
|
|
1632
|
+
href
|
|
1633
|
+
})),
|
|
1634
|
+
...deps.js.map((href) => React.createElement("script", {
|
|
1635
|
+
key: "js:" + href,
|
|
1636
|
+
type: "module",
|
|
1637
|
+
async: true,
|
|
1638
|
+
src: href
|
|
1639
|
+
})),
|
|
1640
|
+
RemoveDuplicateServerCss && React.createElement(RemoveDuplicateServerCss, { key: "remove-duplicate-css" })
|
|
1641
|
+
]);
|
|
1586
1642
|
};
|
|
1587
1643
|
};
|
|
1588
1644
|
return `
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1645
|
+
import __vite_rsc_react__ from "react";
|
|
1646
|
+
|
|
1647
|
+
${config.command === "serve" ? `import RemoveDuplicateServerCss from "virtual:vite-rsc/remove-duplicate-server-css";` : `const RemoveDuplicateServerCss = undefined;`}
|
|
1648
|
+
|
|
1649
|
+
export const Resources = (${ResourcesFn.toString()})(
|
|
1650
|
+
__vite_rsc_react__,
|
|
1651
|
+
${depsCode},
|
|
1652
|
+
RemoveDuplicateServerCss,
|
|
1653
|
+
);
|
|
1654
|
+
`;
|
|
1592
1655
|
}
|
|
1593
1656
|
async function transformRscCssExport(options) {
|
|
1594
1657
|
if (hasDirective(options.ast.body, "use client")) return;
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss, vitePluginRscMinimal } from "./plugin-
|
|
1
|
+
import { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss, vitePluginRscMinimal } from "./plugin-BQszG7oj.js";
|
|
2
2
|
export { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, vitePluginRsc as default, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRscCss, vitePluginRscMinimal };
|
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./dist-DiJnRA1C.js";
|
|
2
2
|
import "./plugin-CZbI4rhS.js";
|
|
3
|
-
import { __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss, vitePluginRscMinimal } from "./plugin-
|
|
3
|
+
import { __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss, vitePluginRscMinimal } from "./plugin-CzZCeIwj.js";
|
|
4
4
|
import "./encryption-utils-BDwwcMVT.js";
|
|
5
5
|
import "./rpc-tGuLT8PD.js";
|
|
6
6
|
import "./vite-utils-Vzd7cqfv.js";
|
package/dist/rsc.js
CHANGED
|
@@ -4,6 +4,6 @@ import "./encryption-utils-BDwwcMVT.js";
|
|
|
4
4
|
import { createClientManifest, createServerManifest, loadServerAction, setRequireModule } from "./rsc-BfBPoIV8.js";
|
|
5
5
|
import { createClientTemporaryReferenceSet, createFromReadableStream, createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, encodeReply, registerClientReference, registerServerReference, renderToReadableStream } from "./rsc-VjVw_i-M.js";
|
|
6
6
|
import { decryptActionBoundArgs, encryptActionBoundArgs } from "./encryption-runtime-CJUalqt3.js";
|
|
7
|
-
import "./rsc-
|
|
7
|
+
import "./rsc-BwEwbLG4.js";
|
|
8
8
|
|
|
9
9
|
export { createClientManifest, createClientTemporaryReferenceSet, createFromReadableStream, createServerManifest, createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, decryptActionBoundArgs, encodeReply, encryptActionBoundArgs, loadServerAction, registerClientReference, registerServerReference, renderToReadableStream, setRequireModule };
|
package/dist/ssr.js
CHANGED
|
@@ -2,6 +2,6 @@ import "./dist-DiJnRA1C.js";
|
|
|
2
2
|
import "./shared-CEyKoKAb.js";
|
|
3
3
|
import { createServerConsumerManifest, setRequireModule } from "./ssr--rFiBtws.js";
|
|
4
4
|
import { callServer, createFromReadableStream, createServerReference, findSourceMapURL } from "./ssr-BEKKb_cw.js";
|
|
5
|
-
import "./ssr-
|
|
5
|
+
import "./ssr-BMTRhW5g.js";
|
|
6
6
|
|
|
7
7
|
export { callServer, createFromReadableStream, createServerConsumerManifest, createServerReference, findSourceMapURL, setRequireModule };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/plugin-rsc",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.21",
|
|
4
4
|
"description": "React Server Components (RSC) support for Vite.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@playwright/test": "^1.54.2",
|
|
52
52
|
"@tsconfig/strictest": "^2.0.5",
|
|
53
53
|
"@types/estree": "^1.0.8",
|
|
54
|
-
"@types/node": "^22.17.
|
|
55
|
-
"@types/react": "^19.1.
|
|
54
|
+
"@types/node": "^22.17.2",
|
|
55
|
+
"@types/react": "^19.1.10",
|
|
56
56
|
"@types/react-dom": "^19.1.7",
|
|
57
57
|
"@vitejs/plugin-react": "workspace:*",
|
|
58
58
|
"react": "^19.1.1",
|
|
@@ -60,8 +60,7 @@
|
|
|
60
60
|
"react-server-dom-webpack": "^19.1.1",
|
|
61
61
|
"rsc-html-stream": "^0.0.7",
|
|
62
62
|
"tinyexec": "^1.0.1",
|
|
63
|
-
"tsdown": "^0.14.
|
|
64
|
-
"vite-plugin-inspect": "^11.3.2"
|
|
63
|
+
"tsdown": "^0.14.1"
|
|
65
64
|
},
|
|
66
65
|
"peerDependencies": {
|
|
67
66
|
"react": "*",
|