@vitejs/plugin-rsc 0.5.32 → 0.5.33
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 +18 -18
- package/dist/{cjs-Cxg_7upE.js → cjs-AWVWfddx.js} +3 -2
- package/dist/{client-reference-Dy7j0iU8.d.ts → client-reference-DEZtXTv1.d.ts} +1 -1
- package/dist/{index-COzKOTR1.d.ts → index-XXYjyFr6.d.ts} +291 -37
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{picocolors-CKiBgsDn.js → picocolors-D28_L_A0.js} +1 -1
- package/dist/{plugin-DqLpibhH.d.ts → plugin-CKqXjp8D.d.ts} +5 -4
- package/dist/{plugin-C27mwbgw.js → plugin-DarRieDr.js} +9 -17
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugins/cjs.js +1 -1
- package/dist/rsc/server.d.ts +1 -1
- package/dist/rsc/static.d.ts +1 -1
- package/dist/{scope-Do08R7C2.js → scope-Bdx33sQv.js} +10 -5
- package/dist/ssr.d.ts +3 -2
- package/dist/ssr.js +6 -1
- package/dist/transforms/index.d.ts +2 -2
- package/dist/transforms/index.js +484 -187
- package/package.json +16 -15
- package/types/index.d.ts +1 -0
package/dist/transforms/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as tinyassert } from "../dist-uqdtSkzK.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as isDirective, i as hasDirective, n as extractIdentifiers, o as rejectNonAsyncFunction, r as extractNames, s as validateNonAsyncFunction, t as buildScopeTree } from "../scope-Bdx33sQv.js";
|
|
3
3
|
import MagicString from "magic-string";
|
|
4
4
|
import { walk } from "estree-walker";
|
|
5
5
|
//#region src/transforms/hoist.ts
|
|
@@ -55,13 +55,33 @@ import { walk } from "estree-walker";
|
|
|
55
55
|
*
|
|
56
56
|
* In this second sketch, `__ENCODE__(...)` and `__DECODE__(...)` likewise
|
|
57
57
|
* represent the expressions returned by those code-generation callbacks.
|
|
58
|
+
*
|
|
59
|
+
* With `hoistRuntime`, the runtime result becomes the module-level binding and
|
|
60
|
+
* the moved function becomes its private implementation:
|
|
61
|
+
*
|
|
62
|
+
* ```js
|
|
63
|
+
* function Component() {
|
|
64
|
+
* const x = 1
|
|
65
|
+
* const action = $$hoist_0_action.bind(null, x)
|
|
66
|
+
* }
|
|
67
|
+
* export const $$hoist_0_action = __RUNTIME__($$hoist_0_action$$impl)
|
|
68
|
+
* async function $$hoist_0_action$$impl(x, y) {
|
|
69
|
+
* "use server"
|
|
70
|
+
* return x + y
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* `noExport` independently keeps `$$hoist_0_action` module-local when an
|
|
75
|
+
* integration needs module-scope runtime initialization without an export.
|
|
58
76
|
*/
|
|
59
|
-
function transformHoistInlineDirective(input,
|
|
77
|
+
function transformHoistInlineDirective(input, viteAst, { runtime, rejectNonAsyncFunction, ...options }) {
|
|
78
|
+
const ast = viteAst;
|
|
60
79
|
if (!input.endsWith("\n")) input += "\n";
|
|
61
80
|
const output = new MagicString(input);
|
|
62
81
|
const directive = typeof options.directive === "string" ? exactRegex(options.directive) : options.directive;
|
|
63
82
|
const scopeTree = buildScopeTree(ast);
|
|
64
83
|
const names = [];
|
|
84
|
+
const runtimeHoists = [];
|
|
65
85
|
walk(ast, { enter(node, parent) {
|
|
66
86
|
if ((node.type === "FunctionExpression" || node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression") && node.body.type === "BlockStatement") {
|
|
67
87
|
const match = matchDirective(node.body.body, directive)?.match;
|
|
@@ -77,10 +97,16 @@ function transformHoistInlineDirective(input, ast, { runtime, rejectNonAsyncFunc
|
|
|
77
97
|
}
|
|
78
98
|
const newName = `$$hoist_${names.length}` + (originalName ? `_${originalName}` : "");
|
|
79
99
|
names.push(newName);
|
|
80
|
-
|
|
81
|
-
output.
|
|
100
|
+
const implementationName = options.hoistRuntime ? `${newName}$$impl` : newName;
|
|
101
|
+
output.update(node.start, node.body.start, `\n;${options.noExport || options.hoistRuntime ? "" : "export "}${node.async ? "async " : ""}function${node.generator ? "*" : ""} ${implementationName}(${newParams}) `);
|
|
102
|
+
const runtimeCode = `/* #__PURE__ */ ${runtime(implementationName, newName, {
|
|
103
|
+
directiveMatch: match,
|
|
104
|
+
valueNode: node
|
|
105
|
+
})}`;
|
|
106
|
+
if (options.hoistRuntime) runtimeHoists.push(`${options.noExport ? "" : "export "}const ${newName} = ${runtimeCode};\n`);
|
|
107
|
+
output.appendLeft(node.end, `;\n/* #__PURE__ */ Object.defineProperty(${implementationName}, "name", { value: ${JSON.stringify(originalName)} });\n`);
|
|
82
108
|
output.move(node.start, node.end, input.length);
|
|
83
|
-
let newCode =
|
|
109
|
+
let newCode = options.hoistRuntime ? newName : runtimeCode;
|
|
84
110
|
if (bindVars.length > 0) {
|
|
85
111
|
const bindArgs = options.encode ? options.encode("[" + bindVars.map((b) => b.expr).join(", ") + "]") : bindVars.map((b) => b.expr).join(", ");
|
|
86
112
|
newCode = `${newCode}.bind(null, ${bindArgs})`;
|
|
@@ -95,22 +121,29 @@ function transformHoistInlineDirective(input, ast, { runtime, rejectNonAsyncFunc
|
|
|
95
121
|
output.appendLeft(node.start, newCode);
|
|
96
122
|
}
|
|
97
123
|
} });
|
|
124
|
+
if (runtimeHoists.length > 0) output.prependLeft(getRuntimeHoistPosition(ast), runtimeHoists.join(""));
|
|
98
125
|
return {
|
|
99
126
|
output,
|
|
100
127
|
names
|
|
101
128
|
};
|
|
102
129
|
}
|
|
130
|
+
function getRuntimeHoistPosition(ast) {
|
|
131
|
+
for (const statement of ast.body) if (!isDirective(statement)) return statement.start;
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
103
134
|
const exactRegex = (s) => new RegExp("^" + s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$");
|
|
104
135
|
function matchDirective(body, directive) {
|
|
105
|
-
for (const stmt of body)
|
|
106
|
-
|
|
136
|
+
for (const stmt of body) {
|
|
137
|
+
if (!isDirective(stmt)) return;
|
|
138
|
+
const match = stmt.directive.match(directive);
|
|
107
139
|
if (match) return {
|
|
108
140
|
match,
|
|
109
141
|
node: stmt.expression
|
|
110
142
|
};
|
|
111
143
|
}
|
|
112
144
|
}
|
|
113
|
-
function findDirectives(
|
|
145
|
+
function findDirectives(viteAst, directive) {
|
|
146
|
+
const ast = viteAst;
|
|
114
147
|
const directiveRE = exactRegex(directive);
|
|
115
148
|
const nodes = [];
|
|
116
149
|
walk(ast, { enter(node) {
|
|
@@ -209,128 +242,374 @@ function dedupeByPrefix(paths) {
|
|
|
209
242
|
return result;
|
|
210
243
|
}
|
|
211
244
|
//#endregion
|
|
245
|
+
//#region src/transforms/module-export-scan.ts
|
|
246
|
+
function scanModuleExports(viteAst) {
|
|
247
|
+
const ast = viteAst;
|
|
248
|
+
const groups = [];
|
|
249
|
+
for (const node of ast.body) if (node.type === "ExportNamedDeclaration") if (node.declaration) if (node.declaration.type === "VariableDeclaration") {
|
|
250
|
+
const declaration = node.declaration;
|
|
251
|
+
groups.push({
|
|
252
|
+
type: "variable-declaration",
|
|
253
|
+
node,
|
|
254
|
+
declaration,
|
|
255
|
+
declarators: declaration.declarations.map((declarator) => {
|
|
256
|
+
const isFunction = declarator.id.type === "Identifier" && declarator.init ? getIsFunction(declarator.init) : void 0;
|
|
257
|
+
return {
|
|
258
|
+
node: declarator,
|
|
259
|
+
exports: extractNames(declarator.id).map((name) => ({
|
|
260
|
+
localName: name,
|
|
261
|
+
exportName: name,
|
|
262
|
+
meta: {
|
|
263
|
+
declName: name,
|
|
264
|
+
isFunction,
|
|
265
|
+
valueNode: declarator.init ?? void 0
|
|
266
|
+
}
|
|
267
|
+
}))
|
|
268
|
+
};
|
|
269
|
+
})
|
|
270
|
+
});
|
|
271
|
+
} else {
|
|
272
|
+
tinyassert(node.declaration.id);
|
|
273
|
+
const name = node.declaration.id.name;
|
|
274
|
+
groups.push({
|
|
275
|
+
type: "declaration",
|
|
276
|
+
node,
|
|
277
|
+
declaration: node.declaration,
|
|
278
|
+
export: {
|
|
279
|
+
localName: name,
|
|
280
|
+
exportName: name,
|
|
281
|
+
meta: {
|
|
282
|
+
declName: name,
|
|
283
|
+
isFunction: getIsFunction(node.declaration),
|
|
284
|
+
valueNode: node.declaration
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
else groups.push({
|
|
290
|
+
type: "specifiers",
|
|
291
|
+
node,
|
|
292
|
+
exports: node.specifiers.map((specifier) => {
|
|
293
|
+
return {
|
|
294
|
+
node: specifier,
|
|
295
|
+
localName: specifier.local.type === "Identifier" ? specifier.local.name : "__unsupported_string_export__",
|
|
296
|
+
exportName: specifier.exported.type === "Identifier" ? specifier.exported.name : "__unsupported_string_export__",
|
|
297
|
+
meta: {}
|
|
298
|
+
};
|
|
299
|
+
})
|
|
300
|
+
});
|
|
301
|
+
else if (node.type === "ExportAllDeclaration") groups.push({
|
|
302
|
+
type: "export-all",
|
|
303
|
+
node
|
|
304
|
+
});
|
|
305
|
+
else if (node.type === "ExportDefaultDeclaration") {
|
|
306
|
+
let kind;
|
|
307
|
+
let localName;
|
|
308
|
+
let meta;
|
|
309
|
+
if ((node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") && node.declaration.id) {
|
|
310
|
+
kind = "named-declaration";
|
|
311
|
+
localName = node.declaration.id.name;
|
|
312
|
+
meta = {
|
|
313
|
+
declName: node.declaration.id.name,
|
|
314
|
+
isFunction: getIsFunction(node.declaration),
|
|
315
|
+
valueNode: node.declaration
|
|
316
|
+
};
|
|
317
|
+
} else if (node.declaration.type === "Identifier") {
|
|
318
|
+
kind = "identifier";
|
|
319
|
+
meta = {
|
|
320
|
+
defaultExportIdentifierName: node.declaration.name,
|
|
321
|
+
valueNode: node.declaration
|
|
322
|
+
};
|
|
323
|
+
} else {
|
|
324
|
+
kind = "other";
|
|
325
|
+
meta = {
|
|
326
|
+
isFunction: getIsFunction(node.declaration),
|
|
327
|
+
valueNode: node.declaration
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
groups.push({
|
|
331
|
+
type: "default",
|
|
332
|
+
kind,
|
|
333
|
+
node,
|
|
334
|
+
localName,
|
|
335
|
+
meta
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return groups;
|
|
339
|
+
}
|
|
340
|
+
function getIsFunction(node) {
|
|
341
|
+
if (node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") return true;
|
|
342
|
+
if (node.type === "ClassDeclaration" || node.type === "Literal" || node.type === "ObjectExpression" || node.type === "ArrayExpression" || node.type === "ClassExpression") return false;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/transforms/module-export-effect.ts
|
|
346
|
+
/**
|
|
347
|
+
* Preserves source bindings and emits registration effects at module end.
|
|
348
|
+
*
|
|
349
|
+
* Conceptually:
|
|
350
|
+
*
|
|
351
|
+
* ```js
|
|
352
|
+
* export async function action() {}
|
|
353
|
+
* export default async () => {}
|
|
354
|
+
* ```
|
|
355
|
+
*
|
|
356
|
+
* becomes:
|
|
357
|
+
*
|
|
358
|
+
* ```js
|
|
359
|
+
* async function action() {}
|
|
360
|
+
* const $$effect_default = async () => {}
|
|
361
|
+
*
|
|
362
|
+
* __GENERATE__(action, 'action')
|
|
363
|
+
* export { action }
|
|
364
|
+
* __GENERATE__($$effect_default, 'default')
|
|
365
|
+
* export default $$effect_default
|
|
366
|
+
* ```
|
|
367
|
+
*
|
|
368
|
+
* Here, `__GENERATE__(...)` represents the expression returned by the
|
|
369
|
+
* `generate` callback for each `{ binding, exportName, meta }` context.
|
|
370
|
+
* `references` returns those contexts in generation order, while
|
|
371
|
+
* `referenceNames` returns only their export names.
|
|
372
|
+
*
|
|
373
|
+
* Effects emitted through declaration and default-export rewrites remain mapped
|
|
374
|
+
* to their original export sites. Export-specifier effects are appended without
|
|
375
|
+
* explicit mappings and rely on adjacent-source fallback. React captures the
|
|
376
|
+
* `registerServerReference` caller as the reference source location.
|
|
377
|
+
*
|
|
378
|
+
* Generated bindings such as `$$effect_default` and `$$effect_import_*` are not
|
|
379
|
+
* deconflicted from user bindings, consistent with the other transform helpers.
|
|
380
|
+
*/
|
|
381
|
+
function transformModuleExportEffect(input, viteAst, options) {
|
|
382
|
+
const output = new MagicString(input);
|
|
383
|
+
const filter = options.filter ?? (() => true);
|
|
384
|
+
const references = [];
|
|
385
|
+
function generate(context) {
|
|
386
|
+
references.push(context);
|
|
387
|
+
return `${options.generate(context)};`;
|
|
388
|
+
}
|
|
389
|
+
function replaceAndMove(start, end, destination, code) {
|
|
390
|
+
output.update(start, end, `\n${code}\n`);
|
|
391
|
+
if (end !== destination) output.move(start, end, destination);
|
|
392
|
+
}
|
|
393
|
+
for (const group of scanModuleExports(viteAst)) if (group.type === "declaration") {
|
|
394
|
+
const { localName: binding, exportName, meta } = group.export;
|
|
395
|
+
if (!filter(exportName, meta)) continue;
|
|
396
|
+
validateNonAsyncFunction(options, group.declaration);
|
|
397
|
+
replaceAndMove(group.node.start, group.declaration.start, input.length, `${generate({
|
|
398
|
+
binding,
|
|
399
|
+
exportName,
|
|
400
|
+
meta
|
|
401
|
+
})}\nexport { ${binding} };`);
|
|
402
|
+
} else if (group.type === "variable-declaration") {
|
|
403
|
+
const exportNames = [];
|
|
404
|
+
const effects = [];
|
|
405
|
+
for (const declarator of group.declarators) {
|
|
406
|
+
let validate = false;
|
|
407
|
+
for (const entry of declarator.exports) {
|
|
408
|
+
const { localName: binding, exportName, meta } = entry;
|
|
409
|
+
exportNames.push(exportName);
|
|
410
|
+
if (filter(exportName, meta)) {
|
|
411
|
+
validate = true;
|
|
412
|
+
effects.push(generate({
|
|
413
|
+
binding,
|
|
414
|
+
exportName,
|
|
415
|
+
meta
|
|
416
|
+
}));
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (validate) {
|
|
420
|
+
const init = declarator.node.init;
|
|
421
|
+
if (init) validateNonAsyncFunction(options, init);
|
|
422
|
+
else rejectNonAsyncFunction(options, declarator.node.start);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (effects.length > 0) replaceAndMove(group.node.start, group.declaration.start, input.length, `${effects.join("\n")}\nexport { ${exportNames.join(", ")} };`);
|
|
426
|
+
} else if (group.type === "specifiers") for (const entry of group.exports) {
|
|
427
|
+
tinyassert(entry.node.local.type === "Identifier");
|
|
428
|
+
if (entry.node.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: entry.node.exported.start });
|
|
429
|
+
const { exportName, meta } = entry;
|
|
430
|
+
if (!filter(exportName, meta)) continue;
|
|
431
|
+
let binding = entry.localName;
|
|
432
|
+
if (group.node.source) {
|
|
433
|
+
binding = `$$effect_import_${exportName}`;
|
|
434
|
+
output.append(`\nimport { ${entry.localName} as ${binding} } from ${group.node.source.raw};`);
|
|
435
|
+
}
|
|
436
|
+
output.append(`\n${generate({
|
|
437
|
+
binding,
|
|
438
|
+
exportName,
|
|
439
|
+
meta
|
|
440
|
+
})}`);
|
|
441
|
+
}
|
|
442
|
+
else if (group.type === "export-all") {
|
|
443
|
+
if (options.exportAll !== "preserve") throw Object.assign(/* @__PURE__ */ new Error("unsupported ExportAllDeclaration"), { pos: group.node.start });
|
|
444
|
+
} else if (group.type === "default") {
|
|
445
|
+
const node = group.node;
|
|
446
|
+
const binding = group.localName ?? "$$effect_default";
|
|
447
|
+
const meta = group.meta;
|
|
448
|
+
if (!filter("default", meta)) continue;
|
|
449
|
+
validateNonAsyncFunction(options, node.declaration);
|
|
450
|
+
const effect = generate({
|
|
451
|
+
binding,
|
|
452
|
+
exportName: "default",
|
|
453
|
+
meta
|
|
454
|
+
});
|
|
455
|
+
if (group.kind === "identifier") {
|
|
456
|
+
const declaration = node.declaration;
|
|
457
|
+
const exportTokenEnd = node.start + 6;
|
|
458
|
+
output.update(exportTokenEnd, node.end, `const ${binding} = ${declaration.name};`);
|
|
459
|
+
replaceAndMove(node.start, exportTokenEnd, input.length, `${effect}\nexport default ${binding};`);
|
|
460
|
+
} else if (group.kind === "named-declaration") replaceAndMove(node.start, node.declaration.start, input.length, `${effect}\nexport default ${binding};`);
|
|
461
|
+
else {
|
|
462
|
+
const exportTokenEnd = node.start + 6;
|
|
463
|
+
output.update(exportTokenEnd, node.declaration.start, `const ${binding} = `);
|
|
464
|
+
replaceAndMove(node.start, exportTokenEnd, input.length, `${effect}\nexport default ${binding};`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return {
|
|
468
|
+
output,
|
|
469
|
+
references,
|
|
470
|
+
referenceNames: references.map((reference) => reference.exportName)
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
//#endregion
|
|
212
474
|
//#region src/transforms/wrap-export.ts
|
|
213
|
-
|
|
475
|
+
/**
|
|
476
|
+
* Replaces selected module-local export bindings with runtime wrappers.
|
|
477
|
+
*
|
|
478
|
+
* Conceptually:
|
|
479
|
+
*
|
|
480
|
+
* ```js
|
|
481
|
+
* export async function action() {}
|
|
482
|
+
* export const loader = async () => {}
|
|
483
|
+
* export default function Page() {}
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* becomes:
|
|
487
|
+
*
|
|
488
|
+
* ```js
|
|
489
|
+
* async function action() {}
|
|
490
|
+
* let loader = async () => {}
|
|
491
|
+
* function Page() {}
|
|
492
|
+
*
|
|
493
|
+
* action = __WRAP__(action, 'action')
|
|
494
|
+
* export { action }
|
|
495
|
+
* loader = __WRAP__(loader, 'loader')
|
|
496
|
+
* export { loader }
|
|
497
|
+
* const $$wrap_Page = __WRAP__(Page, 'default')
|
|
498
|
+
* export { $$wrap_Page as default }
|
|
499
|
+
* ```
|
|
500
|
+
*
|
|
501
|
+
* Here, `__WRAP__(...)` represents the expression returned by `runtime`.
|
|
502
|
+
* Unlike `transformModuleExportWrap`, direct local references observe the
|
|
503
|
+
* wrapped value because the original binding itself is reassigned.
|
|
504
|
+
*
|
|
505
|
+
* Declaration rewrites are moved to the end of the module so each generated
|
|
506
|
+
* runtime call retains the original export token's source mapping. Wrappers for
|
|
507
|
+
* export specifiers and default exports are appended without explicit mappings.
|
|
508
|
+
*
|
|
509
|
+
* Generated `$$wrap_*` and `$$import_*` names are not deconflicted from user
|
|
510
|
+
* bindings, consistent with the other transform helpers.
|
|
511
|
+
*/
|
|
512
|
+
function transformWrapExport(input, viteAst, options) {
|
|
214
513
|
const output = new MagicString(input);
|
|
215
514
|
const exportNames = [];
|
|
216
|
-
const
|
|
515
|
+
const appendedCode = [];
|
|
217
516
|
const filter = options.filter ?? (() => true);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
517
|
+
/**
|
|
518
|
+
* Strips a direct export declaration and emits assignments and exports at
|
|
519
|
+
* module end. All bindings are re-exported, but only selected bindings are
|
|
520
|
+
* assigned runtime wrappers.
|
|
521
|
+
*
|
|
522
|
+
* The rewritten source range is moved so generated runtime calls borrow the
|
|
523
|
+
* original export site's mapping:
|
|
524
|
+
*
|
|
525
|
+
* ```js
|
|
526
|
+
* // input
|
|
527
|
+
* export async function action() {}
|
|
528
|
+
* ^^^^^^
|
|
529
|
+
*
|
|
530
|
+
* // output
|
|
531
|
+
* async function action() {}
|
|
532
|
+
* action = __WRAP__(action, 'action') << maps to the `export` token
|
|
533
|
+
* export { action } <<
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
function emitWrappedAssignments(start, end, exports, selectedExportNames) {
|
|
537
|
+
exportNames.push(...selectedExportNames);
|
|
538
|
+
const newCode = exports.map((e) => selectedExportNames.has(e.exportName) && `${e.localName} = /* #__PURE__ */ ${options.runtime(e.localName, e.exportName, e.meta)};\n`).filter(Boolean).join("") + `export { ${exports.map((e) => e.localName).join(", ")} };\n`;
|
|
225
539
|
output.update(start, end, newCode);
|
|
226
540
|
output.move(start, end, input.length);
|
|
227
541
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
542
|
+
/**
|
|
543
|
+
* Emits a separate wrapper binding for exports that cannot reassign an
|
|
544
|
+
* existing direct declaration, such as export specifiers and defaults.
|
|
545
|
+
*
|
|
546
|
+
* ```js
|
|
547
|
+
* // existing source binding remains unchanged
|
|
548
|
+
* const local = init()
|
|
549
|
+
* export { local as renamed } // caller removes the original export
|
|
550
|
+
*
|
|
551
|
+
* // appended code
|
|
552
|
+
* const $$wrap_local = __WRAP__(local, 'renamed')
|
|
553
|
+
* export { $$wrap_local as renamed }
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
function emitWrappedBinding(name, exportName, meta = {}) {
|
|
233
557
|
exportNames.push(exportName);
|
|
234
|
-
|
|
558
|
+
appendedCode.push(`const $$wrap_${name} = /* #__PURE__ */ ${options.runtime(name, exportName, meta)}`, `export { $$wrap_${name} as ${exportName} }`);
|
|
235
559
|
}
|
|
236
|
-
for (const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
*/
|
|
255
|
-
if (
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const isFunction = decl.id.type === "Identifier" && decl.init ? getIsFunction(decl.init) : void 0;
|
|
259
|
-
const declarationExports = extractNames(decl.id).map((name) => ({
|
|
260
|
-
name,
|
|
261
|
-
meta: {
|
|
262
|
-
isFunction,
|
|
263
|
-
declName: name
|
|
264
|
-
}
|
|
265
|
-
}));
|
|
266
|
-
exports.push(...declarationExports);
|
|
267
|
-
if (decl.init && declarationExports.some(({ name, meta }) => filter(name, meta))) validateNonAsyncFunction(options, decl.init);
|
|
268
|
-
}
|
|
269
|
-
wrapSimple(node.start, node.declaration.start, exports);
|
|
270
|
-
} else node.declaration;
|
|
271
|
-
else if (node.source) {
|
|
272
|
-
/**
|
|
273
|
-
* export { foo, bar as car } from './foo'
|
|
274
|
-
*/
|
|
275
|
-
output.remove(node.start, node.end);
|
|
276
|
-
for (const spec of node.specifiers) {
|
|
277
|
-
tinyassert(spec.local.type === "Identifier");
|
|
278
|
-
if (spec.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: spec.exported.start });
|
|
279
|
-
const name = spec.local.name;
|
|
280
|
-
toAppend.push(`import { ${name} as $$import_${name} } from ${node.source.raw}`);
|
|
281
|
-
wrapExport(`$$import_${name}`, spec.exported.name);
|
|
560
|
+
for (const group of scanModuleExports(viteAst)) if (group.type === "declaration") {
|
|
561
|
+
const entry = group.export;
|
|
562
|
+
if (!filter(entry.exportName, entry.meta)) continue;
|
|
563
|
+
validateNonAsyncFunction(options, group.declaration);
|
|
564
|
+
emitWrappedAssignments(group.node.start, group.declaration.start, [entry], /* @__PURE__ */ new Set([entry.exportName]));
|
|
565
|
+
} else if (group.type === "variable-declaration") {
|
|
566
|
+
const exports = group.declarators.flatMap((item) => item.exports);
|
|
567
|
+
const selectedExportNames = new Set(exports.filter((entry) => filter(entry.exportName, entry.meta)).map((entry) => entry.exportName));
|
|
568
|
+
if (selectedExportNames.size === 0) continue;
|
|
569
|
+
if (group.declaration.kind === "const") output.update(group.declaration.start, group.declaration.start + 5, "let");
|
|
570
|
+
for (const declarator of group.declarators) if (declarator.exports.some(({ exportName }) => selectedExportNames.has(exportName))) if (declarator.node.init) validateNonAsyncFunction(options, declarator.node.init);
|
|
571
|
+
else rejectNonAsyncFunction(options, declarator.node.start);
|
|
572
|
+
emitWrappedAssignments(group.node.start, group.declaration.start, exports, selectedExportNames);
|
|
573
|
+
} else if (group.type === "specifiers") {
|
|
574
|
+
const skippedExports = [];
|
|
575
|
+
let selected = false;
|
|
576
|
+
for (const entry of group.exports) {
|
|
577
|
+
tinyassert(entry.node.local.type === "Identifier");
|
|
578
|
+
if (entry.node.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: entry.node.exported.start });
|
|
579
|
+
if (!filter(entry.exportName, entry.meta)) {
|
|
580
|
+
skippedExports.push(entry.localName === entry.exportName ? entry.localName : `${entry.localName} as ${entry.exportName}`);
|
|
581
|
+
continue;
|
|
282
582
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
tinyassert(spec.local.type === "Identifier");
|
|
290
|
-
if (spec.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: spec.exported.start });
|
|
291
|
-
wrapExport(spec.local.name, spec.exported.name);
|
|
583
|
+
selected = true;
|
|
584
|
+
let binding = entry.localName;
|
|
585
|
+
const source = group.node.source;
|
|
586
|
+
if (source) {
|
|
587
|
+
binding = `$$import_${entry.localName}`;
|
|
588
|
+
appendedCode.push(`import { ${entry.localName} as ${binding} } from ${source.raw}`);
|
|
292
589
|
}
|
|
590
|
+
emitWrappedBinding(binding, entry.exportName, entry.meta);
|
|
293
591
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (!options.ignoreExportAllDeclaration) throw Object.assign(/* @__PURE__ */ new Error("unsupported ExportAllDeclaration"), { pos: node.start });
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* export default function foo() {}
|
|
303
|
-
* export default class Foo {}
|
|
304
|
-
* export default () => {}
|
|
305
|
-
*/
|
|
306
|
-
if (node.type === "ExportDefaultDeclaration") {
|
|
307
|
-
let localName;
|
|
308
|
-
let isFunction;
|
|
309
|
-
let declName;
|
|
310
|
-
let defaultExportIdentifierName;
|
|
311
|
-
if ((node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") && node.declaration.id) {
|
|
312
|
-
localName = node.declaration.id.name;
|
|
313
|
-
output.remove(node.start, node.declaration.start);
|
|
314
|
-
isFunction = getIsFunction(node.declaration);
|
|
315
|
-
declName = node.declaration.id.name;
|
|
316
|
-
} else {
|
|
317
|
-
localName = "$$default";
|
|
318
|
-
output.update(node.start, node.declaration.start, "const $$default = ");
|
|
319
|
-
if (node.declaration.type === "Identifier") defaultExportIdentifierName = node.declaration.name;
|
|
320
|
-
else isFunction = getIsFunction(node.declaration);
|
|
592
|
+
if (selected) {
|
|
593
|
+
output.remove(group.node.start, group.node.end);
|
|
594
|
+
if (skippedExports.length > 0) {
|
|
595
|
+
const source = group.node.source ? ` from ${group.node.source.raw}` : "";
|
|
596
|
+
appendedCode.push(`export { ${skippedExports.join(", ")} }${source}`);
|
|
321
597
|
}
|
|
322
|
-
const defaultMeta = {
|
|
323
|
-
isFunction,
|
|
324
|
-
declName,
|
|
325
|
-
defaultExportIdentifierName
|
|
326
|
-
};
|
|
327
|
-
if (filter("default", defaultMeta)) validateNonAsyncFunction(options, node.declaration);
|
|
328
|
-
wrapExport(localName, "default", defaultMeta);
|
|
329
598
|
}
|
|
599
|
+
} else if (group.type === "export-all") {
|
|
600
|
+
if (!options.ignoreExportAllDeclaration) throw Object.assign(/* @__PURE__ */ new Error("unsupported ExportAllDeclaration"), { pos: group.node.start });
|
|
601
|
+
} else if (group.type === "default") {
|
|
602
|
+
const meta = group.meta;
|
|
603
|
+
if (!filter("default", meta)) continue;
|
|
604
|
+
const localName = group.localName ?? "$$default";
|
|
605
|
+
if (group.kind === "named-declaration") output.remove(group.node.start, group.node.declaration.start);
|
|
606
|
+
else output.update(group.node.start, group.node.declaration.start, "const $$default = ");
|
|
607
|
+
validateNonAsyncFunction(options, group.node.declaration);
|
|
608
|
+
emitWrappedBinding(localName, "default", meta);
|
|
330
609
|
}
|
|
331
|
-
if (
|
|
610
|
+
if (appendedCode.length > 0) output.append([
|
|
332
611
|
"",
|
|
333
|
-
...
|
|
612
|
+
...appendedCode,
|
|
334
613
|
""
|
|
335
614
|
].join(";\n"));
|
|
336
615
|
return {
|
|
@@ -338,90 +617,103 @@ function transformWrapExport(input, ast, options) {
|
|
|
338
617
|
output
|
|
339
618
|
};
|
|
340
619
|
}
|
|
341
|
-
function getIsFunction(node) {
|
|
342
|
-
if (node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") return true;
|
|
343
|
-
if (node.type === "ClassDeclaration" || node.type === "Literal" || node.type === "ObjectExpression" || node.type === "ArrayExpression" || node.type === "ClassExpression") return false;
|
|
344
|
-
}
|
|
345
620
|
//#endregion
|
|
346
621
|
//#region src/transforms/proxy-export.ts
|
|
347
622
|
function transformDirectiveProxyExport(ast, options) {
|
|
348
623
|
if (!hasDirective(ast.body, options.directive)) return;
|
|
349
624
|
return transformProxyExport(ast, options);
|
|
350
625
|
}
|
|
351
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Replaces selected exports with proxies created by `runtime` and removes the
|
|
628
|
+
* original module implementation.
|
|
629
|
+
*
|
|
630
|
+
* Conceptually, with a filter that excludes `objectValue`:
|
|
631
|
+
*
|
|
632
|
+
* ```js
|
|
633
|
+
* import { dependency } from './dep'
|
|
634
|
+
* export async function action() {}
|
|
635
|
+
* export const objectValue = {}
|
|
636
|
+
* export { dependency as renamed }
|
|
637
|
+
* export default async () => {}
|
|
638
|
+
* ```
|
|
639
|
+
*
|
|
640
|
+
* becomes:
|
|
641
|
+
*
|
|
642
|
+
* ```js
|
|
643
|
+
* export const action = __PROXY__('action')
|
|
644
|
+
* export const renamed = __PROXY__('renamed')
|
|
645
|
+
* export default __PROXY__('default')
|
|
646
|
+
* ```
|
|
647
|
+
*
|
|
648
|
+
* Unlike `transformWrapExport`, this transform does not evaluate the original
|
|
649
|
+
* exports. Unknown values are represented only by their export names, so the
|
|
650
|
+
* caller must filter solely from the available static `ModuleExportMeta`.
|
|
651
|
+
* `keep` is a specialized mode that retains non-export implementation code and
|
|
652
|
+
* passes a single variable initializer to `runtime`.
|
|
653
|
+
*/
|
|
654
|
+
function transformProxyExport(viteAst, options) {
|
|
655
|
+
const ast = viteAst;
|
|
352
656
|
if (options.keep && typeof options.code !== "string") throw new Error("`keep` option requires `code`");
|
|
657
|
+
if (options.keep && options.filter) throw new Error("`filter` option is not supported with `keep`");
|
|
353
658
|
const output = new MagicString(options.code ?? " ".repeat(ast.end));
|
|
354
659
|
const exportNames = [];
|
|
660
|
+
const filter = options.filter ?? (() => true);
|
|
661
|
+
function removeNode(node) {
|
|
662
|
+
output.remove(node.start, node.end);
|
|
663
|
+
}
|
|
664
|
+
/** Replaces one complete export statement with the selected proxy exports. */
|
|
355
665
|
function createExport(node, names) {
|
|
356
666
|
exportNames.push(...names);
|
|
357
667
|
const newCode = names.map((name) => (name === "default" ? `export default` : `export const ${name} =`) + ` /* #__PURE__ */ ${options.runtime(name)};\n`).join("");
|
|
358
668
|
output.update(node.start, node.end, newCode);
|
|
359
669
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (decl.id.type === "Identifier" && decl.init) {
|
|
377
|
-
const name = decl.id.name;
|
|
378
|
-
const value = options.code.slice(decl.init.start, decl.init.end);
|
|
379
|
-
const newCode = `export const ${name} = /* #__PURE__ */ ${options.runtime(name, { value })};`;
|
|
380
|
-
output.update(node.start, node.end, newCode);
|
|
381
|
-
exportNames.push(name);
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
createExport(node, node.declaration.declarations.flatMap((decl) => extractNames(decl.id)));
|
|
387
|
-
} else node.declaration;
|
|
388
|
-
else {
|
|
389
|
-
/**
|
|
390
|
-
* export { foo, bar as car } from './foo'
|
|
391
|
-
* export { foo, bar as car }
|
|
392
|
-
*/
|
|
393
|
-
const names = [];
|
|
394
|
-
for (const spec of node.specifiers) {
|
|
395
|
-
if (spec.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: spec.exported.start });
|
|
396
|
-
names.push(spec.exported.name);
|
|
397
|
-
}
|
|
398
|
-
createExport(node, names);
|
|
670
|
+
const exportNodes = /* @__PURE__ */ new Set();
|
|
671
|
+
for (const group of scanModuleExports(viteAst)) {
|
|
672
|
+
const node = group.node;
|
|
673
|
+
exportNodes.add(node);
|
|
674
|
+
if (group.type === "declaration") {
|
|
675
|
+
const entry = group.export;
|
|
676
|
+
if (filter(entry.exportName, entry.meta)) {
|
|
677
|
+
validateNonAsyncFunction(options, group.declaration);
|
|
678
|
+
createExport(node, [entry.exportName]);
|
|
679
|
+
} else removeNode(node);
|
|
680
|
+
} else if (group.type === "variable-declaration") {
|
|
681
|
+
const selectedNames = [];
|
|
682
|
+
for (const declarator of group.declarators) {
|
|
683
|
+
const names = declarator.exports.filter((entry) => filter(entry.exportName, entry.meta)).map((entry) => entry.exportName);
|
|
684
|
+
if (declarator.node.init && (!options.filter || declarator.exports.length === 0 || names.length > 0)) validateNonAsyncFunction(options, declarator.node.init);
|
|
685
|
+
selectedNames.push(...names);
|
|
399
686
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
687
|
+
if (options.keep && group.declaration.declarations.length === 1) {
|
|
688
|
+
const decl = group.declaration.declarations[0];
|
|
689
|
+
if (decl.id.type === "Identifier" && decl.init) {
|
|
690
|
+
const name = decl.id.name;
|
|
691
|
+
const value = options.code.slice(decl.init.start, decl.init.end);
|
|
692
|
+
const newCode = `export const ${name} = /* #__PURE__ */ ${options.runtime(name, { value })};`;
|
|
693
|
+
output.update(node.start, node.end, newCode);
|
|
694
|
+
exportNames.push(name);
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
410
697
|
}
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
698
|
+
createExport(node, selectedNames);
|
|
699
|
+
} else if (group.type === "specifiers") createExport(node, group.exports.filter((entry) => {
|
|
700
|
+
if (entry.node.exported.type !== "Identifier") throw Object.assign(/* @__PURE__ */ new Error("unsupported string literal export name"), { pos: entry.node.exported.start });
|
|
701
|
+
return filter(entry.exportName, entry.meta);
|
|
702
|
+
}).map((entry) => entry.exportName));
|
|
703
|
+
else if (group.type === "export-all") {
|
|
704
|
+
if (group.node.exported?.type === "Identifier") {
|
|
705
|
+
const name = group.node.exported.name;
|
|
706
|
+
if (filter(name, {})) createExport(node, [name]);
|
|
707
|
+
else removeNode(node);
|
|
708
|
+
} else if (!options.ignoreExportAllDeclaration) throw new Error("unsupported ExportAllDeclaration");
|
|
709
|
+
else if (!options.keep) removeNode(node);
|
|
710
|
+
} else if (group.type === "default") if (filter("default", group.meta)) {
|
|
711
|
+
validateNonAsyncFunction(options, group.node.declaration);
|
|
420
712
|
createExport(node, ["default"]);
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
713
|
+
} else removeNode(node);
|
|
714
|
+
}
|
|
715
|
+
if (!options.keep) {
|
|
716
|
+
for (const node of ast.body) if (!exportNodes.has(node)) removeNode(node);
|
|
425
717
|
}
|
|
426
718
|
return {
|
|
427
719
|
exportNames,
|
|
@@ -432,10 +724,13 @@ function transformProxyExport(ast, options) {
|
|
|
432
724
|
//#region src/transforms/server-action.ts
|
|
433
725
|
function transformServerActionServer(input, ast, options) {
|
|
434
726
|
if (hasDirective(ast.body, "use server")) {
|
|
435
|
-
const result =
|
|
727
|
+
const result = transformModuleExportEffect(input, ast, {
|
|
728
|
+
rejectNonAsyncFunction: options.rejectNonAsyncFunction,
|
|
729
|
+
generate: ({ binding, exportName }) => options.runtime(binding, exportName)
|
|
730
|
+
});
|
|
436
731
|
return {
|
|
437
732
|
...result,
|
|
438
|
-
|
|
733
|
+
exportNames: result.referenceNames
|
|
439
734
|
};
|
|
440
735
|
}
|
|
441
736
|
const result = transformHoistInlineDirective(input, ast, {
|
|
@@ -450,7 +745,9 @@ function transformServerActionServer(input, ast, options) {
|
|
|
450
745
|
//#endregion
|
|
451
746
|
//#region src/transforms/expand-export-all.ts
|
|
452
747
|
async function transformExpandExportAll(options) {
|
|
453
|
-
const
|
|
748
|
+
const ast = options.ast;
|
|
749
|
+
const context = options;
|
|
750
|
+
const { plans } = resolveStarExports(await scanModuleExports$1(ast, options.importer, context));
|
|
454
751
|
if (plans.length === 0) return;
|
|
455
752
|
const output = new MagicString(options.code);
|
|
456
753
|
for (const item of plans) {
|
|
@@ -459,7 +756,7 @@ async function transformExpandExportAll(options) {
|
|
|
459
756
|
}
|
|
460
757
|
return { code: output.toString() };
|
|
461
758
|
}
|
|
462
|
-
async function scanModuleExports(ast, importer, context, seen = /* @__PURE__ */ new Set()) {
|
|
759
|
+
async function scanModuleExports$1(ast, importer, context, seen = /* @__PURE__ */ new Set()) {
|
|
463
760
|
const starSources = [];
|
|
464
761
|
const bareStars = ast.body.filter((n) => n.type === "ExportAllDeclaration" && !n.exported);
|
|
465
762
|
for (const node of bareStars) {
|
|
@@ -482,7 +779,7 @@ async function collectExportScan(resolvedId, context, seen) {
|
|
|
482
779
|
ambiguousNames: /* @__PURE__ */ new Set()
|
|
483
780
|
};
|
|
484
781
|
seen.add(resolvedId);
|
|
485
|
-
const scan = await scanModuleExports(await context.load(resolvedId), resolvedId, context, seen);
|
|
782
|
+
const scan = await scanModuleExports$1(await context.load(resolvedId), resolvedId, context, seen);
|
|
486
783
|
const resolved = resolveStarExports(scan);
|
|
487
784
|
return {
|
|
488
785
|
names: [...scan.explicitNames, ...resolved.plans.flatMap((item) => item.names)],
|
|
@@ -526,4 +823,4 @@ function resolveStarExports(scan) {
|
|
|
526
823
|
};
|
|
527
824
|
}
|
|
528
825
|
//#endregion
|
|
529
|
-
export { extractIdentifiers, extractNames, findDirectives, hasDirective, transformDirectiveProxyExport, transformExpandExportAll, transformHoistInlineDirective, transformProxyExport, transformServerActionServer, transformWrapExport, validateNonAsyncFunction };
|
|
826
|
+
export { extractIdentifiers, extractNames, findDirectives, hasDirective, isDirective, rejectNonAsyncFunction, scanModuleExports, transformDirectiveProxyExport, transformExpandExportAll, transformHoistInlineDirective, transformModuleExportEffect, transformProxyExport, transformServerActionServer, transformWrapExport, validateNonAsyncFunction };
|