Skip to content

Commit 58fd819

Browse files
pass rsc path to RSC Client Root and move the config to RORP
1 parent 78aaa28 commit 58fd819

File tree

9 files changed

+101
-40
lines changed

9 files changed

+101
-40
lines changed

lib/react_on_rails/configuration.rb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ def self.configure
99
end
1010

1111
DEFAULT_GENERATED_ASSETS_DIR = File.join(%w[public webpack], Rails.env).freeze
12-
DEFAULT_RSC_RENDERING_URL = "rsc/".freeze
1312

1413
def self.configuration
1514
@configuration ||= Configuration.new(
@@ -43,9 +42,7 @@ def self.configuration
4342
make_generated_server_bundle_the_entrypoint: false,
4443
defer_generated_component_packs: true,
4544
# forces the loading of React components
46-
force_load: false,
47-
auto_load_server_components: true,
48-
rsc_rendering_url: DEFAULT_RSC_RENDERING_URL
45+
force_load: false
4946
)
5047
end
5148

@@ -61,7 +58,7 @@ class Configuration
6158
:same_bundle_for_client_and_server, :rendering_props_extension,
6259
:make_generated_server_bundle_the_entrypoint,
6360
:defer_generated_component_packs, :rsc_bundle_js_file,
64-
:force_load, :auto_load_server_components, :rsc_rendering_url
61+
:force_load
6562

6663
# rubocop:disable Metrics/AbcSize
6764
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
@@ -77,7 +74,7 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
7774
i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, i18n_yml_safe_load_options: nil,
7875
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
7976
components_subdirectory: nil, auto_load_bundle: nil, force_load: nil,
80-
rsc_bundle_js_file: nil, auto_load_server_components: nil, rsc_rendering_url: nil)
77+
rsc_bundle_js_file: nil)
8178
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
8279
self.generated_assets_dirs = generated_assets_dirs
8380
self.generated_assets_dir = generated_assets_dir
@@ -118,8 +115,6 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
118115
self.make_generated_server_bundle_the_entrypoint = make_generated_server_bundle_the_entrypoint
119116
self.defer_generated_component_packs = defer_generated_component_packs
120117
self.force_load = force_load
121-
self.auto_load_server_components = auto_load_server_components
122-
self.rsc_rendering_url = rsc_rendering_url
123118
end
124119
# rubocop:enable Metrics/AbcSize
125120

lib/react_on_rails/packs_generator.rb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,30 @@ def create_pack(file_path)
4646

4747
def first_js_statement_in_code(content)
4848
return "" if content.nil? || content.empty?
49-
49+
5050
start_index = 0
5151
content_length = content.length
52-
52+
5353
while start_index < content_length
5454
# Skip whitespace
55-
while start_index < content_length && content[start_index].match?(/\s/)
56-
start_index += 1
57-
end
58-
55+
start_index += 1 while start_index < content_length && content[start_index].match?(/\s/)
56+
5957
break if start_index >= content_length
60-
58+
6159
current_chars = content[start_index, 2]
62-
60+
6361
case current_chars
64-
when '//'
62+
when "//"
6563
# Single-line comment
6664
newline_index = content.index("\n", start_index)
6765
return "" if newline_index.nil?
66+
6867
start_index = newline_index + 1
69-
when '/*'
68+
when "/*"
7069
# Multi-line comment
71-
comment_end = content.index('*/', start_index)
70+
comment_end = content.index("*/", start_index)
7271
return "" if comment_end.nil?
72+
7373
start_index = comment_end + 2
7474
else
7575
# Found actual content
@@ -89,9 +89,21 @@ def is_client_entrypoint?(file_path)
8989

9090
def pack_file_contents(file_path)
9191
registered_component_name = component_name(file_path)
92-
register_as_server_component = ReactOnRails.configuration.auto_load_server_components && !is_client_entrypoint?(file_path)
93-
import_statement = register_as_server_component ? "" : "import #{registered_component_name} from '#{relative_component_path_from_generated_pack(file_path)}';"
94-
register_call = register_as_server_component ? "registerServerComponent(\"#{registered_component_name}\")" : "register({#{registered_component_name}})";
92+
load_server_components = ReactOnRails::Utils.react_on_rails_pro? && ReactOnRailsPro.configuration.enable_rsc_support
93+
94+
if load_server_components && !is_client_entrypoint?(file_path)
95+
import_statement = ""
96+
rsc_rendering_url_path = ReactOnRailsPro.configuration.rsc_rendering_url_path
97+
register_call = <<~REGISTER_CALL.strip
98+
registerServerComponent({
99+
rscRenderingUrlPath: "#{rsc_rendering_url_path}",
100+
}, "#{registered_component_name}")
101+
REGISTER_CALL
102+
else
103+
relative_component_path = relative_component_path_from_generated_pack(file_path)
104+
import_statement = "import #{registered_component_name} from '#{relative_component_path}';"
105+
register_call = "register({#{registered_component_name}})"
106+
end
95107

96108
<<~FILE_CONTENT
97109
import ReactOnRails from 'react-on-rails';

lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def reset_pool
1919
def reset_pool_if_server_bundle_was_modified
2020
return unless ReactOnRails.configuration.development_mode
2121

22+
# RSC (React Server Components) bundle changes are not monitored here since:
23+
# 1. RSC is only supported in the Pro version of React on Rails
24+
# 2. This RubyEmbeddedJavaScript pool is used exclusively in the non-Pro version
25+
# 3. This pool uses ExecJS for JavaScript evaluation which does not support RSC
2226
if ReactOnRails::Utils.server_bundle_path_is_http?
2327
return if @server_bundle_url == ReactOnRails::Utils.server_bundle_js_file_path
2428

lib/react_on_rails/test_helper/webpack_assets_status_checker.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def stale_generated_files(files)
5050
def all_compiled_assets
5151
@all_compiled_assets ||= begin
5252
webpack_generated_files = @webpack_generated_files.map do |bundle_name|
53-
if bundle_name == ReactOnRails.configuration.server_bundle_js_file
54-
ReactOnRails::Utils.server_bundle_js_file_path
53+
if bundle_name == ReactOnRails.configuration.react_client_manifest_file
54+
ReactOnRails::Utils.react_client_manifest_file_path
5555
else
5656
ReactOnRails::Utils.bundle_js_file_path(bundle_name)
5757
end

node_package/src/ComponentRegistry.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
type ReactComponentOrRenderFunction,
55
type RenderFunction,
66
type ItemRegistrationCallback,
7+
type RegisterServerComponentOptions,
78
} from './types';
89
import isRenderFunction from './isRenderFunction';
910
import CallbackRegistry from './CallbackRegistry';
@@ -49,12 +50,18 @@ export default {
4950
});
5051
},
5152

52-
registerServerComponent(...componentNames: string[]): void {
53+
registerServerComponent(options: RegisterServerComponentOptions, ...componentNames: string[]): void {
5354
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
5455
const RSCClientRoot = (require('./RSCClientRoot') as typeof import('./RSCClientRoot')).default;
5556

5657
const componentsWrappedInRSCClientRoot = componentNames.reduce(
57-
(acc, name) => ({ ...acc, [name]: () => React.createElement(RSCClientRoot, { componentName: name }) }),
58+
(acc, name) => ({
59+
...acc,
60+
[name]: () => React.createElement(RSCClientRoot, {
61+
componentName: name,
62+
rscRenderingUrlPath: options.rscRenderingUrlPath
63+
})
64+
}),
5865
{}
5966
);
6067
this.register(componentsWrappedInRSCClientRoot);

node_package/src/RSCClientRoot.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ const { use } = React;
99

1010
const renderCache: Record<string, Promise<React.ReactNode>> = {};
1111

12-
const fetchRSC = ({ componentName }: { componentName: string }) => {
12+
export type RSCClientRootProps = {
13+
componentName: string;
14+
rscRenderingUrlPath: string;
15+
}
16+
17+
const fetchRSC = ({ componentName, rscRenderingUrlPath }: RSCClientRootProps) => {
1318
if (!renderCache[componentName]) {
14-
renderCache[componentName] = RSDWClient.createFromFetch(fetch(`/rsc/${componentName}`)) as Promise<React.ReactNode>;
19+
renderCache[componentName] = RSDWClient.createFromFetch(fetch(`${rscRenderingUrlPath}/${componentName}`)) as Promise<React.ReactNode>;
1520
}
1621
return renderCache[componentName];
1722
}
1823

19-
const RSCClientRoot = ({ componentName }: { componentName: string }) => use(fetchRSC({ componentName }));
24+
const RSCClientRoot = ({
25+
componentName,
26+
rscRenderingUrlPath,
27+
}: RSCClientRootProps) => use(fetchRSC({ componentName, rscRenderingUrlPath }));
2028

2129
export default RSCClientRoot;

node_package/src/ReactOnRails.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {
1919
AuthenticityHeaders,
2020
Store,
2121
StoreGenerator,
22+
RegisterServerComponentOptions,
2223
} from './types';
2324
import reactHydrateOrRender from './reactHydrateOrRender';
2425

@@ -60,8 +61,8 @@ ctx.ReactOnRails = {
6061
* When it's rendered, a call will be made to the server to render it.
6162
* @param componentNames
6263
*/
63-
registerServerComponent(...componentNames: string[]): void {
64-
ComponentRegistry.registerServerComponent(...componentNames);
64+
registerServerComponent(options: RegisterServerComponentOptions, ...componentNames: string[]): void {
65+
ComponentRegistry.registerServerComponent(options, ...componentNames);
6566
},
6667

6768
registerStore(stores: { [id: string]: StoreGenerator }): void {

node_package/src/types/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export interface RegisteredComponent {
107107
isRenderer: boolean;
108108
}
109109

110+
export interface RegisterServerComponentOptions {
111+
rscRenderingUrlPath: string;
112+
}
113+
110114
export type ItemRegistrationCallback<T> = (component: T) => void;
111115

112116
interface Params {
@@ -156,7 +160,7 @@ export type RenderReturnType = void | Element | Component | Root;
156160

157161
export interface ReactOnRails {
158162
register(components: { [id: string]: ReactComponentOrRenderFunction }): void;
159-
registerServerComponent(...componentNames: string[]): void;
163+
registerServerComponent(options: RegisterServerComponentOptions, ...componentNames: string[]): void;
160164
/** @deprecated Use registerStoreGenerators instead */
161165
registerStore(stores: { [id: string]: StoreGenerator }): void;
162166
registerStoreGenerators(storeGenerators: { [id: string]: StoreGenerator }): void;

0 commit comments

Comments
 (0)