From b2a908fe42ecd87c71ca3ae4bedf74ce01c19b9d Mon Sep 17 00:00:00 2001 From: sebmarkbage Date: Sat, 3 Jun 2023 20:03:38 +0000 Subject: [PATCH] [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 [f181ba8aa6339d62f6e2572109c61242606f16b3](https://github.com/facebook/react/commit/f181ba8aa6339d62f6e2572109c61242606f16b3) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/React-dev.classic.js | 2 +- compiled/facebook-www/React-dev.modern.js | 2 +- compiled/facebook-www/React-prod.classic.js | 2 +- compiled/facebook-www/React-prod.modern.js | 2 +- compiled/facebook-www/React-profiling.classic.js | 2 +- compiled/facebook-www/ReactART-dev.classic.js | 2 +- compiled/facebook-www/ReactART-dev.modern.js | 2 +- compiled/facebook-www/ReactART-prod.classic.js | 4 ++-- compiled/facebook-www/ReactART-prod.modern.js | 4 ++-- compiled/facebook-www/ReactDOM-dev.classic.js | 2 +- compiled/facebook-www/ReactDOM-dev.modern.js | 2 +- compiled/facebook-www/ReactDOM-prod.classic.js | 6 +++--- compiled/facebook-www/ReactDOM-prod.modern.js | 6 +++--- compiled/facebook-www/ReactDOM-profiling.classic.js | 6 +++--- compiled/facebook-www/ReactDOMServer-dev.classic.js | 2 +- compiled/facebook-www/ReactDOMServer-dev.modern.js | 2 +- compiled/facebook-www/ReactDOMServer-prod.classic.js | 2 +- compiled/facebook-www/ReactDOMServer-prod.modern.js | 2 +- compiled/facebook-www/ReactDOMTesting-dev.classic.js | 2 +- compiled/facebook-www/ReactDOMTesting-prod.modern.js | 6 +++--- compiled/facebook-www/ReactTestRenderer-dev.classic.js | 2 +- compiled/facebook-www/ReactTestRenderer-dev.modern.js | 2 +- 23 files changed, 33 insertions(+), 33 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index a1f27a6b0f..30cf77eec2 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -e1ad4aa3615333009d76f947ff05ddeff01039c6 +f181ba8aa6339d62f6e2572109c61242606f16b3 diff --git a/compiled/facebook-www/React-dev.classic.js b/compiled/facebook-www/React-dev.classic.js index 4f84c9442b..4922226d4f 100644 --- a/compiled/facebook-www/React-dev.classic.js +++ b/compiled/facebook-www/React-dev.classic.js @@ -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, diff --git a/compiled/facebook-www/React-dev.modern.js b/compiled/facebook-www/React-dev.modern.js index f652ba5816..9f07945452 100644 --- a/compiled/facebook-www/React-dev.modern.js +++ b/compiled/facebook-www/React-dev.modern.js @@ -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, diff --git a/compiled/facebook-www/React-prod.classic.js b/compiled/facebook-www/React-prod.classic.js index 3f2acfd678..60012e11b8 100644 --- a/compiled/facebook-www/React-prod.classic.js +++ b/compiled/facebook-www/React-prod.classic.js @@ -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"; diff --git a/compiled/facebook-www/React-prod.modern.js b/compiled/facebook-www/React-prod.modern.js index 74e2d987d6..c13984ff96 100644 --- a/compiled/facebook-www/React-prod.modern.js +++ b/compiled/facebook-www/React-prod.modern.js @@ -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"; diff --git a/compiled/facebook-www/React-profiling.classic.js b/compiled/facebook-www/React-profiling.classic.js index 5f9ee302af..be534b42eb 100644 --- a/compiled/facebook-www/React-profiling.classic.js +++ b/compiled/facebook-www/React-profiling.classic.js @@ -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 ( diff --git a/compiled/facebook-www/ReactART-dev.classic.js b/compiled/facebook-www/ReactART-dev.classic.js index a942da4a27..ce40e1dc03 100644 --- a/compiled/facebook-www/ReactART-dev.classic.js +++ b/compiled/facebook-www/ReactART-dev.classic.js @@ -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; diff --git a/compiled/facebook-www/ReactART-dev.modern.js b/compiled/facebook-www/ReactART-dev.modern.js index c42219519b..8c972bb4bb 100644 --- a/compiled/facebook-www/ReactART-dev.modern.js +++ b/compiled/facebook-www/ReactART-dev.modern.js @@ -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; diff --git a/compiled/facebook-www/ReactART-prod.classic.js b/compiled/facebook-www/ReactART-prod.classic.js index 679ad879e2..41f028e253 100644 --- a/compiled/facebook-www/ReactART-prod.classic.js +++ b/compiled/facebook-www/ReactART-prod.classic.js @@ -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 = { @@ -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__; diff --git a/compiled/facebook-www/ReactART-prod.modern.js b/compiled/facebook-www/ReactART-prod.modern.js index b4853b62cb..f4f429d171 100644 --- a/compiled/facebook-www/ReactART-prod.modern.js +++ b/compiled/facebook-www/ReactART-prod.modern.js @@ -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 = { @@ -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__; diff --git a/compiled/facebook-www/ReactDOM-dev.classic.js b/compiled/facebook-www/ReactDOM-dev.classic.js index 7f55207bcc..360650401a 100644 --- a/compiled/facebook-www/ReactDOM-dev.classic.js +++ b/compiled/facebook-www/ReactDOM-dev.classic.js @@ -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, diff --git a/compiled/facebook-www/ReactDOM-dev.modern.js b/compiled/facebook-www/ReactDOM-dev.modern.js index 918e7d8626..91d083462c 100644 --- a/compiled/facebook-www/ReactDOM-dev.modern.js +++ b/compiled/facebook-www/ReactDOM-dev.modern.js @@ -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, diff --git a/compiled/facebook-www/ReactDOM-prod.classic.js b/compiled/facebook-www/ReactDOM-prod.classic.js index 4a10f61a9c..31ce1d54ee 100644 --- a/compiled/facebook-www/ReactDOM-prod.classic.js +++ b/compiled/facebook-www/ReactDOM-prod.classic.js @@ -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 = { @@ -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__; @@ -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"; diff --git a/compiled/facebook-www/ReactDOM-prod.modern.js b/compiled/facebook-www/ReactDOM-prod.modern.js index f7c768abef..495ac5e752 100644 --- a/compiled/facebook-www/ReactDOM-prod.modern.js +++ b/compiled/facebook-www/ReactDOM-prod.modern.js @@ -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 = { @@ -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__; @@ -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"; diff --git a/compiled/facebook-www/ReactDOM-profiling.classic.js b/compiled/facebook-www/ReactDOM-profiling.classic.js index 1f0c12c12e..7ab109d0c4 100644 --- a/compiled/facebook-www/ReactDOM-profiling.classic.js +++ b/compiled/facebook-www/ReactDOM-profiling.classic.js @@ -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) { @@ -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: { @@ -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 ( diff --git a/compiled/facebook-www/ReactDOMServer-dev.classic.js b/compiled/facebook-www/ReactDOMServer-dev.classic.js index 4b2ff6ecc1..4775670a11 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.classic.js +++ b/compiled/facebook-www/ReactDOMServer-dev.classic.js @@ -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"); diff --git a/compiled/facebook-www/ReactDOMServer-dev.modern.js b/compiled/facebook-www/ReactDOMServer-dev.modern.js index 18e8f1c3ac..12f8cae00a 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.modern.js +++ b/compiled/facebook-www/ReactDOMServer-dev.modern.js @@ -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"); diff --git a/compiled/facebook-www/ReactDOMServer-prod.classic.js b/compiled/facebook-www/ReactDOMServer-prod.classic.js index 89bbcc1b45..ee9133f3da 100644 --- a/compiled/facebook-www/ReactDOMServer-prod.classic.js +++ b/compiled/facebook-www/ReactDOMServer-prod.classic.js @@ -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"; diff --git a/compiled/facebook-www/ReactDOMServer-prod.modern.js b/compiled/facebook-www/ReactDOMServer-prod.modern.js index c084c7e759..d75fd11e98 100644 --- a/compiled/facebook-www/ReactDOMServer-prod.modern.js +++ b/compiled/facebook-www/ReactDOMServer-prod.modern.js @@ -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"; diff --git a/compiled/facebook-www/ReactDOMTesting-dev.classic.js b/compiled/facebook-www/ReactDOMTesting-dev.classic.js index 2f8d2c3297..cf5f378ca4 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.classic.js @@ -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, diff --git a/compiled/facebook-www/ReactDOMTesting-prod.modern.js b/compiled/facebook-www/ReactDOMTesting-prod.modern.js index 6cddb89c8d..adcd27fbae 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.modern.js @@ -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 = { @@ -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__; @@ -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"; diff --git a/compiled/facebook-www/ReactTestRenderer-dev.classic.js b/compiled/facebook-www/ReactTestRenderer-dev.classic.js index 28105427ec..45f71c359f 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.classic.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.classic.js @@ -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. diff --git a/compiled/facebook-www/ReactTestRenderer-dev.modern.js b/compiled/facebook-www/ReactTestRenderer-dev.modern.js index bd9d476cba..f0cd316972 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.modern.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.modern.js @@ -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.