@ivogt/rsc-router 0.0.0-experimental.1 → 0.0.0-experimental.3
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/package.json +1 -1
- package/src/server/root-layout.tsx +1 -1
- package/src/vite/index.ts +123 -4
package/package.json
CHANGED
package/src/vite/index.ts
CHANGED
|
@@ -21,6 +21,64 @@ export { exposeLocationStateId } from "./expose-location-state-id.ts";
|
|
|
21
21
|
|
|
22
22
|
// Virtual module type declarations in ./version.d.ts
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Modules that must be excluded from Vite's dependency optimization.
|
|
26
|
+
*
|
|
27
|
+
* When rsc-router is installed from npm, Vite's dep optimizer bundles these modules
|
|
28
|
+
* into separate chunks. However, @vitejs/plugin-rsc creates virtual proxy modules
|
|
29
|
+
* for client components that import from the original source paths.
|
|
30
|
+
*
|
|
31
|
+
* This creates two different module instances:
|
|
32
|
+
* 1. Bundled version in /node_modules/.vite/deps/
|
|
33
|
+
* 2. Original source via plugin-rsc proxy
|
|
34
|
+
*
|
|
35
|
+
* When both instances create React Contexts (e.g., OutletContext), React sees them
|
|
36
|
+
* as different contexts, causing useContext to return undefined even when a Provider
|
|
37
|
+
* exists in the tree.
|
|
38
|
+
*
|
|
39
|
+
* By excluding these modules, we ensure a single module instance is used everywhere.
|
|
40
|
+
*/
|
|
41
|
+
const RSC_ROUTER_EXCLUDE_DEPS = [
|
|
42
|
+
"@ivogt/rsc-router",
|
|
43
|
+
"@ivogt/rsc-router/browser",
|
|
44
|
+
"@ivogt/rsc-router/client",
|
|
45
|
+
"@ivogt/rsc-router/internal/deps/browser",
|
|
46
|
+
"@ivogt/rsc-router/internal/deps/html-stream-client",
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Plugin to transform CJS react-server-dom vendor file to ESM.
|
|
51
|
+
* The @vitejs/plugin-rsc package ships client.browser.js as CommonJS
|
|
52
|
+
* which doesn't work in the browser. This transforms it to ESM re-exports.
|
|
53
|
+
*/
|
|
54
|
+
function createCjsToEsmPlugin(): Plugin {
|
|
55
|
+
return {
|
|
56
|
+
name: "rsc-router:cjs-to-esm",
|
|
57
|
+
enforce: "pre",
|
|
58
|
+
transform(code, id) {
|
|
59
|
+
// Transform the client.browser.js file from CJS to ESM
|
|
60
|
+
// Match any path containing vendor/react-server-dom/client.browser.js
|
|
61
|
+
if (
|
|
62
|
+
id.includes("vendor/react-server-dom/client.browser.js") ||
|
|
63
|
+
id.includes("vendor\\react-server-dom\\client.browser.js")
|
|
64
|
+
) {
|
|
65
|
+
// The original file uses: module.exports = require('./cjs/...')
|
|
66
|
+
// Transform to ESM re-export from the development or production CJS file
|
|
67
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
68
|
+
const cjsFile = isProd
|
|
69
|
+
? "./cjs/react-server-dom-webpack-client.browser.production.js"
|
|
70
|
+
: "./cjs/react-server-dom-webpack-client.browser.development.js";
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
code: `export * from "${cjsFile}";`,
|
|
74
|
+
map: null,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
24
82
|
/**
|
|
25
83
|
* RSC plugin entry points configuration.
|
|
26
84
|
* All entries use virtual modules by default. Specify a path to use a custom entry file.
|
|
@@ -422,6 +480,32 @@ export async function rscRouter(
|
|
|
422
480
|
config() {
|
|
423
481
|
// Configure environments for cloudflare deployment
|
|
424
482
|
return {
|
|
483
|
+
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
484
|
+
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
485
|
+
optimizeDeps: {
|
|
486
|
+
exclude: RSC_ROUTER_EXCLUDE_DEPS,
|
|
487
|
+
},
|
|
488
|
+
resolve: {
|
|
489
|
+
alias: {
|
|
490
|
+
// Map rsc-router/* to @ivogt/rsc-router/* for virtual entries
|
|
491
|
+
// This allows the package to work when published under a scoped name
|
|
492
|
+
"rsc-router/internal/deps/browser":
|
|
493
|
+
"@ivogt/rsc-router/internal/deps/browser",
|
|
494
|
+
"rsc-router/internal/deps/ssr":
|
|
495
|
+
"@ivogt/rsc-router/internal/deps/ssr",
|
|
496
|
+
"rsc-router/internal/deps/rsc":
|
|
497
|
+
"@ivogt/rsc-router/internal/deps/rsc",
|
|
498
|
+
"rsc-router/internal/deps/html-stream-client":
|
|
499
|
+
"@ivogt/rsc-router/internal/deps/html-stream-client",
|
|
500
|
+
"rsc-router/internal/deps/html-stream-server":
|
|
501
|
+
"@ivogt/rsc-router/internal/deps/html-stream-server",
|
|
502
|
+
"rsc-router/browser": "@ivogt/rsc-router/browser",
|
|
503
|
+
"rsc-router/client": "@ivogt/rsc-router/client",
|
|
504
|
+
"rsc-router/server": "@ivogt/rsc-router/server",
|
|
505
|
+
"rsc-router/rsc": "@ivogt/rsc-router/rsc",
|
|
506
|
+
"rsc-router/ssr": "@ivogt/rsc-router/ssr",
|
|
507
|
+
},
|
|
508
|
+
},
|
|
425
509
|
environments: {
|
|
426
510
|
client: {
|
|
427
511
|
build: {
|
|
@@ -432,8 +516,10 @@ export async function rscRouter(
|
|
|
432
516
|
},
|
|
433
517
|
},
|
|
434
518
|
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
519
|
+
// Exclude rsc-router modules to ensure same Context instance
|
|
435
520
|
optimizeDeps: {
|
|
436
521
|
include: ["rsc-html-stream/client"],
|
|
522
|
+
exclude: RSC_ROUTER_EXCLUDE_DEPS,
|
|
437
523
|
},
|
|
438
524
|
},
|
|
439
525
|
ssr: {
|
|
@@ -515,6 +601,32 @@ export async function rscRouter(
|
|
|
515
601
|
const useVirtualRSC = finalEntries.rsc === VIRTUAL_IDS.rsc;
|
|
516
602
|
|
|
517
603
|
return {
|
|
604
|
+
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
605
|
+
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
606
|
+
optimizeDeps: {
|
|
607
|
+
exclude: RSC_ROUTER_EXCLUDE_DEPS,
|
|
608
|
+
},
|
|
609
|
+
resolve: {
|
|
610
|
+
alias: {
|
|
611
|
+
// Map rsc-router/* to @ivogt/rsc-router/* for virtual entries
|
|
612
|
+
// This allows the package to work when published under a scoped name
|
|
613
|
+
"rsc-router/internal/deps/browser":
|
|
614
|
+
"@ivogt/rsc-router/internal/deps/browser",
|
|
615
|
+
"rsc-router/internal/deps/ssr":
|
|
616
|
+
"@ivogt/rsc-router/internal/deps/ssr",
|
|
617
|
+
"rsc-router/internal/deps/rsc":
|
|
618
|
+
"@ivogt/rsc-router/internal/deps/rsc",
|
|
619
|
+
"rsc-router/internal/deps/html-stream-client":
|
|
620
|
+
"@ivogt/rsc-router/internal/deps/html-stream-client",
|
|
621
|
+
"rsc-router/internal/deps/html-stream-server":
|
|
622
|
+
"@ivogt/rsc-router/internal/deps/html-stream-server",
|
|
623
|
+
"rsc-router/browser": "@ivogt/rsc-router/browser",
|
|
624
|
+
"rsc-router/client": "@ivogt/rsc-router/client",
|
|
625
|
+
"rsc-router/server": "@ivogt/rsc-router/server",
|
|
626
|
+
"rsc-router/rsc": "@ivogt/rsc-router/rsc",
|
|
627
|
+
"rsc-router/ssr": "@ivogt/rsc-router/ssr",
|
|
628
|
+
},
|
|
629
|
+
},
|
|
518
630
|
environments: {
|
|
519
631
|
client: {
|
|
520
632
|
build: {
|
|
@@ -524,12 +636,14 @@ export async function rscRouter(
|
|
|
524
636
|
},
|
|
525
637
|
},
|
|
526
638
|
},
|
|
527
|
-
|
|
528
|
-
|
|
639
|
+
// Always exclude rsc-router modules, conditionally add virtual entry
|
|
640
|
+
optimizeDeps: {
|
|
641
|
+
exclude: RSC_ROUTER_EXCLUDE_DEPS,
|
|
642
|
+
...(useVirtualClient && {
|
|
529
643
|
// Tell Vite to scan the virtual entry for dependencies
|
|
530
644
|
entries: [VIRTUAL_IDS.browser],
|
|
531
|
-
},
|
|
532
|
-
}
|
|
645
|
+
}),
|
|
646
|
+
},
|
|
533
647
|
},
|
|
534
648
|
...(useVirtualSSR && {
|
|
535
649
|
ssr: {
|
|
@@ -537,6 +651,7 @@ export async function rscRouter(
|
|
|
537
651
|
entries: [VIRTUAL_IDS.ssr],
|
|
538
652
|
// Pre-bundle React for SSR to ensure single instance
|
|
539
653
|
include: ["react", "react-dom/server.edge", "react/jsx-runtime"],
|
|
654
|
+
exclude: RSC_ROUTER_EXCLUDE_DEPS,
|
|
540
655
|
},
|
|
541
656
|
},
|
|
542
657
|
}),
|
|
@@ -603,6 +718,10 @@ export async function rscRouter(
|
|
|
603
718
|
plugins.push(createVersionInjectorPlugin(rscEntryPath));
|
|
604
719
|
}
|
|
605
720
|
|
|
721
|
+
// Add CJS-to-ESM transform for @vitejs/plugin-rsc vendor files
|
|
722
|
+
// This must be added to transform the CommonJS client.browser.js to ESM
|
|
723
|
+
plugins.push(createCjsToEsmPlugin());
|
|
724
|
+
|
|
606
725
|
return plugins;
|
|
607
726
|
}
|
|
608
727
|
|