Skip to content

Commit bf50f57

Browse files
refactoring
1 parent 58cd6e7 commit bf50f57

File tree

4 files changed

+37
-31
lines changed

4 files changed

+37
-31
lines changed

lib/react_on_rails/configuration.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,13 @@ def configure_generated_assets_dirs_deprecation
305305
def ensure_webpack_generated_files_exists
306306
return unless webpack_generated_files.empty?
307307

308-
files = ["manifest.json"]
309-
files << server_bundle_js_file if server_bundle_js_file.present?
310-
files << rsc_bundle_js_file if rsc_bundle_js_file.present?
311-
files << react_client_manifest_file if react_client_manifest_file.present?
312-
files << react_server_client_manifest_file if react_server_client_manifest_file.present?
308+
self.webpack_generated_files = [
309+
"manifest.json",
310+
server_bundle_js_file,
311+
rsc_bundle_js_file,
312+
react_client_manifest_file,
313+
react_server_client_manifest_file
314+
].compact_blank
313315

314316
self.webpack_generated_files = files
315317
end

node_package/src/RSCClientRoot.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ import { createFromReadableStream } from 'react-on-rails-rsc/client';
66
import { fetch } from './utils.ts';
77
import transformRSCStreamAndReplayConsoleLogs from './transformRSCStreamAndReplayConsoleLogs.ts';
88
import { RailsContext, RenderFunction, RSCPayloadChunk } from './types/index.ts';
9+
import { ensureReactUseAvailable } from './reactApis.cts';
910

10-
const { use } = React;
11-
12-
if (typeof use !== 'function') {
13-
throw new Error('React.use is not defined. Please ensure you are using React 19 to use server components.');
14-
}
11+
ensureReactUseAvailable();
1512

1613
declare global {
1714
interface Window {
18-
REACT_ON_RAILS_RSC_PAYLOAD: RSCPayloadChunk[];
15+
REACT_ON_RAILS_RSC_PAYLOAD?: RSCPayloadChunk[];
1916
}
2017
}
2118

node_package/src/RSCServerRoot.tsx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import * as React from 'react';
22
import { createFromNodeStream } from 'react-on-rails-rsc/client.node';
33
import { PassThrough } from 'stream';
4-
import type { RenderFunction, RailsContext } from './types';
5-
import transformRSCStream from './transformRSCNodeStream';
6-
import loadJsonFile from './loadJsonFile';
7-
import RSCPayloadContainer from './RSCPayloadContainer';
4+
import type { RenderFunction, RailsContext } from './types/index.ts';
5+
import transformRSCStream from './transformRSCNodeStream.ts';
6+
import loadJsonFile from './loadJsonFile.ts';
7+
import RSCPayloadContainer from './RSCPayloadContainer.tsx';
8+
import { ensureReactUseAvailable } from './reactApis.cts';
9+
10+
ensureReactUseAvailable();
811

912
declare global {
1013
function generateRSCPayload(
@@ -19,12 +22,6 @@ type RSCServerRootProps = {
1922
componentProps: Record<string, unknown>;
2023
};
2124

22-
if (!('use' in React && typeof React.use === 'function')) {
23-
throw new Error(
24-
'React.use is not defined. Please ensure you are using React 18 with experimental features enabled or React 19+ to use server components.',
25-
);
26-
}
27-
2825
const { use } = React;
2926

3027
const createFromReactOnRailsNodeStream = (
@@ -40,24 +37,25 @@ const createSSRManifest = async (
4037
reactClientManifestFileName: string,
4138
) => {
4239
const [reactServerManifest, reactClientManifest] = await Promise.all([
43-
loadJsonFile(reactServerManifestFileName),
44-
loadJsonFile(reactClientManifestFileName),
40+
loadJsonFile(reactServerManifestFileName) as Promise<Record<string, { id: string; chunks: string[] }>>,
41+
loadJsonFile(reactClientManifestFileName) as Promise<Record<string, { id: string }>>,
4542
]);
4643

4744
const ssrManifest = {
48-
moduleLoading: {
49-
prefix: '/webpack/development/',
50-
crossOrigin: null,
51-
},
45+
// The `moduleLoading` property is utilized by the React runtime to load JavaScript modules.
46+
// It can accept options such as `prefix` and `crossOrigin` to specify the path and crossorigin attribute for the modules.
47+
// In our case, since the server code is bundled into a single bundle, there is no need to load additional JavaScript modules.
48+
// As a result, we set this property to an empty object because it will not be used.
49+
moduleLoading: {},
5250
moduleMap: {} as Record<string, unknown>,
5351
};
5452

5553
Object.entries(reactClientManifest).forEach(([aboluteFileUrl, clientFileBundlingInfo]) => {
56-
const serverFileBundlingInfo = reactServerManifest[aboluteFileUrl];
57-
ssrManifest.moduleMap[(clientFileBundlingInfo as { id: string }).id] = {
54+
const { id, chunks } = reactServerManifest[aboluteFileUrl];
55+
ssrManifest.moduleMap[clientFileBundlingInfo.id] = {
5856
'*': {
59-
id: (serverFileBundlingInfo as { id: string }).id,
60-
chunks: (serverFileBundlingInfo as { chunks: string[] }).chunks,
57+
id,
58+
chunks,
6159
name: '*',
6260
},
6361
};

node_package/src/reactApis.cts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable global-require,@typescript-eslint/no-require-imports */
2+
import * as React from 'react';
23
import * as ReactDOM from 'react-dom';
34
import type { ReactElement } from 'react';
45
import type { RenderReturnType } from './types/index.ts' with { 'resolution-mode': 'import' };
@@ -50,3 +51,11 @@ export const unmountComponentAtNode: typeof ReactDOM.unmountComponentAtNode = su
5051
? // not used if we use root API
5152
() => false
5253
: ReactDOM.unmountComponentAtNode;
54+
55+
export const ensureReactUseAvailable = () => {
56+
if (!('use' in React) || typeof React.use !== 'function') {
57+
throw new Error(
58+
'React.use is not defined. Please ensure you are using React 19 to use server components.',
59+
);
60+
}
61+
};

0 commit comments

Comments
 (0)