@samitouri / QOS-React / commits / 1228a28398

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',