Remove turbopack unbundled/register/loader (#30756)
The unbundled form is just a way to show case a prototype for how an unbundled version of RSC can work. It's not really intended for every bundler combination to provide such a configuration. There's no configuration of Turbopack that supports this mode atm and possibly never will be since it's more of an integrated server/client experience. This removes the unbundled form and node register/loaders from the turbopack build.
Sebastian Markbåge committed
Aug 21, 2024 at 09:58 UTC
1228a28398bbf7b4d15cd148496853342e63c041
28 files changed
+38
-1066
packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack-bundled.js
deleted
-16
@@ -1,16 +0,0 @@
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 'react-client/src/ReactFlightClientStreamConfigNode';
11
-export * from 'react-client/src/ReactClientConsoleConfigServer';
12
-export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack';
13
-export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer';
14
-export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigTargetTurbopackServer';
15
-export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
16
-export const usedWithSSR = true;
packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack.js
+2
-1
@@ -9,7 +9,8 @@
9
10
export * from 'react-client/src/ReactFlightClientStreamConfigNode';
11
export * from 'react-client/src/ReactClientConsoleConfigServer';
12
-export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerNode';
12
+export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack';
13
+export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer';
14
export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigTargetTurbopackServer';
15
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
16
export const usedWithSSR = true;
packages/react-server-dom-turbopack/client.node.unbundled.js
deleted
-10
@@ -1,10 +0,0 @@
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 './src/client/ReactFlightDOMClientNode';
packages/react-server-dom-turbopack/esm/package.json
deleted
-3
@@ -1,3 +0,0 @@
1
-{
2
- "type": "module"
3
-}
packages/react-server-dom-turbopack/esm/react-server-dom-turbopack-node-loader.production.js
deleted
-10
@@ -1,10 +0,0 @@
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 '../src/ReactFlightTurbopackNodeLoader.js';
packages/react-server-dom-turbopack/node-register.js
deleted
-10
@@ -1,10 +0,0 @@
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
-module.exports = require('./src/ReactFlightTurbopackNodeRegister');
packages/react-server-dom-turbopack/npm/client.node.unbundled.js
deleted
-7
@@ -1,7 +0,0 @@
1
-'use strict';
2
-
3
-if (process.env.NODE_ENV === 'production') {
4
- module.exports = require('./cjs/react-server-dom-turbopack-client.node.unbundled.production.js');
5
-} else {
6
- module.exports = require('./cjs/react-server-dom-turbopack-client.node.unbundled.development.js');
7
-}
packages/react-server-dom-turbopack/npm/esm/package.json
deleted
-3
@@ -1,3 +0,0 @@
1
-{
2
- "type": "module"
3
-}
packages/react-server-dom-turbopack/npm/node-register.js
deleted
-3
@@ -1,3 +0,0 @@
1
-'use strict';
2
-
3
-module.exports = require('./cjs/react-server-dom-turbopack-node-register.js');
packages/react-server-dom-turbopack/npm/server.node.unbundled.js
deleted
-18
@@ -1,18 +0,0 @@
1
-'use strict';
2
-
3
-var s;
4
-if (process.env.NODE_ENV === 'production') {
5
- s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.production.js');
6
-} else {
7
- s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.development.js');
8
-}
9
-
10
-exports.renderToPipeableStream = s.renderToPipeableStream;
11
-exports.decodeReplyFromBusboy = s.decodeReplyFromBusboy;
12
-exports.decodeReply = s.decodeReply;
13
-exports.decodeAction = s.decodeAction;
14
-exports.decodeFormState = s.decodeFormState;
15
-exports.registerServerReference = s.registerServerReference;
16
-exports.registerClientReference = s.registerClientReference;
17
-exports.createClientModuleProxy = s.createClientModuleProxy;
18
-exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;
packages/react-server-dom-turbopack/npm/static.node.unbundled.js
deleted
-12
@@ -1,12 +0,0 @@
1
-'use strict';
2
-
3
-var s;
4
-if (process.env.NODE_ENV === 'production') {
5
- s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.production.js');
6
-} else {
7
- s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.development.js');
8
-}
9
-
10
-if (s.prerenderToNodeStream) {
11
- exports.prerenderToNodeStream = s.prerenderToNodeStream;
12
-}
packages/react-server-dom-turbopack/package.json
+4
-26
@@ -16,20 +16,15 @@
16
"client.browser.js",
17
"client.edge.js",
18
"client.node.js",
19
- "client.node.unbundled.js",
19
"server.js",
20
"server.browser.js",
21
"server.edge.js",
22
"server.node.js",
24
- "server.node.unbundled.js",
23
"static.js",
24
"static.browser.js",
25
"static.edge.js",
26
"static.node.js",
29
- "static.node.unbundled.js",
30
- "node-register.js",
31
- "cjs/",
32
- "esm/"
27
+ "cjs/"
28
],
29
"exports": {
30
".": "./index.js",
@@ -37,11 +32,7 @@
32
"workerd": "./client.edge.js",
33
"deno": "./client.edge.js",
34
"worker": "./client.edge.js",
40
- "node": {
41
- "turbopack": "./client.node.js",
42
- "webpack": "./client.node.js",
43
- "default": "./client.node.unbundled.js"
44
- },
35
+ "node": "./client.node.js",
36
"edge-light": "./client.edge.js",
37
"browser": "./client.browser.js",
38
"default": "./client.browser.js"
@@ -49,16 +40,11 @@
40
"./client.browser": "./client.browser.js",
41
"./client.edge": "./client.edge.js",
42
"./client.node": "./client.node.js",
52
- "./client.node.unbundled": "./client.node.unbundled.js",
43
"./server": {
44
"react-server": {
45
"workerd": "./server.edge.js",
46
"deno": "./server.browser.js",
57
- "node": {
58
- "turbopack": "./server.node.js",
59
- "webpack": "./server.node.js",
60
- "default": "./server.node.unbundled.js"
61
- },
47
+ "node": "./server.node.js",
48
"edge-light": "./server.edge.js",
49
"browser": "./server.browser.js"
50
},
@@ -67,16 +53,11 @@
53
"./server.browser": "./server.browser.js",
54
"./server.edge": "./server.edge.js",
55
"./server.node": "./server.node.js",
70
- "./server.node.unbundled": "./server.node.unbundled.js",
56
"./static": {
57
"react-server": {
58
"workerd": "./static.edge.js",
59
"deno": "./static.browser.js",
75
- "node": {
76
- "turbopack": "./static.node.js",
77
- "webpack": "./static.node.js",
78
- "default": "./static.node.unbundled.js"
79
- },
60
+ "node": "./static.node.js",
61
"edge-light": "./static.edge.js",
62
"browser": "./static.browser.js"
63
},
@@ -85,9 +66,6 @@
66
"./static.browser": "./static.browser.js",
67
"./static.edge": "./static.edge.js",
68
"./static.node": "./static.node.js",
88
- "./static.node.unbundled": "./static.node.unbundled.js",
89
- "./node-loader": "./esm/react-server-dom-turbopack-node-loader.production.js",
90
- "./node-register": "./node-register.js",
69
"./src/*": "./src/*.js",
70
"./package.json": "./package.json"
71
},
packages/react-server-dom-turbopack/server.node.unbundled.js
deleted
-20
@@ -1,20 +0,0 @@
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
- renderToPipeableStream,
12
- decodeReplyFromBusboy,
13
- decodeReply,
14
- decodeAction,
15
- decodeFormState,
16
- registerServerReference,
17
- registerClientReference,
18
- createClientModuleProxy,
19
- createTemporaryReferenceSet,
20
-} from './src/server/react-flight-dom-server.node.unbundled';
packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeLoader.js
deleted
-483
@@ -1,483 +0,0 @@
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
-import * as acorn from 'acorn-loose';
11
-
12
-type ResolveContext = {
13
- conditions: Array<string>,
14
- parentURL: string | void,
15
-};
16
-
17
-type ResolveFunction = (
18
- string,
19
- ResolveContext,
20
- ResolveFunction,
21
-) => {url: string} | Promise<{url: string}>;
22
-
23
-type GetSourceContext = {
24
- format: string,
25
-};
26
-
27
-type GetSourceFunction = (
28
- string,
29
- GetSourceContext,
30
- GetSourceFunction,
31
-) => Promise<{source: Source}>;
32
-
33
-type TransformSourceContext = {
34
- format: string,
35
- url: string,
36
-};
37
-
38
-type TransformSourceFunction = (
39
- Source,
40
- TransformSourceContext,
41
- TransformSourceFunction,
42
-) => Promise<{source: Source}>;
43
-
44
-type LoadContext = {
45
- conditions: Array<string>,
46
- format: string | null | void,
47
- importAssertions: Object,
48
-};
49
-
50
-type LoadFunction = (
51
- string,
52
- LoadContext,
53
- LoadFunction,
54
-) => Promise<{format: string, shortCircuit?: boolean, source: Source}>;
55
-
56
-type Source = string | ArrayBuffer | Uint8Array;
57
-
58
-let warnedAboutConditionsFlag = false;
59
-
60
-let stashedGetSource: null | GetSourceFunction = null;
61
-let stashedResolve: null | ResolveFunction = null;
62
-
63
-export async function resolve(
64
- specifier: string,
65
- context: ResolveContext,
66
- defaultResolve: ResolveFunction,
67
-): Promise<{url: string}> {
68
- // We stash this in case we end up needing to resolve export * statements later.
69
- stashedResolve = defaultResolve;
70
-
71
- if (!context.conditions.includes('react-server')) {
72
- context = {
73
- ...context,
74
- conditions: [...context.conditions, 'react-server'],
75
- };
76
- if (!warnedAboutConditionsFlag) {
77
- warnedAboutConditionsFlag = true;
78
- // eslint-disable-next-line react-internal/no-production-logging
79
- console.warn(
80
- 'You did not run Node.js with the `--conditions react-server` flag. ' +
81
- 'Any "react-server" override will only work with ESM imports.',
82
- );
83
- }
84
- }
85
- return await defaultResolve(specifier, context, defaultResolve);
86
-}
87
-
88
-export async function getSource(
89
- url: string,
90
- context: GetSourceContext,
91
- defaultGetSource: GetSourceFunction,
92
-): Promise<{source: Source}> {
93
- // We stash this in case we end up needing to resolve export * statements later.
94
- stashedGetSource = defaultGetSource;
95
- return defaultGetSource(url, context, defaultGetSource);
96
-}
97
-
98
-function addLocalExportedNames(names: Map<string, string>, node: any) {
99
- switch (node.type) {
100
- case 'Identifier':
101
- names.set(node.name, node.name);
102
- return;
103
- case 'ObjectPattern':
104
- for (let i = 0; i < node.properties.length; i++)
105
- addLocalExportedNames(names, node.properties[i]);
106
- return;
107
- case 'ArrayPattern':
108
- for (let i = 0; i < node.elements.length; i++) {
109
- const element = node.elements[i];
110
- if (element) addLocalExportedNames(names, element);
111
- }
112
- return;
113
- case 'Property':
114
- addLocalExportedNames(names, node.value);
115
- return;
116
- case 'AssignmentPattern':
117
- addLocalExportedNames(names, node.left);
118
- return;
119
- case 'RestElement':
120
- addLocalExportedNames(names, node.argument);
121
- return;
122
- case 'ParenthesizedExpression':
123
- addLocalExportedNames(names, node.expression);
124
- return;
125
- }
126
-}
127
-
128
-function transformServerModule(
129
- source: string,
130
- body: any,
131
- url: string,
132
- loader: LoadFunction,
133
-): string {
134
- // If the same local name is exported more than once, we only need one of the names.
135
- const localNames: Map<string, string> = new Map();
136
- const localTypes: Map<string, string> = new Map();
137
-
138
- for (let i = 0; i < body.length; i++) {
139
- const node = body[i];
140
- switch (node.type) {
141
- case 'ExportAllDeclaration':
142
- // If export * is used, the other file needs to explicitly opt into "use server" too.
143
- break;
144
- case 'ExportDefaultDeclaration':
145
- if (node.declaration.type === 'Identifier') {
146
- localNames.set(node.declaration.name, 'default');
147
- } else if (node.declaration.type === 'FunctionDeclaration') {
148
- if (node.declaration.id) {
149
- localNames.set(node.declaration.id.name, 'default');
150
- localTypes.set(node.declaration.id.name, 'function');
151
- } else {
152
- // TODO: This needs to be rewritten inline because it doesn't have a local name.
153
- }
154
- }
155
- continue;
156
- case 'ExportNamedDeclaration':
157
- if (node.declaration) {
158
- if (node.declaration.type === 'VariableDeclaration') {
159
- const declarations = node.declaration.declarations;
160
- for (let j = 0; j < declarations.length; j++) {
161
- addLocalExportedNames(localNames, declarations[j].id);
162
- }
163
- } else {
164
- const name = node.declaration.id.name;
165
- localNames.set(name, name);
166
- if (node.declaration.type === 'FunctionDeclaration') {
167
- localTypes.set(name, 'function');
168
- }
169
- }
170
- }
171
- if (node.specifiers) {
172
- const specifiers = node.specifiers;
173
- for (let j = 0; j < specifiers.length; j++) {
174
- const specifier = specifiers[j];
175
- localNames.set(specifier.local.name, specifier.exported.name);
176
- }
177
- }
178
- continue;
179
- }
180
- }
181
- if (localNames.size === 0) {
182
- return source;
183
- }
184
- let newSrc = source + '\n\n;';
185
- newSrc +=
186
- 'import {registerServerReference} from "react-server-dom-turbopack/server";\n';
187
- localNames.forEach(function (exported, local) {
188
- if (localTypes.get(local) !== 'function') {
189
- // We first check if the export is a function and if so annotate it.
190
- newSrc += 'if (typeof ' + local + ' === "function") ';
191
- }
192
- newSrc += 'registerServerReference(' + local + ',';
193
- newSrc += JSON.stringify(url) + ',';
194
- newSrc += JSON.stringify(exported) + ');\n';
195
- });
196
- return newSrc;
197
-}
198
-
199
-function addExportNames(names: Array<string>, node: any) {
200
- switch (node.type) {
201
- case 'Identifier':
202
- names.push(node.name);
203
- return;
204
- case 'ObjectPattern':
205
- for (let i = 0; i < node.properties.length; i++)
206
- addExportNames(names, node.properties[i]);
207
- return;
208
- case 'ArrayPattern':
209
- for (let i = 0; i < node.elements.length; i++) {
210
- const element = node.elements[i];
211
- if (element) addExportNames(names, element);
212
- }
213
- return;
214
- case 'Property':
215
- addExportNames(names, node.value);
216
- return;
217
- case 'AssignmentPattern':
218
- addExportNames(names, node.left);
219
- return;
220
- case 'RestElement':
221
- addExportNames(names, node.argument);
222
- return;
223
- case 'ParenthesizedExpression':
224
- addExportNames(names, node.expression);
225
- return;
226
- }
227
-}
228
-
229
-function resolveClientImport(
230
- specifier: string,
231
- parentURL: string,
232
-): {url: string} | Promise<{url: string}> {
233
- // Resolve an import specifier as if it was loaded by the client. This doesn't use
234
- // the overrides that this loader does but instead reverts to the default.
235
- // This resolution algorithm will not necessarily have the same configuration
236
- // as the actual client loader. It should mostly work and if it doesn't you can
237
- // always convert to explicit exported names instead.
238
- const conditions = ['node', 'import'];
239
- if (stashedResolve === null) {
240
- throw new Error(
241
- 'Expected resolve to have been called before transformSource',
242
- );
243
- }
244
- return stashedResolve(specifier, {conditions, parentURL}, stashedResolve);
245
-}
246
-
247
-async function parseExportNamesInto(
248
- body: any,
249
- names: Array<string>,
250
- parentURL: string,
251
- loader: LoadFunction,
252
-): Promise<void> {
253
- for (let i = 0; i < body.length; i++) {
254
- const node = body[i];
255
- switch (node.type) {
256
- case 'ExportAllDeclaration':
257
- if (node.exported) {
258
- addExportNames(names, node.exported);
259
- continue;
260
- } else {
261
- const {url} = await resolveClientImport(node.source.value, parentURL);
262
- const {source} = await loader(
263
- url,
264
- {format: 'module', conditions: [], importAssertions: {}},
265
- loader,
266
- );
267
- if (typeof source !== 'string') {
268
- throw new Error('Expected the transformed source to be a string.');
269
- }
270
- let childBody;
271
- try {
272
- childBody = acorn.parse(source, {
273
- ecmaVersion: '2024',
274
- sourceType: 'module',
275
- }).body;
276
- } catch (x) {
277
- // eslint-disable-next-line react-internal/no-production-logging
278
- console.error('Error parsing %s %s', url, x.message);
279
- continue;
280
- }
281
- await parseExportNamesInto(childBody, names, url, loader);
282
- continue;
283
- }
284
- case 'ExportDefaultDeclaration':
285
- names.push('default');
286
- continue;
287
- case 'ExportNamedDeclaration':
288
- if (node.declaration) {
289
- if (node.declaration.type === 'VariableDeclaration') {
290
- const declarations = node.declaration.declarations;
291
- for (let j = 0; j < declarations.length; j++) {
292
- addExportNames(names, declarations[j].id);
293
- }
294
- } else {
295
- addExportNames(names, node.declaration.id);
296
- }
297
- }
298
- if (node.specifiers) {
299
- const specifiers = node.specifiers;
300
- for (let j = 0; j < specifiers.length; j++) {
301
- addExportNames(names, specifiers[j].exported);
302
- }
303
- }
304
- continue;
305
- }
306
- }
307
-}
308
-
309
-async function transformClientModule(
310
- body: any,
311
- url: string,
312
- loader: LoadFunction,
313
-): Promise<string> {
314
- const names: Array<string> = [];
315
-
316
- await parseExportNamesInto(body, names, url, loader);
317
-
318
- if (names.length === 0) {
319
- return '';
320
- }
321
-
322
- let newSrc =
323
- 'import {registerClientReference} from "react-server-dom-turbopack/server";\n';
324
- for (let i = 0; i < names.length; i++) {
325
- const name = names[i];
326
- if (name === 'default') {
327
- newSrc += 'export default ';
328
- newSrc += 'registerClientReference(function() {';
329
- newSrc +=
330
- 'throw new Error(' +
331
- JSON.stringify(
332
- `Attempted to call the default export of ${url} from the server ` +
333
- `but it's on the client. It's not possible to invoke a client function from ` +
334
- `the server, it can only be rendered as a Component or passed to props of a ` +
335
- `Client Component.`,
336
- ) +
337
- ');';
338
- } else {
339
- newSrc += 'export const ' + name + ' = ';
340
- newSrc += 'registerClientReference(function() {';
341
- newSrc +=
342
- 'throw new Error(' +
343
- JSON.stringify(
344
- `Attempted to call ${name}() from the server but ${name} is on the client. ` +
345
- `It's not possible to invoke a client function from the server, it can ` +
346
- `only be rendered as a Component or passed to props of a Client Component.`,
347
- ) +
348
- ');';
349
- }
350
- newSrc += '},';
351
- newSrc += JSON.stringify(url) + ',';
352
- newSrc += JSON.stringify(name) + ');\n';
353
- }
354
- return newSrc;
355
-}
356
-
357
-async function loadClientImport(
358
- url: string,
359
- defaultTransformSource: TransformSourceFunction,
360
-): Promise<{format: string, shortCircuit?: boolean, source: Source}> {
361
- if (stashedGetSource === null) {
362
- throw new Error(
363
- 'Expected getSource to have been called before transformSource',
364
- );
365
- }
366
- // TODO: Validate that this is another module by calling getFormat.
367
- const {source} = await stashedGetSource(
368
- url,
369
- {format: 'module'},
370
- stashedGetSource,
371
- );
372
- const result = await defaultTransformSource(
373
- source,
374
- {format: 'module', url},
375
- defaultTransformSource,
376
- );
377
- return {format: 'module', source: result.source};
378
-}
379
-
380
-async function transformModuleIfNeeded(
381
- source: string,
382
- url: string,
383
- loader: LoadFunction,
384
-): Promise<string> {
385
- // Do a quick check for the exact string. If it doesn't exist, don't
386
- // bother parsing.
387
- if (
388
- source.indexOf('use client') === -1 &&
389
- source.indexOf('use server') === -1
390
- ) {
391
- return source;
392
- }
393
-
394
- let body;
395
- try {
396
- body = acorn.parse(source, {
397
- ecmaVersion: '2024',
398
- sourceType: 'module',
399
- }).body;
400
- } catch (x) {
401
- // eslint-disable-next-line react-internal/no-production-logging
402
- console.error('Error parsing %s %s', url, x.message);
403
- return source;
404
- }
405
-
406
- let useClient = false;
407
- let useServer = false;
408
- for (let i = 0; i < body.length; i++) {
409
- const node = body[i];
410
- if (node.type !== 'ExpressionStatement' || !node.directive) {
411
- break;
412
- }
413
- if (node.directive === 'use client') {
414
- useClient = true;
415
- }
416
- if (node.directive === 'use server') {
417
- useServer = true;
418
- }
419
- }
420
-
421
- if (!useClient && !useServer) {
422
- return source;
423
- }
424
-
425
- if (useClient && useServer) {
426
- throw new Error(
427
- 'Cannot have both "use client" and "use server" directives in the same file.',
428
- );
429
- }
430
-
431
- if (useClient) {
432
- return transformClientModule(body, url, loader);
433
- }
434
-
435
- return transformServerModule(source, body, url, loader);
436
-}
437
-
438
-export async function transformSource(
439
- source: Source,
440
- context: TransformSourceContext,
441
- defaultTransformSource: TransformSourceFunction,
442
-): Promise<{source: Source}> {
443
- const transformed = await defaultTransformSource(
444
- source,
445
- context,
446
- defaultTransformSource,
447
- );
448
- if (context.format === 'module') {
449
- const transformedSource = transformed.source;
450
- if (typeof transformedSource !== 'string') {
451
- throw new Error('Expected source to have been transformed to a string.');
452
- }
453
- const newSrc = await transformModuleIfNeeded(
454
- transformedSource,
455
- context.url,
456
- (url: string, ctx: LoadContext, defaultLoad: LoadFunction) => {
457
- return loadClientImport(url, defaultTransformSource);
458
- },
459
- );
460
- return {source: newSrc};
461
- }
462
- return transformed;
463
-}
464
-
465
-export async function load(
466
- url: string,
467
- context: LoadContext,
468
- defaultLoad: LoadFunction,
469
-): Promise<{format: string, shortCircuit?: boolean, source: Source}> {
470
- const result = await defaultLoad(url, context, defaultLoad);
471
- if (result.format === 'module') {
472
- if (typeof result.source !== 'string') {
473
- throw new Error('Expected source to have been loaded into a string.');
474
- }
475
- const newSrc = await transformModuleIfNeeded(
476
- result.source,
477
- url,
478
- defaultLoad,
479
- );
480
- return {format: 'module', source: newSrc};
481
- }
482
- return result;
483
-}
packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js
deleted
-109
@@ -1,109 +0,0 @@
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
-const acorn = require('acorn-loose');
11
-
12
-const url = require('url');
13
-
14
-const Module = require('module');
15
-
16
-module.exports = function register() {
17
- const Server: any = require('react-server-dom-turbopack/server');
18
- const registerServerReference = Server.registerServerReference;
19
- const createClientModuleProxy = Server.createClientModuleProxy;
20
-
21
- // $FlowFixMe[prop-missing] found when upgrading Flow
22
- const originalCompile = Module.prototype._compile;
23
-
24
- // $FlowFixMe[prop-missing] found when upgrading Flow
25
- Module.prototype._compile = function (
26
- this: any,
27
- content: string,
28
- filename: string,
29
- ): void {
30
- // Do a quick check for the exact string. If it doesn't exist, don't
31
- // bother parsing.
32
- if (
33
- content.indexOf('use client') === -1 &&
34
- content.indexOf('use server') === -1
35
- ) {
36
- return originalCompile.apply(this, arguments);
37
- }
38
-
39
- let body;
40
- try {
41
- body = acorn.parse(content, {
42
- ecmaVersion: '2024',
43
- sourceType: 'source',
44
- }).body;
45
- } catch (x) {
46
- console['error']('Error parsing %s %s', url, x.message);
47
- return originalCompile.apply(this, arguments);
48
- }
49
-
50
- let useClient = false;
51
- let useServer = false;
52
- for (let i = 0; i < body.length; i++) {
53
- const node = body[i];
54
- if (node.type !== 'ExpressionStatement' || !node.directive) {
55
- break;
56
- }
57
- if (node.directive === 'use client') {
58
- useClient = true;
59
- }
60
- if (node.directive === 'use server') {
61
- useServer = true;
62
- }
63
- }
64
-
65
- if (!useClient && !useServer) {
66
- return originalCompile.apply(this, arguments);
67
- }
68
-
69
- if (useClient && useServer) {
70
- throw new Error(
71
- 'Cannot have both "use client" and "use server" directives in the same file.',
72
- );
73
- }
74
-
75
- if (useClient) {
76
- const moduleId: string = (url.pathToFileURL(filename).href: any);
77
- this.exports = createClientModuleProxy(moduleId);
78
- }
79
-
80
- if (useServer) {
81
- originalCompile.apply(this, arguments);
82
-
83
- const moduleId: string = (url.pathToFileURL(filename).href: any);
84
-
85
- const exports = this.exports;
86
-
87
- // This module is imported server to server, but opts in to exposing functions by
88
- // reference. If there are any functions in the export.
89
- if (typeof exports === 'function') {
90
- // The module exports a function directly,
91
- registerServerReference(
92
- (exports: any),
93
- moduleId,
94
- // Represents the whole Module object instead of a particular import.
95
- null,
96
- );
97
- } else {
98
- const keys = Object.keys(exports);
99
- for (let i = 0; i < keys.length; i++) {
100
- const key = keys[i];
101
- const value = exports[keys[i]];
102
- if (typeof value === 'function') {
103
- registerServerReference((value: any), moduleId, key);
104
- }
105
- }
106
- }
107
- }
108
- };
109
-};
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js
+2
-2
@@ -30,7 +30,7 @@ let Suspense;
30
let ReactServerScheduler;
31
let reactServerAct;
32
33
-describe('ReactFlightDOM', () => {
33
+describe('ReactFlightTurbopackDOM', () => {
34
beforeEach(() => {
35
// For this first reset we are going to load the dom-node version of react-server-dom-turbopack/server
36
// This can be thought of as essentially being the React Server Components scope with react-server
@@ -43,7 +43,7 @@ describe('ReactFlightDOM', () => {
43
44
// Simulate the condition resolution
45
jest.mock('react-server-dom-turbopack/server', () =>
46
- require('react-server-dom-turbopack/server.node.unbundled'),
46
+ require('react-server-dom-turbopack/server.node'),
47
);
48
jest.mock('react', () => require('react/react.react-server'));
49
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js
+1
-1
@@ -23,7 +23,7 @@ let ReactServerDOMClient;
23
let ReactServerScheduler;
24
let reactServerAct;
25
26
-describe('ReactFlightDOMBrowser', () => {
26
+describe('ReactFlightTurbopackDOMBrowser', () => {
27
beforeEach(() => {
28
jest.resetModules();
29
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMEdge-test.js
+1
-1
@@ -28,7 +28,7 @@ let ReactServerDOMServer;
28
let ReactServerDOMClient;
29
let use;
30
31
-describe('ReactFlightDOMEdge', () => {
31
+describe('ReactFlightTurbopackDOMEdge', () => {
32
beforeEach(() => {
33
jest.resetModules();
34
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMForm-test.js
deleted
-147
@@ -1,147 +0,0 @@
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
- * @emails react-core
8
- */
9
-
10
-'use strict';
11
-
12
-import {insertNodesAndExecuteScripts} from 'react-dom/src/test-utils/FizzTestUtils';
13
-
14
-// Polyfills for test environment
15
-global.ReadableStream =
16
- require('web-streams-polyfill/ponyfill/es6').ReadableStream;
17
-global.TextEncoder = require('util').TextEncoder;
18
-global.TextDecoder = require('util').TextDecoder;
19
-
20
-// Don't wait before processing work on the server.
21
-// TODO: we can replace this with FlightServer.act().
22
-global.setTimeout = cb => cb();
23
-
24
-let container;
25
-let serverExports;
26
-let turbopackServerMap;
27
-let React;
28
-let ReactDOMServer;
29
-let ReactServerDOMServer;
30
-let ReactServerDOMClient;
31
-
32
-describe('ReactFlightDOMForm', () => {
33
- beforeEach(() => {
34
- jest.resetModules();
35
- // Simulate the condition resolution
36
- jest.mock('react', () => require('react/react.react-server'));
37
- jest.mock('react-server-dom-turbopack/server', () =>
38
- require('react-server-dom-turbopack/server.edge'),
39
- );
40
- ReactServerDOMServer = require('react-server-dom-turbopack/server.edge');
41
- const TurbopackMock = require('./utils/TurbopackMock');
42
- serverExports = TurbopackMock.serverExports;
43
- turbopackServerMap = TurbopackMock.turbopackServerMap;
44
- __unmockReact();
45
- jest.resetModules();
46
- React = require('react');
47
- ReactServerDOMClient = require('react-server-dom-turbopack/client.edge');
48
- ReactDOMServer = require('react-dom/server.edge');
49
- container = document.createElement('div');
50
- document.body.appendChild(container);
51
- });
52
-
53
- afterEach(() => {
54
- document.body.removeChild(container);
55
- });
56
-
57
- async function POST(formData) {
58
- const boundAction = await ReactServerDOMServer.decodeAction(
59
- formData,
60
- turbopackServerMap,
61
- );
62
- return boundAction();
63
- }
64
-
65
- function submit(submitter) {
66
- const form = submitter.form || submitter;
67
- if (!submitter.form) {
68
- submitter = undefined;
69
- }
70
- const submitEvent = new Event('submit', {bubbles: true, cancelable: true});
71
- submitEvent.submitter = submitter;
72
- const returnValue = form.dispatchEvent(submitEvent);
73
- if (!returnValue) {
74
- return;
75
- }
76
- const action =
77
- (submitter && submitter.getAttribute('formaction')) || form.action;
78
- if (!/\s*javascript:/i.test(action)) {
79
- const method = (submitter && submitter.formMethod) || form.method;
80
- const encType = (submitter && submitter.formEnctype) || form.enctype;
81
- if (method === 'post' && encType === 'multipart/form-data') {
82
- let formData;
83
- if (submitter) {
84
- const temp = document.createElement('input');
85
- temp.name = submitter.name;
86
- temp.value = submitter.value;
87
- submitter.parentNode.insertBefore(temp, submitter);
88
- formData = new FormData(form);
89
- temp.parentNode.removeChild(temp);
90
- } else {
91
- formData = new FormData(form);
92
- }
93
- return POST(formData);
94
- }
95
- throw new Error('Navigate to: ' + action);
96
- }
97
- }
98
-
99
- async function readIntoContainer(stream) {
100
- const reader = stream.getReader();
101
- let result = '';
102
- while (true) {
103
- const {done, value} = await reader.read();
104
- if (done) {
105
- break;
106
- }
107
- result += Buffer.from(value).toString('utf8');
108
- }
109
- const temp = document.createElement('div');
110
- temp.innerHTML = result;
111
- insertNodesAndExecuteScripts(temp, container, null);
112
- }
113
-
114
- it('can submit a passed server action without hydrating it', async () => {
115
- let foo = null;
116
-
117
- const serverAction = serverExports(function action(formData) {
118
- foo = formData.get('foo');
119
- return 'hello';
120
- });
121
- function App() {
122
- return (
123
- <form action={serverAction}>
124
- <input type="text" name="foo" defaultValue="bar" />
125
- </form>
126
- );
127
- }
128
- const rscStream = ReactServerDOMServer.renderToReadableStream(<App />);
129
- const response = ReactServerDOMClient.createFromReadableStream(rscStream, {
130
- ssrManifest: {
131
- moduleMap: null,
132
- moduleLoading: null,
133
- },
134
- });
135
- const ssrStream = await ReactDOMServer.renderToReadableStream(response);
136
- await readIntoContainer(ssrStream);
137
-
138
- const form = container.firstChild;
139
-
140
- expect(foo).toBe(null);
141
-
142
- const result = await submit(form);
143
-
144
- expect(result).toBe('hello');
145
- expect(foo).toBe('bar');
146
- });
147
-});
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js
+1
-1
@@ -24,7 +24,7 @@ let use;
24
let ReactServerScheduler;
25
let reactServerAct;
26
27
-describe('ReactFlightDOMNode', () => {
27
+describe('ReactFlightTurbopackDOMNode', () => {
28
beforeEach(() => {
29
jest.resetModules();
30
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js
+1
-1
@@ -23,7 +23,7 @@ let ReactServerDOMServer;
23
let ReactServerDOMClient;
24
let ReactServerScheduler;
25
26
-describe('ReactFlightDOMReply', () => {
26
+describe('ReactFlightTurbopackDOMReply', () => {
27
beforeEach(() => {
28
jest.resetModules();
29
packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReplyEdge-test.js
+1
-1
@@ -20,7 +20,7 @@ let turbopackServerMap;
20
let ReactServerDOMServer;
21
let ReactServerDOMClient;
22
23
-describe('ReactFlightDOMReply', () => {
23
+describe('ReactFlightDOMTurbopackReply', () => {
24
beforeEach(() => {
25
jest.resetModules();
26
// Simulate the condition resolution
packages/react-server-dom-turbopack/src/__tests__/utils/TurbopackMock.js
+25
-37
@@ -8,7 +8,6 @@
8
'use strict';
9
10
const url = require('url');
11
-const Module = require('module');
11
12
let turbopackModuleIdx = 0;
13
const turbopackServerModules = {};
@@ -23,21 +22,9 @@ global.__turbopack_require__ = function (id) {
22
return turbopackClientModules[id] || turbopackServerModules[id];
23
};
24
26
-const previousCompile = Module.prototype._compile;
27
-
28
-const register = require('react-server-dom-turbopack/node-register');
29
-// Register node compile
30
-register();
31
-
32
-const nodeCompile = Module.prototype._compile;
33
-
34
-if (previousCompile === nodeCompile) {
35
- throw new Error(
36
- 'Expected the Node loader to register the _compile extension',
37
- );
38
-}
39
-
40
-Module.prototype._compile = previousCompile;
25
+const Server = require('react-server-dom-turbopack/server');
26
+const registerServerReference = Server.registerServerReference;
27
+const createClientModuleProxy = Server.createClientModuleProxy;
28
29
exports.turbopackMap = turbopackClientMap;
30
exports.turbopackModules = turbopackClientModules;
@@ -46,20 +33,6 @@ exports.moduleLoading = {
33
prefix: '/prefix/',
34
};
35
49
-exports.clientModuleError = function clientModuleError(moduleError) {
50
- const idx = '' + turbopackModuleIdx++;
51
- turbopackErroredModules[idx] = moduleError;
52
- const path = url.pathToFileURL(idx).href;
53
- turbopackClientMap[path] = {
54
- id: idx,
55
- chunks: [],
56
- name: '*',
57
- };
58
- const mod = new Module();
59
- nodeCompile.call(mod, '"use client"', idx);
60
- return mod.exports;
61
-};
62
-
36
exports.clientExports = function clientExports(moduleExports, chunkUrl) {
37
const chunks = [];
38
if (chunkUrl !== undefined) {
@@ -107,9 +80,7 @@ exports.clientExports = function clientExports(moduleExports, chunkUrl) {
80
name: 's',
81
};
82
}
110
- const mod = new Module();
111
- nodeCompile.call(mod, '"use client"', idx);
112
- return mod.exports;
83
+ return createClientModuleProxy(path);
84
};
85
86
// This tests server to server references. There's another case of client to server references.
@@ -142,8 +113,25 @@ exports.serverExports = function serverExports(moduleExports) {
113
name: 's',
114
};
115
}
145
- const mod = new Module();
146
- mod.exports = moduleExports;
147
- nodeCompile.call(mod, '"use server"', idx);
148
- return mod.exports;
116
+
117
+ if (typeof exports === 'function') {
118
+ // The module exports a function directly,
119
+ registerServerReference(
120
+ (exports: any),
121
+ idx,
122
+ // Represents the whole Module object instead of a particular import.
123
+ null,
124
+ );
125
+ } else {
126
+ const keys = Object.keys(exports);
127
+ for (let i = 0; i < keys.length; i++) {
128
+ const key = keys[i];
129
+ const value = exports[keys[i]];
130
+ if (typeof value === 'function') {
131
+ registerServerReference((value: any), idx, key);
132
+ }
133
+ }
134
+ }
135
+
136
+ return moduleExports;
137
};
packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.js
deleted
-21
@@ -1,21 +0,0 @@
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
- renderToPipeableStream,
12
- prerenderToNodeStream,
13
- decodeReplyFromBusboy,
14
- decodeReply,
15
- decodeAction,
16
- decodeFormState,
17
- registerServerReference,
18
- registerClientReference,
19
- createClientModuleProxy,
20
- createTemporaryReferenceSet,
21
-} from './ReactFlightDOMServerNode';
packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.stable.js
deleted
-20
@@ -1,20 +0,0 @@
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
- renderToPipeableStream,
12
- decodeReplyFromBusboy,
13
- decodeReply,
14
- decodeAction,
15
- decodeFormState,
16
- registerServerReference,
17
- registerClientReference,
18
- createClientModuleProxy,
19
- createTemporaryReferenceSet,
20
-} from './ReactFlightDOMServerNode';
packages/react-server-dom-turbopack/static.node.unbundled.js
deleted
-10
@@ -1,10 +0,0 @@
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 {prerenderToNodeStream} from './src/server/react-flight-dom-server.node.unbundled';
scripts/rollup/bundles.js
-50
@@ -534,18 +534,6 @@ const bundles = [
534
wrapWithModuleBoundaries: false,
535
externals: ['react', 'util', 'async_hooks', 'react-dom'],
536
},
537
- {
538
- bundleTypes: [NODE_DEV, NODE_PROD],
539
- moduleType: RENDERER,
540
- entry:
541
- 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled',
542
- name: 'react-server-dom-turbopack-server.node.unbundled',
543
- condition: 'react-server',
544
- global: 'ReactServerDOMServer',
545
- minifyWithProdErrorCodes: false,
546
- wrapWithModuleBoundaries: false,
547
- externals: ['react', 'util', 'async_hooks', 'react-dom'],
548
- },
537
{
538
bundleTypes: [NODE_DEV, NODE_PROD],
539
moduleType: RENDERER,
@@ -577,15 +565,6 @@ const bundles = [
565
wrapWithModuleBoundaries: false,
566
externals: ['react', 'react-dom', 'util'],
567
},
580
- {
581
- bundleTypes: [NODE_DEV, NODE_PROD],
582
- moduleType: RENDERER,
583
- entry: 'react-server-dom-turbopack/client.node.unbundled',
584
- global: 'ReactServerDOMClient',
585
- minifyWithProdErrorCodes: false,
586
- wrapWithModuleBoundaries: false,
587
- externals: ['react', 'react-dom', 'util'],
588
- },
568
{
569
bundleTypes: [NODE_DEV, NODE_PROD],
570
moduleType: RENDERER,
@@ -596,35 +575,6 @@ const bundles = [
575
externals: ['react', 'react-dom'],
576
},
577
599
- /******* React Server DOM Turbopack Plugin *******/
600
- // There is no plugin the moment because Turbopack
601
- // does not expose a plugin interface yet.
602
-
603
- /******* React Server DOM Turbopack Node.js Loader *******/
604
- {
605
- bundleTypes: [ESM_PROD],
606
- moduleType: RENDERER_UTILS,
607
- entry: 'react-server-dom-turbopack/node-loader',
608
- condition: 'react-server',
609
- global: 'ReactServerTurbopackNodeLoader',
610
- minifyWithProdErrorCodes: false,
611
- wrapWithModuleBoundaries: false,
612
- externals: ['acorn'],
613
- },
614
-
615
- /******* React Server DOM Turbopack Node.js CommonJS Loader *******/
616
- {
617
- bundleTypes: [NODE_ES2015],
618
- moduleType: RENDERER_UTILS,
619
- entry: 'react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister',
620
- name: 'react-server-dom-turbopack-node-register',
621
- condition: 'react-server',
622
- global: 'ReactFlightWebpackNodeRegister',
623
- minifyWithProdErrorCodes: false,
624
- wrapWithModuleBoundaries: false,
625
- externals: ['url', 'module', 'react-server-dom-turbopack/server'],
626
- },
627
-
578
/******* React Server DOM ESM Server *******/
579
{
580
bundleTypes: [NODE_DEV, NODE_PROD],
scripts/shared/inlinedHostConfigs.js
-43
@@ -104,49 +104,6 @@ module.exports = [
104
},
105
{
106
shortName: 'dom-node-turbopack',
107
- entryPoints: [
108
- 'react-server-dom-turbopack/client.node.unbundled',
109
- 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled',
110
- ],
111
- paths: [
112
- 'react-dom',
113
- 'react-dom-bindings',
114
- 'react-dom/client',
115
- 'react-dom/profiling',
116
- 'react-dom/server',
117
- 'react-dom/server.node',
118
- 'react-dom/static',
119
- 'react-dom/static.node',
120
- 'react-dom/src/server/react-dom-server.node',
121
- 'react-dom/src/server/ReactDOMFizzServerNode.js', // react-dom/server.node
122
- 'react-dom/src/server/ReactDOMFizzStaticNode.js',
123
- 'react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js',
124
- 'react-dom-bindings/src/server/ReactFlightServerConfigDOM.js',
125
- 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM.js',
126
- 'react-server-dom-turbopack',
127
- 'react-server-dom-turbopack/client.node.unbundled',
128
- 'react-server-dom-turbopack/server',
129
- 'react-server-dom-turbopack/server.node.unbundled',
130
- 'react-server-dom-turbopack/static',
131
- 'react-server-dom-turbopack/static.node.unbundled',
132
- 'react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js', // react-server-dom-turbopack/client.node.unbundled
133
- 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerNode.js',
134
- 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled',
135
- 'react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js', // react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled
136
- 'react-server-dom-turbopack/node-register',
137
- 'react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js',
138
- 'react-devtools',
139
- 'react-devtools-core',
140
- 'react-devtools-shell',
141
- 'react-devtools-shared',
142
- 'shared/ReactDOMSharedInternals',
143
- 'react-server/src/ReactFlightServerConfigDebugNode.js',
144
- ],
145
- isFlowTyped: true,
146
- isServerSupported: true,
147
- },
148
- {
149
- shortName: 'dom-node-turbopack-bundled',
107
entryPoints: [
108
'react-server-dom-turbopack/client.node',
109
'react-server-dom-turbopack/src/server/react-flight-dom-server.node',