Skip to content

Commit b2a908f

Browse files
committed
[Flight] Add bundler-less version of RSC using plain ESM (#26889)
This isn't really meant to be actually used, there are many issues with this approach, but it shows the capabilities as a proof-of-concept. It's a new reference implementation package `react-server-dom-esm` as well as a fixture in `fixtures/flight-esm` (fork of `fixtures/flight`). This works pretty much the same as pieces we already have in the Webpack implementation but instead of loading modules using Webpack on the client it uses native browser ESM. To really show it off, I don't use any JSX in the fixture and so it also doesn't use Babel or any compilation of the files. This works because we don't actually bundle the server in the reference implementation in the first place. We instead use [Node.js Loaders](https://nodejs.org/api/esm.html#loaders) to intercept files that contain `"use client"` and `"use server"` and replace them. There's a simple check for those exact bytes, and no parsing, so this is very fast. Since the client isn't actually bundled, there's no module map needed. We can just send the file path to the file we want to load in the RSC payload for client references. Since the existing reference implementation for Node.js already used ESM to load modules on the server, that all works the same, including Server Actions. No bundling. There is one case that isn't implemented here. Importing a `"use server"` file from a Client Component. We don't have that implemented in the Webpack reference implementation neither - only in Next.js atm. In Webpack it would be implemented as a Webpack loader. There are a few ways this can be implemented without a bundler: - We can intercept the request from the browser importing this file in the HTTP server, and do a quick scan for `"use server"` in the file and replace it just like we do with loaders in Node.js. This is effectively how Vite works and likely how anyone using this technique would have to support JSX anyway. - We can use native browser "loaders" once that's eventually available in the same way as in Node.js. - We can generate import maps for each file and replace it with a pointer to a placeholder file. This requires scanning these ahead of time which defeats the purposes. Another case that's not implemented is the inline `"use server"` closure in a Server Component. That would require the existing loader to be a bit smarter but would still only "compile" files that contains those bytes in the fast path check. This would also happen in the loader that already exists so wouldn't do anything substantially different than what we currently have here. DiffTrain build for [f181ba8](f181ba8)
1 parent 650431a commit b2a908f

23 files changed

+33
-33
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e1ad4aa3615333009d76f947ff05ddeff01039c6
1+
f181ba8aa6339d62f6e2572109c61242606f16b3

compiled/facebook-www/React-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-www-classic-ef8c27b4";
30+
var ReactVersion = "18.3.0-www-classic-f2045cca";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-www-modern-c6e529af";
30+
var ReactVersion = "18.3.0-www-modern-180bd813";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,4 +649,4 @@ exports.useSyncExternalStore = function (
649649
);
650650
};
651651
exports.useTransition = useTransition;
652-
exports.version = "18.3.0-www-classic-bb5eb625";
652+
exports.version = "18.3.0-www-classic-6b556dd3";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,4 @@ exports.useSyncExternalStore = function (
641641
);
642642
};
643643
exports.useTransition = useTransition;
644-
exports.version = "18.3.0-www-modern-916dbaab";
644+
exports.version = "18.3.0-www-modern-a8c2f2ff";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ exports.useSyncExternalStore = function (
660660
);
661661
};
662662
exports.useTransition = useTransition;
663-
exports.version = "18.3.0-www-classic-14fbbcad";
663+
exports.version = "18.3.0-www-classic-e9e36727";
664664

665665
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
666666
if (

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
6969
return self;
7070
}
7171

72-
var ReactVersion = "18.3.0-www-classic-98dc4286";
72+
var ReactVersion = "18.3.0-www-classic-26848b3f";
7373

7474
var LegacyRoot = 0;
7575
var ConcurrentRoot = 1;

compiled/facebook-www/ReactART-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
6969
return self;
7070
}
7171

72-
var ReactVersion = "18.3.0-www-modern-c6e529af";
72+
var ReactVersion = "18.3.0-www-modern-0a8a0f8c";
7373

7474
var LegacyRoot = 0;
7575
var ConcurrentRoot = 1;

compiled/facebook-www/ReactART-prod.classic.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10193,7 +10193,7 @@ var slice = Array.prototype.slice,
1019310193
return null;
1019410194
},
1019510195
bundleType: 0,
10196-
version: "18.3.0-www-classic-ced03d12",
10196+
version: "18.3.0-www-classic-f2045cca",
1019710197
rendererPackageName: "react-art"
1019810198
};
1019910199
var internals$jscomp$inline_1318 = {
@@ -10224,7 +10224,7 @@ var internals$jscomp$inline_1318 = {
1022410224
scheduleRoot: null,
1022510225
setRefreshHandler: null,
1022610226
getCurrentFiber: null,
10227-
reconcilerVersion: "18.3.0-www-classic-ced03d12"
10227+
reconcilerVersion: "18.3.0-www-classic-f2045cca"
1022810228
};
1022910229
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1023010230
var hook$jscomp$inline_1319 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled/facebook-www/ReactART-prod.modern.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9858,7 +9858,7 @@ var slice = Array.prototype.slice,
98589858
return null;
98599859
},
98609860
bundleType: 0,
9861-
version: "18.3.0-www-modern-916dbaab",
9861+
version: "18.3.0-www-modern-27da91db",
98629862
rendererPackageName: "react-art"
98639863
};
98649864
var internals$jscomp$inline_1298 = {
@@ -9889,7 +9889,7 @@ var internals$jscomp$inline_1298 = {
98899889
scheduleRoot: null,
98909890
setRefreshHandler: null,
98919891
getCurrentFiber: null,
9892-
reconcilerVersion: "18.3.0-www-modern-916dbaab"
9892+
reconcilerVersion: "18.3.0-www-modern-27da91db"
98939893
};
98949894
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
98959895
var hook$jscomp$inline_1299 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

0 commit comments

Comments
 (0)