Skip to content

Commit

Permalink
[Flight] Add bundler-less version of RSC using plain ESM (#26889)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
sebmarkbage committed Jun 3, 2023
1 parent 650431a commit b2a908f
Show file tree
Hide file tree
Showing 23 changed files with 33 additions and 33 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
e1ad4aa3615333009d76f947ff05ddeff01039c6
f181ba8aa6339d62f6e2572109c61242606f16b3
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (
}
"use strict";

var ReactVersion = "18.3.0-www-classic-ef8c27b4";
var ReactVersion = "18.3.0-www-classic-f2045cca";

// ATTENTION
// When adding new symbols to this file,
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (
}
"use strict";

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

// ATTENTION
// When adding new symbols to this file,
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,4 +649,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-classic-bb5eb625";
exports.version = "18.3.0-www-classic-6b556dd3";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,4 +641,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-modern-916dbaab";
exports.version = "18.3.0-www-modern-a8c2f2ff";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-classic-14fbbcad";
exports.version = "18.3.0-www-classic-e9e36727";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactART-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
return self;
}

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

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactART-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
return self;
}

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

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10193,7 +10193,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-classic-ced03d12",
version: "18.3.0-www-classic-f2045cca",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1318 = {
Expand Down Expand Up @@ -10224,7 +10224,7 @@ var internals$jscomp$inline_1318 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-ced03d12"
reconcilerVersion: "18.3.0-www-classic-f2045cca"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1319 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -9858,7 +9858,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-modern-916dbaab",
version: "18.3.0-www-modern-27da91db",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1298 = {
Expand Down Expand Up @@ -9889,7 +9889,7 @@ var internals$jscomp$inline_1298 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-916dbaab"
reconcilerVersion: "18.3.0-www-modern-27da91db"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1299 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOM-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -34178,7 +34178,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-494075fe";
var ReactVersion = "18.3.0-www-classic-202be78c";

function createPortal$1(
children,
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOM-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -34023,7 +34023,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-modern-88494b05";
var ReactVersion = "18.3.0-www-modern-0a8a0f8c";

function createPortal$1(
children,
Expand Down
6 changes: 3 additions & 3 deletions compiled/facebook-www/ReactDOM-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -16643,7 +16643,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1815 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-98dc4286",
version: "18.3.0-www-classic-a78c92e7",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2184 = {
Expand Down Expand Up @@ -16673,7 +16673,7 @@ var internals$jscomp$inline_2184 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-98dc4286"
reconcilerVersion: "18.3.0-www-classic-a78c92e7"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2185 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16916,4 +16916,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-98dc4286";
exports.version = "18.3.0-www-classic-a78c92e7";
6 changes: 3 additions & 3 deletions compiled/facebook-www/ReactDOM-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16172,7 +16172,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1774 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-4aa83b49",
version: "18.3.0-www-modern-27da91db",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2148 = {
Expand Down Expand Up @@ -16203,7 +16203,7 @@ var internals$jscomp$inline_2148 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-4aa83b49"
reconcilerVersion: "18.3.0-www-modern-27da91db"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2149 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16374,4 +16374,4 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-4aa83b49";
exports.version = "18.3.0-www-modern-27da91db";
6 changes: 3 additions & 3 deletions compiled/facebook-www/ReactDOM-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -17418,7 +17418,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1900 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-ced03d12",
version: "18.3.0-www-classic-6cc31d50",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -17462,7 +17462,7 @@ var devToolsConfig$jscomp$inline_1900 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-ced03d12"
reconcilerVersion: "18.3.0-www-classic-6cc31d50"
});
assign(Internals, {
ReactBrowserEventEmitter: {
Expand Down Expand Up @@ -17692,7 +17692,7 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-ced03d12";
exports.version = "18.3.0-www-classic-6cc31d50";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOMServer-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-classic-68266b58";
var ReactVersion = "18.3.0-www-classic-4458edc9";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOMServer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-modern-f8ac3cf3";
var ReactVersion = "18.3.0-www-modern-e8e32d5d";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOMServer-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4001,4 +4001,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-classic-ab72f1f4";
exports.version = "18.3.0-www-classic-f551099d";
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOMServer-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -3899,4 +3899,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-modern-fcb528e2";
exports.version = "18.3.0-www-modern-76cd6d02";
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactDOMTesting-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -34795,7 +34795,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-555e8941";
var ReactVersion = "18.3.0-www-classic-a43be0aa";

function createPortal$1(
children,
Expand Down
6 changes: 3 additions & 3 deletions compiled/facebook-www/ReactDOMTesting-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16556,7 +16556,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1803 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-c6e529af",
version: "18.3.0-www-modern-180bd813",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2182 = {
Expand Down Expand Up @@ -16587,7 +16587,7 @@ var internals$jscomp$inline_2182 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-c6e529af"
reconcilerVersion: "18.3.0-www-modern-180bd813"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2183 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16909,4 +16909,4 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-c6e529af";
exports.version = "18.3.0-www-modern-180bd813";
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactTestRenderer-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -24553,7 +24553,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-3c89ae32";
var ReactVersion = "18.3.0-www-classic-a43be0aa";

// Might add PROFILE later.

Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactTestRenderer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -24553,7 +24553,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-modern-3c89ae32";
var ReactVersion = "18.3.0-www-modern-a8c2f2ff";

// Might add PROFILE later.

Expand Down

0 comments on commit b2a908f

Please sign in to comment.