@vitejs/plugin-rsc 0.4.10 → 0.4.12
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 +4 -3
- package/dist/browser-D8OPzpF5.js +35 -0
- package/dist/browser-DjnGtEmB.d.ts +15 -0
- package/dist/browser-Dw18EFgE.d.ts +6 -0
- package/dist/browser-LizIyxet.js +17 -0
- package/dist/browser-QWbIPyhO.js +17 -0
- package/dist/browser.d.ts +4 -0
- package/dist/browser.js +7 -0
- package/dist/client-edAdk2GF.js +23 -0
- package/dist/core/browser.d.ts +2 -0
- package/dist/core/browser.js +5 -0
- package/dist/core/plugin.d.ts +6 -0
- package/dist/core/plugin.js +3 -0
- package/dist/core/rsc.d.ts +3 -0
- package/dist/core/rsc.js +5 -0
- package/dist/core/ssr.d.ts +3 -0
- package/dist/core/ssr.js +5 -0
- package/dist/dist-DEF94lDJ.js +41 -0
- package/dist/encryption-utils-BDwwcMVT.js +73 -0
- package/dist/extra/browser.d.ts +7 -0
- package/dist/extra/browser.js +83 -0
- package/dist/extra/rsc.d.ts +2 -0
- package/dist/extra/rsc.js +60 -0
- package/dist/extra/ssr.d.ts +10 -0
- package/dist/extra/ssr.js +35 -0
- package/dist/index-BHqtj9tT.d.ts +26 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +8 -0
- package/dist/plugin-BvUB-eig.js +1470 -0
- package/dist/plugin-CZbI4rhS.js +24 -0
- package/dist/plugin-Dg2agPFN.d.ts +88 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +8 -0
- package/dist/react/browser.d.ts +4 -0
- package/dist/react/browser.js +6 -0
- package/dist/react/rsc.d.ts +4 -0
- package/dist/react/rsc.js +6 -0
- package/dist/react/ssr.d.ts +4 -0
- package/dist/react/ssr.js +6 -0
- package/dist/rpc-tGuLT8PD.js +47 -0
- package/dist/rsc-BOV3yNSd.d.ts +12 -0
- package/dist/rsc-Cmvt9txp.d.ts +13 -0
- package/dist/rsc-DHfL29FT.js +36 -0
- package/dist/rsc-DKA6wwTB.js +78 -0
- package/dist/rsc-DgrejoNf.d.ts +15 -0
- package/dist/rsc-DmPsJrxF.js +42 -0
- package/dist/rsc-html-stream/browser.d.ts +4 -0
- package/dist/rsc-html-stream/browser.js +7 -0
- package/dist/rsc-html-stream/ssr.d.ts +6 -0
- package/dist/rsc-html-stream/ssr.js +7 -0
- package/dist/rsc.d.ts +13 -0
- package/dist/rsc.js +8 -0
- package/dist/server-DS3S6m0g.js +67 -0
- package/dist/shared-CEyKoKAb.js +22 -0
- package/dist/ssr-BOIYlvSn.js +23 -0
- package/dist/ssr-D5pxP29F.js +18 -0
- package/dist/ssr-D708H86k.d.ts +7 -0
- package/dist/ssr-DgSrGrln.d.ts +9 -0
- package/dist/ssr-Do_Ok_bB.js +47 -0
- package/dist/ssr.d.ts +4 -0
- package/dist/ssr.js +7 -0
- package/dist/utils/rpc.d.ts +7 -0
- package/dist/utils/rpc.js +3 -0
- package/dist/vendor/react-server-dom/LICENSE +21 -0
- package/dist/vendor/react-server-dom/README.md +5 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.browser.development.js +2785 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.browser.production.js +1664 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.edge.development.js +2959 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.edge.production.js +1845 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.development.js +3002 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.production.js +1894 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.unbundled.development.js +2964 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.unbundled.production.js +1859 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-node-register.js +69 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-plugin.js +400 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.browser.development.js +4079 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.browser.production.js +2806 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.edge.development.js +4187 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.edge.production.js +2845 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.development.js +4195 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.production.js +2902 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.unbundled.development.js +4158 -0
- package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.unbundled.production.js +2868 -0
- package/dist/vendor/react-server-dom/client.browser.js +7 -0
- package/dist/vendor/react-server-dom/client.edge.js +7 -0
- package/dist/vendor/react-server-dom/client.js +3 -0
- package/dist/vendor/react-server-dom/client.node.js +7 -0
- package/dist/vendor/react-server-dom/client.node.unbundled.js +7 -0
- package/dist/vendor/react-server-dom/esm/package.json +3 -0
- package/dist/vendor/react-server-dom/esm/react-server-dom-webpack-node-loader.production.js +515 -0
- package/dist/vendor/react-server-dom/index.js +12 -0
- package/dist/vendor/react-server-dom/node-register.js +3 -0
- package/dist/vendor/react-server-dom/package.json +111 -0
- package/dist/vendor/react-server-dom/plugin.js +3 -0
- package/dist/vendor/react-server-dom/server.browser.js +17 -0
- package/dist/vendor/react-server-dom/server.edge.js +18 -0
- package/dist/vendor/react-server-dom/server.js +6 -0
- package/dist/vendor/react-server-dom/server.node.js +18 -0
- package/dist/vendor/react-server-dom/server.node.unbundled.js +18 -0
- package/dist/vendor/react-server-dom/static.browser.js +12 -0
- package/dist/vendor/react-server-dom/static.edge.js +12 -0
- package/dist/vendor/react-server-dom/static.js +6 -0
- package/dist/vendor/react-server-dom/static.node.js +12 -0
- package/dist/vendor/react-server-dom/static.node.unbundled.js +12 -0
- package/dist/vite-utils-CcqBE-C4.js +64 -0
- package/dist/vite-utils.d.ts +21 -0
- package/dist/vite-utils.js +3 -0
- package/package.json +3 -2
|
@@ -0,0 +1,1470 @@
|
|
|
1
|
+
import { tinyassert } from "./dist-DEF94lDJ.js";
|
|
2
|
+
import { vitePluginRscCore } from "./plugin-CZbI4rhS.js";
|
|
3
|
+
import { generateEncryptionKey, toBase64 } from "./encryption-utils-BDwwcMVT.js";
|
|
4
|
+
import { createRpcServer } from "./rpc-tGuLT8PD.js";
|
|
5
|
+
import { normalizeViteImportAnalysisUrl } from "./vite-utils-CcqBE-C4.js";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import assert from "node:assert";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
12
|
+
import { createRequestListener } from "@mjackson/node-fetch-server";
|
|
13
|
+
import * as esModuleLexer from "es-module-lexer";
|
|
14
|
+
import MagicString from "magic-string";
|
|
15
|
+
import { defaultServerConditions, isCSSRequest, normalizePath, parseAstAsync } from "vite";
|
|
16
|
+
import { crawlFrameworkPkgs } from "vitefu";
|
|
17
|
+
import { walk } from "estree-walker";
|
|
18
|
+
import { analyze, extract_names } from "periscopic";
|
|
19
|
+
|
|
20
|
+
//#region src/transforms/hoist.ts
|
|
21
|
+
function transformHoistInlineDirective(input, ast, { runtime, rejectNonAsyncFunction,...options }) {
|
|
22
|
+
const output = new MagicString(input);
|
|
23
|
+
const directive = typeof options.directive === "string" ? exactRegex(options.directive) : options.directive;
|
|
24
|
+
walk(ast, { enter(node) {
|
|
25
|
+
if (node.type === "ExportAllDeclaration") this.remove();
|
|
26
|
+
if (node.type === "ExportNamedDeclaration" && !node.declaration) this.remove();
|
|
27
|
+
} });
|
|
28
|
+
const analyzed = analyze(ast);
|
|
29
|
+
const names = [];
|
|
30
|
+
walk(ast, { enter(node, parent) {
|
|
31
|
+
if ((node.type === "FunctionExpression" || node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression") && node.body.type === "BlockStatement") {
|
|
32
|
+
const match = matchDirective(node.body.body, directive);
|
|
33
|
+
if (!match) return;
|
|
34
|
+
if (!node.async && rejectNonAsyncFunction) throw Object.assign(/* @__PURE__ */ new Error(`"${directive}" doesn't allow non async function`), { pos: node.start });
|
|
35
|
+
const scope = analyzed.map.get(node);
|
|
36
|
+
tinyassert(scope);
|
|
37
|
+
const declName = node.type === "FunctionDeclaration" && node.id.name;
|
|
38
|
+
const originalName = declName || parent?.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.id.name || "anonymous_server_function";
|
|
39
|
+
const bindVars = [...scope.references].filter((ref) => {
|
|
40
|
+
if (ref === declName) return false;
|
|
41
|
+
const owner = scope.find_owner(ref);
|
|
42
|
+
return owner && owner !== scope && owner !== analyzed.scope;
|
|
43
|
+
});
|
|
44
|
+
let newParams = [...bindVars, ...node.params.map((n) => input.slice(n.start, n.end))].join(", ");
|
|
45
|
+
if (bindVars.length > 0 && options.decode) {
|
|
46
|
+
newParams = ["$$hoist_encoded", ...node.params.map((n) => input.slice(n.start, n.end))].join(", ");
|
|
47
|
+
output.appendLeft(node.body.body[0].start, `const [${bindVars.join(",")}] = ${options.decode("$$hoist_encoded")};\n`);
|
|
48
|
+
}
|
|
49
|
+
const newName = `$$hoist_${names.length}` + (originalName ? `_${originalName}` : "");
|
|
50
|
+
names.push(newName);
|
|
51
|
+
output.update(node.start, node.body.start, `\n;${options.noExport ? "" : "export "}${node.async ? "async " : ""}function ${newName}(${newParams}) `);
|
|
52
|
+
output.appendLeft(node.end, `;\n/* #__PURE__ */ Object.defineProperty(${newName}, "name", { value: ${JSON.stringify(originalName)} });\n`);
|
|
53
|
+
output.move(node.start, node.end, input.length);
|
|
54
|
+
let newCode = `/* #__PURE__ */ ${runtime(newName, newName, { directiveMatch: match })}`;
|
|
55
|
+
if (bindVars.length > 0) {
|
|
56
|
+
const bindArgs = options.encode ? options.encode("[" + bindVars.join(", ") + "]") : bindVars.join(", ");
|
|
57
|
+
newCode = `${newCode}.bind(null, ${bindArgs})`;
|
|
58
|
+
}
|
|
59
|
+
if (declName) {
|
|
60
|
+
newCode = `const ${declName} = ${newCode};`;
|
|
61
|
+
if (parent?.type === "ExportDefaultDeclaration") {
|
|
62
|
+
output.remove(parent.start, node.start);
|
|
63
|
+
newCode = `${newCode}\nexport default ${declName};`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
output.appendLeft(node.start, newCode);
|
|
67
|
+
}
|
|
68
|
+
} });
|
|
69
|
+
return {
|
|
70
|
+
output,
|
|
71
|
+
names
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const exactRegex = (s) => /* @__PURE__ */ new RegExp("^" + s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$");
|
|
75
|
+
function matchDirective(body, directive) {
|
|
76
|
+
for (const stable of body) if (stable.type === "ExpressionStatement" && stable.expression.type === "Literal" && typeof stable.expression.value === "string") {
|
|
77
|
+
const match = stable.expression.value.match(directive);
|
|
78
|
+
if (match) return match;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/transforms/wrap-export.ts
|
|
84
|
+
function transformWrapExport(input, ast, options) {
|
|
85
|
+
const output = new MagicString(input);
|
|
86
|
+
const exportNames = [];
|
|
87
|
+
const toAppend = [];
|
|
88
|
+
const filter = options.filter ?? (() => true);
|
|
89
|
+
function wrapSimple(start, end, exports) {
|
|
90
|
+
const newCode = exports.map((e) => [filter(e.name, e.meta) && `${e.name} = /* #__PURE__ */ ${options.runtime(e.name, e.name, e.meta)};\n`, `export { ${e.name} };\n`]).flat().filter(Boolean).join("");
|
|
91
|
+
output.update(start, end, newCode);
|
|
92
|
+
output.move(start, end, input.length);
|
|
93
|
+
}
|
|
94
|
+
function wrapExport(name, exportName, meta = {}) {
|
|
95
|
+
if (!filter(exportName, meta)) {
|
|
96
|
+
toAppend.push(`export { ${name} as ${exportName} }`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
toAppend.push(`const $$wrap_${name} = /* #__PURE__ */ ${options.runtime(name, exportName, meta)}`, `export { $$wrap_${name} as ${exportName} }`);
|
|
100
|
+
}
|
|
101
|
+
function validateNonAsyncFunction(node, ok) {
|
|
102
|
+
if (options.rejectNonAsyncFunction && !ok) throw Object.assign(/* @__PURE__ */ new Error(`unsupported non async function`), { pos: node.start });
|
|
103
|
+
}
|
|
104
|
+
for (const node of ast.body) {
|
|
105
|
+
if (node.type === "ExportNamedDeclaration") if (node.declaration) if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
|
|
106
|
+
/**
|
|
107
|
+
* export function foo() {}
|
|
108
|
+
*/
|
|
109
|
+
validateNonAsyncFunction(node, node.declaration.type === "FunctionDeclaration" && node.declaration.async);
|
|
110
|
+
const name = node.declaration.id.name;
|
|
111
|
+
wrapSimple(node.start, node.declaration.start, [{
|
|
112
|
+
name,
|
|
113
|
+
meta: {
|
|
114
|
+
isFunction: true,
|
|
115
|
+
declName: name
|
|
116
|
+
}
|
|
117
|
+
}]);
|
|
118
|
+
} else if (node.declaration.type === "VariableDeclaration") {
|
|
119
|
+
/**
|
|
120
|
+
* export const foo = 1, bar = 2
|
|
121
|
+
*/
|
|
122
|
+
validateNonAsyncFunction(node, node.declaration.declarations.every((decl) => decl.init?.type === "ArrowFunctionExpression" && decl.init.async));
|
|
123
|
+
if (node.declaration.kind === "const") output.update(node.declaration.start, node.declaration.start + 5, "let");
|
|
124
|
+
const names = node.declaration.declarations.flatMap((decl) => extract_names(decl.id));
|
|
125
|
+
let isFunction = false;
|
|
126
|
+
if (node.declaration.declarations.length === 1) {
|
|
127
|
+
const decl = node.declaration.declarations[0];
|
|
128
|
+
isFunction = decl.id.type === "Identifier" && (decl.init?.type === "ArrowFunctionExpression" || decl.init?.type === "FunctionExpression");
|
|
129
|
+
}
|
|
130
|
+
wrapSimple(node.start, node.declaration.start, names.map((name) => ({
|
|
131
|
+
name,
|
|
132
|
+
meta: {
|
|
133
|
+
isFunction,
|
|
134
|
+
declName: name
|
|
135
|
+
}
|
|
136
|
+
})));
|
|
137
|
+
} else node.declaration;
|
|
138
|
+
else if (node.source) {
|
|
139
|
+
/**
|
|
140
|
+
* export { foo, bar as car } from './foo'
|
|
141
|
+
*/
|
|
142
|
+
output.remove(node.start, node.end);
|
|
143
|
+
for (const spec of node.specifiers) {
|
|
144
|
+
tinyassert(spec.local.type === "Identifier");
|
|
145
|
+
tinyassert(spec.exported.type === "Identifier");
|
|
146
|
+
const name = spec.local.name;
|
|
147
|
+
toAppend.push(`import { ${name} as $$import_${name} } from ${node.source.raw}`);
|
|
148
|
+
wrapExport(`$$import_${name}`, spec.exported.name);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
/**
|
|
152
|
+
* export { foo, bar as car }
|
|
153
|
+
*/
|
|
154
|
+
output.remove(node.start, node.end);
|
|
155
|
+
for (const spec of node.specifiers) {
|
|
156
|
+
tinyassert(spec.local.type === "Identifier");
|
|
157
|
+
tinyassert(spec.exported.type === "Identifier");
|
|
158
|
+
wrapExport(spec.local.name, spec.exported.name);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* export * from './foo'
|
|
163
|
+
*/
|
|
164
|
+
if (!options.ignoreExportAllDeclaration && node.type === "ExportAllDeclaration") throw Object.assign(/* @__PURE__ */ new Error("unsupported ExportAllDeclaration"), { pos: node.start });
|
|
165
|
+
/**
|
|
166
|
+
* export default function foo() {}
|
|
167
|
+
* export default class Foo {}
|
|
168
|
+
* export default () => {}
|
|
169
|
+
*/
|
|
170
|
+
if (node.type === "ExportDefaultDeclaration") {
|
|
171
|
+
validateNonAsyncFunction(node, node.declaration.type === "Identifier" || node.declaration.type === "FunctionDeclaration" && node.declaration.async);
|
|
172
|
+
let localName;
|
|
173
|
+
let isFunction = false;
|
|
174
|
+
let declName;
|
|
175
|
+
let defaultExportIdentifierName;
|
|
176
|
+
if ((node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") && node.declaration.id) {
|
|
177
|
+
localName = node.declaration.id.name;
|
|
178
|
+
output.remove(node.start, node.declaration.start);
|
|
179
|
+
isFunction = node.declaration.type === "FunctionDeclaration";
|
|
180
|
+
declName = node.declaration.id.name;
|
|
181
|
+
} else {
|
|
182
|
+
localName = "$$default";
|
|
183
|
+
output.update(node.start, node.declaration.start, "const $$default = ");
|
|
184
|
+
if (node.declaration.type === "Identifier") defaultExportIdentifierName = node.declaration.name;
|
|
185
|
+
}
|
|
186
|
+
wrapExport(localName, "default", {
|
|
187
|
+
isFunction,
|
|
188
|
+
declName,
|
|
189
|
+
defaultExportIdentifierName
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (toAppend.length > 0) output.append([
|
|
194
|
+
"",
|
|
195
|
+
...toAppend,
|
|
196
|
+
""
|
|
197
|
+
].join(";\n"));
|
|
198
|
+
return {
|
|
199
|
+
exportNames,
|
|
200
|
+
output
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/transforms/utils.ts
|
|
206
|
+
function hasDirective(body, directive) {
|
|
207
|
+
return !!body.find((stmt) => stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && stmt.expression.value === directive);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/transforms/proxy-export.ts
|
|
212
|
+
function transformDirectiveProxyExport(ast, options) {
|
|
213
|
+
if (!hasDirective(ast.body, options.directive)) return;
|
|
214
|
+
return transformProxyExport(ast, options);
|
|
215
|
+
}
|
|
216
|
+
function transformProxyExport(ast, options) {
|
|
217
|
+
if (options.keep && typeof options.code !== "string") throw new Error("`keep` option requires `code`");
|
|
218
|
+
const output = new MagicString(options.code ?? " ".repeat(ast.end));
|
|
219
|
+
const exportNames = [];
|
|
220
|
+
function createExport(node, names) {
|
|
221
|
+
exportNames.push(...names);
|
|
222
|
+
const newCode = names.map((name) => (name === "default" ? `export default` : `export const ${name} =`) + ` /* #__PURE__ */ ${options.runtime(name)};\n`).join("");
|
|
223
|
+
output.update(node.start, node.end, newCode);
|
|
224
|
+
}
|
|
225
|
+
function validateNonAsyncFunction(node, ok) {
|
|
226
|
+
if (options.rejectNonAsyncFunction && !ok) throw Object.assign(/* @__PURE__ */ new Error(`unsupported non async function`), { pos: node.start });
|
|
227
|
+
}
|
|
228
|
+
for (const node of ast.body) {
|
|
229
|
+
if (node.type === "ExportNamedDeclaration") {
|
|
230
|
+
if (node.declaration) if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
|
|
231
|
+
/**
|
|
232
|
+
* export function foo() {}
|
|
233
|
+
*/
|
|
234
|
+
validateNonAsyncFunction(node, node.declaration.type === "FunctionDeclaration" && node.declaration.async);
|
|
235
|
+
createExport(node, [node.declaration.id.name]);
|
|
236
|
+
} else if (node.declaration.type === "VariableDeclaration") {
|
|
237
|
+
/**
|
|
238
|
+
* export const foo = 1, bar = 2
|
|
239
|
+
*/
|
|
240
|
+
validateNonAsyncFunction(node, node.declaration.declarations.every((decl) => decl.init?.type === "ArrowFunctionExpression" && decl.init.async));
|
|
241
|
+
if (options.keep && options.code) {
|
|
242
|
+
if (node.declaration.declarations.length === 1) {
|
|
243
|
+
const decl = node.declaration.declarations[0];
|
|
244
|
+
if (decl.id.type === "Identifier" && decl.init) {
|
|
245
|
+
const name = decl.id.name;
|
|
246
|
+
const value = options.code.slice(decl.init.start, decl.init.end);
|
|
247
|
+
const newCode = `export const ${name} = /* #__PURE__ */ ${options.runtime(name, { value })};`;
|
|
248
|
+
output.update(node.start, node.end, newCode);
|
|
249
|
+
exportNames.push(name);
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const names = node.declaration.declarations.flatMap((decl) => extract_names(decl.id));
|
|
255
|
+
createExport(node, names);
|
|
256
|
+
} else node.declaration;
|
|
257
|
+
else {
|
|
258
|
+
/**
|
|
259
|
+
* export { foo, bar as car } from './foo'
|
|
260
|
+
* export { foo, bar as car }
|
|
261
|
+
*/
|
|
262
|
+
const names = [];
|
|
263
|
+
for (const spec of node.specifiers) {
|
|
264
|
+
tinyassert(spec.exported.type === "Identifier");
|
|
265
|
+
names.push(spec.exported.name);
|
|
266
|
+
}
|
|
267
|
+
createExport(node, names);
|
|
268
|
+
}
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* export * from './foo'
|
|
273
|
+
*/
|
|
274
|
+
if (!options.ignoreExportAllDeclaration && node.type === "ExportAllDeclaration") throw new Error("unsupported ExportAllDeclaration");
|
|
275
|
+
/**
|
|
276
|
+
* export default function foo() {}
|
|
277
|
+
* export default class Foo {}
|
|
278
|
+
* export default () => {}
|
|
279
|
+
*/
|
|
280
|
+
if (node.type === "ExportDefaultDeclaration") {
|
|
281
|
+
validateNonAsyncFunction(node, node.declaration.type === "Identifier" || node.declaration.type === "FunctionDeclaration" && node.declaration.async);
|
|
282
|
+
createExport(node, ["default"]);
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (options.keep) continue;
|
|
286
|
+
output.remove(node.start, node.end);
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
exportNames,
|
|
290
|
+
output
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/transforms/server-action.ts
|
|
296
|
+
function transformServerActionServer(input, ast, options) {
|
|
297
|
+
if (hasDirective(ast.body, "use server")) return transformWrapExport(input, ast, options);
|
|
298
|
+
return transformHoistInlineDirective(input, ast, {
|
|
299
|
+
...options,
|
|
300
|
+
directive: "use server"
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/plugin.ts
|
|
306
|
+
let serverReferences = {};
|
|
307
|
+
let server;
|
|
308
|
+
let config;
|
|
309
|
+
let rscBundle;
|
|
310
|
+
let buildAssetsManifest;
|
|
311
|
+
let isScanBuild = false;
|
|
312
|
+
const BUILD_ASSETS_MANIFEST_NAME = "__vite_rsc_assets_manifest.js";
|
|
313
|
+
let clientReferenceMetaMap = {};
|
|
314
|
+
let serverResourcesMetaMap = {};
|
|
315
|
+
const PKG_NAME = "@vitejs/plugin-rsc";
|
|
316
|
+
const REACT_SERVER_DOM_NAME = `${PKG_NAME}/vendor/react-server-dom`;
|
|
317
|
+
const VIRTUAL_ENTRIES = { browser: "virtual:vite-rsc/entry-browser" };
|
|
318
|
+
const require = createRequire(import.meta.url);
|
|
319
|
+
function resolvePackage(name) {
|
|
320
|
+
return pathToFileURL(require.resolve(name)).href;
|
|
321
|
+
}
|
|
322
|
+
function vitePluginRsc(rscPluginOptions = {}) {
|
|
323
|
+
return [
|
|
324
|
+
{
|
|
325
|
+
name: "rsc",
|
|
326
|
+
async config(config$1, env) {
|
|
327
|
+
await esModuleLexer.init;
|
|
328
|
+
const result = await crawlFrameworkPkgs({
|
|
329
|
+
root: process.cwd(),
|
|
330
|
+
isBuild: env.command === "build",
|
|
331
|
+
isFrameworkPkgByJson(pkgJson) {
|
|
332
|
+
if ([PKG_NAME, "react-dom"].includes(pkgJson.name)) return;
|
|
333
|
+
const deps = pkgJson["peerDependencies"];
|
|
334
|
+
return deps && "react" in deps;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
const noExternal = [
|
|
338
|
+
"react",
|
|
339
|
+
"react-dom",
|
|
340
|
+
"server-only",
|
|
341
|
+
"client-only",
|
|
342
|
+
PKG_NAME,
|
|
343
|
+
...result.ssr.noExternal.sort()
|
|
344
|
+
];
|
|
345
|
+
return {
|
|
346
|
+
appType: "custom",
|
|
347
|
+
define: { "import.meta.env.__vite_rsc_build__": JSON.stringify(env.command === "build") },
|
|
348
|
+
environments: {
|
|
349
|
+
client: {
|
|
350
|
+
build: {
|
|
351
|
+
outDir: config$1.environments?.client?.build?.outDir ?? "dist/client",
|
|
352
|
+
rollupOptions: { input: rscPluginOptions.entries?.client && { index: rscPluginOptions.entries.client } }
|
|
353
|
+
},
|
|
354
|
+
optimizeDeps: {
|
|
355
|
+
include: ["react-dom/client", `${REACT_SERVER_DOM_NAME}/client.browser`],
|
|
356
|
+
exclude: [PKG_NAME]
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
ssr: {
|
|
360
|
+
build: {
|
|
361
|
+
outDir: config$1.environments?.ssr?.build?.outDir ?? "dist/ssr",
|
|
362
|
+
rollupOptions: { input: rscPluginOptions.entries?.ssr && { index: rscPluginOptions.entries.ssr } }
|
|
363
|
+
},
|
|
364
|
+
resolve: { noExternal },
|
|
365
|
+
optimizeDeps: {
|
|
366
|
+
include: [
|
|
367
|
+
"react",
|
|
368
|
+
"react-dom",
|
|
369
|
+
"react/jsx-runtime",
|
|
370
|
+
"react/jsx-dev-runtime",
|
|
371
|
+
"react-dom/server.edge",
|
|
372
|
+
`${REACT_SERVER_DOM_NAME}/client.edge`
|
|
373
|
+
],
|
|
374
|
+
exclude: [PKG_NAME]
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
rsc: {
|
|
378
|
+
build: {
|
|
379
|
+
outDir: config$1.environments?.rsc?.build?.outDir ?? "dist/rsc",
|
|
380
|
+
emitAssets: true,
|
|
381
|
+
rollupOptions: { input: rscPluginOptions.entries?.rsc && { index: rscPluginOptions.entries.rsc } }
|
|
382
|
+
},
|
|
383
|
+
resolve: {
|
|
384
|
+
conditions: ["react-server", ...defaultServerConditions],
|
|
385
|
+
noExternal
|
|
386
|
+
},
|
|
387
|
+
optimizeDeps: {
|
|
388
|
+
include: [
|
|
389
|
+
"react",
|
|
390
|
+
"react-dom",
|
|
391
|
+
"react/jsx-runtime",
|
|
392
|
+
"react/jsx-dev-runtime",
|
|
393
|
+
`${REACT_SERVER_DOM_NAME}/server.edge`,
|
|
394
|
+
`${REACT_SERVER_DOM_NAME}/client.edge`
|
|
395
|
+
],
|
|
396
|
+
exclude: [PKG_NAME]
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
builder: {
|
|
401
|
+
sharedPlugins: true,
|
|
402
|
+
sharedConfigBuild: true,
|
|
403
|
+
async buildApp(builder) {
|
|
404
|
+
if (!builder.environments.ssr?.config.build.rollupOptions.input) {
|
|
405
|
+
isScanBuild = true;
|
|
406
|
+
builder.environments.rsc.config.build.write = false;
|
|
407
|
+
builder.environments.client.config.build.write = false;
|
|
408
|
+
await builder.build(builder.environments.rsc);
|
|
409
|
+
await builder.build(builder.environments.client);
|
|
410
|
+
isScanBuild = false;
|
|
411
|
+
builder.environments.rsc.config.build.write = true;
|
|
412
|
+
builder.environments.client.config.build.write = true;
|
|
413
|
+
await builder.build(builder.environments.rsc);
|
|
414
|
+
clientReferenceMetaMap = sortObject(clientReferenceMetaMap);
|
|
415
|
+
serverResourcesMetaMap = sortObject(serverResourcesMetaMap);
|
|
416
|
+
await builder.build(builder.environments.client);
|
|
417
|
+
const assetsManifestCode = `export default ${JSON.stringify(buildAssetsManifest, null, 2)}`;
|
|
418
|
+
const manifestPath = path.join(builder.environments.rsc.config.build.outDir, BUILD_ASSETS_MANIFEST_NAME);
|
|
419
|
+
fs.writeFileSync(manifestPath, assetsManifestCode);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
isScanBuild = true;
|
|
423
|
+
builder.environments.rsc.config.build.write = false;
|
|
424
|
+
builder.environments.ssr.config.build.write = false;
|
|
425
|
+
await builder.build(builder.environments.rsc);
|
|
426
|
+
await builder.build(builder.environments.ssr);
|
|
427
|
+
isScanBuild = false;
|
|
428
|
+
builder.environments.rsc.config.build.write = true;
|
|
429
|
+
builder.environments.ssr.config.build.write = true;
|
|
430
|
+
await builder.build(builder.environments.rsc);
|
|
431
|
+
clientReferenceMetaMap = sortObject(clientReferenceMetaMap);
|
|
432
|
+
serverResourcesMetaMap = sortObject(serverResourcesMetaMap);
|
|
433
|
+
await builder.build(builder.environments.client);
|
|
434
|
+
await builder.build(builder.environments.ssr);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
},
|
|
439
|
+
configResolved(config_) {
|
|
440
|
+
config = config_;
|
|
441
|
+
},
|
|
442
|
+
configureServer(server_) {
|
|
443
|
+
server = server_;
|
|
444
|
+
globalThis.__viteRscDevServer = server;
|
|
445
|
+
if (rscPluginOptions.disableServerHandler) return;
|
|
446
|
+
if (rscPluginOptions.serverHandler === false) return;
|
|
447
|
+
const options = rscPluginOptions.serverHandler ?? {
|
|
448
|
+
environmentName: "rsc",
|
|
449
|
+
entryName: "index"
|
|
450
|
+
};
|
|
451
|
+
const environment = server.environments[options.environmentName];
|
|
452
|
+
const source = getEntrySource(environment.config, options.entryName);
|
|
453
|
+
return () => {
|
|
454
|
+
server.middlewares.use(async (req, res, next) => {
|
|
455
|
+
try {
|
|
456
|
+
const resolved = await environment.pluginContainer.resolveId(source);
|
|
457
|
+
assert(resolved, `[vite-rsc] failed to resolve server handler '${source}'`);
|
|
458
|
+
const mod = await environment.runner.import(resolved.id);
|
|
459
|
+
createRequestListener(mod.default)(req, res);
|
|
460
|
+
} catch (e) {
|
|
461
|
+
next(e);
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
};
|
|
465
|
+
},
|
|
466
|
+
async configurePreviewServer(server$1) {
|
|
467
|
+
if (rscPluginOptions.disableServerHandler) return;
|
|
468
|
+
if (rscPluginOptions.serverHandler === false) return;
|
|
469
|
+
const options = rscPluginOptions.serverHandler ?? {
|
|
470
|
+
environmentName: "rsc",
|
|
471
|
+
entryName: "index"
|
|
472
|
+
};
|
|
473
|
+
const entryFile = path.join(config.environments[options.environmentName].build.outDir, `${options.entryName}.js`);
|
|
474
|
+
const entry = pathToFileURL(entryFile).href;
|
|
475
|
+
const mod = await import(
|
|
476
|
+
/* @vite-ignore */
|
|
477
|
+
entry);
|
|
478
|
+
const handler = createRequestListener(mod.default);
|
|
479
|
+
server$1.middlewares.use((req, _res, next) => {
|
|
480
|
+
delete req.headers["accept-encoding"];
|
|
481
|
+
next();
|
|
482
|
+
});
|
|
483
|
+
return () => {
|
|
484
|
+
server$1.middlewares.use(async (req, res, next) => {
|
|
485
|
+
try {
|
|
486
|
+
handler(req, res);
|
|
487
|
+
} catch (e) {
|
|
488
|
+
next(e);
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
};
|
|
492
|
+
},
|
|
493
|
+
async hotUpdate(ctx) {
|
|
494
|
+
if (isCSSRequest(ctx.file)) {
|
|
495
|
+
if (this.environment.name === "client") return ctx.modules.filter((m) => !m.id?.includes("?direct"));
|
|
496
|
+
}
|
|
497
|
+
const ids = ctx.modules.map((mod) => mod.id).filter((v) => v !== null);
|
|
498
|
+
if (ids.length === 0) return;
|
|
499
|
+
function isInsideClientBoundary(mods) {
|
|
500
|
+
const visited = /* @__PURE__ */ new Set();
|
|
501
|
+
function recurse(mod) {
|
|
502
|
+
if (!mod.id) return false;
|
|
503
|
+
if (clientReferenceMetaMap[mod.id]) return true;
|
|
504
|
+
if (visited.has(mod.id)) return false;
|
|
505
|
+
visited.add(mod.id);
|
|
506
|
+
for (const importer of mod.importers) if (recurse(importer)) return true;
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
return mods.some((mod) => recurse(mod));
|
|
510
|
+
}
|
|
511
|
+
if (!isInsideClientBoundary(ctx.modules)) {
|
|
512
|
+
if (this.environment.name === "rsc") ctx.server.environments.client.hot.send({
|
|
513
|
+
type: "custom",
|
|
514
|
+
event: "rsc:update",
|
|
515
|
+
data: { file: ctx.file }
|
|
516
|
+
});
|
|
517
|
+
if (this.environment.name === "client") {
|
|
518
|
+
const env = ctx.server.environments.rsc;
|
|
519
|
+
const mod = env.moduleGraph.getModuleById(ctx.file);
|
|
520
|
+
if (mod) {
|
|
521
|
+
for (const clientMod of ctx.modules) for (const importer of clientMod.importers) if (importer.id && isCSSRequest(importer.id)) await this.environment.reloadModule(importer);
|
|
522
|
+
return [];
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "rsc:patch-browser-raw-import",
|
|
530
|
+
transform: {
|
|
531
|
+
order: "post",
|
|
532
|
+
handler(code) {
|
|
533
|
+
if (code.includes("__vite_rsc_raw_import__")) return code.replace("__vite_rsc_raw_import__", "import");
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
name: "rsc:load-ssr-module",
|
|
539
|
+
transform(code) {
|
|
540
|
+
if (code.includes("import.meta.viteRsc.loadSsrModule(")) return code.replaceAll(`import.meta.viteRsc.loadSsrModule(`, `import.meta.viteRsc.loadModule("ssr", `);
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
name: "rsc:load-environment-module",
|
|
545
|
+
async transform(code) {
|
|
546
|
+
if (!code.includes("import.meta.viteRsc.loadModule")) return;
|
|
547
|
+
const s = new MagicString(code);
|
|
548
|
+
for (const match of code.matchAll(/import\.meta\.viteRsc\.loadModule\(([\s\S]*?)\)/dg)) {
|
|
549
|
+
const argCode = match[1].trim();
|
|
550
|
+
const [environmentName, entryName] = evalValue(`[${argCode}]`);
|
|
551
|
+
let replacement;
|
|
552
|
+
if (this.environment.mode === "dev" && rscPluginOptions.loadModuleDevProxy) {
|
|
553
|
+
const origin = server.resolvedUrls?.local[0];
|
|
554
|
+
assert(origin, "[vite-rsc] no server for loadModueleDevProxy");
|
|
555
|
+
const endpoint = origin + "__vite_rsc_load_module_dev_proxy?" + new URLSearchParams({
|
|
556
|
+
environmentName,
|
|
557
|
+
entryName
|
|
558
|
+
});
|
|
559
|
+
replacement = `__vite_rsc_rpc.createRpcClient(${JSON.stringify({ endpoint })})`;
|
|
560
|
+
s.prepend(`import * as __vite_rsc_rpc from "@vitejs/plugin-rsc/utils/rpc";`);
|
|
561
|
+
} else if (this.environment.mode === "dev") {
|
|
562
|
+
const environment = server.environments[environmentName];
|
|
563
|
+
const source = getEntrySource(environment.config, entryName);
|
|
564
|
+
const resolved = await environment.pluginContainer.resolveId(source);
|
|
565
|
+
assert(resolved, `[vite-rsc] failed to resolve entry '${source}'`);
|
|
566
|
+
replacement = `globalThis.__viteRscDevServer.environments[${JSON.stringify(environmentName)}].runner.import(${JSON.stringify(resolved.id)})`;
|
|
567
|
+
} else replacement = JSON.stringify(`__vite_rsc_load_module:${this.environment.name}:${environmentName}:${entryName}`);
|
|
568
|
+
const [start, end] = match.indices[0];
|
|
569
|
+
s.overwrite(start, end, replacement);
|
|
570
|
+
}
|
|
571
|
+
if (s.hasChanged()) return {
|
|
572
|
+
code: s.toString(),
|
|
573
|
+
map: s.generateMap({ hires: "boundary" })
|
|
574
|
+
};
|
|
575
|
+
},
|
|
576
|
+
renderChunk(code, chunk) {
|
|
577
|
+
if (!code.includes("__vite_rsc_load_module")) return;
|
|
578
|
+
const s = new MagicString(code);
|
|
579
|
+
for (const match of code.matchAll(/['"]__vite_rsc_load_module:(\w+):(\w+):(\w+)['"]/dg)) {
|
|
580
|
+
const [fromEnv, toEnv, entryName] = match.slice(1);
|
|
581
|
+
const importPath = normalizeRelativePath(path.relative(path.join(config.environments[fromEnv].build.outDir, chunk.fileName, ".."), path.join(config.environments[toEnv].build.outDir, `${entryName}.js`)));
|
|
582
|
+
const replacement = `(import(${JSON.stringify(importPath)}))`;
|
|
583
|
+
const [start, end] = match.indices[0];
|
|
584
|
+
s.overwrite(start, end, replacement);
|
|
585
|
+
}
|
|
586
|
+
if (s.hasChanged()) return {
|
|
587
|
+
code: s.toString(),
|
|
588
|
+
map: s.generateMap({ hires: "boundary" })
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
name: "vite-rsc-load-module-dev-proxy",
|
|
594
|
+
apply: () => !!rscPluginOptions.loadModuleDevProxy,
|
|
595
|
+
configureServer(server$1) {
|
|
596
|
+
async function createHandler(url) {
|
|
597
|
+
const { environmentName, entryName } = Object.fromEntries(url.searchParams);
|
|
598
|
+
assert(environmentName);
|
|
599
|
+
assert(entryName);
|
|
600
|
+
const environment = server$1.environments[environmentName];
|
|
601
|
+
const source = getEntrySource(environment.config, entryName);
|
|
602
|
+
const resolvedEntry = await environment.pluginContainer.resolveId(source);
|
|
603
|
+
assert(resolvedEntry, `[vite-rsc] failed to resolve entry '${source}'`);
|
|
604
|
+
const runnerProxy = new Proxy({}, { get(_target, p, _receiver) {
|
|
605
|
+
if (typeof p !== "string" || p === "then") return;
|
|
606
|
+
return async (...args) => {
|
|
607
|
+
const mod = await environment.runner.import(resolvedEntry.id);
|
|
608
|
+
return mod[p](...args);
|
|
609
|
+
};
|
|
610
|
+
} });
|
|
611
|
+
return createRpcServer(runnerProxy);
|
|
612
|
+
}
|
|
613
|
+
server$1.middlewares.use(async (req, res, next) => {
|
|
614
|
+
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
615
|
+
if (url.pathname === "/__vite_rsc_load_module_dev_proxy") {
|
|
616
|
+
try {
|
|
617
|
+
const handler = await createHandler(url);
|
|
618
|
+
createRequestListener(handler)(req, res);
|
|
619
|
+
} catch (e) {
|
|
620
|
+
next(e);
|
|
621
|
+
}
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
next();
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
name: "rsc:virtual:vite-rsc/assets-manifest",
|
|
630
|
+
resolveId(source) {
|
|
631
|
+
if (source === "virtual:vite-rsc/assets-manifest") {
|
|
632
|
+
if (this.environment.mode === "build") return {
|
|
633
|
+
id: source,
|
|
634
|
+
external: true
|
|
635
|
+
};
|
|
636
|
+
return `\0` + source;
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
load(id) {
|
|
640
|
+
if (id === "\0virtual:vite-rsc/assets-manifest") {
|
|
641
|
+
assert(this.environment.name !== "client");
|
|
642
|
+
assert(this.environment.mode === "dev");
|
|
643
|
+
const entryUrl = assetsURL("@id/__x00__" + VIRTUAL_ENTRIES.browser);
|
|
644
|
+
const manifest = {
|
|
645
|
+
bootstrapScriptContent: `import(${JSON.stringify(entryUrl)})`,
|
|
646
|
+
clientReferenceDeps: {}
|
|
647
|
+
};
|
|
648
|
+
return `export default ${JSON.stringify(manifest, null, 2)}`;
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
generateBundle(_options, bundle) {
|
|
652
|
+
if (this.environment.name === "rsc") rscBundle = bundle;
|
|
653
|
+
if (this.environment.name === "client") {
|
|
654
|
+
const filterAssets = rscPluginOptions.copyServerAssetsToClient ?? (() => true);
|
|
655
|
+
const rscBuildOptions = config.environments.rsc.build;
|
|
656
|
+
const rscViteManifest = typeof rscBuildOptions.manifest === "string" ? rscBuildOptions.manifest : rscBuildOptions.manifest && ".vite/manifest.json";
|
|
657
|
+
for (const asset of Object.values(rscBundle)) {
|
|
658
|
+
if (asset.fileName === rscViteManifest) continue;
|
|
659
|
+
if (asset.type === "asset" && filterAssets(asset.fileName)) this.emitFile({
|
|
660
|
+
type: "asset",
|
|
661
|
+
fileName: asset.fileName,
|
|
662
|
+
source: asset.source
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
const serverResources = {};
|
|
666
|
+
const rscAssetDeps = collectAssetDeps(rscBundle);
|
|
667
|
+
for (const [id, meta] of Object.entries(serverResourcesMetaMap)) serverResources[meta.key] = assetsURLOfDeps({
|
|
668
|
+
js: [],
|
|
669
|
+
css: rscAssetDeps[id]?.deps.css ?? []
|
|
670
|
+
});
|
|
671
|
+
const assetDeps = collectAssetDeps(bundle);
|
|
672
|
+
const entry = Object.values(assetDeps).find((v) => v.chunk.name === "index");
|
|
673
|
+
assert(entry);
|
|
674
|
+
const entryUrl = assetsURL(entry.chunk.fileName);
|
|
675
|
+
const clientReferenceDeps = {};
|
|
676
|
+
for (const [id, meta] of Object.entries(clientReferenceMetaMap)) {
|
|
677
|
+
const deps = assetDeps[id]?.deps ?? {
|
|
678
|
+
js: [],
|
|
679
|
+
css: []
|
|
680
|
+
};
|
|
681
|
+
clientReferenceDeps[meta.referenceKey] = assetsURLOfDeps(mergeAssetDeps(deps, entry.deps));
|
|
682
|
+
}
|
|
683
|
+
buildAssetsManifest = {
|
|
684
|
+
bootstrapScriptContent: `import(${JSON.stringify(entryUrl)})`,
|
|
685
|
+
clientReferenceDeps,
|
|
686
|
+
serverResources
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
renderChunk(code, chunk) {
|
|
691
|
+
if (code.includes("virtual:vite-rsc/assets-manifest")) {
|
|
692
|
+
assert(this.environment.name !== "client");
|
|
693
|
+
const replacement = normalizeRelativePath(path.relative(path.join(chunk.fileName, ".."), BUILD_ASSETS_MANIFEST_NAME));
|
|
694
|
+
code = code.replaceAll("virtual:vite-rsc/assets-manifest", () => replacement);
|
|
695
|
+
return { code };
|
|
696
|
+
}
|
|
697
|
+
return;
|
|
698
|
+
},
|
|
699
|
+
writeBundle() {
|
|
700
|
+
if (this.environment.name === "ssr") {
|
|
701
|
+
const assetsManifestCode = `export default ${JSON.stringify(buildAssetsManifest, null, 2)}`;
|
|
702
|
+
for (const name of ["ssr", "rsc"]) {
|
|
703
|
+
const manifestPath = path.join(config.environments[name].build.outDir, BUILD_ASSETS_MANIFEST_NAME);
|
|
704
|
+
fs.writeFileSync(manifestPath, assetsManifestCode);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
createVirtualPlugin("vite-rsc/bootstrap-script-content", function() {
|
|
710
|
+
assert(this.environment.name !== "client");
|
|
711
|
+
return `\
|
|
712
|
+
import assetsManifest from "virtual:vite-rsc/assets-manifest";
|
|
713
|
+
export default assetsManifest.bootstrapScriptContent;
|
|
714
|
+
`;
|
|
715
|
+
}),
|
|
716
|
+
{
|
|
717
|
+
name: "rsc:bootstrap-script-content",
|
|
718
|
+
async transform(code) {
|
|
719
|
+
if (!code.includes("loadBootstrapScriptContent") || !/import\s*\.\s*meta\s*\.\s*viteRsc\s*\.\s*loadBootstrapScriptContent/.test(code)) return;
|
|
720
|
+
assert(this.environment.name !== "client");
|
|
721
|
+
const output = new MagicString(code);
|
|
722
|
+
for (const match of code.matchAll(/import\s*\.\s*meta\s*\.\s*viteRsc\s*\.\s*loadBootstrapScriptContent\(([\s\S]*?)\)/dg)) {
|
|
723
|
+
const argCode = match[1].trim();
|
|
724
|
+
const entryName = evalValue(argCode);
|
|
725
|
+
assert(entryName, `[vite-rsc] expected 'loadBootstrapScriptContent("index")' but got ${argCode}`);
|
|
726
|
+
let replacement = `Promise.resolve(__vite_rsc_assets_manifest.bootstrapScriptContent)`;
|
|
727
|
+
const [start, end] = match.indices[0];
|
|
728
|
+
output.overwrite(start, end, replacement);
|
|
729
|
+
}
|
|
730
|
+
if (output.hasChanged()) {
|
|
731
|
+
if (!code.includes("__vite_rsc_assets_manifest")) output.prepend(`import __vite_rsc_assets_manifest from "virtual:vite-rsc/assets-manifest";`);
|
|
732
|
+
return {
|
|
733
|
+
code: output.toString(),
|
|
734
|
+
map: output.generateMap({ hires: "boundary" })
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
createVirtualPlugin(VIRTUAL_ENTRIES.browser.slice(8), async function() {
|
|
740
|
+
assert(this.environment.mode === "dev");
|
|
741
|
+
let code = "";
|
|
742
|
+
const resolved = await this.resolve("/@react-refresh");
|
|
743
|
+
if (resolved) code += `
|
|
744
|
+
import RefreshRuntime from "/@react-refresh";
|
|
745
|
+
RefreshRuntime.injectIntoGlobalHook(window);
|
|
746
|
+
window.$RefreshReg$ = () => {};
|
|
747
|
+
window.$RefreshSig$ = () => (type) => type;
|
|
748
|
+
window.__vite_plugin_react_preamble_installed__ = true;
|
|
749
|
+
`;
|
|
750
|
+
const source = getEntrySource(this.environment.config, "index");
|
|
751
|
+
const resolvedEntry = await this.resolve(source);
|
|
752
|
+
assert(resolvedEntry, `[vite-rsc] failed to resolve entry '${source}'`);
|
|
753
|
+
code += `await import(${JSON.stringify(resolvedEntry.id)});`;
|
|
754
|
+
code += `
|
|
755
|
+
const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
|
|
756
|
+
import.meta.hot.on("vite:beforeUpdate", () => ssrCss.forEach(node => node.remove()));
|
|
757
|
+
`;
|
|
758
|
+
return code;
|
|
759
|
+
}),
|
|
760
|
+
{
|
|
761
|
+
name: "rsc:inject-async-local-storage",
|
|
762
|
+
async configureServer() {
|
|
763
|
+
const __viteRscAyncHooks = await import("node:async_hooks");
|
|
764
|
+
globalThis.AsyncLocalStorage = __viteRscAyncHooks.AsyncLocalStorage;
|
|
765
|
+
},
|
|
766
|
+
banner(chunk) {
|
|
767
|
+
if ((this.environment.name === "ssr" || this.environment.name === "rsc") && this.environment.mode === "build" && chunk.isEntry) return `\
|
|
768
|
+
import * as __viteRscAyncHooks from "node:async_hooks";
|
|
769
|
+
globalThis.AsyncLocalStorage = __viteRscAyncHooks.AsyncLocalStorage;
|
|
770
|
+
`;
|
|
771
|
+
return "";
|
|
772
|
+
}
|
|
773
|
+
},
|
|
774
|
+
...vitePluginRscCore(),
|
|
775
|
+
...vitePluginUseClient(rscPluginOptions),
|
|
776
|
+
...vitePluginUseServer(rscPluginOptions),
|
|
777
|
+
...vitePluginDefineEncryptionKey(rscPluginOptions),
|
|
778
|
+
...vitePluginFindSourceMapURL(),
|
|
779
|
+
...vitePluginRscCss({ rscCssTransform: rscPluginOptions.rscCssTransform }),
|
|
780
|
+
scanBuildStripPlugin()
|
|
781
|
+
];
|
|
782
|
+
}
|
|
783
|
+
function scanBuildStripPlugin() {
|
|
784
|
+
return {
|
|
785
|
+
name: "rsc:scan-strip",
|
|
786
|
+
apply: "build",
|
|
787
|
+
enforce: "post",
|
|
788
|
+
transform(code, _id, _options) {
|
|
789
|
+
if (!isScanBuild) return;
|
|
790
|
+
const [imports] = esModuleLexer.parse(code);
|
|
791
|
+
const output = imports.map((e) => e.n && `import ${JSON.stringify(e.n)};\n`).filter(Boolean).join("");
|
|
792
|
+
return {
|
|
793
|
+
code: output,
|
|
794
|
+
map: { mappings: "" }
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
function normalizeRelativePath(s) {
|
|
800
|
+
s = normalizePath(s);
|
|
801
|
+
return s[0] === "." ? s : "./" + s;
|
|
802
|
+
}
|
|
803
|
+
function getEntrySource(config$1, name = "index") {
|
|
804
|
+
const input = config$1.build.rollupOptions.input;
|
|
805
|
+
assert(input);
|
|
806
|
+
assert(typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string");
|
|
807
|
+
return input[name];
|
|
808
|
+
}
|
|
809
|
+
function hashString(v) {
|
|
810
|
+
return createHash("sha256").update(v).digest().toString("hex").slice(0, 12);
|
|
811
|
+
}
|
|
812
|
+
function normalizeReferenceId(id, name) {
|
|
813
|
+
if (!server) return hashString(path.relative(config.root, id));
|
|
814
|
+
const environment = server.environments[name];
|
|
815
|
+
return normalizeViteImportAnalysisUrl(environment, id);
|
|
816
|
+
}
|
|
817
|
+
function vitePluginUseClient(useClientPluginOptions) {
|
|
818
|
+
const packageSources = /* @__PURE__ */ new Map();
|
|
819
|
+
const bareImportRE = /^(?![a-zA-Z]:)[\w@](?!.*:\/\/)/;
|
|
820
|
+
return [
|
|
821
|
+
{
|
|
822
|
+
name: "rsc:use-client",
|
|
823
|
+
async transform(code, id) {
|
|
824
|
+
if (this.environment.name !== "rsc") return;
|
|
825
|
+
if (!code.includes("use client")) return;
|
|
826
|
+
const ast = await parseAstAsync(code);
|
|
827
|
+
if (!hasDirective(ast.body, "use client")) return;
|
|
828
|
+
let importId;
|
|
829
|
+
let referenceKey;
|
|
830
|
+
const packageSource = packageSources.get(id);
|
|
831
|
+
if (!packageSource && id.includes("?v=")) {
|
|
832
|
+
assert(this.environment.mode === "dev");
|
|
833
|
+
const ignored = useClientPluginOptions.ignoredPackageWarnings?.some((pattern) => pattern instanceof RegExp ? pattern.test(id) : id.includes(`/node_modules/${pattern}/`));
|
|
834
|
+
if (!ignored) this.warn(`[vite-rsc] detected an internal client boundary created by a package imported on rsc environment`);
|
|
835
|
+
importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent(id.split("?v=")[0])}`;
|
|
836
|
+
referenceKey = importId;
|
|
837
|
+
} else if (packageSource) if (this.environment.mode === "dev") {
|
|
838
|
+
importId = `/@id/__x00__virtual:vite-rsc/client-package-proxy/${packageSource}`;
|
|
839
|
+
referenceKey = importId;
|
|
840
|
+
} else {
|
|
841
|
+
importId = packageSource;
|
|
842
|
+
referenceKey = hashString(packageSource);
|
|
843
|
+
}
|
|
844
|
+
else if (this.environment.mode === "dev") {
|
|
845
|
+
importId = normalizeViteImportAnalysisUrl(server.environments.client, id);
|
|
846
|
+
referenceKey = importId;
|
|
847
|
+
} else {
|
|
848
|
+
importId = id;
|
|
849
|
+
referenceKey = hashString(normalizePath(path.relative(config.root, id)));
|
|
850
|
+
}
|
|
851
|
+
const transformDirectiveProxyExport_ = withRollupError(this, transformDirectiveProxyExport);
|
|
852
|
+
const result = transformDirectiveProxyExport_(ast, {
|
|
853
|
+
directive: "use client",
|
|
854
|
+
code,
|
|
855
|
+
keep: !!useClientPluginOptions.keepUseCientProxy,
|
|
856
|
+
runtime: (name, meta) => {
|
|
857
|
+
let proxyValue = `() => { throw new Error("Unexpectedly client reference export '" + ` + JSON.stringify(name) + ` + "' is called on server") }`;
|
|
858
|
+
if (meta?.value) proxyValue = `(${meta.value})`;
|
|
859
|
+
return `$$ReactServer.registerClientReference( ${proxyValue}, ${JSON.stringify(referenceKey)}, ${JSON.stringify(name)})`;
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
if (!result) return;
|
|
863
|
+
const { output, exportNames } = result;
|
|
864
|
+
clientReferenceMetaMap[id] = {
|
|
865
|
+
importId,
|
|
866
|
+
referenceKey,
|
|
867
|
+
packageSource,
|
|
868
|
+
exportNames,
|
|
869
|
+
renderedExports: []
|
|
870
|
+
};
|
|
871
|
+
const importSource = resolvePackage(`${PKG_NAME}/react/rsc`);
|
|
872
|
+
output.prepend(`import * as $$ReactServer from "${importSource}";\n`);
|
|
873
|
+
return {
|
|
874
|
+
code: output.toString(),
|
|
875
|
+
map: { mappings: "" }
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
},
|
|
879
|
+
createVirtualPlugin("vite-rsc/client-references", function() {
|
|
880
|
+
if (this.environment.mode === "dev") return {
|
|
881
|
+
code: `export default {}`,
|
|
882
|
+
map: null
|
|
883
|
+
};
|
|
884
|
+
let code = "";
|
|
885
|
+
for (const meta of Object.values(clientReferenceMetaMap)) {
|
|
886
|
+
const key = JSON.stringify(meta.referenceKey);
|
|
887
|
+
const id = JSON.stringify(meta.importId);
|
|
888
|
+
const exports = meta.renderedExports.map((name) => name === "default" ? "default: _default" : name).sort();
|
|
889
|
+
code += `
|
|
890
|
+
${key}: async () => {
|
|
891
|
+
const {${exports}} = await import(${id});
|
|
892
|
+
return {${exports}};
|
|
893
|
+
},
|
|
894
|
+
`;
|
|
895
|
+
}
|
|
896
|
+
code = `export default {${code}};\n`;
|
|
897
|
+
return {
|
|
898
|
+
code,
|
|
899
|
+
map: null
|
|
900
|
+
};
|
|
901
|
+
}),
|
|
902
|
+
{
|
|
903
|
+
name: "rsc:virtual-client-in-server-package",
|
|
904
|
+
async load(id) {
|
|
905
|
+
if (id.startsWith("\0virtual:vite-rsc/client-in-server-package-proxy/")) {
|
|
906
|
+
assert.equal(this.environment.mode, "dev");
|
|
907
|
+
assert.notEqual(this.environment.name, "rsc");
|
|
908
|
+
id = decodeURIComponent(id.slice(49));
|
|
909
|
+
return `
|
|
910
|
+
export * from ${JSON.stringify(id)};
|
|
911
|
+
import * as __all__ from ${JSON.stringify(id)};
|
|
912
|
+
export default __all__.default;
|
|
913
|
+
`;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
name: "rsc:virtual-client-package",
|
|
919
|
+
resolveId: {
|
|
920
|
+
order: "pre",
|
|
921
|
+
async handler(source, importer, options) {
|
|
922
|
+
if (this.environment.name === "rsc" && bareImportRE.test(source)) {
|
|
923
|
+
const resolved = await this.resolve(source, importer, options);
|
|
924
|
+
if (resolved && resolved.id.includes("/node_modules/")) {
|
|
925
|
+
packageSources.set(resolved.id, source);
|
|
926
|
+
return resolved;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
async load(id) {
|
|
932
|
+
if (id.startsWith("\0virtual:vite-rsc/client-package-proxy/")) {
|
|
933
|
+
assert(this.environment.mode === "dev");
|
|
934
|
+
const source = id.slice(39);
|
|
935
|
+
const meta = Object.values(clientReferenceMetaMap).find((v) => v.packageSource === source);
|
|
936
|
+
const exportNames = meta.exportNames;
|
|
937
|
+
return `export {${exportNames.join(",")}} from ${JSON.stringify(source)};\n`;
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
generateBundle(_options, bundle) {
|
|
941
|
+
if (this.environment.name !== "rsc") return;
|
|
942
|
+
for (const chunk of Object.values(bundle)) if (chunk.type === "chunk") for (const [id, mod] of Object.entries(chunk.modules)) {
|
|
943
|
+
const meta = clientReferenceMetaMap[id];
|
|
944
|
+
if (meta) meta.renderedExports = mod.renderedExports;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
];
|
|
949
|
+
}
|
|
950
|
+
function vitePluginDefineEncryptionKey(useServerPluginOptions) {
|
|
951
|
+
let defineEncryptionKey;
|
|
952
|
+
let emitEncryptionKey = false;
|
|
953
|
+
const KEY_PLACEHOLDER = "__vite_rsc_define_encryption_key";
|
|
954
|
+
const KEY_FILE = "__vite_rsc_encryption_key.js";
|
|
955
|
+
return [{
|
|
956
|
+
name: "rsc:encryption-key",
|
|
957
|
+
async configEnvironment(name, _config, env) {
|
|
958
|
+
if (name === "rsc" && !env.isPreview) defineEncryptionKey = useServerPluginOptions.defineEncryptionKey ?? JSON.stringify(toBase64(await generateEncryptionKey()));
|
|
959
|
+
},
|
|
960
|
+
resolveId(source) {
|
|
961
|
+
if (source === "virtual:vite-rsc/encryption-key") return {
|
|
962
|
+
id: "\0" + source,
|
|
963
|
+
moduleSideEffects: false
|
|
964
|
+
};
|
|
965
|
+
},
|
|
966
|
+
load(id) {
|
|
967
|
+
if (id === "\0virtual:vite-rsc/encryption-key") {
|
|
968
|
+
if (this.environment.mode === "build") return `export default () => ${KEY_PLACEHOLDER}`;
|
|
969
|
+
return `export default () => (${defineEncryptionKey})`;
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
renderChunk(code, chunk) {
|
|
973
|
+
if (code.includes(KEY_PLACEHOLDER)) {
|
|
974
|
+
assert.equal(this.environment.name, "rsc");
|
|
975
|
+
emitEncryptionKey = true;
|
|
976
|
+
const normalizedPath = normalizeRelativePath(path.relative(path.join(chunk.fileName, ".."), KEY_FILE));
|
|
977
|
+
const replacement = `import(${JSON.stringify(normalizedPath)}).then(__m => __m.default)`;
|
|
978
|
+
code = code.replaceAll(KEY_PLACEHOLDER, () => replacement);
|
|
979
|
+
return { code };
|
|
980
|
+
}
|
|
981
|
+
},
|
|
982
|
+
writeBundle() {
|
|
983
|
+
if (this.environment.name === "rsc" && emitEncryptionKey) fs.writeFileSync(path.join(this.environment.config.build.outDir, KEY_FILE), `export default ${defineEncryptionKey};\n`);
|
|
984
|
+
}
|
|
985
|
+
}];
|
|
986
|
+
}
|
|
987
|
+
function vitePluginUseServer(useServerPluginOptions) {
|
|
988
|
+
return [{
|
|
989
|
+
name: "rsc:use-server",
|
|
990
|
+
async transform(code, id) {
|
|
991
|
+
if (!code.includes("use server")) return;
|
|
992
|
+
const ast = await parseAstAsync(code);
|
|
993
|
+
let normalizedId_;
|
|
994
|
+
const getNormalizedId = () => {
|
|
995
|
+
if (!normalizedId_) {
|
|
996
|
+
if (id.includes("?v=")) {
|
|
997
|
+
assert(this.environment.mode === "dev");
|
|
998
|
+
const ignored = useServerPluginOptions.ignoredPackageWarnings?.some((pattern) => pattern instanceof RegExp ? pattern.test(id) : id.includes(`/node_modules/${pattern}/`));
|
|
999
|
+
if (!ignored) this.warn(`[vite-rsc] detected an internal server function created by a package imported on ${this.environment.name} environment`);
|
|
1000
|
+
id = id.split("?v=")[0];
|
|
1001
|
+
}
|
|
1002
|
+
normalizedId_ = normalizeReferenceId(id, "rsc");
|
|
1003
|
+
}
|
|
1004
|
+
return normalizedId_;
|
|
1005
|
+
};
|
|
1006
|
+
if (this.environment.name === "rsc") {
|
|
1007
|
+
const transformServerActionServer_ = withRollupError(this, transformServerActionServer);
|
|
1008
|
+
const enableEncryption = useServerPluginOptions.enableActionEncryption ?? true;
|
|
1009
|
+
const { output } = transformServerActionServer_(code, ast, {
|
|
1010
|
+
runtime: (value, name) => `$$ReactServer.registerServerReference(${value}, ${JSON.stringify(getNormalizedId())}, ${JSON.stringify(name)})`,
|
|
1011
|
+
rejectNonAsyncFunction: true,
|
|
1012
|
+
encode: enableEncryption ? (value) => `$$ReactServer.encryptActionBoundArgs(${value})` : void 0,
|
|
1013
|
+
decode: enableEncryption ? (value) => `await $$ReactServer.decryptActionBoundArgs(${value})` : void 0
|
|
1014
|
+
});
|
|
1015
|
+
if (!output.hasChanged()) return;
|
|
1016
|
+
serverReferences[getNormalizedId()] = id;
|
|
1017
|
+
const importSource = resolvePackage(`${PKG_NAME}/rsc`);
|
|
1018
|
+
output.prepend(`import * as $$ReactServer from "${importSource}";\n`);
|
|
1019
|
+
return {
|
|
1020
|
+
code: output.toString(),
|
|
1021
|
+
map: output.generateMap({ hires: "boundary" })
|
|
1022
|
+
};
|
|
1023
|
+
} else {
|
|
1024
|
+
if (!hasDirective(ast.body, "use server")) return;
|
|
1025
|
+
const transformDirectiveProxyExport_ = withRollupError(this, transformDirectiveProxyExport);
|
|
1026
|
+
const result = transformDirectiveProxyExport_(ast, {
|
|
1027
|
+
code,
|
|
1028
|
+
runtime: (name$1) => `$$ReactClient.createServerReference(${JSON.stringify(getNormalizedId() + "#" + name$1)},$$ReactClient.callServer, undefined, ` + (this.environment.mode === "dev" ? `$$ReactClient.findSourceMapURL,` : "undefined,") + `${JSON.stringify(name$1)})`,
|
|
1029
|
+
directive: "use server",
|
|
1030
|
+
rejectNonAsyncFunction: true
|
|
1031
|
+
});
|
|
1032
|
+
const output = result?.output;
|
|
1033
|
+
if (!output?.hasChanged()) return;
|
|
1034
|
+
serverReferences[getNormalizedId()] = id;
|
|
1035
|
+
const name = this.environment.name === "client" ? "browser" : "ssr";
|
|
1036
|
+
const importSource = resolvePackage(`${PKG_NAME}/react/${name}`);
|
|
1037
|
+
output.prepend(`import * as $$ReactClient from "${importSource}";\n`);
|
|
1038
|
+
return {
|
|
1039
|
+
code: output.toString(),
|
|
1040
|
+
map: output.generateMap({ hires: "boundary" })
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}, createVirtualPlugin("vite-rsc/server-references", function() {
|
|
1045
|
+
if (this.environment.mode === "dev") return {
|
|
1046
|
+
code: `export {}`,
|
|
1047
|
+
map: null
|
|
1048
|
+
};
|
|
1049
|
+
const code = generateDynamicImportCode(serverReferences);
|
|
1050
|
+
return {
|
|
1051
|
+
code,
|
|
1052
|
+
map: null
|
|
1053
|
+
};
|
|
1054
|
+
})];
|
|
1055
|
+
}
|
|
1056
|
+
function withRollupError(ctx, f) {
|
|
1057
|
+
function processError(e) {
|
|
1058
|
+
if (e && typeof e === "object" && typeof e.pos === "number") return ctx.error(e, e.pos);
|
|
1059
|
+
throw e;
|
|
1060
|
+
}
|
|
1061
|
+
return function(...args) {
|
|
1062
|
+
try {
|
|
1063
|
+
const result = f.apply(this, args);
|
|
1064
|
+
if (result instanceof Promise) return result.catch((e) => processError(e));
|
|
1065
|
+
return result;
|
|
1066
|
+
} catch (e) {
|
|
1067
|
+
processError(e);
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
function createVirtualPlugin(name, load) {
|
|
1072
|
+
name = "virtual:" + name;
|
|
1073
|
+
return {
|
|
1074
|
+
name: `rsc:virtual-${name}`,
|
|
1075
|
+
resolveId(source, _importer, _options) {
|
|
1076
|
+
return source === name ? "\0" + name : void 0;
|
|
1077
|
+
},
|
|
1078
|
+
load(id, options) {
|
|
1079
|
+
if (id === "\0" + name) return load.apply(this, [id, options]);
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
function generateDynamicImportCode(map) {
|
|
1084
|
+
let code = Object.entries(map).map(([key, id]) => `${JSON.stringify(key)}: () => import(${JSON.stringify(id)}),`).join("\n");
|
|
1085
|
+
return `export default {${code}};\n`;
|
|
1086
|
+
}
|
|
1087
|
+
function assetsURL(url) {
|
|
1088
|
+
return config.base + url;
|
|
1089
|
+
}
|
|
1090
|
+
function assetsURLOfDeps(deps) {
|
|
1091
|
+
return {
|
|
1092
|
+
js: deps.js.map((href) => assetsURL(href)),
|
|
1093
|
+
css: deps.css.map((href) => assetsURL(href))
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
function mergeAssetDeps(a, b) {
|
|
1097
|
+
return {
|
|
1098
|
+
js: [...new Set([...a.js, ...b.js])],
|
|
1099
|
+
css: [...new Set([...a.css, ...b.css])]
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
function collectAssetDeps(bundle) {
|
|
1103
|
+
const chunkToDeps = /* @__PURE__ */ new Map();
|
|
1104
|
+
for (const chunk of Object.values(bundle)) if (chunk.type === "chunk") chunkToDeps.set(chunk, collectAssetDepsInner(chunk.fileName, bundle));
|
|
1105
|
+
const idToDeps = {};
|
|
1106
|
+
for (const [chunk, deps] of chunkToDeps.entries()) for (const id of chunk.moduleIds) idToDeps[id] = {
|
|
1107
|
+
chunk,
|
|
1108
|
+
deps
|
|
1109
|
+
};
|
|
1110
|
+
return idToDeps;
|
|
1111
|
+
}
|
|
1112
|
+
function collectAssetDepsInner(fileName, bundle) {
|
|
1113
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1114
|
+
const css = [];
|
|
1115
|
+
function recurse(k) {
|
|
1116
|
+
if (visited.has(k)) return;
|
|
1117
|
+
visited.add(k);
|
|
1118
|
+
const v = bundle[k];
|
|
1119
|
+
assert(v, `Not found '${k}' in the bundle`);
|
|
1120
|
+
if (v.type === "chunk") {
|
|
1121
|
+
css.push(...v.viteMetadata?.importedCss ?? []);
|
|
1122
|
+
for (const k2 of v.imports) if (k2 in bundle) recurse(k2);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
recurse(fileName);
|
|
1126
|
+
return {
|
|
1127
|
+
js: [...visited],
|
|
1128
|
+
css: [...new Set(css)]
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
function vitePluginFindSourceMapURL() {
|
|
1132
|
+
return [{
|
|
1133
|
+
name: "rsc:findSourceMapURL",
|
|
1134
|
+
apply: "serve",
|
|
1135
|
+
configureServer(server$1) {
|
|
1136
|
+
server$1.middlewares.use(async (req, res, next) => {
|
|
1137
|
+
const url = new URL(req.url, `http://localhost`);
|
|
1138
|
+
if (url.pathname === "/__vite_rsc_findSourceMapURL") {
|
|
1139
|
+
let filename = url.searchParams.get("filename");
|
|
1140
|
+
let environmentName = url.searchParams.get("environmentName");
|
|
1141
|
+
try {
|
|
1142
|
+
const map = await findSourceMapURL(server$1, filename, environmentName);
|
|
1143
|
+
res.setHeader("content-type", "application/json");
|
|
1144
|
+
if (!map) res.statusCode = 404;
|
|
1145
|
+
res.end(JSON.stringify(map ?? {}));
|
|
1146
|
+
} catch (e) {
|
|
1147
|
+
next(e);
|
|
1148
|
+
}
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
next();
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
}];
|
|
1155
|
+
}
|
|
1156
|
+
async function findSourceMapURL(server$1, filename, environmentName) {
|
|
1157
|
+
if (filename.startsWith("file://")) {
|
|
1158
|
+
filename = fileURLToPath(filename);
|
|
1159
|
+
if (fs.existsSync(filename)) {
|
|
1160
|
+
const content = fs.readFileSync(filename, "utf-8");
|
|
1161
|
+
return {
|
|
1162
|
+
version: 3,
|
|
1163
|
+
sources: [filename],
|
|
1164
|
+
sourcesContent: [content],
|
|
1165
|
+
mappings: "AAAA" + ";AACA".repeat(content.split("\n").length)
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
let mod;
|
|
1171
|
+
let map;
|
|
1172
|
+
if (environmentName === "Server") {
|
|
1173
|
+
mod = server$1.environments.rsc.moduleGraph.getModuleById(filename);
|
|
1174
|
+
map = mod?.transformResult?.map;
|
|
1175
|
+
if (map && map.mappings) map = {
|
|
1176
|
+
...map,
|
|
1177
|
+
mappings: ";;" + map.mappings
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
const base = server$1.config.base.slice(0, -1);
|
|
1181
|
+
if (environmentName === "Client") try {
|
|
1182
|
+
const url = new URL(filename).pathname.slice(base.length);
|
|
1183
|
+
mod = server$1.environments.client.moduleGraph.urlToModuleMap.get(url);
|
|
1184
|
+
map = mod?.transformResult?.map;
|
|
1185
|
+
} catch (e) {}
|
|
1186
|
+
if (mod && map) return {
|
|
1187
|
+
...map,
|
|
1188
|
+
sources: [base + mod.url]
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
function vitePluginRscCss(rscCssOptions) {
|
|
1192
|
+
function collectCss(environment, entryId) {
|
|
1193
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1194
|
+
const cssIds = /* @__PURE__ */ new Set();
|
|
1195
|
+
const visitedFiles = /* @__PURE__ */ new Set();
|
|
1196
|
+
function recurse(id) {
|
|
1197
|
+
if (visited.has(id)) return;
|
|
1198
|
+
visited.add(id);
|
|
1199
|
+
const mod = environment.moduleGraph.getModuleById(id);
|
|
1200
|
+
if (mod?.file) visitedFiles.add(mod.file);
|
|
1201
|
+
for (const next of mod?.importedModules ?? []) if (next.id) if (isCSSRequest(next.id)) cssIds.add(next.id);
|
|
1202
|
+
else recurse(next.id);
|
|
1203
|
+
}
|
|
1204
|
+
recurse(entryId);
|
|
1205
|
+
const hrefs = [...cssIds].map((id) => normalizeViteImportAnalysisUrl(environment, id));
|
|
1206
|
+
return {
|
|
1207
|
+
ids: [...cssIds],
|
|
1208
|
+
hrefs,
|
|
1209
|
+
visitedFiles: [...visitedFiles]
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function getRscCssTransformFilter({ id, code }) {
|
|
1213
|
+
const { query } = parseIdQuery(id);
|
|
1214
|
+
if ("vite-rsc-css-export" in query) {
|
|
1215
|
+
const value = query["vite-rsc-css-export"];
|
|
1216
|
+
if (value) {
|
|
1217
|
+
const names = value.split(",");
|
|
1218
|
+
return (name) => names.includes(name);
|
|
1219
|
+
}
|
|
1220
|
+
return (name) => /^[A-Z]/.test(name);
|
|
1221
|
+
}
|
|
1222
|
+
const options = rscCssOptions?.rscCssTransform;
|
|
1223
|
+
if (options === false) return false;
|
|
1224
|
+
if (options?.filter && !options.filter(id)) return false;
|
|
1225
|
+
if (id.includes("/node_modules/") || !/\.[tj]sx$/.test(id)) return false;
|
|
1226
|
+
const result = esModuleLexer.parse(code);
|
|
1227
|
+
if (!result[0].some((i) => i.t === 1 && i.n && isCSSRequest(i.n))) return false;
|
|
1228
|
+
return (_name, meta) => !!(meta.isFunction && meta.declName && /^[A-Z]/.test(meta.declName) || meta.defaultExportIdentifierName && /^[A-Z]/.test(meta.defaultExportIdentifierName));
|
|
1229
|
+
}
|
|
1230
|
+
return [
|
|
1231
|
+
{
|
|
1232
|
+
name: "rsc:rsc-css-export-transform",
|
|
1233
|
+
async transform(code, id) {
|
|
1234
|
+
if (this.environment.name !== "rsc") return;
|
|
1235
|
+
const filter = getRscCssTransformFilter({
|
|
1236
|
+
id,
|
|
1237
|
+
code
|
|
1238
|
+
});
|
|
1239
|
+
if (!filter) return;
|
|
1240
|
+
const ast = await parseAstAsync(code);
|
|
1241
|
+
const result = await transformRscCssExport({
|
|
1242
|
+
ast,
|
|
1243
|
+
code,
|
|
1244
|
+
filter
|
|
1245
|
+
});
|
|
1246
|
+
if (result) return {
|
|
1247
|
+
code: result.output.toString(),
|
|
1248
|
+
map: result.output.generateMap({ hires: "boundary" })
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
name: "rsc:css/dev-ssr-virtual",
|
|
1254
|
+
resolveId(source) {
|
|
1255
|
+
if (source.startsWith("virtual:vite-rsc/css/dev-ssr/")) return "\0" + source;
|
|
1256
|
+
},
|
|
1257
|
+
async load(id) {
|
|
1258
|
+
if (id.startsWith("\0virtual:vite-rsc/css/dev-ssr/")) {
|
|
1259
|
+
id = id.slice(30);
|
|
1260
|
+
const mod = await server.environments.ssr.moduleGraph.getModuleByUrl(id);
|
|
1261
|
+
if (!mod?.id || !mod?.file) return `export default []`;
|
|
1262
|
+
const result = collectCss(server.environments.ssr, mod.id);
|
|
1263
|
+
for (const file of [mod.file, ...result.visitedFiles]) this.addWatchFile(file);
|
|
1264
|
+
const hrefs = result.hrefs.map((href) => assetsURL(href.slice(1)));
|
|
1265
|
+
return `export default ${JSON.stringify(hrefs)}`;
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
name: "rsc:importer-resources",
|
|
1271
|
+
async transform(code, id) {
|
|
1272
|
+
if (!code.includes("import.meta.viteRsc.loadCss")) return;
|
|
1273
|
+
assert(this.environment.name === "rsc");
|
|
1274
|
+
const output = new MagicString(code);
|
|
1275
|
+
for (const match of code.matchAll(/import\.meta\.viteRsc\.loadCss\(([\s\S]*?)\)/dg)) {
|
|
1276
|
+
const [start, end] = match.indices[0];
|
|
1277
|
+
const argCode = match[1].trim();
|
|
1278
|
+
let importer = id;
|
|
1279
|
+
if (argCode) {
|
|
1280
|
+
const argValue = evalValue(argCode);
|
|
1281
|
+
const resolved = await this.resolve(argValue, id);
|
|
1282
|
+
if (resolved) importer = resolved.id;
|
|
1283
|
+
else {
|
|
1284
|
+
this.warn(`[vite-rsc] failed to transform 'import.meta.viteRsc.loadCss(${argCode})'`);
|
|
1285
|
+
output.update(start, end, `null`);
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
const importId = `virtual:vite-rsc/importer-resources?importer=${encodeURIComponent(importer)}`;
|
|
1290
|
+
let replacement;
|
|
1291
|
+
if (this.environment.mode === "dev") replacement = `__vite_rsc_react__.createElement(async () => {
|
|
1292
|
+
const __m = await import(${JSON.stringify(importId)});
|
|
1293
|
+
return __vite_rsc_react__.createElement(__m.Resources);
|
|
1294
|
+
})`;
|
|
1295
|
+
else {
|
|
1296
|
+
const hash = hashString(importId);
|
|
1297
|
+
if (!code.includes(`__vite_rsc_importer_resources_${hash}`)) output.prepend(`import * as __vite_rsc_importer_resources_${hash} from ${JSON.stringify(importId)};`);
|
|
1298
|
+
replacement = `__vite_rsc_react__.createElement(__vite_rsc_importer_resources_${hash}.Resources)`;
|
|
1299
|
+
}
|
|
1300
|
+
output.update(start, end, replacement);
|
|
1301
|
+
}
|
|
1302
|
+
if (output.hasChanged()) {
|
|
1303
|
+
if (!code.includes("__vite_rsc_react__")) output.prepend(`import __vite_rsc_react__ from "react";`);
|
|
1304
|
+
return {
|
|
1305
|
+
code: output.toString(),
|
|
1306
|
+
map: output.generateMap({ hires: "boundary" })
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
},
|
|
1310
|
+
resolveId(source) {
|
|
1311
|
+
if (source.startsWith("virtual:vite-rsc/importer-resources?importer=")) {
|
|
1312
|
+
assert(this.environment.name === "rsc");
|
|
1313
|
+
return "\0" + source;
|
|
1314
|
+
}
|
|
1315
|
+
},
|
|
1316
|
+
load(id) {
|
|
1317
|
+
if (id.startsWith("\0virtual:vite-rsc/importer-resources?importer=")) {
|
|
1318
|
+
const importer = decodeURIComponent(parseIdQuery(id).query["importer"]);
|
|
1319
|
+
if (this.environment.mode === "dev") {
|
|
1320
|
+
const result = collectCss(server.environments.rsc, importer);
|
|
1321
|
+
const cssHrefs = result.hrefs.map((href) => href.slice(1));
|
|
1322
|
+
const jsHrefs = ["@id/__x00__virtual:vite-rsc/importer-resources-browser?importer=" + encodeURIComponent(importer)];
|
|
1323
|
+
const deps = assetsURLOfDeps({
|
|
1324
|
+
css: cssHrefs,
|
|
1325
|
+
js: jsHrefs
|
|
1326
|
+
});
|
|
1327
|
+
return generateResourcesCode(JSON.stringify(deps, null, 2));
|
|
1328
|
+
} else {
|
|
1329
|
+
const key = normalizePath(path.relative(config.root, importer));
|
|
1330
|
+
serverResourcesMetaMap[importer] = { key };
|
|
1331
|
+
return `
|
|
1332
|
+
import __vite_rsc_assets_manifest__ from "virtual:vite-rsc/assets-manifest";
|
|
1333
|
+
${generateResourcesCode(`__vite_rsc_assets_manifest__.serverResources[${JSON.stringify(key)}]`)}
|
|
1334
|
+
`;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
if (id.startsWith("\0virtual:vite-rsc/importer-resources-browser?importer=")) {
|
|
1338
|
+
assert(this.environment.name === "client");
|
|
1339
|
+
assert(this.environment.mode === "dev");
|
|
1340
|
+
const importer = decodeURIComponent(parseIdQuery(id).query["importer"]);
|
|
1341
|
+
const result = collectCss(server.environments.rsc, importer);
|
|
1342
|
+
let code = result.ids.map((id$1) => id$1.replace(/^\0/, "")).map((id$1) => `import ${JSON.stringify(id$1)};\n`).join("");
|
|
1343
|
+
code += `if (import.meta.hot) { import.meta.hot.accept() }\n`;
|
|
1344
|
+
return code;
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1347
|
+
hotUpdate(ctx) {
|
|
1348
|
+
if (this.environment.name === "rsc") {
|
|
1349
|
+
const mods = collectModuleDependents(ctx.modules);
|
|
1350
|
+
for (const mod of mods) if (mod.id) {
|
|
1351
|
+
const importer = encodeURIComponent(mod.id);
|
|
1352
|
+
invalidteModuleById(server.environments.rsc, `\0virtual:vite-rsc/importer-resources?importer=${importer}`);
|
|
1353
|
+
invalidteModuleById(server.environments.client, `\0virtual:vite-rsc/importer-resources-browser?importer=${importer}`);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
];
|
|
1359
|
+
}
|
|
1360
|
+
function invalidteModuleById(environment, id) {
|
|
1361
|
+
const mod = environment.moduleGraph.getModuleById(id);
|
|
1362
|
+
if (mod) environment.moduleGraph.invalidateModule(mod);
|
|
1363
|
+
return mod;
|
|
1364
|
+
}
|
|
1365
|
+
function collectModuleDependents(mods) {
|
|
1366
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1367
|
+
function recurse(mod) {
|
|
1368
|
+
if (visited.has(mod)) return;
|
|
1369
|
+
visited.add(mod);
|
|
1370
|
+
for (const importer of mod.importers) recurse(importer);
|
|
1371
|
+
}
|
|
1372
|
+
for (const mod of mods) recurse(mod);
|
|
1373
|
+
return [...visited];
|
|
1374
|
+
}
|
|
1375
|
+
function generateResourcesCode(depsCode) {
|
|
1376
|
+
const ResourcesFn = (React, deps) => {
|
|
1377
|
+
return function Resources() {
|
|
1378
|
+
return React.createElement(React.Fragment, null, [...deps.css.map((href) => React.createElement("link", {
|
|
1379
|
+
key: "css:" + href,
|
|
1380
|
+
rel: "stylesheet",
|
|
1381
|
+
precedence: "vite-rsc/importer-resources",
|
|
1382
|
+
href
|
|
1383
|
+
})), ...deps.js.map((href) => React.createElement("script", {
|
|
1384
|
+
key: "js:" + href,
|
|
1385
|
+
type: "module",
|
|
1386
|
+
async: true,
|
|
1387
|
+
src: href
|
|
1388
|
+
}))]);
|
|
1389
|
+
};
|
|
1390
|
+
};
|
|
1391
|
+
return `
|
|
1392
|
+
import __vite_rsc_react__ from "react";
|
|
1393
|
+
export const Resources = (${ResourcesFn.toString()})(__vite_rsc_react__, ${depsCode});
|
|
1394
|
+
`;
|
|
1395
|
+
}
|
|
1396
|
+
function evalValue(rawValue) {
|
|
1397
|
+
const fn = new Function(`
|
|
1398
|
+
var console, exports, global, module, process, require
|
|
1399
|
+
return (\n${rawValue}\n)
|
|
1400
|
+
`);
|
|
1401
|
+
return fn();
|
|
1402
|
+
}
|
|
1403
|
+
function parseIdQuery(id) {
|
|
1404
|
+
if (!id.includes("?")) return {
|
|
1405
|
+
filename: id,
|
|
1406
|
+
query: {}
|
|
1407
|
+
};
|
|
1408
|
+
const [filename, rawQuery] = id.split(`?`, 2);
|
|
1409
|
+
const query = Object.fromEntries(new URLSearchParams(rawQuery));
|
|
1410
|
+
return {
|
|
1411
|
+
filename,
|
|
1412
|
+
query
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
async function transformRscCssExport(options) {
|
|
1416
|
+
if (hasDirective(options.ast.body, "use client")) return;
|
|
1417
|
+
const result = transformWrapExport(options.code, options.ast, {
|
|
1418
|
+
runtime: (value, name, meta) => `__vite_rsc_wrap_css__(${value}, ${JSON.stringify(meta.defaultExportIdentifierName ?? name)})`,
|
|
1419
|
+
filter: options.filter,
|
|
1420
|
+
ignoreExportAllDeclaration: true
|
|
1421
|
+
});
|
|
1422
|
+
if (result.output.hasChanged()) {
|
|
1423
|
+
if (!options.code.includes("__vite_rsc_react__")) result.output.prepend(`import __vite_rsc_react__ from "react";`);
|
|
1424
|
+
result.output.append(`
|
|
1425
|
+
function __vite_rsc_wrap_css__(value, name) {
|
|
1426
|
+
if (typeof value !== 'function') return value;
|
|
1427
|
+
|
|
1428
|
+
function __wrapper(props) {
|
|
1429
|
+
return __vite_rsc_react__.createElement(
|
|
1430
|
+
__vite_rsc_react__.Fragment,
|
|
1431
|
+
null,
|
|
1432
|
+
import.meta.viteRsc.loadCss(${options.id ? JSON.stringify(options.id) : ""}),
|
|
1433
|
+
__vite_rsc_react__.createElement(value, props),
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
Object.defineProperty(__wrapper, "name", { value: name });
|
|
1437
|
+
return __wrapper;
|
|
1438
|
+
}
|
|
1439
|
+
`);
|
|
1440
|
+
return { output: result.output };
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* temporary workaround for
|
|
1445
|
+
* - https://github.com/cloudflare/workers-sdk/issues/9538 (fixed in @cloudflare/vite-plugin@1.8.0)
|
|
1446
|
+
* - https://github.com/vitejs/vite/pull/20077 (fixed in vite@7.0.0)
|
|
1447
|
+
*/
|
|
1448
|
+
function __fix_cloudflare() {
|
|
1449
|
+
return {
|
|
1450
|
+
name: "rsc:workaround-cloudflare",
|
|
1451
|
+
enforce: "post",
|
|
1452
|
+
config(config$1) {
|
|
1453
|
+
const plugin = config$1.plugins.flat().find((p) => p && "name" in p && p.name === "vite-plugin-cloudflare");
|
|
1454
|
+
const original = plugin.configResolved;
|
|
1455
|
+
plugin.configResolved = function(...args) {
|
|
1456
|
+
try {
|
|
1457
|
+
return original.apply(this, args);
|
|
1458
|
+
} catch (e) {}
|
|
1459
|
+
};
|
|
1460
|
+
config$1.environments.ssr.resolve.noExternal = true;
|
|
1461
|
+
config$1.environments.rsc.resolve.noExternal = true;
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
function sortObject(o) {
|
|
1466
|
+
return Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b)));
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
//#endregion
|
|
1470
|
+
export { __fix_cloudflare, findSourceMapURL, transformHoistInlineDirective, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss };
|