@vitejs/plugin-rsc 0.4.13 → 0.4.15

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RscPluginOptions, vitePluginRsc } from "./plugin-CCrsoChj.js";
1
+ import { RscPluginOptions, vitePluginRsc } from "./plugin-DXIhXGMa.js";
2
2
  import MagicString from "magic-string";
3
3
  import { Program } from "estree";
4
4
 
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./dist-DEF94lDJ.js";
2
2
  import "./plugin-CZbI4rhS.js";
3
- import { transformHoistInlineDirective, vitePluginRsc } from "./plugin-DgH7V82E.js";
3
+ import { transformHoistInlineDirective, vitePluginRsc } from "./plugin-_STtCzuL.js";
4
4
  import "./encryption-utils-BDwwcMVT.js";
5
5
  import "./rpc-tGuLT8PD.js";
6
- import "./vite-utils-CcqBE-C4.js";
6
+ import "./vite-utils-Vzd7cqfv.js";
7
7
 
8
8
  export { vitePluginRsc as default, transformHoistInlineDirective };
@@ -31,18 +31,30 @@ type RscPluginOptions = {
31
31
  ignoredPackageWarnings?: (string | RegExp)[];
32
32
  /**
33
33
  * This option allows customizing how client build copies assets from server build.
34
- * By default, all assets are copied, but frameworks might want to establish some convention
35
- * to tighten security based on this option.
34
+ * By default, all assets are copied, but frameworks can establish server asset convention
35
+ * to tighten security using this option.
36
36
  */
37
37
  copyServerAssetsToClient?: (fileName: string) => boolean;
38
- defineEncryptionKey?: string;
39
38
  /**
40
- * Allows enabling action closure encryption for debugging purpose.
39
+ * This option allows disabling action closure encryption for debugging purpose.
41
40
  * @default true
42
41
  */
43
42
  enableActionEncryption?: boolean;
43
+ /**
44
+ * By default, the plugin uses a build-time generated encryption key for
45
+ * "use server" closure argument binding.
46
+ * This can be overwritten by configuring `defineEncryptionKey` option,
47
+ * for example, to obtain a key through environment variable during runtime.
48
+ * cf. https://nextjs.org/docs/app/guides/data-security#overwriting-encryption-keys-advanced
49
+ */
50
+ defineEncryptionKey?: string;
44
51
  /** Escape hatch for Waku's `allowServer` */
45
52
  keepUseCientProxy?: boolean;
53
+ /**
54
+ * Enable build-time validation of 'client-only' and 'server-only' imports
55
+ * @default true
56
+ */
57
+ validateImports?: boolean;
46
58
  };
47
59
  declare function vitePluginRsc(rscPluginOptions?: RscPluginOptions): Plugin[];
48
60
  declare class RuntimeAsset {
@@ -2,7 +2,7 @@ import { tinyassert } from "./dist-DEF94lDJ.js";
2
2
  import { vitePluginRscCore } from "./plugin-CZbI4rhS.js";
3
3
  import { generateEncryptionKey, toBase64 } from "./encryption-utils-BDwwcMVT.js";
4
4
  import { createRpcServer } from "./rpc-tGuLT8PD.js";
5
- import { normalizeViteImportAnalysisUrl } from "./vite-utils-CcqBE-C4.js";
5
+ import { normalizeViteImportAnalysisUrl, prepareError } from "./vite-utils-Vzd7cqfv.js";
6
6
  import { createRequire } from "node:module";
7
7
  import assert from "node:assert";
8
8
  import { createHash } from "node:crypto";
@@ -13,7 +13,7 @@ import { createRequestListener } from "@mjackson/node-fetch-server";
13
13
  import * as esModuleLexer from "es-module-lexer";
14
14
  import MagicString from "magic-string";
15
15
  import { defaultServerConditions, isCSSRequest, normalizePath, parseAstAsync } from "vite";
16
- import { crawlFrameworkPkgs } from "vitefu";
16
+ import { crawlFrameworkPkgs, findClosestPkgJsonPath } from "vitefu";
17
17
  import { walk } from "estree-walker";
18
18
  import { analyze, extract_names } from "periscopic";
19
19
 
@@ -510,11 +510,22 @@ function vitePluginRsc(rscPluginOptions = {}) {
510
510
  return mods.some((mod) => recurse(mod));
511
511
  }
512
512
  if (!isInsideClientBoundary(ctx.modules)) {
513
- if (this.environment.name === "rsc") ctx.server.environments.client.hot.send({
514
- type: "custom",
515
- event: "rsc:update",
516
- data: { file: ctx.file }
517
- });
513
+ if (this.environment.name === "rsc") {
514
+ for (const mod of ctx.modules) if (mod.type === "js") try {
515
+ await this.environment.transformRequest(mod.url);
516
+ } catch (e) {
517
+ server.environments.client.hot.send({
518
+ type: "error",
519
+ err: prepareError(e)
520
+ });
521
+ throw e;
522
+ }
523
+ ctx.server.environments.client.hot.send({
524
+ type: "custom",
525
+ event: "rsc:update",
526
+ data: { file: ctx.file }
527
+ });
528
+ }
518
529
  if (this.environment.name === "client") {
519
530
  const env = ctx.server.environments.rsc;
520
531
  const mod = env.moduleGraph.getModuleById(ctx.file);
@@ -758,6 +769,11 @@ window.__vite_plugin_react_preamble_installed__ = true;
758
769
  code += `
759
770
  const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
760
771
  import.meta.hot.on("vite:beforeUpdate", () => ssrCss.forEach(node => node.remove()));
772
+ `;
773
+ code += `
774
+ import.meta.hot.on("rsc:update", () => {
775
+ document.querySelectorAll("vite-error-overlay").forEach((n) => n.close())
776
+ });
761
777
  `;
762
778
  return code;
763
779
  }),
@@ -781,9 +797,31 @@ globalThis.AsyncLocalStorage = __viteRscAyncHooks.AsyncLocalStorage;
781
797
  ...vitePluginDefineEncryptionKey(rscPluginOptions),
782
798
  ...vitePluginFindSourceMapURL(),
783
799
  ...vitePluginRscCss({ rscCssTransform: rscPluginOptions.rscCssTransform }),
784
- scanBuildStripPlugin()
800
+ ...rscPluginOptions.validateImports !== false ? [validateImportPlugin()] : [],
801
+ scanBuildStripPlugin(),
802
+ detectNonOptimizedCjsPlugin()
785
803
  ];
786
804
  }
805
+ function detectNonOptimizedCjsPlugin() {
806
+ return {
807
+ name: "rsc:detect-non-optimized-cjs",
808
+ apply: "serve",
809
+ async transform(code, id) {
810
+ if (id.includes("/node_modules/") && !id.startsWith(this.environment.config.cacheDir) && /\b(require|exports)\b/.test(code)) {
811
+ id = parseIdQuery(id).filename;
812
+ let isEsm = id.endsWith(".mjs");
813
+ if (id.endsWith(".js")) {
814
+ const pkgJsonPath = await findClosestPkgJsonPath(path.dirname(id));
815
+ if (pkgJsonPath) {
816
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
817
+ isEsm = pkgJson.type === "module";
818
+ }
819
+ }
820
+ if (!isEsm) this.warn(`[vite-rsc] found non-optimized CJS dependency in '${this.environment.name}' environment. It is recommended to manually add the dependency to 'environments.${this.environment.name}.optimizeDeps.include'.`);
821
+ }
822
+ }
823
+ };
824
+ }
787
825
  function scanBuildStripPlugin() {
788
826
  return {
789
827
  name: "rsc:scan-strip",
@@ -806,8 +844,7 @@ function normalizeRelativePath(s) {
806
844
  }
807
845
  function getEntrySource(config$1, name = "index") {
808
846
  const input = config$1.build.rollupOptions.input;
809
- assert(input);
810
- assert(typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string");
847
+ assert(typeof input === "object" && !Array.isArray(input) && name in input && typeof input[name] === "string", `[vite-rsc:getEntrySource] expected 'build.rollupOptions.input' to be an object with a '${name}' property that is a string, but got ${JSON.stringify(input)}`);
811
848
  return input[name];
812
849
  }
813
850
  function hashString(v) {
@@ -1251,7 +1288,7 @@ function vitePluginRscCss(rscCssOptions) {
1251
1288
  };
1252
1289
  }
1253
1290
  function getRscCssTransformFilter({ id, code }) {
1254
- const { query } = parseIdQuery(id);
1291
+ const { filename, query } = parseIdQuery(id);
1255
1292
  if ("vite-rsc-css-export" in query) {
1256
1293
  const value = query["vite-rsc-css-export"];
1257
1294
  if (value) {
@@ -1262,8 +1299,8 @@ function vitePluginRscCss(rscCssOptions) {
1262
1299
  }
1263
1300
  const options = rscCssOptions?.rscCssTransform;
1264
1301
  if (options === false) return false;
1265
- if (options?.filter && !options.filter(id)) return false;
1266
- if (id.includes("/node_modules/") || !/\.[tj]sx$/.test(id)) return false;
1302
+ if (options?.filter && !options.filter(filename)) return false;
1303
+ if (!/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)\b/.test(code) || !/\.[tj]sx?$/.test(filename)) return false;
1267
1304
  const result = esModuleLexer.parse(code);
1268
1305
  if (!result[0].some((i) => i.t === 1 && i.n && isCSSRequest(i.n))) return false;
1269
1306
  return (_name, meta) => !!(meta.isFunction && meta.declName && /^[A-Z]/.test(meta.declName) || meta.defaultExportIdentifierName && /^[A-Z]/.test(meta.defaultExportIdentifierName));
@@ -1503,6 +1540,35 @@ function __fix_cloudflare() {
1503
1540
  }
1504
1541
  };
1505
1542
  }
1543
+ function validateImportPlugin() {
1544
+ return {
1545
+ name: "rsc:validate-imports",
1546
+ resolveId: {
1547
+ order: "pre",
1548
+ async handler(source, importer, options) {
1549
+ if ("scan" in options && options.scan) return;
1550
+ if (source === "client-only") {
1551
+ if (this.environment.name === "rsc") throw new Error(`'client-only' cannot be imported in server build (importer: '${importer ?? "unknown"}', environment: ${this.environment.name})`);
1552
+ return {
1553
+ id: `\0virtual:vite-rsc/empty`,
1554
+ moduleSideEffects: false
1555
+ };
1556
+ }
1557
+ if (source === "server-only") {
1558
+ if (this.environment.name !== "rsc") throw new Error(`'server-only' cannot be imported in client build (importer: '${importer ?? "unknown"}', environment: ${this.environment.name})`);
1559
+ return {
1560
+ id: `\0virtual:vite-rsc/empty`,
1561
+ moduleSideEffects: false
1562
+ };
1563
+ }
1564
+ return;
1565
+ }
1566
+ },
1567
+ load(id) {
1568
+ if (id.startsWith("\0virtual:vite-rsc/empty")) return `export {}`;
1569
+ }
1570
+ };
1571
+ }
1506
1572
  function sortObject(o) {
1507
1573
  return Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b)));
1508
1574
  }
package/dist/plugin.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss } from "./plugin-CCrsoChj.js";
1
+ import { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss } from "./plugin-DXIhXGMa.js";
2
2
  export { AssetDeps, AssetsManifest, ResolvedAssetDeps, ResolvedAssetsManifest, RscPluginOptions, __fix_cloudflare, vitePluginRsc as default, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRscCss };
package/dist/plugin.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./dist-DEF94lDJ.js";
2
2
  import "./plugin-CZbI4rhS.js";
3
- import { __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss } from "./plugin-DgH7V82E.js";
3
+ import { __fix_cloudflare, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRsc, vitePluginRscCss } from "./plugin-_STtCzuL.js";
4
4
  import "./encryption-utils-BDwwcMVT.js";
5
5
  import "./rpc-tGuLT8PD.js";
6
- import "./vite-utils-CcqBE-C4.js";
6
+ import "./vite-utils-Vzd7cqfv.js";
7
7
 
8
8
  export { __fix_cloudflare, vitePluginRsc as default, findSourceMapURL, transformRscCssExport, vitePluginFindSourceMapURL, vitePluginRscCss };
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { stripVTControlCharacters } from "node:util";
3
4
 
4
5
  //#region src/vite-utils.ts
5
6
  const VALID_ID_PREFIX = `/@id/`;
@@ -59,6 +60,20 @@ function normalizeViteImportAnalysisUrl(environment, id) {
59
60
  }
60
61
  return url;
61
62
  }
63
+ function prepareError(err) {
64
+ return {
65
+ message: stripVTControlCharacters(err.message),
66
+ stack: stripVTControlCharacters(cleanStack(err.stack || "")),
67
+ id: err.id,
68
+ frame: stripVTControlCharacters(err.frame || ""),
69
+ plugin: err.plugin,
70
+ pluginCode: err.pluginCode?.toString(),
71
+ loc: err.loc
72
+ };
73
+ }
74
+ function cleanStack(stack) {
75
+ return stack.split(/\n/).filter((l) => /^\s*at/.test(l)).join("\n");
76
+ }
62
77
 
63
78
  //#endregion
64
- export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
79
+ export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, prepareError, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
@@ -1,4 +1,4 @@
1
- import { DevEnvironment, Rollup } from "vite";
1
+ import { DevEnvironment, ErrorPayload, Rollup } from "vite";
2
2
 
3
3
  //#region src/vite-utils.d.ts
4
4
  declare const VALID_ID_PREFIX = "/@id/";
@@ -17,5 +17,7 @@ declare function injectQuery(url: string, queryToInject: string): string;
17
17
  declare function joinUrlSegments(a: string, b: string): string;
18
18
  declare function normalizeResolvedIdToUrl(environment: DevEnvironment, url: string, resolved: Rollup.PartialResolvedId): string;
19
19
  declare function normalizeViteImportAnalysisUrl(environment: DevEnvironment, id: string): string;
20
+ type RollupError = Rollup.RollupError;
21
+ declare function prepareError(err: Error | RollupError): ErrorPayload["err"];
20
22
  //#endregion
21
- export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
23
+ export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, prepareError, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
@@ -1,3 +1,3 @@
1
- import { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId } from "./vite-utils-CcqBE-C4.js";
1
+ import { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, prepareError, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId } from "./vite-utils-Vzd7cqfv.js";
2
2
 
3
- export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
3
+ export { FS_PREFIX, NULL_BYTE_PLACEHOLDER, VALID_ID_PREFIX, cleanUrl, injectQuery, joinUrlSegments, normalizeResolvedIdToUrl, normalizeViteImportAnalysisUrl, prepareError, slash, splitFileAndPostfix, unwrapId, withTrailingSlash, wrapId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitejs/plugin-rsc",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "React Server Components (RSC) support for Vite.",
5
5
  "keywords": [
6
6
  "vite",