Skip to content

Commit

Permalink
[Flight] createServerReference should export $$FORM_ACTION on the Ser…
Browse files Browse the repository at this point in the history
…ver (#26987)

Currently, only the browser build exposes the `$$FORM_ACTION` helper.
It's used for creating progressive enhancement fro Server Actions
imported from Client Components. This helper is only useful in SSR
builds so it should be included in the Edge/Node builds of the client.

I also removed it from the browser build. We assume that only the Edge
or Node builds of the client are used
together with SSR. On the client this feature is not needed so we can
exclude the code. This might be a bit unnecessary because it's not that
much code and in theory you might use SSR in a Service Worker or
something where the Browser build would be used but currently we assume
that build is only for the client. That's why it also don't take an
option for reverse
look up of file names.
  • Loading branch information
sebmarkbage authored Jun 28, 2023
1 parent 5945e06 commit 2153a29
Show file tree
Hide file tree
Showing 14 changed files with 36 additions and 11 deletions.
7 changes: 5 additions & 2 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
readPartialStringChunk,
readFinalStringChunk,
createStringDecoder,
usedWithSSR,
} from './ReactFlightClientConfig';

import {
Expand Down Expand Up @@ -529,8 +530,10 @@ function createServerReferenceProxy<A: Iterable<any>, T>(
});
};
// Expose encoder for use by SSR.
// TODO: Only expose this in SSR builds and not the browser client.
proxy.$$FORM_ACTION = encodeFormAction;
if (usedWithSSR) {
// Only expose this in builds that would actually use it. Not needed on the client.
(proxy: any).$$FORM_ACTION = encodeFormAction;
}
knownServerReferences.set(proxy, metaData);
return proxy;
}
Expand Down
8 changes: 6 additions & 2 deletions packages/react-client/src/ReactFlightReplyClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import type {
RejectedThenable,
} from '../../shared/ReactTypes';

import {usedWithSSR} from './ReactFlightClientConfig';

type ReactJSONValue =
| string
| boolean
Expand Down Expand Up @@ -496,8 +498,10 @@ export function createServerReference<A: Iterable<any>, T>(
return callServer(id, args);
};
// Expose encoder for use by SSR.
// TODO: Only expose this in SSR builds and not the browser client.
proxy.$$FORM_ACTION = encodeFormAction;
if (usedWithSSR) {
// Only expose this in builds that would actually use it. Not needed on the client.
(proxy: any).$$FORM_ACTION = encodeFormAction;
}
knownServerReferences.set(proxy, {id: id, bound: null});
return proxy;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const resolveServerReference = $$$config.resolveServerReference;
export const preloadModule = $$$config.preloadModule;
export const requireModule = $$$config.requireModule;
export const dispatchHint = $$$config.dispatchHint;
export const usedWithSSR = true;

export opaque type Source = mixed;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export * from 'react-client/src/ReactFlightClientConfigBrowser';
export * from 'react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = false;
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export const resolveClientReference: any = null;
export const resolveServerReference: any = null;
export const preloadModule: any = null;
export const requireModule: any = null;
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export * from 'react-client/src/ReactFlightClientConfigBrowser';
export * from 'react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export * from 'react-client/src/ReactFlightClientConfigBrowser';
export * from 'react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
export * from 'react-client/src/ReactFlightClientConfigBrowser';
export * from 'react-server-dom-esm/src/ReactFlightClientConfigESMBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export * from 'react-client/src/ReactFlightClientConfigNode';
export * from 'react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
export * from 'react-client/src/ReactFlightClientConfigNode';
export * from 'react-server-dom-webpack/src/ReactFlightClientConfigNodeBundler';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
close,
} from 'react-client/src/ReactFlightClient';

import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';

function noServerCall() {
throw new Error(
'Server Functions cannot be called during initial render. ' +
Expand All @@ -33,7 +35,7 @@ export function createServerReference<A: Iterable<any>, T>(
id: any,
callServer: any,
): (...A) => Promise<T> {
return noServerCall;
return createServerReferenceImpl(id, noServerCall);
}

function createFromNodeStream<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
close,
} from 'react-client/src/ReactFlightClient';

import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';

function noServerCall() {
throw new Error(
'Server Functions cannot be called during initial render. ' +
Expand All @@ -33,7 +35,7 @@ export function createServerReference<A: Iterable<any>, T>(
id: any,
callServer: any,
): (...A) => Promise<T> {
return noServerCall;
return createServerReferenceImpl(id, noServerCall);
}

export type Options = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
close,
} from 'react-client/src/ReactFlightClient';

import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';

function noServerCall() {
throw new Error(
'Server Functions cannot be called during initial render. ' +
Expand All @@ -35,7 +37,7 @@ export function createServerReference<A: Iterable<any>, T>(
id: any,
callServer: any,
): (...A) => Promise<T> {
return noServerCall;
return createServerReferenceImpl(id, noServerCall);
}

function createFromNodeStream<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ global.ReadableStream =
global.TextEncoder = require('util').TextEncoder;
global.TextDecoder = require('util').TextDecoder;

// Don't wait before processing work on the server.
// TODO: we can replace this with FlightServer.act().
global.setTimeout = cb => cb();

let container;
let serverExports;
let webpackServerMap;
Expand All @@ -25,16 +29,16 @@ let ReactDOMServer;
let ReactServerDOMServer;
let ReactServerDOMClient;

describe('ReactFlightDOMReply', () => {
describe('ReactFlightDOMForm', () => {
beforeEach(() => {
jest.resetModules();
const WebpackMock = require('./utils/WebpackMock');
serverExports = WebpackMock.serverExports;
webpackServerMap = WebpackMock.webpackServerMap;
React = require('react');
ReactServerDOMServer = require('react-server-dom-webpack/server.browser');
ReactServerDOMClient = require('react-server-dom-webpack/client');
ReactDOMServer = require('react-dom/server.browser');
ReactServerDOMServer = require('react-server-dom-webpack/server.edge');
ReactServerDOMClient = require('react-server-dom-webpack/client.edge');
ReactDOMServer = require('react-dom/server.edge');
container = document.createElement('div');
document.body.appendChild(container);
});
Expand Down

0 comments on commit 2153a29

Please sign in to comment.