@samitouri / QOS-React / commits / e8d15fa19e

[Flight] Build node-webstreams version of bundled webpack server (#33456)

Follow up to #33442. This is the bundled version. To keep type check passes from exploding and the maintainance of the annoying `paths: []` list small, this doesn't add this to flow type checks. We might miss some config but every combination should already be covered by other one passes. I also don't add any jest tests because to test these double export entry points we need conditional importing to cover builds and non-builds which turns out to be difficult for the Flight builds so these aren't covered by any basic build tests. This approach is what I'm going for, for the other bundlers too.

Sebastian Markbåge committed Jun 6, 2025 at 11:07 UTC e8d15fa19efcd18f0947fe4189652f5b64f74256
8 files changed +124 -7
packages/react-client/src/forks/ReactFlightClientConfig.dom-node-webstreams-webpack.js new
+19
@@ -0,0 +1,19 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +export {default as rendererVersion} from 'shared/ReactVersion';
11 +export const rendererPackageName = 'react-server-dom-webpack';
12 +
13 +export * from 'react-client/src/ReactFlightClientStreamConfigWeb';
14 +export * from 'react-client/src/ReactClientConsoleConfigServer';
15 +export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack';
16 +export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer';
17 +export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigTargetWebpackServer';
18 +export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
19 +export const usedWithSSR = true;
packages/react-server-dom-webpack/npm/client.node.js
+23 -2
@@ -1,7 +1,28 @@
1 'use strict';
2
3 +var n, w;
4 if (process.env.NODE_ENV === 'production') {
4 - module.exports = require('./cjs/react-server-dom-webpack-client.node.production.js');
5 + n = require('./cjs/react-server-dom-webpack-client.node.production.js');
6 + w = require('./cjs/react-server-dom-webpack-client.node-webstreams.production.js');
7 } else {
6 - module.exports = require('./cjs/react-server-dom-webpack-client.node.development.js');
8 + n = require('./cjs/react-server-dom-webpack-client.node.development.js');
9 + w = require('./cjs/react-server-dom-webpack-client.node-webstreams.development.js');
10 }
11 +
12 +exports.registerServerReference = function (r, i, e) {
13 + return w.registerServerReference(n.registerServerReference(r, i, e), i, e);
14 +};
15 +exports.createServerReference = function (i, c, e, d, f) {
16 + return w.registerServerReference(
17 + n.createServerReference(i, c, e, d, f),
18 + i,
19 + e
20 + );
21 +};
22 +
23 +exports.createFromNodeStream = n.createFromNodeStream;
24 +exports.createFromFetch = w.createFromFetch;
25 +exports.createFromReadableStream = w.createFromReadableStream;
26 +
27 +exports.createTemporaryReferenceSet = w.createTemporaryReferenceSet;
28 +exports.encodeReply = w.encodeReply;
packages/react-server-dom-webpack/npm/server.node.js
+8 -3
@@ -1,10 +1,12 @@
1 'use strict';
2
3 -var s;
3 +var s, w;
4 if (process.env.NODE_ENV === 'production') {
5 - s = require('./cjs/react-server-dom-webpack-server.node.production.js');
5 + s = require('./cjs/react-server-dom-webpack-server.node.unbundled.production.js');
6 + w = require('./cjs/react-server-dom-webpack-server.node-webstreams.unbundled.production.js');
7 } else {
7 - s = require('./cjs/react-server-dom-webpack-server.node.development.js');
8 + s = require('./cjs/react-server-dom-webpack-server.node.unbundled.development.js');
9 + w = require('./cjs/react-server-dom-webpack-server.node-webstreams.unbundled.development.js');
10 }
11
12 exports.renderToPipeableStream = s.renderToPipeableStream;
@@ -16,3 +18,6 @@ exports.registerServerReference = s.registerServerReference;
18 exports.registerClientReference = s.registerClientReference;
19 exports.createClientModuleProxy = s.createClientModuleProxy;
20 exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;
21 +
22 +exports.renderToReadableStream = w.renderToReadableStream;
23 +exports.decodeReplyFromAsyncIterable = w.decodeReplyFromAsyncIterable;
packages/react-server-dom-webpack/src/client/react-flight-dom-client.node-webstreams.js new
+10
@@ -0,0 +1,10 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +export * from './ReactFlightDOMClientEdge';
packages/react-server-dom-webpack/src/server/react-flight-dom-server.node-webstreams.js new
+21
@@ -0,0 +1,21 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +export {
11 + renderToReadableStream,
12 + prerender as unstable_prerender,
13 + decodeReply,
14 + decodeReplyFromAsyncIterable,
15 + decodeAction,
16 + decodeFormState,
17 + registerServerReference,
18 + registerClientReference,
19 + createClientModuleProxy,
20 + createTemporaryReferenceSet,
21 +} from './ReactFlightDOMServerEdge';
scripts/jest/setupTests.js
+7 -2
@@ -296,14 +296,19 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
296
297 // We mock createHook so that we can automatically clean it up.
298 let installedHook = null;
299 +let outgoingHook = null;
300 jest.mock('async_hooks', () => {
301 const actual = jest.requireActual('async_hooks');
302 return {
303 ...actual,
304 createHook(config) {
304 - if (installedHook) {
305 - installedHook.disable();
305 + // We unmount when there's more than two hooks installed.
306 + // We use two because the build of server.node actually installs two hooks.
307 + // One in each build.
308 + if (outgoingHook) {
309 + outgoingHook.disable();
310 }
311 + outgoingHook = installedHook;
312 return (installedHook = actual.createHook(config));
313 },
314 };
scripts/rollup/bundles.js
+23
@@ -472,6 +472,18 @@ const bundles = [
472 wrapWithModuleBoundaries: false,
473 externals: ['react', 'util', 'crypto', 'async_hooks', 'react-dom'],
474 },
475 + {
476 + bundleTypes: [NODE_DEV, NODE_PROD],
477 + moduleType: RENDERER,
478 + entry:
479 + 'react-server-dom-webpack/src/server/react-flight-dom-server.node-webstreams',
480 + name: 'react-server-dom-webpack-server.node-webstreams',
481 + condition: 'react-server',
482 + global: 'ReactServerDOMServer',
483 + minifyWithProdErrorCodes: false,
484 + wrapWithModuleBoundaries: false,
485 + externals: ['react', 'util', 'crypto', 'async_hooks', 'react-dom'],
486 + },
487 {
488 bundleTypes: [NODE_DEV, NODE_PROD],
489 moduleType: RENDERER,
@@ -530,6 +542,17 @@ const bundles = [
542 wrapWithModuleBoundaries: false,
543 externals: ['react', 'react-dom', 'util', 'crypto'],
544 },
545 + {
546 + bundleTypes: [NODE_DEV, NODE_PROD],
547 + moduleType: RENDERER,
548 + entry:
549 + 'react-server-dom-webpack/src/client/react-flight-dom-client.node-webstreams',
550 + name: 'react-server-dom-webpack-client.node-webstreams',
551 + global: 'ReactServerDOMClient',
552 + minifyWithProdErrorCodes: false,
553 + wrapWithModuleBoundaries: false,
554 + externals: ['react', 'react-dom', 'util', 'crypto'],
555 + },
556 {
557 bundleTypes: [NODE_DEV, NODE_PROD],
558 moduleType: RENDERER,
scripts/shared/inlinedHostConfigs.js
+13
@@ -190,6 +190,19 @@ module.exports = [
190 isFlowTyped: true,
191 isServerSupported: true,
192 },
193 + {
194 + shortName: 'dom-node-webstreams-webpack',
195 + entryPoints: [
196 + 'react-server-dom-webpack/src/client/react-flight-dom-client.node-webstreams',
197 + 'react-server-dom-webpack/src/server/react-flight-dom-server.node-webstreams',
198 + ],
199 + paths: [
200 + 'react-server-dom-webpack/src/client/react-flight-dom-client.node-webstreams',
201 + 'react-server-dom-webpack/src/server/react-flight-dom-server.node-webstreams',
202 + ],
203 + isFlowTyped: false,
204 + isServerSupported: true,
205 + },
206 {
207 shortName: 'dom-node-turbopack',
208 entryPoints: [