@vitejs/plugin-rsc 0.5.19 → 0.5.20

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.
Files changed (41) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/{chunk-Dj_d7TT4.js → chunk-f2BShn47.js} +1 -1
  3. package/dist/{cjs-D2v1gYgq.js → cjs-v2jRTNln.js} +1 -61
  4. package/dist/core/browser.d.ts +5 -1
  5. package/dist/core/browser.js +1 -1
  6. package/dist/core/plugin.js +25 -1
  7. package/dist/core/rsc.d.ts +1 -1
  8. package/dist/core/rsc.js +84 -1
  9. package/dist/core/ssr.d.ts +1 -1
  10. package/dist/core/ssr.js +1 -1
  11. package/dist/import-environment-B994HXEc.d.ts +11 -0
  12. package/dist/index.d.ts +3 -2
  13. package/dist/index.js +4 -4
  14. package/dist/{picocolors-BRyoHAlU.js → picocolors-B0A1T24z.js} +1 -1
  15. package/dist/plugin.d.ts +179 -3
  16. package/dist/plugin.js +1461 -4
  17. package/dist/plugins/cjs.js +62 -1
  18. package/dist/react/browser.d.ts +2 -2
  19. package/dist/react/rsc.js +1 -1
  20. package/dist/rsc.d.ts +3 -2
  21. package/dist/rsc.js +2 -2
  22. package/dist/ssr.d.ts +3 -2
  23. package/dist/ssr.js +1 -1
  24. package/dist/transforms/index.d.ts +1 -1
  25. package/dist/transforms/index.js +1 -1
  26. package/dist/utils/encryption-runtime.js +1 -2
  27. package/dist/utils/rpc.js +89 -1
  28. package/dist/validate-import-DJumtHRw.js +498 -0
  29. package/package.json +7 -7
  30. package/dist/browser-s-WcB8A7.d.ts +0 -6
  31. package/dist/plugin-BGmSmdwL.js +0 -27
  32. package/dist/plugin-K7i9F4Fd.d.ts +0 -187
  33. package/dist/plugin-Xwi_Uxiv.js +0 -1947
  34. package/dist/rpc-EIuXyQpO.js +0 -91
  35. package/dist/rsc-Bhp6O2qz.js +0 -86
  36. /package/dist/{encryption-utils-DdqSKS_O.js → encryption-utils-Bk5eKdu6.js} +0 -0
  37. /package/dist/{index-now_lP2V.d.ts → index-BIbdRBfk.d.ts} +0 -0
  38. /package/dist/{index-CLmWsR1c.d.ts → server-action-B2zS9t-J.d.ts} +0 -0
  39. /package/dist/{transforms-B2EJTNXG.js → server-action-JkEy-6yW.js} +0 -0
  40. /package/dist/{shared-rtJPs0Yj.js → shared-Dhw3vs8e.js} +0 -0
  41. /package/dist/{shared-CGK4coF3.js → shared-d80_k_tn.js} +0 -0
@@ -1,1947 +0,0 @@
1
- import { n as __toESM } from "./chunk-Dj_d7TT4.js";
2
- import { t as createDebug } from "./dist-yW9-EeG1.js";
3
- import { t as vitePluginRscCore } from "./plugin-BGmSmdwL.js";
4
- import { t as cjsModuleRunnerPlugin } from "./cjs-D2v1gYgq.js";
5
- import { i as toCssVirtual, n as parseIdQuery, r as parseReferenceValidationVirtual, t as parseCssVirtual } from "./shared-CGK4coF3.js";
6
- import { a as hasDirective, n as transformDirectiveProxyExport, o as transformWrapExport, s as findDirectives, t as transformServerActionServer } from "./transforms-B2EJTNXG.js";
7
- import { o as generateEncryptionKey, s as toBase64 } from "./encryption-utils-DdqSKS_O.js";
8
- import { n as createRpcServer } from "./rpc-EIuXyQpO.js";
9
- import { createRequire } from "node:module";
10
- import assert from "node:assert";
11
- import fs from "node:fs";
12
- import path from "node:path";
13
- import { fileURLToPath, pathToFileURL } from "node:url";
14
- import { exactRegex, prefixRegex } from "@rolldown/pluginutils";
15
- import * as esModuleLexer from "es-module-lexer";
16
- import MagicString from "magic-string";
17
- import { toNodeHandler } from "srvx/node";
18
- import { stripLiteral } from "strip-literal";
19
- import * as vite from "vite";
20
- import { defaultServerConditions, isCSSRequest, isFileLoadingAllowed, normalizePath, parseAstAsync } from "vite";
21
- import { crawlFrameworkPkgs } from "vitefu";
22
- import { walk } from "estree-walker";
23
- import { stripVTControlCharacters } from "node:util";
24
- import { createHash } from "node:crypto";
25
-
26
- //#region src/plugins/vite-utils.ts
27
- const VALID_ID_PREFIX = `/@id/`;
28
- const NULL_BYTE_PLACEHOLDER = `__x00__`;
29
- const FS_PREFIX = `/@fs/`;
30
- function wrapId(id) {
31
- return id.startsWith(VALID_ID_PREFIX) ? id : VALID_ID_PREFIX + id.replace("\0", NULL_BYTE_PLACEHOLDER);
32
- }
33
- function withTrailingSlash(path) {
34
- if (path[path.length - 1] !== "/") return `${path}/`;
35
- return path;
36
- }
37
- const postfixRE = /[?#].*$/;
38
- function cleanUrl(url) {
39
- return url.replace(postfixRE, "");
40
- }
41
- function splitFileAndPostfix(path) {
42
- const file = cleanUrl(path);
43
- return {
44
- file,
45
- postfix: path.slice(file.length)
46
- };
47
- }
48
- const windowsSlashRE = /\\/g;
49
- function slash(p) {
50
- return p.replace(windowsSlashRE, "/");
51
- }
52
- const isWindows = typeof process !== "undefined" && process.platform === "win32";
53
- function injectQuery(url, queryToInject) {
54
- const { file, postfix } = splitFileAndPostfix(url);
55
- return `${isWindows ? slash(file) : file}?${queryToInject}${postfix[0] === "?" ? `&${postfix.slice(1)}` : postfix}`;
56
- }
57
- function normalizeResolvedIdToUrl(environment, url, resolved) {
58
- const root = environment.config.root;
59
- const depsOptimizer = environment.depsOptimizer;
60
- if (resolved.id.startsWith(withTrailingSlash(root))) url = resolved.id.slice(root.length);
61
- else if (depsOptimizer?.isOptimizedDepFile(resolved.id) || resolved.id !== "/@react-refresh" && path.isAbsolute(resolved.id) && fs.existsSync(cleanUrl(resolved.id))) url = path.posix.join(FS_PREFIX, resolved.id);
62
- else url = resolved.id;
63
- if (url[0] !== "." && url[0] !== "/") url = wrapId(resolved.id);
64
- return url;
65
- }
66
- function normalizeViteImportAnalysisUrl(environment, id) {
67
- let url = normalizeResolvedIdToUrl(environment, id, { id });
68
- if (environment.config.consumer === "client") {
69
- const mod = environment.moduleGraph.getModuleById(id);
70
- if (mod && mod.lastHMRTimestamp > 0) url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
71
- }
72
- return url;
73
- }
74
- function prepareError(err) {
75
- return {
76
- message: stripVTControlCharacters(err.message),
77
- stack: stripVTControlCharacters(cleanStack(err.stack || "")),
78
- id: err.id,
79
- frame: stripVTControlCharacters(err.frame || ""),
80
- plugin: err.plugin,
81
- pluginCode: err.pluginCode?.toString(),
82
- loc: err.loc
83
- };
84
- }
85
- function cleanStack(stack) {
86
- return stack.split(/\n/).filter((l) => /^\s*at/.test(l)).join("\n");
87
- }
88
- function evalValue(rawValue) {
89
- return new Function(`
90
- var console, exports, global, module, process, require
91
- return (\n${rawValue}\n)
92
- `)();
93
- }
94
- const directRequestRE = /(\?|&)direct=?(?:&|$)/;
95
-
96
- //#endregion
97
- //#region src/plugins/find-source-map-url.ts
98
- function vitePluginFindSourceMapURL() {
99
- return [{
100
- name: "rsc:findSourceMapURL",
101
- apply: "serve",
102
- configureServer(server) {
103
- server.middlewares.use(async (req, res, next) => {
104
- const url = new URL(req.url, `http://localhost`);
105
- if (url.pathname === "/__vite_rsc_findSourceMapURL") {
106
- let filename = url.searchParams.get("filename");
107
- let environmentName = url.searchParams.get("environmentName");
108
- try {
109
- const map = await findSourceMapURL(server, filename, environmentName);
110
- res.setHeader("content-type", "application/json");
111
- if (!map) res.statusCode = 404;
112
- res.end(JSON.stringify(map ?? {}));
113
- } catch (e) {
114
- next(e);
115
- }
116
- return;
117
- }
118
- next();
119
- });
120
- }
121
- }];
122
- }
123
- async function findSourceMapURL(server, filename, environmentName) {
124
- if (filename.startsWith("file://")) {
125
- filename = slash(fileURLToPath(filename));
126
- if (isFileLoadingAllowed(server.config, filename) && fs.existsSync(filename)) {
127
- const content = fs.readFileSync(filename, "utf-8");
128
- return {
129
- version: 3,
130
- sources: [filename],
131
- sourcesContent: [content],
132
- mappings: "AAAA" + ";AACA".repeat(content.split("\n").length)
133
- };
134
- }
135
- return;
136
- }
137
- let mod;
138
- let map;
139
- if (environmentName === "Server") {
140
- mod = server.environments.rsc.moduleGraph.getModuleById(filename);
141
- map = mod?.transformResult?.map;
142
- if (map && map.mappings) map = {
143
- ...map,
144
- mappings: ";;" + map.mappings
145
- };
146
- }
147
- const base = server.config.base.slice(0, -1);
148
- if (environmentName === "Client") try {
149
- const url = new URL(filename).pathname.slice(base.length);
150
- mod = server.environments.client.moduleGraph.urlToModuleMap.get(url);
151
- map = mod?.transformResult?.map;
152
- } catch (e) {}
153
- if (mod && map) return {
154
- ...map,
155
- sources: [base + mod.url]
156
- };
157
- }
158
-
159
- //#endregion
160
- //#region src/plugins/utils.ts
161
- function sortObject(o) {
162
- return Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b)));
163
- }
164
- function withRollupError(ctx, f) {
165
- function processError(e) {
166
- if (e && typeof e === "object" && typeof e.pos === "number") return ctx.error(e, e.pos);
167
- throw e;
168
- }
169
- return function(...args) {
170
- try {
171
- const result = f.apply(this, args);
172
- if (result instanceof Promise) return result.catch((e) => processError(e));
173
- return result;
174
- } catch (e) {
175
- processError(e);
176
- }
177
- };
178
- }
179
- function createVirtualPlugin(name, load) {
180
- const virtualId = "virtual:" + name;
181
- const resolvedId = "\0" + virtualId;
182
- return {
183
- name: `rsc:virtual-${name}`,
184
- resolveId: {
185
- filter: { id: exactRegex(virtualId) },
186
- handler(source) {
187
- if (source === virtualId) return resolvedId;
188
- }
189
- },
190
- load: {
191
- filter: { id: exactRegex(resolvedId) },
192
- handler(id, options) {
193
- if (id === resolvedId) return load.apply(this, [id, options]);
194
- }
195
- }
196
- };
197
- }
198
- function normalizeRelativePath(s) {
199
- s = normalizePath(s);
200
- return s[0] === "." ? s : "./" + s;
201
- }
202
- function getEntrySource(config, name) {
203
- const input = config.build.rollupOptions.input;
204
- if (!name) return getFallbackRollupEntry(input).source;
205
- if (typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string") return input[name];
206
- 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)}`);
207
- }
208
- function getFallbackRollupEntry(input = {}) {
209
- const inputEntries = Object.entries(normalizeRollupOpitonsInput(input));
210
- if (inputEntries.length === 1) {
211
- const [name, source] = inputEntries[0];
212
- return {
213
- name,
214
- source
215
- };
216
- }
217
- throw new Error(`[vite-rsc] cannot determine fallback entry name from multiple entries, please specify the entry name explicitly`);
218
- }
219
- function normalizeRollupOpitonsInput(input = {}) {
220
- if (typeof input === "string") input = [input];
221
- if (Array.isArray(input)) return Object.fromEntries(input.map((file) => [path.basename(file).slice(0, -path.extname(file).length), file]));
222
- return input;
223
- }
224
- function hashString(v) {
225
- return createHash("sha256").update(v).digest().toString("hex").slice(0, 12);
226
- }
227
- function getFetchHandlerExport(exports) {
228
- if ("default" in exports) {
229
- const default_ = exports.default;
230
- if (default_ && typeof default_ === "object" && "fetch" in default_ && typeof default_.fetch === "function") return default_.fetch;
231
- if (typeof default_ === "function") return default_;
232
- }
233
- throw new Error("Invalid server handler entry");
234
- }
235
-
236
- //#endregion
237
- //#region src/plugins/import-environment.ts
238
- const ENV_IMPORTS_MANIFEST_NAME = "__vite_rsc_env_imports_manifest.js";
239
- const ENV_IMPORTS_MANIFEST_PLACEHOLDER = "virtual:vite-rsc/env-imports-manifest";
240
- const ENV_IMPORTS_ENTRY_FALLBACK = "virtual:vite-rsc/env-imports-entry-fallback";
241
- function ensureEnvironmentImportsEntryFallback({ environments }) {
242
- for (const [name, config] of Object.entries(environments)) {
243
- if (name === "client") continue;
244
- const input = normalizeRollupOpitonsInput(config.build?.rollupOptions?.input);
245
- if (Object.keys(input).length === 0) {
246
- config.build = config.build || {};
247
- config.build.rollupOptions = config.build.rollupOptions || {};
248
- config.build.rollupOptions.input = { __vite_rsc_env_imports_entry_fallback: ENV_IMPORTS_ENTRY_FALLBACK };
249
- }
250
- }
251
- }
252
- function vitePluginImportEnvironment(manager) {
253
- return [{
254
- name: "rsc:import-environment",
255
- resolveId: {
256
- filter: { id: exactRegex(ENV_IMPORTS_MANIFEST_PLACEHOLDER) },
257
- handler(source) {
258
- if (source === ENV_IMPORTS_MANIFEST_PLACEHOLDER) return {
259
- id: ENV_IMPORTS_MANIFEST_PLACEHOLDER,
260
- external: true
261
- };
262
- }
263
- },
264
- buildStart() {
265
- if (this.environment.mode !== "build") return;
266
- const emitted = /* @__PURE__ */ new Set();
267
- for (const byTargetEnv of Object.values(manager.environmentImportMetaMap)) {
268
- const imports = byTargetEnv[this.environment.name];
269
- if (!imports) continue;
270
- for (const meta of Object.values(imports)) if (!emitted.has(meta.resolvedId)) {
271
- emitted.add(meta.resolvedId);
272
- this.emitFile({
273
- type: "chunk",
274
- id: meta.resolvedId
275
- });
276
- }
277
- }
278
- },
279
- transform: {
280
- filter: { code: "import.meta.viteRsc.import" },
281
- async handler(code, id) {
282
- if (!code.includes("import.meta.viteRsc.import")) return;
283
- const { server } = manager;
284
- const s = new MagicString(code);
285
- for (const match of stripLiteral(code).matchAll(/import\.meta\.viteRsc\.import\s*(<[\s\S]*?>)?\s*\(([\s\S]*?)\)/dg)) {
286
- const [argStart, argEnd] = match.indices[2];
287
- const [specifier, options] = evalValue(`[${code.slice(argStart, argEnd).trim()}]`);
288
- const environmentName = options.environment;
289
- let resolvedId;
290
- if (this.environment.mode === "dev") {
291
- const targetEnv = server.environments[environmentName];
292
- assert(targetEnv, `[vite-rsc] unknown environment '${environmentName}'`);
293
- const resolved = await targetEnv.pluginContainer.resolveId(specifier, id);
294
- assert(resolved, `[vite-rsc] failed to resolve '${specifier}' in environment '${environmentName}'`);
295
- resolvedId = resolved.id;
296
- } else {
297
- const targetEnvConfig = manager.config.environments[environmentName];
298
- assert(targetEnvConfig, `[vite-rsc] unknown environment '${environmentName}'`);
299
- const resolved = await this.resolve(specifier, id);
300
- assert(resolved, `[vite-rsc] failed to resolve '${specifier}' in environment '${environmentName}'`);
301
- resolvedId = resolved.id;
302
- }
303
- const sourceEnv = this.environment.name;
304
- const targetEnv = environmentName;
305
- manager.environmentImportMetaMap[sourceEnv] ??= {};
306
- manager.environmentImportMetaMap[sourceEnv][targetEnv] ??= {};
307
- manager.environmentImportMetaMap[sourceEnv][targetEnv][resolvedId] = {
308
- resolvedId,
309
- targetEnv,
310
- sourceEnv,
311
- specifier
312
- };
313
- let replacement;
314
- if (this.environment.mode === "dev") replacement = `globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__(${JSON.stringify(environmentName)}, ${JSON.stringify(resolvedId)})`;
315
- else {
316
- const relativeId = manager.toRelativeId(resolvedId);
317
- replacement = `(await import(${JSON.stringify(ENV_IMPORTS_MANIFEST_PLACEHOLDER)})).default[${JSON.stringify(relativeId)}]()`;
318
- }
319
- const [start, end] = match.indices[0];
320
- s.overwrite(start, end, replacement);
321
- }
322
- if (s.hasChanged()) return {
323
- code: s.toString(),
324
- map: s.generateMap({ hires: "boundary" })
325
- };
326
- }
327
- },
328
- renderChunk(code, chunk) {
329
- if (code.includes(ENV_IMPORTS_MANIFEST_PLACEHOLDER)) {
330
- const replacement = normalizeRelativePath(path.relative(path.join(chunk.fileName, ".."), ENV_IMPORTS_MANIFEST_NAME));
331
- code = code.replaceAll(ENV_IMPORTS_MANIFEST_PLACEHOLDER, () => replacement);
332
- return { code };
333
- }
334
- }
335
- }, createVirtualPlugin(ENV_IMPORTS_ENTRY_FALLBACK.slice(8), () => {
336
- return `export default "__vite_rsc_env_imports_entry_fallback";`;
337
- })];
338
- }
339
- function writeEnvironmentImportsManifest(manager) {
340
- if (Object.keys(manager.environmentImportMetaMap).length === 0) return;
341
- for (const [sourceEnv, byTargetEnv] of Object.entries(manager.environmentImportMetaMap)) {
342
- const sourceOutDir = manager.config.environments[sourceEnv].build.outDir;
343
- const manifestPath = path.join(sourceOutDir, ENV_IMPORTS_MANIFEST_NAME);
344
- let code = "export default {\n";
345
- for (const [_targetEnv, imports] of Object.entries(byTargetEnv)) for (const [resolvedId, meta] of Object.entries(imports)) {
346
- const bundle = manager.bundles[meta.targetEnv];
347
- if (!bundle) throw new Error(`[vite-rsc] missing bundle for environment import: ${meta.targetEnv}`);
348
- const chunk = Object.values(bundle).find((c) => c.type === "chunk" && c.facadeModuleId === resolvedId);
349
- if (!chunk) throw new Error(`[vite-rsc] missing output for environment import: ${resolvedId}`);
350
- const targetOutDir = manager.config.environments[meta.targetEnv].build.outDir;
351
- const relativePath = normalizeRelativePath(path.relative(sourceOutDir, path.join(targetOutDir, chunk.fileName)));
352
- const relativeId = manager.toRelativeId(resolvedId);
353
- code += ` ${JSON.stringify(relativeId)}: () => import(${JSON.stringify(relativePath)}),\n`;
354
- }
355
- code += "}\n";
356
- fs.writeFileSync(manifestPath, code);
357
- }
358
- }
359
-
360
- //#endregion
361
- //#region src/plugins/resolved-id-proxy.ts
362
- const RESOLVED_ID_PROXY_PREFIX = "virtual:vite-rsc/resolved-id/";
363
- function toResolvedIdProxy(resolvedId) {
364
- return RESOLVED_ID_PROXY_PREFIX + encodeURIComponent(resolvedId);
365
- }
366
- function withResolvedIdProxy(resolvedId) {
367
- return resolvedId.startsWith("\0") ? toResolvedIdProxy(resolvedId) : resolvedId;
368
- }
369
- function fromResolvedIdProxy(source) {
370
- if (!source.startsWith(RESOLVED_ID_PROXY_PREFIX)) return;
371
- const clean = source.split("?")[0];
372
- return decodeURIComponent(clean.slice(29));
373
- }
374
- /**
375
- * Vite plugin that resolves proxy import specifiers to the original resolved IDs.
376
- */
377
- function vitePluginResolvedIdProxy() {
378
- return {
379
- name: "rsc:resolved-id-proxy",
380
- resolveId: {
381
- filter: { id: prefixRegex(RESOLVED_ID_PROXY_PREFIX) },
382
- handler(source) {
383
- const originalId = fromResolvedIdProxy(source);
384
- if (originalId !== void 0) return originalId;
385
- }
386
- }
387
- };
388
- }
389
-
390
- //#endregion
391
- //#region src/plugins/scan.ts
392
- function scanBuildStripPlugin({ manager }) {
393
- return {
394
- name: "rsc:scan-strip",
395
- apply: "build",
396
- enforce: "post",
397
- transform: {
398
- filter: { id: { exclude: exactRegex("\0rolldown/runtime.js") } },
399
- async handler(code, _id, _options) {
400
- if (!manager.isScanBuild) return;
401
- return {
402
- code: await transformScanBuildStrip(code),
403
- map: { mappings: "" }
404
- };
405
- }
406
- }
407
- };
408
- }
409
- const importGlobRE = /\bimport\.meta\.glob(?:<\w+>)?\s*\(/g;
410
- async function transformScanBuildStrip(code) {
411
- const [imports] = esModuleLexer.parse(code);
412
- let output = imports.map((e) => e.n && `import ${JSON.stringify(e.n)};\n`).filter(Boolean).join("");
413
- if (importGlobRE.test(code)) {
414
- walk(await parseAstAsync(code), { enter(node) {
415
- 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") {
416
- const importMetaGlob = code.slice(node.start, node.end);
417
- output += `console.log(${importMetaGlob});\n`;
418
- }
419
- } });
420
- output += "";
421
- }
422
- return output;
423
- }
424
-
425
- //#endregion
426
- //#region src/plugins/validate-import.ts
427
- function validateImportPlugin() {
428
- return {
429
- name: "rsc:validate-imports",
430
- resolveId: {
431
- order: "pre",
432
- filter: { id: /^(client-only|server-only)$/ },
433
- async handler(source, _importer, options) {
434
- if ("scan" in options && options.scan) return;
435
- if (source === "client-only" || source === "server-only") {
436
- if (source === "client-only" && this.environment.name === "rsc" || source === "server-only" && this.environment.name !== "rsc") return {
437
- id: `\0virtual:vite-rsc/validate-imports/invalid/${source}`,
438
- moduleSideEffects: true
439
- };
440
- return {
441
- id: `\0virtual:vite-rsc/validate-imports/valid/${source}`,
442
- moduleSideEffects: false
443
- };
444
- }
445
- }
446
- },
447
- load: {
448
- filter: { id: prefixRegex("\0virtual:vite-rsc/validate-imports/") },
449
- handler(id) {
450
- if (id.startsWith("\0virtual:vite-rsc/validate-imports/invalid/")) return `throw new Error("invalid import of '${id.slice(id.lastIndexOf("/") + 1)}'")`;
451
- if (id.startsWith("\0virtual:vite-rsc/validate-imports/")) return `export {}`;
452
- }
453
- },
454
- transform: {
455
- order: "post",
456
- filter: { id: prefixRegex("\0virtual:vite-rsc/validate-imports/invalid/") },
457
- async handler(_code, id) {
458
- if (this.environment.mode === "dev") {
459
- if (id.startsWith(`\0virtual:vite-rsc/validate-imports/invalid/`)) validateImportChain(getImportChainDev(this.environment, id), this.environment.name, this.environment.config.root);
460
- }
461
- }
462
- },
463
- buildEnd() {
464
- if (this.environment.mode === "build") {
465
- validateImportChain(getImportChainBuild(this, "\0virtual:vite-rsc/validate-imports/invalid/server-only"), this.environment.name, this.environment.config.root);
466
- validateImportChain(getImportChainBuild(this, "\0virtual:vite-rsc/validate-imports/invalid/client-only"), this.environment.name, this.environment.config.root);
467
- }
468
- }
469
- };
470
- }
471
- function getImportChainDev(environment, id) {
472
- const chain = [];
473
- const recurse = (id) => {
474
- if (chain.includes(id)) return;
475
- const info = environment.moduleGraph.getModuleById(id);
476
- if (!info) return;
477
- chain.push(id);
478
- const next = [...info.importers][0];
479
- if (next && next.id) recurse(next.id);
480
- };
481
- recurse(id);
482
- return chain;
483
- }
484
- function getImportChainBuild(ctx, id) {
485
- const chain = [];
486
- const recurse = (id) => {
487
- if (chain.includes(id)) return;
488
- const info = ctx.getModuleInfo(id);
489
- if (!info) return;
490
- chain.push(id);
491
- const next = info.importers[0];
492
- if (next) recurse(next);
493
- };
494
- recurse(id);
495
- return chain;
496
- }
497
- function validateImportChain(chain, environmentName, root) {
498
- if (chain.length === 0) return;
499
- const id = chain[0];
500
- const source = id.slice(id.lastIndexOf("/") + 1);
501
- let result = `'${source}' cannot be imported in ${source === "server-only" ? "client" : "server"} build ('${environmentName}' environment):\n`;
502
- result += chain.slice(1, 6).map((id, i) => " ".repeat(i + 1) + `imported by ${path.relative(root, id).replaceAll("\0", "")}\n`).join("");
503
- if (chain.length > 6) result += " ".repeat(7) + "...\n";
504
- const error = new Error(result);
505
- if (chain[1]) Object.assign(error, { id: chain[1] });
506
- throw error;
507
- }
508
-
509
- //#endregion
510
- //#region src/plugin.ts
511
- const isRolldownVite = "rolldownVersion" in vite;
512
- const BUILD_ASSETS_MANIFEST_NAME = "__vite_rsc_assets_manifest.js";
513
- const PKG_NAME = "@vitejs/plugin-rsc";
514
- const REACT_SERVER_DOM_NAME = `${PKG_NAME}/vendor/react-server-dom`;
515
- const VIRTUAL_ENTRIES = { browser: "virtual:vite-rsc/entry-browser" };
516
- const require = createRequire(import.meta.url);
517
- function resolvePackage(name) {
518
- return pathToFileURL(require.resolve(name)).href;
519
- }
520
- /**
521
- * @experimental
522
- */
523
- var RscPluginManager = class {
524
- server;
525
- config;
526
- bundles = {};
527
- buildAssetsManifest;
528
- isScanBuild = false;
529
- clientReferenceMetaMap = {};
530
- clientReferenceGroups = {};
531
- serverReferenceMetaMap = {};
532
- serverResourcesMetaMap = {};
533
- environmentImportMetaMap = {};
534
- stabilize() {
535
- this.clientReferenceMetaMap = sortObject(this.clientReferenceMetaMap);
536
- this.serverResourcesMetaMap = sortObject(this.serverResourcesMetaMap);
537
- }
538
- toRelativeId(id) {
539
- return normalizePath(path.relative(this.config.root, id));
540
- }
541
- writeAssetsManifest(environmentNames) {
542
- const assetsManifestCode = `export default ${serializeValueWithRuntime(this.buildAssetsManifest)}`;
543
- for (const name of environmentNames) {
544
- const manifestPath = path.join(this.config.environments[name].build.outDir, BUILD_ASSETS_MANIFEST_NAME);
545
- fs.writeFileSync(manifestPath, assetsManifestCode);
546
- }
547
- }
548
- writeEnvironmentImportsManifest() {
549
- writeEnvironmentImportsManifest(this);
550
- }
551
- };
552
- /** @experimental */
553
- function getPluginApi(config) {
554
- return config.plugins.find((p) => p.name === "rsc:minimal")?.api;
555
- }
556
- /** @experimental */
557
- function vitePluginRscMinimal(rscPluginOptions = {}, manager = new RscPluginManager()) {
558
- return [
559
- {
560
- name: "rsc:minimal",
561
- enforce: "pre",
562
- api: { manager },
563
- async config() {
564
- await esModuleLexer.init;
565
- },
566
- configResolved(config) {
567
- manager.config = config;
568
- for (const e of Object.values(config.environments)) e.build.outDir = path.resolve(config.root, e.build.outDir);
569
- },
570
- configureServer(server_) {
571
- manager.server = server_;
572
- }
573
- },
574
- {
575
- name: "rsc:vite-client-raw-import",
576
- transform: {
577
- order: "post",
578
- filter: { code: "__vite_rsc_raw_import__" },
579
- handler(code) {
580
- if (code.includes("__vite_rsc_raw_import__")) return code.replace("__vite_rsc_raw_import__", "import");
581
- }
582
- }
583
- },
584
- ...vitePluginRscCore(),
585
- ...vitePluginUseClient(rscPluginOptions, manager),
586
- ...vitePluginUseServer(rscPluginOptions, manager),
587
- ...vitePluginDefineEncryptionKey(rscPluginOptions),
588
- {
589
- name: "rsc:reference-validation",
590
- apply: "serve",
591
- load: {
592
- filter: { id: prefixRegex("\0virtual:vite-rsc/reference-validation?") },
593
- handler(id, _options) {
594
- if (id.startsWith("\0virtual:vite-rsc/reference-validation?")) {
595
- const parsed = parseReferenceValidationVirtual(id);
596
- assert(parsed);
597
- if (parsed.type === "client") {
598
- if (Object.values(manager.clientReferenceMetaMap).find((meta) => meta.referenceKey === parsed.id)) return `export {}`;
599
- }
600
- if (parsed.type === "server") {
601
- if (Object.values(manager.serverReferenceMetaMap).find((meta) => meta.referenceKey === parsed.id)) return `export {}`;
602
- }
603
- this.error(`[vite-rsc] invalid ${parsed.type} reference '${parsed.id}'`);
604
- }
605
- }
606
- }
607
- },
608
- scanBuildStripPlugin({ manager }),
609
- vitePluginResolvedIdProxy()
610
- ];
611
- }
612
- function vitePluginRsc(rscPluginOptions = {}) {
613
- const manager = new RscPluginManager();
614
- const buildApp = async (builder) => {
615
- const colors = await import("./picocolors-BRyoHAlU.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1));
616
- const logStep = (msg) => {
617
- builder.config.logger.info(colors.blue(msg));
618
- };
619
- const rscOutDir = builder.environments.rsc.config.build.outDir;
620
- const ssrOutDir = builder.environments.ssr.config.build.outDir;
621
- const rscInsideSsr = path.normalize(rscOutDir).startsWith(path.normalize(ssrOutDir) + path.sep);
622
- const tempRscOutDir = path.join(builder.config.root, "node_modules", ".vite-rsc-temp", "rsc");
623
- ensureEnvironmentImportsEntryFallback(builder.config);
624
- manager.isScanBuild = true;
625
- builder.environments.rsc.config.build.write = false;
626
- builder.environments.ssr.config.build.write = false;
627
- logStep("[1/5] analyze client references...");
628
- await builder.build(builder.environments.rsc);
629
- logStep("[2/5] analyze server references...");
630
- await builder.build(builder.environments.ssr);
631
- manager.isScanBuild = false;
632
- builder.environments.rsc.config.build.write = true;
633
- builder.environments.ssr.config.build.write = true;
634
- logStep("[3/5] build rsc environment...");
635
- await builder.build(builder.environments.rsc);
636
- if (rscInsideSsr) {
637
- if (fs.existsSync(tempRscOutDir)) fs.rmSync(tempRscOutDir, { recursive: true });
638
- fs.mkdirSync(path.dirname(tempRscOutDir), { recursive: true });
639
- fs.renameSync(rscOutDir, tempRscOutDir);
640
- }
641
- manager.stabilize();
642
- logStep("[4/5] build client environment...");
643
- await builder.build(builder.environments.client);
644
- logStep("[5/5] build ssr environment...");
645
- await builder.build(builder.environments.ssr);
646
- if (rscInsideSsr) {
647
- if (fs.existsSync(rscOutDir)) fs.rmSync(rscOutDir, { recursive: true });
648
- fs.mkdirSync(path.dirname(rscOutDir), { recursive: true });
649
- fs.renameSync(tempRscOutDir, rscOutDir);
650
- }
651
- manager.writeAssetsManifest(["ssr", "rsc"]);
652
- manager.writeEnvironmentImportsManifest();
653
- };
654
- let hasReactServerDomWebpack = false;
655
- return [
656
- {
657
- name: "rsc",
658
- async config(config, env) {
659
- if (config.rsc) Object.assign(rscPluginOptions, vite.mergeConfig(config.rsc, rscPluginOptions));
660
- const result = await crawlFrameworkPkgs({
661
- root: process.cwd(),
662
- isBuild: env.command === "build",
663
- isFrameworkPkgByJson(pkgJson) {
664
- if ([PKG_NAME, "react-dom"].includes(pkgJson.name)) return;
665
- const deps = pkgJson["peerDependencies"];
666
- return deps && "react" in deps;
667
- }
668
- });
669
- const noExternal = [
670
- "react",
671
- "react-dom",
672
- "server-only",
673
- "client-only",
674
- PKG_NAME,
675
- ...result.ssr.noExternal.sort()
676
- ];
677
- hasReactServerDomWebpack = result.ssr.noExternal.includes("react-server-dom-webpack");
678
- const reactServerDomPackageName = hasReactServerDomWebpack ? "react-server-dom-webpack" : REACT_SERVER_DOM_NAME;
679
- return {
680
- appType: config.appType ?? "custom",
681
- define: { "import.meta.env.__vite_rsc_build__": JSON.stringify(env.command === "build") },
682
- environments: {
683
- client: {
684
- build: {
685
- outDir: config.environments?.client?.build?.outDir ?? "dist/client",
686
- rollupOptions: { input: rscPluginOptions.entries?.client && { index: rscPluginOptions.entries.client } }
687
- },
688
- optimizeDeps: {
689
- include: ["react-dom/client", `${reactServerDomPackageName}/client.browser`],
690
- exclude: [PKG_NAME]
691
- }
692
- },
693
- ssr: {
694
- build: {
695
- outDir: config.environments?.ssr?.build?.outDir ?? "dist/ssr",
696
- copyPublicDir: false,
697
- rollupOptions: { input: rscPluginOptions.entries?.ssr && { index: rscPluginOptions.entries.ssr } }
698
- },
699
- resolve: { noExternal },
700
- optimizeDeps: {
701
- include: [
702
- "react",
703
- "react-dom",
704
- "react/jsx-runtime",
705
- "react/jsx-dev-runtime",
706
- "react-dom/server.edge",
707
- "react-dom/static.edge",
708
- `${reactServerDomPackageName}/client.edge`
709
- ],
710
- exclude: [PKG_NAME]
711
- }
712
- },
713
- rsc: {
714
- build: {
715
- outDir: config.environments?.rsc?.build?.outDir ?? "dist/rsc",
716
- copyPublicDir: false,
717
- emitAssets: true,
718
- rollupOptions: { input: rscPluginOptions.entries?.rsc && { index: rscPluginOptions.entries.rsc } }
719
- },
720
- resolve: {
721
- conditions: ["react-server", ...defaultServerConditions],
722
- noExternal
723
- },
724
- optimizeDeps: {
725
- include: [
726
- "react",
727
- "react-dom",
728
- "react/jsx-runtime",
729
- "react/jsx-dev-runtime",
730
- `${reactServerDomPackageName}/server.edge`,
731
- `${reactServerDomPackageName}/client.edge`
732
- ],
733
- exclude: [PKG_NAME]
734
- }
735
- }
736
- },
737
- builder: rscPluginOptions.customBuildApp ? void 0 : {
738
- sharedPlugins: true,
739
- sharedConfigBuild: true,
740
- async buildApp(builder) {
741
- if (!rscPluginOptions.useBuildAppHook) await buildApp(builder);
742
- }
743
- }
744
- };
745
- },
746
- configResolved() {
747
- if (Number(vite.version.split(".")[0]) >= 7) rscPluginOptions.useBuildAppHook ??= true;
748
- },
749
- buildApp: { async handler(builder) {
750
- if (rscPluginOptions.customBuildApp) return;
751
- if (rscPluginOptions.useBuildAppHook) await buildApp(builder);
752
- } },
753
- configureServer(server) {
754
- globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__ = async function(environmentName, id) {
755
- const environment = server.environments[environmentName];
756
- if (!environment) throw new Error(`[vite-rsc] unknown environment '${environmentName}'`);
757
- if (!vite.isRunnableDevEnvironment(environment)) throw new Error(`[vite-rsc] environment '${environmentName}' is not runnable`);
758
- return environment.runner.import(id);
759
- };
760
- const oldSend = server.environments.client.hot.send;
761
- server.environments.client.hot.send = async function(...args) {
762
- const e = args[0];
763
- if (e && typeof e === "object" && e.type === "update") {
764
- for (const update of e.updates) if (update.type === "js-update") {
765
- const mod = server.environments.client.moduleGraph.urlToModuleMap.get(update.path);
766
- if (mod && mod.id && manager.clientReferenceMetaMap[mod.id]) {
767
- const serverMod = server.environments.rsc.moduleGraph.getModuleById(mod.id);
768
- if (serverMod) server.environments.rsc.moduleGraph.invalidateModule(serverMod);
769
- }
770
- }
771
- }
772
- return oldSend.apply(this, args);
773
- };
774
- if (rscPluginOptions.serverHandler === false) return;
775
- const options = rscPluginOptions.serverHandler ?? {
776
- environmentName: "rsc",
777
- entryName: "index"
778
- };
779
- const environment = server.environments[options.environmentName];
780
- const source = getEntrySource(environment.config, options.entryName);
781
- return () => {
782
- server.middlewares.use(async (req, res, next) => {
783
- try {
784
- const resolved = await environment.pluginContainer.resolveId(source);
785
- assert(resolved, `[vite-rsc] failed to resolve server handler '${source}'`);
786
- const fetchHandler = getFetchHandlerExport(await environment.runner.import(resolved.id));
787
- req.url = req.originalUrl ?? req.url;
788
- await toNodeHandler(fetchHandler)(req, res);
789
- } catch (e) {
790
- next(e);
791
- }
792
- });
793
- };
794
- },
795
- async configurePreviewServer(server) {
796
- if (rscPluginOptions.serverHandler === false) return;
797
- const options = rscPluginOptions.serverHandler ?? {
798
- environmentName: "rsc",
799
- entryName: "index"
800
- };
801
- const handler = toNodeHandler(getFetchHandlerExport(await import(pathToFileURL(path.join(manager.config.environments[options.environmentName].build.outDir, `${options.entryName}.js`)).href)));
802
- server.middlewares.use((req, _res, next) => {
803
- delete req.headers["accept-encoding"];
804
- next();
805
- });
806
- return () => {
807
- server.middlewares.use(async (req, res, next) => {
808
- try {
809
- req.url = req.originalUrl ?? req.url;
810
- await handler(req, res);
811
- } catch (e) {
812
- next(e);
813
- }
814
- });
815
- };
816
- },
817
- async hotUpdate(ctx) {
818
- if (isCSSRequest(ctx.file)) {
819
- if (this.environment.name === "client") return;
820
- }
821
- if (ctx.modules.map((mod) => mod.id).filter((v) => v !== null).length === 0) return;
822
- if (this.environment.name === "rsc") {
823
- for (const mod of ctx.modules) if (mod.type === "js" && mod.id && mod.id in manager.clientReferenceMetaMap) try {
824
- await this.environment.transformRequest(mod.url);
825
- } catch {}
826
- }
827
- function isInsideClientBoundary(mods) {
828
- const visited = /* @__PURE__ */ new Set();
829
- function recurse(mod) {
830
- if (!mod.id) return false;
831
- if (manager.clientReferenceMetaMap[mod.id]) return true;
832
- if (visited.has(mod.id)) return false;
833
- visited.add(mod.id);
834
- for (const importer of mod.importers) if (recurse(importer)) return true;
835
- return false;
836
- }
837
- return mods.some((mod) => recurse(mod));
838
- }
839
- if (!isInsideClientBoundary(ctx.modules)) {
840
- if (this.environment.name === "rsc") {
841
- if (ctx.modules.length === 1) {
842
- const importers = [...ctx.modules[0].importers];
843
- if (importers.length > 0 && importers.every((m) => m.id && isCSSRequest(m.id))) return [];
844
- }
845
- for (const mod of ctx.modules) if (mod.type === "js") try {
846
- await this.environment.transformRequest(mod.url);
847
- } catch (e) {
848
- manager.server.environments.client.hot.send({
849
- type: "error",
850
- err: prepareError(e)
851
- });
852
- throw e;
853
- }
854
- ctx.server.environments.client.hot.send({
855
- type: "custom",
856
- event: "rsc:update",
857
- data: { file: ctx.file }
858
- });
859
- }
860
- if (this.environment.name === "client") {
861
- if (ctx.server.environments.rsc.moduleGraph.getModuleById(ctx.file)) {
862
- for (const clientMod of ctx.modules) for (const importer of clientMod.importers) if (importer.id && isCSSRequest(importer.id)) await this.environment.reloadModule(importer);
863
- return [];
864
- }
865
- }
866
- }
867
- }
868
- },
869
- {
870
- name: "rsc:react-server-dom-webpack-alias",
871
- resolveId: {
872
- order: "pre",
873
- filter: { id: prefixRegex(`${PKG_NAME}/vendor/react-server-dom/`) },
874
- async handler(source, importer, options) {
875
- if (hasReactServerDomWebpack && source.startsWith(`${PKG_NAME}/vendor/react-server-dom/`)) {
876
- const newSource = source.replace(`${PKG_NAME}/vendor/react-server-dom`, "react-server-dom-webpack");
877
- return await this.resolve(newSource, importer, {
878
- ...options,
879
- skipSelf: true
880
- });
881
- }
882
- }
883
- }
884
- },
885
- {
886
- name: "rsc:load-environment-module",
887
- transform: {
888
- filter: { code: "import.meta.viteRsc.loadModule" },
889
- async handler(code) {
890
- if (!code.includes("import.meta.viteRsc.loadModule")) return;
891
- const { server } = manager;
892
- const s = new MagicString(code);
893
- for (const match of stripLiteral(code).matchAll(/import\.meta\.viteRsc\.loadModule\(([\s\S]*?)\)/dg)) {
894
- const [argStart, argEnd] = match.indices[1];
895
- const [environmentName, entryName] = evalValue(`[${code.slice(argStart, argEnd).trim()}]`);
896
- let replacement;
897
- if (this.environment.mode === "dev" && rscPluginOptions.loadModuleDevProxy) replacement = `import("virtual:vite-rsc/rpc-client").then((module) => module.createRpcClient(${JSON.stringify({
898
- environmentName,
899
- entryName
900
- })}))`;
901
- else if (this.environment.mode === "dev") {
902
- const environment = server.environments[environmentName];
903
- const source = getEntrySource(environment.config, entryName);
904
- const resolved = await environment.pluginContainer.resolveId(source);
905
- assert(resolved, `[vite-rsc] failed to resolve entry '${source}'`);
906
- replacement = `globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__(${JSON.stringify(environmentName)}, ${JSON.stringify(resolved.id)})`;
907
- } else {
908
- const environment = manager.config.environments[environmentName];
909
- const targetName = entryName || getFallbackRollupEntry(environment.build.rollupOptions.input).name;
910
- replacement = JSON.stringify(`__vite_rsc_load_module_start__:` + JSON.stringify({
911
- fromEnv: this.environment.name,
912
- toEnv: environmentName,
913
- targetFileName: `${targetName}.js`
914
- }) + `:__vite_rsc_load_module_end__`);
915
- }
916
- const [start, end] = match.indices[0];
917
- s.overwrite(start, end, replacement);
918
- }
919
- if (s.hasChanged()) return {
920
- code: s.toString(),
921
- map: s.generateMap({ hires: "boundary" })
922
- };
923
- }
924
- },
925
- renderChunk(code, chunk) {
926
- if (!code.includes("__vite_rsc_load_module")) return;
927
- const { config } = manager;
928
- const s = new MagicString(code);
929
- for (const match of code.matchAll(/[`'"]__vite_rsc_load_module_start__:([\s\S]*?):__vite_rsc_load_module_end__[`'"]/dg)) {
930
- const markerString = evalValue(match[0]);
931
- const { fromEnv, toEnv, targetFileName } = JSON.parse(markerString.slice(31, -29));
932
- const importPath = normalizeRelativePath(path.relative(path.join(config.environments[fromEnv].build.outDir, chunk.fileName, ".."), path.join(config.environments[toEnv].build.outDir, targetFileName)));
933
- const replacement = `(import(${JSON.stringify(importPath)}))`;
934
- const [start, end] = match.indices[0];
935
- s.overwrite(start, end, replacement);
936
- }
937
- if (s.hasChanged()) return {
938
- code: s.toString(),
939
- map: s.generateMap({ hires: "boundary" })
940
- };
941
- }
942
- },
943
- {
944
- name: "vite-rsc-load-module-dev-proxy",
945
- configureServer(server) {
946
- if (!rscPluginOptions.loadModuleDevProxy) return;
947
- async function createHandler(url) {
948
- const { environmentName, entryName } = Object.fromEntries(url.searchParams);
949
- assert(environmentName);
950
- const environment = server.environments[environmentName];
951
- const source = getEntrySource(environment.config, entryName);
952
- const resolvedEntry = await environment.pluginContainer.resolveId(source);
953
- assert(resolvedEntry, `[vite-rsc] failed to resolve entry '${source}'`);
954
- return createRpcServer(new Proxy({}, { get(_target, p, _receiver) {
955
- if (typeof p !== "string" || p === "then") return;
956
- return async (...args) => {
957
- return (await environment.runner.import(resolvedEntry.id))[p](...args);
958
- };
959
- } }));
960
- }
961
- server.middlewares.use(async (req, res, next) => {
962
- const url = new URL(req.url ?? "/", `http://localhost`);
963
- if (url.pathname === "/__vite_rsc_load_module_dev_proxy") {
964
- try {
965
- await toNodeHandler(await createHandler(url))(req, res);
966
- } catch (e) {
967
- next(e);
968
- }
969
- return;
970
- }
971
- next();
972
- });
973
- }
974
- },
975
- {
976
- name: "rsc:virtual:vite-rsc/rpc-client",
977
- resolveId: {
978
- filter: { id: exactRegex("virtual:vite-rsc/rpc-client") },
979
- handler(source) {
980
- if (source === "virtual:vite-rsc/rpc-client") return `\0${source}`;
981
- }
982
- },
983
- load: {
984
- filter: { id: exactRegex("\0virtual:vite-rsc/rpc-client") },
985
- handler(id) {
986
- if (id === "\0virtual:vite-rsc/rpc-client") {
987
- const { server } = manager;
988
- const origin = server.resolvedUrls?.local[0];
989
- assert(origin, "[vite-rsc] no server for loadModuleDevProxy");
990
- return `\
991
- import * as __vite_rsc_rpc from "@vitejs/plugin-rsc/utils/rpc";
992
- export function createRpcClient(params) {
993
- const endpoint =
994
- "${origin}" +
995
- "__vite_rsc_load_module_dev_proxy?" +
996
- new URLSearchParams(params);
997
- return __vite_rsc_rpc.createRpcClient({ endpoint });
998
- }
999
- `;
1000
- }
1001
- }
1002
- }
1003
- },
1004
- {
1005
- name: "rsc:virtual:vite-rsc/assets-manifest",
1006
- resolveId: {
1007
- filter: { id: exactRegex("virtual:vite-rsc/assets-manifest") },
1008
- handler(source) {
1009
- if (source === "virtual:vite-rsc/assets-manifest") {
1010
- if (this.environment.mode === "build") return {
1011
- id: source,
1012
- external: true
1013
- };
1014
- return `\0` + source;
1015
- }
1016
- }
1017
- },
1018
- load: {
1019
- filter: { id: exactRegex("\0virtual:vite-rsc/assets-manifest") },
1020
- handler(id) {
1021
- if (id === "\0virtual:vite-rsc/assets-manifest") {
1022
- assert(this.environment.name !== "client");
1023
- assert(this.environment.mode === "dev");
1024
- const manifest = {
1025
- bootstrapScriptContent: `import(${serializeValueWithRuntime(assetsURL("@id/__x00__" + VIRTUAL_ENTRIES.browser, manager))})`,
1026
- clientReferenceDeps: {},
1027
- cssLinkPrecedence: rscPluginOptions.cssLinkPrecedence
1028
- };
1029
- return `export default ${JSON.stringify(manifest, null, 2)}`;
1030
- }
1031
- }
1032
- },
1033
- generateBundle(_options, bundle) {
1034
- manager.bundles[this.environment.name] = bundle;
1035
- if (this.environment.name === "client") {
1036
- const filterAssets = rscPluginOptions.copyServerAssetsToClient ?? (() => true);
1037
- const rscBuildOptions = manager.config.environments.rsc.build;
1038
- const rscViteManifest = typeof rscBuildOptions.manifest === "string" ? rscBuildOptions.manifest : rscBuildOptions.manifest && ".vite/manifest.json";
1039
- for (const asset of Object.values(manager.bundles["rsc"])) {
1040
- if (asset.fileName === rscViteManifest) continue;
1041
- if (asset.type === "asset" && filterAssets(asset.fileName)) this.emitFile({
1042
- type: "asset",
1043
- fileName: asset.fileName,
1044
- source: asset.source
1045
- });
1046
- }
1047
- const serverResources = {};
1048
- const rscAssetDeps = collectAssetDeps(manager.bundles["rsc"]);
1049
- for (const [id, meta] of Object.entries(manager.serverResourcesMetaMap)) serverResources[meta.key] = assetsURLOfDeps({
1050
- js: [],
1051
- css: rscAssetDeps[id]?.deps.css ?? []
1052
- }, manager);
1053
- const assetDeps = collectAssetDeps(bundle);
1054
- let bootstrapScriptContent = "";
1055
- const clientReferenceDeps = {};
1056
- for (const meta of Object.values(manager.clientReferenceMetaMap)) {
1057
- const deps = assetDeps[meta.groupChunkId]?.deps ?? {
1058
- js: [],
1059
- css: []
1060
- };
1061
- clientReferenceDeps[meta.referenceKey] = assetsURLOfDeps(deps, manager);
1062
- }
1063
- if (!rscPluginOptions.customClientEntry) {
1064
- const entry = Object.values(assetDeps).find((v) => v.chunk.name === "index" && v.chunk.isEntry);
1065
- if (!entry) throw new Error(`[vite-rsc] Client build must have an entry chunk named "index". Use 'customClientEntry' option to disable this requirement.`);
1066
- const entryDeps = assetsURLOfDeps(entry.deps, manager);
1067
- for (const [key, deps] of Object.entries(clientReferenceDeps)) clientReferenceDeps[key] = mergeAssetDeps(deps, entryDeps);
1068
- const entryUrl = assetsURL(entry.chunk.fileName, manager);
1069
- if (typeof entryUrl === "string") bootstrapScriptContent = `import(${JSON.stringify(entryUrl)})`;
1070
- else bootstrapScriptContent = new RuntimeAsset(`"import(" + JSON.stringify(${entryUrl.runtime}) + ")"`);
1071
- }
1072
- manager.buildAssetsManifest = {
1073
- bootstrapScriptContent,
1074
- clientReferenceDeps,
1075
- serverResources,
1076
- cssLinkPrecedence: rscPluginOptions.cssLinkPrecedence
1077
- };
1078
- }
1079
- },
1080
- renderChunk(code, chunk) {
1081
- if (code.includes("virtual:vite-rsc/assets-manifest")) {
1082
- assert(this.environment.name !== "client");
1083
- const replacement = normalizeRelativePath(path.relative(path.join(chunk.fileName, ".."), BUILD_ASSETS_MANIFEST_NAME));
1084
- code = code.replaceAll("virtual:vite-rsc/assets-manifest", () => replacement);
1085
- return { code };
1086
- }
1087
- }
1088
- },
1089
- createVirtualPlugin("vite-rsc/bootstrap-script-content", function() {
1090
- assert(this.environment.name !== "client");
1091
- return `\
1092
- import assetsManifest from "virtual:vite-rsc/assets-manifest";
1093
- export default assetsManifest.bootstrapScriptContent;
1094
- `;
1095
- }),
1096
- {
1097
- name: "rsc:bootstrap-script-content",
1098
- transform: {
1099
- filter: { code: "loadBootstrapScriptContent" },
1100
- async handler(code) {
1101
- if (!code.includes("loadBootstrapScriptContent") || !/import\s*\.\s*meta\s*\.\s*viteRsc\s*\.\s*loadBootstrapScriptContent/.test(code)) return;
1102
- assert(!rscPluginOptions.customClientEntry, `[vite-rsc] 'import.meta.viteRsc.loadBootstrapScriptContent' cannot be used with 'customClientEntry' option`);
1103
- assert(this.environment.name !== "client");
1104
- const output = new MagicString(code);
1105
- for (const match of stripLiteral(code).matchAll(/import\s*\.\s*meta\s*\.\s*viteRsc\s*\.\s*loadBootstrapScriptContent\(([\s\S]*?)\)/dg)) {
1106
- const [argStart, argEnd] = match.indices[1];
1107
- const argCode = code.slice(argStart, argEnd).trim();
1108
- assert(evalValue(argCode), `[vite-rsc] expected 'loadBootstrapScriptContent("index")' but got ${argCode}`);
1109
- let replacement = `Promise.resolve(__vite_rsc_assets_manifest.bootstrapScriptContent)`;
1110
- const [start, end] = match.indices[0];
1111
- output.overwrite(start, end, replacement);
1112
- }
1113
- if (output.hasChanged()) {
1114
- if (!code.includes("__vite_rsc_assets_manifest")) output.prepend(`import __vite_rsc_assets_manifest from "virtual:vite-rsc/assets-manifest";`);
1115
- return {
1116
- code: output.toString(),
1117
- map: output.generateMap({ hires: "boundary" })
1118
- };
1119
- }
1120
- }
1121
- }
1122
- },
1123
- createVirtualPlugin(VIRTUAL_ENTRIES.browser.slice(8), async function() {
1124
- assert(this.environment.mode === "dev");
1125
- let code = "";
1126
- if (await this.resolve("/@react-refresh")) code += `
1127
- import RefreshRuntime from "/@react-refresh";
1128
- RefreshRuntime.injectIntoGlobalHook(window);
1129
- window.$RefreshReg$ = () => {};
1130
- window.$RefreshSig$ = () => (type) => type;
1131
- window.__vite_plugin_react_preamble_installed__ = true;
1132
- `;
1133
- const source = getEntrySource(this.environment.config, "index");
1134
- const resolvedEntry = await this.resolve(source);
1135
- assert(resolvedEntry, `[vite-rsc] failed to resolve entry '${source}'`);
1136
- code += `await import(${JSON.stringify(resolvedEntry.id)});`;
1137
- code += `
1138
- const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
1139
- import.meta.hot.on("vite:beforeUpdate", () => {
1140
- ssrCss.forEach(node => {
1141
- if (node.dataset.precedence?.startsWith("vite-rsc/client-references")) {
1142
- node.remove();
1143
- }
1144
- });
1145
- });
1146
- `;
1147
- code += `
1148
- import.meta.hot.on("rsc:update", () => {
1149
- document.querySelectorAll("vite-error-overlay").forEach((n) => n.close())
1150
- });
1151
- `;
1152
- code += `import.meta.hot.on("rsc:prune", ${(e) => {
1153
- document.querySelectorAll("link[rel='stylesheet']").forEach((node) => {
1154
- if (e.paths.includes(node.dataset.rscCssHref)) node.remove();
1155
- });
1156
- }});`;
1157
- return code;
1158
- }),
1159
- ...vitePluginRscMinimal(rscPluginOptions, manager),
1160
- ...vitePluginImportEnvironment(manager),
1161
- ...vitePluginFindSourceMapURL(),
1162
- ...vitePluginRscCss(rscPluginOptions, manager),
1163
- {
1164
- ...validateImportPlugin(),
1165
- apply: () => rscPluginOptions.validateImports !== false
1166
- },
1167
- scanBuildStripPlugin({ manager }),
1168
- ...cjsModuleRunnerPlugin(),
1169
- ...globalAsyncLocalStoragePlugin()
1170
- ];
1171
- }
1172
- function globalAsyncLocalStoragePlugin() {
1173
- return [{
1174
- name: "rsc:inject-async-local-storage",
1175
- transform: {
1176
- filter: { code: "typeof AsyncLocalStorage" },
1177
- handler(code) {
1178
- if ((this.environment.name === "ssr" || this.environment.name === "rsc") && code.includes("typeof AsyncLocalStorage") && code.includes("new AsyncLocalStorage()") && !code.includes("__viteRscAsyncHooks")) return (this.environment.mode === "build" && !isRolldownVite ? `const __viteRscAsyncHooks = require("node:async_hooks");` : `import * as __viteRscAsyncHooks from "node:async_hooks";`) + `globalThis.AsyncLocalStorage = __viteRscAsyncHooks.AsyncLocalStorage;` + code;
1179
- }
1180
- }
1181
- }];
1182
- }
1183
- function vitePluginUseClient(useClientPluginOptions, manager) {
1184
- const packageSources = /* @__PURE__ */ new Map();
1185
- const bareImportRE = /^(?![a-zA-Z]:)[\w@](?!.*:\/\/)/;
1186
- const serverEnvironmentName = useClientPluginOptions.environment?.rsc ?? "rsc";
1187
- const browserEnvironmentName = useClientPluginOptions.environment?.browser ?? "client";
1188
- let optimizerMetadata;
1189
- function warnInoncistentClientOptimization(ctx, id) {
1190
- id = normalizePath(path.relative(process.cwd(), id));
1191
- if (optimizerMetadata?.ids.includes(id)) ctx.warn("client component dependency is inconsistently optimized. It's recommended to add the dependency to 'optimizeDeps.exclude'.");
1192
- }
1193
- const debug = createDebug("vite-rsc:use-client");
1194
- return [
1195
- {
1196
- name: "rsc:use-client",
1197
- transform: { async handler(code, id) {
1198
- if (this.environment.name !== serverEnvironmentName) return;
1199
- if (!code.includes("use client")) {
1200
- delete manager.clientReferenceMetaMap[id];
1201
- return;
1202
- }
1203
- const ast = await parseAstAsync(code);
1204
- if (!hasDirective(ast.body, "use client")) {
1205
- delete manager.clientReferenceMetaMap[id];
1206
- return;
1207
- }
1208
- if (code.includes("use server")) {
1209
- const directives = findDirectives(ast, "use server");
1210
- if (directives.length > 0) this.error(`'use server' directive is not allowed inside 'use client'`, directives[0]?.start);
1211
- }
1212
- let importId;
1213
- let referenceKey;
1214
- const packageSource = packageSources.get(id);
1215
- if (!packageSource && this.environment.mode === "dev" && id.includes("/node_modules/")) {
1216
- debug(`internal client reference created through a package imported in '${this.environment.name}' environment: ${id}`);
1217
- id = cleanUrl(id);
1218
- warnInoncistentClientOptimization(this, id);
1219
- importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent(id)}`;
1220
- referenceKey = importId;
1221
- } else if (packageSource) if (this.environment.mode === "dev") {
1222
- importId = `/@id/__x00__virtual:vite-rsc/client-package-proxy/${packageSource}`;
1223
- referenceKey = importId;
1224
- } else {
1225
- importId = packageSource;
1226
- referenceKey = hashString(packageSource);
1227
- }
1228
- else if (this.environment.mode === "dev") {
1229
- importId = normalizeViteImportAnalysisUrl(manager.server.environments[browserEnvironmentName], id);
1230
- referenceKey = importId;
1231
- } else {
1232
- importId = id;
1233
- referenceKey = hashString(manager.toRelativeId(id));
1234
- }
1235
- const result = withRollupError(this, transformDirectiveProxyExport)(ast, {
1236
- directive: "use client",
1237
- code,
1238
- keep: !!useClientPluginOptions.keepUseCientProxy,
1239
- runtime: (name, meta) => {
1240
- let proxyValue = `() => { throw new Error("Unexpectedly client reference export '" + ` + JSON.stringify(name) + ` + "' is called on server") }`;
1241
- if (meta?.value) proxyValue = `(${meta.value})`;
1242
- return `$$ReactServer.registerClientReference( ${proxyValue}, ${JSON.stringify(referenceKey)}, ${JSON.stringify(name)})`;
1243
- }
1244
- });
1245
- if (!result) return;
1246
- const { output, exportNames } = result;
1247
- manager.clientReferenceMetaMap[id] = {
1248
- importId,
1249
- referenceKey,
1250
- packageSource,
1251
- exportNames,
1252
- renderedExports: []
1253
- };
1254
- const importSource = resolvePackage(`${PKG_NAME}/react/rsc`);
1255
- output.prepend(`import * as $$ReactServer from "${importSource}";\n`);
1256
- return {
1257
- code: output.toString(),
1258
- map: { mappings: "" }
1259
- };
1260
- } }
1261
- },
1262
- {
1263
- name: "rsc:use-client/build-references",
1264
- resolveId: {
1265
- filter: { id: prefixRegex("virtual:vite-rsc/client-references") },
1266
- handler(source) {
1267
- if (source.startsWith("virtual:vite-rsc/client-references")) return "\0" + source;
1268
- }
1269
- },
1270
- load: {
1271
- filter: { id: prefixRegex("\0virtual:vite-rsc/client-references") },
1272
- handler(id) {
1273
- if (id === "\0virtual:vite-rsc/client-references") {
1274
- if (this.environment.mode === "dev") return {
1275
- code: `export default {}`,
1276
- map: null
1277
- };
1278
- if (manager.isScanBuild) {
1279
- let code = ``;
1280
- for (const meta of Object.values(manager.clientReferenceMetaMap)) code += `import ${JSON.stringify(withResolvedIdProxy(meta.importId))};\n`;
1281
- return {
1282
- code,
1283
- map: null
1284
- };
1285
- }
1286
- let code = "";
1287
- manager.clientReferenceGroups = {};
1288
- for (const meta of Object.values(manager.clientReferenceMetaMap)) {
1289
- if (!meta.serverChunk) continue;
1290
- let name = useClientPluginOptions.clientChunks?.({
1291
- id: meta.importId,
1292
- normalizedId: manager.toRelativeId(meta.importId),
1293
- serverChunk: meta.serverChunk
1294
- }) ?? meta.serverChunk;
1295
- name = cleanUrl(name.replaceAll("..", "__"));
1296
- (manager.clientReferenceGroups[name] ??= []).push(meta);
1297
- meta.groupChunkId = `\0virtual:vite-rsc/client-references/group/${name}`;
1298
- }
1299
- debug("client-reference-groups", manager.clientReferenceGroups);
1300
- for (const [name, metas] of Object.entries(manager.clientReferenceGroups)) {
1301
- const groupVirtual = `virtual:vite-rsc/client-references/group/${name}`;
1302
- for (const meta of metas) code += `\
1303
- ${JSON.stringify(meta.referenceKey)}: async () => {
1304
- const m = await import(${JSON.stringify(groupVirtual)});
1305
- return m.export_${meta.referenceKey};
1306
- },
1307
- `;
1308
- }
1309
- code = `export default {${code}};\n`;
1310
- return {
1311
- code,
1312
- map: null
1313
- };
1314
- }
1315
- if (id.startsWith("\0virtual:vite-rsc/client-references/group/")) {
1316
- const name = id.slice(42);
1317
- const metas = manager.clientReferenceGroups[name];
1318
- assert(metas, `unknown client reference group: ${name}`);
1319
- let code = ``;
1320
- for (const meta of metas) {
1321
- const exports = meta.renderedExports.map((name) => `${name}: import_${meta.referenceKey}.${name},\n`).sort().join("");
1322
- code += `
1323
- import * as import_${meta.referenceKey} from ${JSON.stringify(withResolvedIdProxy(meta.importId))};
1324
- export const export_${meta.referenceKey} = {${exports}};
1325
- `;
1326
- }
1327
- return {
1328
- code,
1329
- map: null
1330
- };
1331
- }
1332
- }
1333
- }
1334
- },
1335
- {
1336
- name: "rsc:virtual-client-in-server-package",
1337
- load: {
1338
- filter: { id: prefixRegex("\0virtual:vite-rsc/client-in-server-package-proxy/") },
1339
- async handler(id) {
1340
- if (id.startsWith("\0virtual:vite-rsc/client-in-server-package-proxy/")) {
1341
- assert.equal(this.environment.mode, "dev");
1342
- assert(this.environment.name !== serverEnvironmentName);
1343
- id = decodeURIComponent(id.slice(49));
1344
- return `
1345
- export * from ${JSON.stringify(id)};
1346
- import * as __all__ from ${JSON.stringify(id)};
1347
- export default __all__.default;
1348
- `;
1349
- }
1350
- }
1351
- }
1352
- },
1353
- {
1354
- name: "rsc:virtual-client-package",
1355
- resolveId: {
1356
- order: "pre",
1357
- async handler(source, importer, options) {
1358
- if (this.environment.name === serverEnvironmentName && bareImportRE.test(source) && !(source === "client-only" || source === "server-only")) {
1359
- const resolved = await this.resolve(source, importer, options);
1360
- if (resolved && resolved.id.includes("/node_modules/")) {
1361
- packageSources.set(resolved.id, source);
1362
- return resolved;
1363
- }
1364
- }
1365
- }
1366
- },
1367
- load: {
1368
- filter: { id: prefixRegex("\0virtual:vite-rsc/client-package-proxy/") },
1369
- async handler(id) {
1370
- if (id.startsWith("\0virtual:vite-rsc/client-package-proxy/")) {
1371
- assert(this.environment.mode === "dev");
1372
- const source = id.slice(39);
1373
- return `export {${Object.values(manager.clientReferenceMetaMap).find((v) => v.packageSource === source).exportNames.join(",")}} from ${JSON.stringify(source)};\n`;
1374
- }
1375
- }
1376
- },
1377
- generateBundle(_options, bundle) {
1378
- if (manager.isScanBuild) return;
1379
- if (this.environment.name !== serverEnvironmentName) return;
1380
- for (const chunk of Object.values(bundle)) if (chunk.type === "chunk") {
1381
- const metas = [];
1382
- for (const id of chunk.moduleIds) {
1383
- const meta = manager.clientReferenceMetaMap[id];
1384
- if (meta) metas.push([id, meta]);
1385
- }
1386
- if (metas.length > 0) {
1387
- let serverChunk;
1388
- if (chunk.facadeModuleId) serverChunk = "facade:" + manager.toRelativeId(chunk.facadeModuleId);
1389
- else serverChunk = "shared:" + manager.toRelativeId(metas.map(([id]) => id).sort()[0]);
1390
- for (const [id, meta] of metas) {
1391
- const mod = chunk.modules[id];
1392
- assert(mod);
1393
- meta.renderedExports = mod.renderedExports;
1394
- meta.serverChunk = serverChunk;
1395
- }
1396
- }
1397
- }
1398
- }
1399
- },
1400
- ...customOptimizerMetadataPlugin({ setMetadata: (metadata) => {
1401
- optimizerMetadata = metadata;
1402
- } })
1403
- ];
1404
- }
1405
- function customOptimizerMetadataPlugin({ setMetadata }) {
1406
- const MEATADATA_FILE = "_metadata-rsc.json";
1407
- function optimizerPluginEsbuild() {
1408
- return {
1409
- name: "vite-rsc-metafile",
1410
- setup(build) {
1411
- build.onEnd((result) => {
1412
- if (!result.metafile?.inputs || !build.initialOptions.outdir) return;
1413
- const metadata = { ids: Object.keys(result.metafile.inputs) };
1414
- setMetadata(metadata);
1415
- fs.writeFileSync(path.join(build.initialOptions.outdir, MEATADATA_FILE), JSON.stringify(metadata, null, 2));
1416
- });
1417
- }
1418
- };
1419
- }
1420
- function optimizerPluginRolldown() {
1421
- return {
1422
- name: "vite-rsc-metafile",
1423
- writeBundle(options) {
1424
- assert(options.dir);
1425
- const metadata = { ids: [...this.getModuleIds()].map((id) => path.relative(process.cwd(), id)) };
1426
- setMetadata(metadata);
1427
- fs.writeFileSync(path.join(options.dir, MEATADATA_FILE), JSON.stringify(metadata, null, 2));
1428
- }
1429
- };
1430
- }
1431
- return [{
1432
- name: "rsc:use-client:optimizer-metadata",
1433
- apply: "serve",
1434
- config() {
1435
- return { environments: { client: { optimizeDeps: "rolldownVersion" in vite ? { rolldownOptions: { plugins: [optimizerPluginRolldown()] } } : { esbuildOptions: { plugins: [optimizerPluginEsbuild()] } } } } };
1436
- },
1437
- configResolved(config) {
1438
- const file = path.join(config.cacheDir, "deps", MEATADATA_FILE);
1439
- if (fs.existsSync(file)) try {
1440
- setMetadata(JSON.parse(fs.readFileSync(file, "utf-8")));
1441
- } catch (e) {
1442
- this.warn(`failed to load '${file}'`);
1443
- }
1444
- }
1445
- }];
1446
- }
1447
- function vitePluginDefineEncryptionKey(useServerPluginOptions) {
1448
- let defineEncryptionKey;
1449
- let emitEncryptionKey = false;
1450
- const KEY_PLACEHOLDER = "__vite_rsc_define_encryption_key";
1451
- const KEY_FILE = "__vite_rsc_encryption_key.js";
1452
- const serverEnvironmentName = useServerPluginOptions.environment?.rsc ?? "rsc";
1453
- return [{
1454
- name: "rsc:encryption-key",
1455
- async configEnvironment(name, _config, env) {
1456
- if (name === serverEnvironmentName && !env.isPreview) defineEncryptionKey = useServerPluginOptions.defineEncryptionKey ?? JSON.stringify(toBase64(await generateEncryptionKey()));
1457
- },
1458
- resolveId: {
1459
- filter: { id: exactRegex("virtual:vite-rsc/encryption-key") },
1460
- handler(source) {
1461
- if (source === "virtual:vite-rsc/encryption-key") return {
1462
- id: "\0" + source,
1463
- moduleSideEffects: false
1464
- };
1465
- }
1466
- },
1467
- load: {
1468
- filter: { id: exactRegex("\0virtual:vite-rsc/encryption-key") },
1469
- handler(id) {
1470
- if (id === "\0virtual:vite-rsc/encryption-key") {
1471
- if (this.environment.mode === "build") return `export default () => ${KEY_PLACEHOLDER}`;
1472
- return `export default () => (${defineEncryptionKey})`;
1473
- }
1474
- }
1475
- },
1476
- renderChunk(code, chunk) {
1477
- if (code.includes(KEY_PLACEHOLDER)) {
1478
- assert.equal(this.environment.name, serverEnvironmentName);
1479
- emitEncryptionKey = true;
1480
- const normalizedPath = normalizeRelativePath(path.relative(path.join(chunk.fileName, ".."), KEY_FILE));
1481
- const replacement = `import(${JSON.stringify(normalizedPath)}).then(__m => __m.default)`;
1482
- code = code.replaceAll(KEY_PLACEHOLDER, () => replacement);
1483
- return { code };
1484
- }
1485
- },
1486
- writeBundle() {
1487
- if (this.environment.name === serverEnvironmentName && emitEncryptionKey) fs.writeFileSync(path.join(this.environment.config.build.outDir, KEY_FILE), `export default ${defineEncryptionKey};\n`);
1488
- }
1489
- }];
1490
- }
1491
- function vitePluginUseServer(useServerPluginOptions, manager) {
1492
- const serverEnvironmentName = useServerPluginOptions.environment?.rsc ?? "rsc";
1493
- const browserEnvironmentName = useServerPluginOptions.environment?.browser ?? "client";
1494
- const debug = createDebug("vite-rsc:use-server");
1495
- return [{
1496
- name: "rsc:use-server",
1497
- transform: { async handler(code, id) {
1498
- if (!code.includes("use server")) {
1499
- delete manager.serverReferenceMetaMap[id];
1500
- return;
1501
- }
1502
- const ast = await parseAstAsync(code);
1503
- let normalizedId_;
1504
- const getNormalizedId = () => {
1505
- if (!normalizedId_) {
1506
- if (this.environment.mode === "dev" && id.includes("/node_modules/")) {
1507
- debug(`internal server reference created through a package imported in ${this.environment.name} environment: ${id}`);
1508
- id = cleanUrl(id);
1509
- }
1510
- if (manager.config.command === "build") normalizedId_ = hashString(manager.toRelativeId(id));
1511
- else normalizedId_ = normalizeViteImportAnalysisUrl(manager.server.environments[serverEnvironmentName], id);
1512
- }
1513
- return normalizedId_;
1514
- };
1515
- if (this.environment.name === serverEnvironmentName) {
1516
- const transformServerActionServer_ = withRollupError(this, transformServerActionServer);
1517
- const enableEncryption = useServerPluginOptions.enableActionEncryption ?? true;
1518
- const result = transformServerActionServer_(code, ast, {
1519
- runtime: (value, name) => `$$ReactServer.registerServerReference(${value}, ${JSON.stringify(getNormalizedId())}, ${JSON.stringify(name)})`,
1520
- rejectNonAsyncFunction: true,
1521
- encode: enableEncryption ? (value) => `__vite_rsc_encryption_runtime.encryptActionBoundArgs(${value})` : void 0,
1522
- decode: enableEncryption ? (value) => `await __vite_rsc_encryption_runtime.decryptActionBoundArgs(${value})` : void 0
1523
- });
1524
- const output = result.output;
1525
- if (!result || !output.hasChanged()) {
1526
- delete manager.serverReferenceMetaMap[id];
1527
- return;
1528
- }
1529
- manager.serverReferenceMetaMap[id] = {
1530
- importId: id,
1531
- referenceKey: getNormalizedId(),
1532
- exportNames: "names" in result ? result.names : result.exportNames
1533
- };
1534
- const importSource = resolvePackage(`${PKG_NAME}/react/rsc`);
1535
- output.prepend(`import * as $$ReactServer from "${importSource}";\n`);
1536
- if (enableEncryption) {
1537
- const importSource = resolvePackage(`${PKG_NAME}/utils/encryption-runtime`);
1538
- output.prepend(`import * as __vite_rsc_encryption_runtime from ${JSON.stringify(importSource)};\n`);
1539
- }
1540
- return {
1541
- code: output.toString(),
1542
- map: output.generateMap({ hires: "boundary" })
1543
- };
1544
- } else {
1545
- if (!hasDirective(ast.body, "use server")) {
1546
- delete manager.serverReferenceMetaMap[id];
1547
- return;
1548
- }
1549
- const result = withRollupError(this, transformDirectiveProxyExport)(ast, {
1550
- code,
1551
- runtime: (name) => `$$ReactClient.createServerReference(${JSON.stringify(getNormalizedId() + "#" + name)},$$ReactClient.callServer, undefined, ` + (this.environment.mode === "dev" ? `$$ReactClient.findSourceMapURL,` : "undefined,") + `${JSON.stringify(name)})`,
1552
- directive: "use server",
1553
- rejectNonAsyncFunction: true
1554
- });
1555
- if (!result) return;
1556
- const output = result?.output;
1557
- if (!output?.hasChanged()) return;
1558
- manager.serverReferenceMetaMap[id] = {
1559
- importId: id,
1560
- referenceKey: getNormalizedId(),
1561
- exportNames: result.exportNames
1562
- };
1563
- const importSource = resolvePackage(`${PKG_NAME}/react/${this.environment.name === browserEnvironmentName ? "browser" : "ssr"}`);
1564
- output.prepend(`import * as $$ReactClient from "${importSource}";\n`);
1565
- return {
1566
- code: output.toString(),
1567
- map: output.generateMap({ hires: "boundary" })
1568
- };
1569
- }
1570
- } }
1571
- }, createVirtualPlugin("vite-rsc/server-references", function() {
1572
- if (this.environment.mode === "dev") return {
1573
- code: `export {}`,
1574
- map: null
1575
- };
1576
- let code = "";
1577
- for (const meta of Object.values(manager.serverReferenceMetaMap)) {
1578
- const key = JSON.stringify(meta.referenceKey);
1579
- const id = JSON.stringify(meta.importId);
1580
- const exports = meta.exportNames.map((name) => name === "default" ? "default: _default" : name).sort();
1581
- code += `
1582
- ${key}: async () => {
1583
- const {${exports}} = await import(${id});
1584
- return {${exports}};
1585
- },
1586
- `;
1587
- }
1588
- code = `export default {${code}};\n`;
1589
- return {
1590
- code,
1591
- map: null
1592
- };
1593
- })];
1594
- }
1595
- var RuntimeAsset = class {
1596
- runtime;
1597
- constructor(value) {
1598
- this.runtime = value;
1599
- }
1600
- };
1601
- function serializeValueWithRuntime(value) {
1602
- const replacements = [];
1603
- let result = JSON.stringify(value, (_key, value) => {
1604
- if (value instanceof RuntimeAsset) {
1605
- const placeholder = `__runtime_placeholder_${replacements.length}__`;
1606
- replacements.push([placeholder, value.runtime]);
1607
- return placeholder;
1608
- }
1609
- return value;
1610
- }, 2);
1611
- for (const [placeholder, runtime] of replacements) result = result.replace(`"${placeholder}"`, runtime);
1612
- return result;
1613
- }
1614
- function assetsURL(url, manager) {
1615
- const { config } = manager;
1616
- if (config.command === "build" && typeof config.experimental?.renderBuiltUrl === "function") {
1617
- const result = config.experimental.renderBuiltUrl(url, {
1618
- type: "asset",
1619
- hostType: "js",
1620
- ssr: true,
1621
- hostId: ""
1622
- });
1623
- if (typeof result === "object") {
1624
- if (result.runtime) return new RuntimeAsset(result.runtime);
1625
- assert(!result.relative, "\"result.relative\" not supported on renderBuiltUrl() for RSC");
1626
- } else if (result) return result;
1627
- }
1628
- return config.base + url;
1629
- }
1630
- function assetsURLOfDeps(deps, manager) {
1631
- return {
1632
- js: deps.js.map((href) => {
1633
- assert(typeof href === "string");
1634
- return assetsURL(href, manager);
1635
- }),
1636
- css: deps.css.map((href) => {
1637
- assert(typeof href === "string");
1638
- return assetsURL(href, manager);
1639
- })
1640
- };
1641
- }
1642
- function mergeAssetDeps(a, b) {
1643
- return {
1644
- js: [...new Set([...a.js, ...b.js])],
1645
- css: [...new Set([...a.css, ...b.css])]
1646
- };
1647
- }
1648
- function collectAssetDeps(bundle) {
1649
- const chunkToDeps = /* @__PURE__ */ new Map();
1650
- for (const chunk of Object.values(bundle)) if (chunk.type === "chunk") chunkToDeps.set(chunk, collectAssetDepsInner(chunk.fileName, bundle));
1651
- const idToDeps = {};
1652
- for (const [chunk, deps] of chunkToDeps.entries()) for (const id of chunk.moduleIds) idToDeps[id] = {
1653
- chunk,
1654
- deps
1655
- };
1656
- return idToDeps;
1657
- }
1658
- function collectAssetDepsInner(fileName, bundle) {
1659
- const visited = /* @__PURE__ */ new Set();
1660
- const css = [];
1661
- function recurse(k) {
1662
- if (visited.has(k)) return;
1663
- visited.add(k);
1664
- const v = bundle[k];
1665
- assert(v, `Not found '${k}' in the bundle`);
1666
- if (v.type === "chunk") {
1667
- css.push(...v.viteMetadata?.importedCss ?? []);
1668
- for (const k2 of v.imports) if (k2 in bundle) recurse(k2);
1669
- }
1670
- }
1671
- recurse(fileName);
1672
- return {
1673
- js: [...visited],
1674
- css: [...new Set(css)]
1675
- };
1676
- }
1677
- function vitePluginRscCss(rscCssOptions = {}, manager) {
1678
- function hasSpecialCssQuery(id) {
1679
- return /[?&](url|inline|raw)(\b|=|&|$)/.test(id);
1680
- }
1681
- function collectCss(environment, entryId) {
1682
- const visited = /* @__PURE__ */ new Set();
1683
- const cssIds = /* @__PURE__ */ new Set();
1684
- const visitedFiles = /* @__PURE__ */ new Set();
1685
- function recurse(id) {
1686
- if (visited.has(id)) return;
1687
- visited.add(id);
1688
- const mod = environment.moduleGraph.getModuleById(id);
1689
- if (mod?.file) visitedFiles.add(mod.file);
1690
- for (const next of mod?.importedModules ?? []) if (next.id) if (isCSSRequest(next.id)) {
1691
- if (hasSpecialCssQuery(next.id)) continue;
1692
- cssIds.add(next.id);
1693
- } else recurse(next.id);
1694
- }
1695
- recurse(entryId);
1696
- const hrefs = [...cssIds].map((id) => normalizeViteImportAnalysisUrl(environment, id));
1697
- return {
1698
- ids: [...cssIds],
1699
- hrefs,
1700
- visitedFiles: [...visitedFiles]
1701
- };
1702
- }
1703
- function getRscCssTransformFilter({ id, code }) {
1704
- const { filename, query } = parseIdQuery(id);
1705
- if ("vite-rsc-css-export" in query) {
1706
- const value = query["vite-rsc-css-export"];
1707
- if (value) {
1708
- const names = value.split(",");
1709
- return (name) => names.includes(name);
1710
- }
1711
- return (name) => /^[A-Z]/.test(name);
1712
- }
1713
- const options = rscCssOptions?.rscCssTransform;
1714
- if (options === false) return false;
1715
- if (options?.filter && !options.filter(filename)) return false;
1716
- if (!/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)\b/.test(code) || !/\.[tj]sx?$/.test(filename)) return false;
1717
- if (!esModuleLexer.parse(code)[0].some((i) => i.t === 1 && i.n && isCSSRequest(i.n))) return false;
1718
- return (_name, meta) => !!(meta.isFunction && meta.declName && /^[A-Z]/.test(meta.declName) || meta.defaultExportIdentifierName && /^[A-Z]/.test(meta.defaultExportIdentifierName));
1719
- }
1720
- return [
1721
- {
1722
- name: "rsc:rsc-css-export-transform",
1723
- transform: { async handler(code, id) {
1724
- if (this.environment.name !== "rsc") return;
1725
- const filter = getRscCssTransformFilter({
1726
- id,
1727
- code
1728
- });
1729
- if (!filter) return;
1730
- const result = await transformRscCssExport({
1731
- ast: await parseAstAsync(code),
1732
- code,
1733
- filter
1734
- });
1735
- if (result) return {
1736
- code: result.output.toString(),
1737
- map: result.output.generateMap({ hires: "boundary" })
1738
- };
1739
- } }
1740
- },
1741
- {
1742
- name: "rsc:rsc-css-self-accept",
1743
- apply: "serve",
1744
- transform: {
1745
- order: "post",
1746
- filter: { id: /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(\?|$)/ },
1747
- handler(_code, id, _options) {
1748
- if (this.environment.name === "client" && this.environment.mode === "dev" && isCSSRequest(id) && directRequestRE.test(id)) {
1749
- const mod = this.environment.moduleGraph.getModuleById(id);
1750
- if (mod && !mod.isSelfAccepting) mod.isSelfAccepting = true;
1751
- }
1752
- }
1753
- }
1754
- },
1755
- {
1756
- name: "rsc:css-virtual",
1757
- resolveId: {
1758
- filter: { id: prefixRegex("virtual:vite-rsc/css?") },
1759
- handler(source) {
1760
- if (source.startsWith("virtual:vite-rsc/css?")) return "\0" + source;
1761
- }
1762
- },
1763
- load: {
1764
- filter: { id: prefixRegex("\0virtual:vite-rsc/css?") },
1765
- async handler(id) {
1766
- const parsed = parseCssVirtual(id);
1767
- if (parsed?.type === "ssr") {
1768
- id = parsed.id;
1769
- const { server } = manager;
1770
- const mod = await server.environments.ssr.moduleGraph.getModuleByUrl(id);
1771
- if (!mod?.id || !mod?.file) return `export default []`;
1772
- const result = collectCss(server.environments.ssr, mod.id);
1773
- for (const file of [mod.file, ...result.visitedFiles]) this.addWatchFile(file);
1774
- return `export default ${serializeValueWithRuntime(result.hrefs.map((href) => assetsURL(href.slice(1), manager)))}`;
1775
- }
1776
- }
1777
- }
1778
- },
1779
- {
1780
- name: "rsc:importer-resources",
1781
- configureServer(server) {
1782
- const hot = server.environments.rsc.hot;
1783
- const original = hot.send;
1784
- hot.send = function(...args) {
1785
- const e = args[0];
1786
- if (e && typeof e === "object" && e.type === "prune") server.environments.client.hot.send({
1787
- type: "custom",
1788
- event: "rsc:prune",
1789
- data: e
1790
- });
1791
- return original.apply(this, args);
1792
- };
1793
- },
1794
- transform: {
1795
- filter: { code: "import.meta.viteRsc.loadCss" },
1796
- async handler(code, id) {
1797
- if (!code.includes("import.meta.viteRsc.loadCss")) return;
1798
- assert(this.environment.name === "rsc");
1799
- const output = new MagicString(code);
1800
- let importAdded = false;
1801
- for (const match of stripLiteral(code).matchAll(/import\.meta\.viteRsc\.loadCss\(([\s\S]*?)\)/dg)) {
1802
- const [start, end] = match.indices[0];
1803
- const [argStart, argEnd] = match.indices[1];
1804
- const argCode = code.slice(argStart, argEnd).trim();
1805
- let importer = id;
1806
- if (argCode) {
1807
- const argValue = evalValue(argCode);
1808
- const resolved = await this.resolve(argValue, id);
1809
- if (resolved) importer = resolved.id;
1810
- else {
1811
- this.warn(`[vite-rsc] failed to transform 'import.meta.viteRsc.loadCss(${argCode})'`);
1812
- output.update(start, end, `null`);
1813
- continue;
1814
- }
1815
- }
1816
- const importId = toCssVirtual({
1817
- id: importer,
1818
- type: "rsc"
1819
- });
1820
- let replacement;
1821
- if (this.environment.mode === "dev") replacement = `__vite_rsc_react__.createElement(async () => {
1822
- const __m = await import(${JSON.stringify(importId)});
1823
- return __vite_rsc_react__.createElement(__m.Resources);
1824
- })`;
1825
- else {
1826
- const hash = hashString(importId);
1827
- if (!importAdded && !code.includes(`__vite_rsc_importer_resources_${hash}`)) {
1828
- importAdded = true;
1829
- output.prepend(`import * as __vite_rsc_importer_resources_${hash} from ${JSON.stringify(importId)};`);
1830
- }
1831
- replacement = `__vite_rsc_react__.createElement(__vite_rsc_importer_resources_${hash}.Resources)`;
1832
- }
1833
- output.update(start, end, replacement);
1834
- }
1835
- if (output.hasChanged()) {
1836
- if (!code.includes("__vite_rsc_react__")) output.prepend(`import __vite_rsc_react__ from "react";`);
1837
- return {
1838
- code: output.toString(),
1839
- map: output.generateMap({ hires: "boundary" })
1840
- };
1841
- }
1842
- }
1843
- },
1844
- load: {
1845
- filter: { id: prefixRegex("\0virtual:vite-rsc/css?") },
1846
- handler(id) {
1847
- const { server } = manager;
1848
- const parsed = parseCssVirtual(id);
1849
- if (parsed?.type === "rsc") {
1850
- assert(this.environment.name === "rsc");
1851
- const importer = parsed.id;
1852
- if (this.environment.mode === "dev") {
1853
- const result = collectCss(server.environments.rsc, importer);
1854
- for (const file of [importer, ...result.visitedFiles]) this.addWatchFile(file);
1855
- return generateResourcesCode(serializeValueWithRuntime(assetsURLOfDeps({
1856
- css: result.hrefs.map((href) => href.slice(1)),
1857
- js: []
1858
- }, manager)), manager, { cssLinkPrecedence: rscCssOptions.cssLinkPrecedence });
1859
- } else {
1860
- const key = manager.toRelativeId(importer);
1861
- manager.serverResourcesMetaMap[importer] = { key };
1862
- return `
1863
- import __vite_rsc_assets_manifest__ from "virtual:vite-rsc/assets-manifest";
1864
- ${generateResourcesCode(`__vite_rsc_assets_manifest__.serverResources[${JSON.stringify(key)}]`, manager, { cssLinkPrecedence: rscCssOptions.cssLinkPrecedence })}
1865
- `;
1866
- }
1867
- }
1868
- }
1869
- }
1870
- },
1871
- createVirtualPlugin("vite-rsc/remove-duplicate-server-css", async function() {
1872
- assert.equal(this.environment.mode, "dev");
1873
- function removeFn() {
1874
- document.querySelectorAll("link[rel='stylesheet']").forEach((node) => {
1875
- if (node instanceof HTMLElement && node.dataset.precedence?.startsWith("vite-rsc/client-reference")) node.remove();
1876
- });
1877
- }
1878
- return `\
1879
- "use client"
1880
- import React from "react";
1881
- export default function RemoveDuplicateServerCss() {
1882
- React.useEffect(() => {
1883
- (${removeFn.toString()})();
1884
- }, []);
1885
- return null;
1886
- }
1887
- `;
1888
- })
1889
- ];
1890
- }
1891
- function generateResourcesCode(depsCode, manager, options = {}) {
1892
- const usePrecedence = options.cssLinkPrecedence !== false;
1893
- const ResourcesFn = (React, deps, RemoveDuplicateServerCss, precedence) => {
1894
- return function Resources() {
1895
- return React.createElement(React.Fragment, null, [...deps.css.map((href) => React.createElement("link", {
1896
- key: "css:" + href,
1897
- rel: "stylesheet",
1898
- ...precedence ? { precedence } : {},
1899
- href,
1900
- "data-rsc-css-href": href
1901
- })), RemoveDuplicateServerCss && React.createElement(RemoveDuplicateServerCss, { key: "remove-duplicate-css" })]);
1902
- };
1903
- };
1904
- return `
1905
- import __vite_rsc_react__ from "react";
1906
-
1907
- ${manager.config.command === "serve" ? `import RemoveDuplicateServerCss from "virtual:vite-rsc/remove-duplicate-server-css";` : `const RemoveDuplicateServerCss = undefined;`}
1908
-
1909
- export const Resources = (${ResourcesFn.toString()})(
1910
- __vite_rsc_react__,
1911
- ${depsCode},
1912
- RemoveDuplicateServerCss,
1913
- ${usePrecedence ? `"vite-rsc/importer-resources"` : `undefined`},
1914
- );
1915
- `;
1916
- }
1917
- async function transformRscCssExport(options) {
1918
- if (hasDirective(options.ast.body, "use client")) return;
1919
- const result = transformWrapExport(options.code, options.ast, {
1920
- runtime: (value, name, meta) => `__vite_rsc_wrap_css__(${value}, ${JSON.stringify(meta.defaultExportIdentifierName ?? name)})`,
1921
- filter: options.filter,
1922
- ignoreExportAllDeclaration: true
1923
- });
1924
- if (result.output.hasChanged()) {
1925
- if (!options.code.includes("__vite_rsc_react__")) result.output.prepend(`import __vite_rsc_react__ from "react";`);
1926
- result.output.append(`
1927
- function __vite_rsc_wrap_css__(value, name) {
1928
- if (typeof value !== 'function') return value;
1929
-
1930
- function __wrapper(props) {
1931
- return __vite_rsc_react__.createElement(
1932
- __vite_rsc_react__.Fragment,
1933
- null,
1934
- import.meta.viteRsc.loadCss(${options.id ? JSON.stringify(options.id) : ""}),
1935
- __vite_rsc_react__.createElement(value, props),
1936
- );
1937
- }
1938
- Object.defineProperty(__wrapper, "name", { value: name });
1939
- return __wrapper;
1940
- }
1941
- `);
1942
- return { output: result.output };
1943
- }
1944
- }
1945
-
1946
- //#endregion
1947
- export { vitePluginRscMinimal as i, transformRscCssExport as n, vitePluginRsc as r, getPluginApi as t };