Skip to content

Commit 7c1513b

Browse files
sebmarkbageAndyPengc12
authored andcommitted
Enforce that the "react-server" build of "react" is used (facebook#27436)
I do this by simply renaming the secret export name in the "subset" bundle and this renamed version is what the FlightServer uses. This requires us to be more diligent about always using the correct instance of "react" in our tests so there's a bunch of clean up for that.
1 parent e6b96fd commit 7c1513b

30 files changed

+245
-1258
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ module.exports = {
517517
__TEST__: 'readonly',
518518
__UMD__: 'readonly',
519519
__VARIANT__: 'readonly',
520+
__unmockReact: 'readonly',
520521
gate: 'readonly',
521522
trustedTypes: 'readonly',
522523
IS_REACT_ACT_ENVIRONMENT: 'readonly',

packages/react-client/src/__tests__/ReactFlight-test.js

+64-30
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ let act;
1414
let use;
1515
let startTransition;
1616
let React;
17+
let ReactServer;
1718
let ReactNoop;
1819
let ReactNoopFlightServer;
1920
let ReactNoopFlightClient;
@@ -25,12 +26,18 @@ let assertLog;
2526
describe('ReactFlight', () => {
2627
beforeEach(() => {
2728
jest.resetModules();
28-
29+
jest.mock('react', () => require('react/react.shared-subset'));
30+
ReactServer = require('react');
31+
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
32+
// This stores the state so we need to preserve it
33+
const flightModules = require('react-noop-renderer/flight-modules');
34+
__unmockReact();
35+
jest.resetModules();
36+
jest.mock('react-noop-renderer/flight-modules', () => flightModules);
2937
React = require('react');
3038
startTransition = React.startTransition;
3139
use = React.use;
3240
ReactNoop = require('react-noop-renderer');
33-
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
3441
ReactNoopFlightClient = require('react-noop-renderer/flight-client');
3542
act = require('internal-test-utils').act;
3643
Scheduler = require('scheduler');
@@ -111,6 +118,19 @@ describe('ReactFlight', () => {
111118
return ctx;
112119
}
113120

121+
function createServerServerContext(globalName, defaultValue, withStack) {
122+
let ctx;
123+
expect(() => {
124+
ctx = ReactServer.createServerContext(globalName, defaultValue);
125+
}).toErrorDev(
126+
'Server Context is deprecated and will soon be removed. ' +
127+
'It was never documented and we have found it not to be useful ' +
128+
'enough to warrant the downside it imposes on all apps.',
129+
{withoutStack: !withStack},
130+
);
131+
return ctx;
132+
}
133+
114134
function clientReference(value) {
115135
return Object.defineProperties(
116136
function () {
@@ -970,7 +990,7 @@ describe('ReactFlight', () => {
970990
const Context = React.createContext();
971991
const ClientContext = clientReference(Context);
972992
function ServerComponent() {
973-
return React.useContext(ClientContext);
993+
return ReactServer.useContext(ClientContext);
974994
}
975995
expect(() => {
976996
const transport = ReactNoopFlightServer.render(<ServerComponent />);
@@ -982,7 +1002,7 @@ describe('ReactFlight', () => {
9821002

9831003
describe('Hooks', () => {
9841004
function DivWithId({children}) {
985-
const id = React.useId();
1005+
const id = ReactServer.useId();
9861006
return <div prop={id}>{children}</div>;
9871007
}
9881008

@@ -1039,7 +1059,7 @@ describe('ReactFlight', () => {
10391059
// so the output passed to the Client has no knowledge of the useId use. In the future we would like to add a DEV warning when this happens. For now
10401060
// we just accept that it is a nuance of useId in Flight
10411061
function App() {
1042-
const id = React.useId();
1062+
const id = ReactServer.useId();
10431063
const div = <div prop={id}>{id}</div>;
10441064
return <ClientDoublerModuleRef el={div} />;
10451065
}
@@ -1076,19 +1096,17 @@ describe('ReactFlight', () => {
10761096
describe('ServerContext', () => {
10771097
// @gate enableServerContext
10781098
it('supports basic createServerContext usage', async () => {
1079-
const ServerContext = createServerContext(
1099+
const ServerContext = createServerServerContext(
10801100
'ServerContext',
10811101
'hello from server',
10821102
);
10831103
function Foo() {
1084-
const context = React.useContext(ServerContext);
1104+
const context = ReactServer.useContext(ServerContext);
10851105
return <div>{context}</div>;
10861106
}
10871107

10881108
const transport = ReactNoopFlightServer.render(<Foo />);
10891109
await act(async () => {
1090-
ServerContext._currentRenderer = null;
1091-
ServerContext._currentRenderer2 = null;
10921110
ReactNoop.render(await ReactNoopFlightClient.read(transport));
10931111
});
10941112

@@ -1097,7 +1115,10 @@ describe('ReactFlight', () => {
10971115

10981116
// @gate enableServerContext
10991117
it('propagates ServerContext providers in flight', async () => {
1100-
const ServerContext = createServerContext('ServerContext', 'default');
1118+
const ServerContext = createServerServerContext(
1119+
'ServerContext',
1120+
'default',
1121+
);
11011122

11021123
function Foo() {
11031124
return (
@@ -1109,14 +1130,12 @@ describe('ReactFlight', () => {
11091130
);
11101131
}
11111132
function Bar() {
1112-
const context = React.useContext(ServerContext);
1133+
const context = ReactServer.useContext(ServerContext);
11131134
return context;
11141135
}
11151136

11161137
const transport = ReactNoopFlightServer.render(<Foo />);
11171138
await act(async () => {
1118-
ServerContext._currentRenderer = null;
1119-
ServerContext._currentRenderer2 = null;
11201139
ReactNoop.render(await ReactNoopFlightClient.read(transport));
11211140
});
11221141

@@ -1125,7 +1144,7 @@ describe('ReactFlight', () => {
11251144

11261145
// @gate enableServerContext
11271146
it('errors if you try passing JSX through ServerContext value', () => {
1128-
const ServerContext = createServerContext('ServerContext', {
1147+
const ServerContext = createServerServerContext('ServerContext', {
11291148
foo: {
11301149
bar: <span>hi this is default</span>,
11311150
},
@@ -1146,7 +1165,7 @@ describe('ReactFlight', () => {
11461165
);
11471166
}
11481167
function Bar() {
1149-
const context = React.useContext(ServerContext);
1168+
const context = ReactServer.useContext(ServerContext);
11501169
return context.foo.bar;
11511170
}
11521171

@@ -1159,7 +1178,10 @@ describe('ReactFlight', () => {
11591178

11601179
// @gate enableServerContext
11611180
it('propagates ServerContext and cleans up the providers in flight', async () => {
1162-
const ServerContext = createServerContext('ServerContext', 'default');
1181+
const ServerContext = createServerServerContext(
1182+
'ServerContext',
1183+
'default',
1184+
);
11631185

11641186
function Foo() {
11651187
return (
@@ -1181,7 +1203,7 @@ describe('ReactFlight', () => {
11811203
);
11821204
}
11831205
function Bar() {
1184-
const context = React.useContext(ServerContext);
1206+
const context = ReactServer.useContext(ServerContext);
11851207
return <span>{context}</span>;
11861208
}
11871209

@@ -1203,7 +1225,10 @@ describe('ReactFlight', () => {
12031225

12041226
// @gate enableServerContext
12051227
it('propagates ServerContext providers in flight after suspending', async () => {
1206-
const ServerContext = createServerContext('ServerContext', 'default');
1228+
const ServerContext = createServerServerContext(
1229+
'ServerContext',
1230+
'default',
1231+
);
12071232

12081233
function Foo() {
12091234
return (
@@ -1231,7 +1256,7 @@ describe('ReactFlight', () => {
12311256
throw promise;
12321257
}
12331258
Scheduler.log('rendered');
1234-
const context = React.useContext(ServerContext);
1259+
const context = ReactServer.useContext(ServerContext);
12351260
return context;
12361261
}
12371262

@@ -1248,8 +1273,6 @@ describe('ReactFlight', () => {
12481273
assertLog(['rendered']);
12491274

12501275
await act(async () => {
1251-
ServerContext._currentRenderer = null;
1252-
ServerContext._currentRenderer2 = null;
12531276
ReactNoop.render(await ReactNoopFlightClient.read(transport));
12541277
});
12551278

@@ -1258,11 +1281,15 @@ describe('ReactFlight', () => {
12581281

12591282
// @gate enableServerContext
12601283
it('serializes ServerContext to client', async () => {
1261-
const ServerContext = createServerContext('ServerContext', 'default');
1284+
const ServerContext = createServerServerContext(
1285+
'ServerContext',
1286+
'default',
1287+
);
1288+
const ClientContext = createServerContext('ServerContext', 'default');
12621289

12631290
function ClientBar() {
12641291
Scheduler.log('ClientBar');
1265-
const context = React.useContext(ServerContext);
1292+
const context = React.useContext(ClientContext);
12661293
return <span>{context}</span>;
12671294
}
12681295

@@ -1285,8 +1312,6 @@ describe('ReactFlight', () => {
12851312
assertLog([]);
12861313

12871314
await act(async () => {
1288-
ServerContext._currentRenderer = null;
1289-
ServerContext._currentRenderer2 = null;
12901315
const flightModel = await ReactNoopFlightClient.read(transport);
12911316
ReactNoop.render(flightModel.foo);
12921317
});
@@ -1301,9 +1326,12 @@ describe('ReactFlight', () => {
13011326

13021327
// @gate enableServerContext
13031328
it('takes ServerContext from the client for refetching use cases', async () => {
1304-
const ServerContext = createServerContext('ServerContext', 'default');
1329+
const ServerContext = createServerServerContext(
1330+
'ServerContext',
1331+
'default',
1332+
);
13051333
function Bar() {
1306-
return <span>{React.useContext(ServerContext)}</span>;
1334+
return <span>{ReactServer.useContext(ServerContext)}</span>;
13071335
}
13081336
const transport = ReactNoopFlightServer.render(<Bar />, {
13091337
context: [['ServerContext', 'Override']],
@@ -1321,7 +1349,7 @@ describe('ReactFlight', () => {
13211349
let ServerContext;
13221350
function inlineLazyServerContextInitialization() {
13231351
if (!ServerContext) {
1324-
ServerContext = createServerContext('ServerContext', 'default');
1352+
ServerContext = createServerServerContext('ServerContext', 'default');
13251353
}
13261354
return ServerContext;
13271355
}
@@ -1346,7 +1374,7 @@ describe('ReactFlight', () => {
13461374
return (
13471375
<article>
13481376
<div>
1349-
{React.useContext(inlineLazyServerContextInitialization())}
1377+
{ReactServer.useContext(inlineLazyServerContextInitialization())}
13501378
</div>
13511379
<Baz />
13521380
</article>
@@ -1381,11 +1409,17 @@ describe('ReactFlight', () => {
13811409
// Reset all modules, except flight-modules which keeps the registry of Client Components
13821410
const flightModules = require('react-noop-renderer/flight-modules');
13831411
jest.resetModules();
1412+
jest.mock('react', () => require('react/react.shared-subset'));
13841413
jest.mock('react-noop-renderer/flight-modules', () => flightModules);
13851414

1415+
ReactServer = require('react');
1416+
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
1417+
1418+
__unmockReact();
1419+
jest.resetModules();
1420+
jest.mock('react-noop-renderer/flight-modules', () => flightModules);
13861421
React = require('react');
13871422
ReactNoop = require('react-noop-renderer');
1388-
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
13891423
ReactNoopFlightClient = require('react-noop-renderer/flight-client');
13901424
act = require('internal-test-utils').act;
13911425
Scheduler = require('scheduler');

packages/react-dom/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"test-utils.js",
4343
"unstable_testing.js",
4444
"unstable_server-external-runtime.js",
45+
"react-dom.shared-subset.js",
4546
"cjs/",
4647
"umd/"
4748
],

packages/react-server-dom-turbopack/src/__tests__/ReactFlightDOM-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ describe('ReactFlightDOM', () => {
6262

6363
// This reset is to load modules for the SSR/Browser scope.
6464
jest.resetModules();
65-
jest.unmock('react');
65+
__unmockReact();
6666
act = require('internal-test-utils').act;
6767
Stream = require('stream');
6868
React = require('react');

0 commit comments

Comments
 (0)