Skip to content

Commit a3b9535

Browse files
ihabadhamclaude
andcommitted
Tighten Pro webpack + initializer setup from reference audit
Four fixes from auditing Sub-PR 2 against the Pro dummy, the :pro generator, and the Pro configuration docs. - config/initializers/react_on_rails_pro.rb: renderer_password now raises in non-local envs instead of falling back to the dev string. Previously any production deploy that forgot to set the env var would silently run with a known-public password; now it fails loudly. Matches the safer pattern from PR #723's final state. - config/webpack/serverWebpackConfig.js: pass clientReferences to RSCWebpackPlugin({ isServer: true }), matching the Pro dummy's serverWebpackConfig at `react_on_rails_pro/spec/dummy/config/webpack/ serverWebpackConfig.js`. Without it, the plugin may walk into node_modules and hit unlodaed .tsx source files and re-scan modules we don't need. Locks client-ref discovery to client/app/**. - config/webpack/serverWebpackConfig.js: drop publicPath from the server-bundle output. Server bundles are loaded by the Node renderer via the filesystem, never served over HTTP — the URL is unused. Matches the Pro dummy's comment. - package.json: pin react-on-rails-rsc to 19.0.4 stable (was ^19.0.4 range) and add "node-renderer" npm script as a convenience shortcut for `node renderer/node-renderer.js`. - .github/workflows/rspec_test.yml: set RENDERER_PASSWORD explicitly in CI to the shared dev default so both the initializer and the launcher use the same concrete value, avoiding silent drift if either side's default is ever touched. Re-verified: webpack build clean; renderer + Rails boot; GET / returns HTTP 200 with "Node Renderer responded" in the Rails log and "[SERVER] RENDERED" in the renderer log, confirming SSR still goes through the Pro path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 758a2c7 commit a3b9535

5 files changed

Lines changed: 33 additions & 11 deletions

File tree

.github/workflows/rspec_test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
DRIVER: selenium_chrome
3434
CHROME_BIN: /usr/bin/google-chrome
3535
USE_COVERALLS: true
36+
# Must match config.renderer_password in config/initializers/react_on_rails_pro.rb.
37+
# Setting explicitly avoids silent drift if the two-sided defaults ever diverge.
38+
RENDERER_PASSWORD: local-dev-renderer-password
3639

3740
steps:
3841
- name: Install Chrome

config/initializers/react_on_rails_pro.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717
config.renderer_url = ENV.fetch("REACT_RENDERER_URL", "http://localhost:3800")
1818

1919
# Shared secret for renderer authentication. Must match renderer/node-renderer.js.
20-
# In production, set RENDERER_PASSWORD to a strong value via your secret store.
21-
# The shared dev default keeps the launcher and initializer in sync locally
22-
# so `bin/dev` just works.
23-
config.renderer_password = ENV.fetch("RENDERER_PASSWORD", "local-dev-renderer-password")
20+
# In dev and test, both sides default to the same value so `bin/dev` works
21+
# without setup. In production, RENDERER_PASSWORD must be set explicitly —
22+
# falling back to a known-public dev string in prod would auth-bypass the
23+
# renderer.
24+
config.renderer_password = if Rails.env.local?
25+
ENV.fetch("RENDERER_PASSWORD", "local-dev-renderer-password")
26+
else
27+
ENV.fetch("RENDERER_PASSWORD")
28+
end
2429
end

config/webpack/serverWebpackConfig.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,31 @@ const configureServer = (rscBundle = false) => {
8787
serverWebpackConfig.plugins.unshift(new bundler.optimize.LimitChunkCountPlugin({ maxChunks: 1 }));
8888

8989
if (!rscBundle) {
90-
serverWebpackConfig.plugins.push(new RSCWebpackPlugin({ isServer: true }));
90+
// Limit client-reference discovery to the app source directory. Without
91+
// `clientReferences`, the plugin may traverse into node_modules/ and hit
92+
// non-JS source files (e.g. .tsx that aren't configured for a loader),
93+
// and would re-scan nodes we don't care about. Matches the Pro dummy
94+
// pattern in react_on_rails_pro/spec/dummy/config/webpack/serverWebpackConfig.js.
95+
serverWebpackConfig.plugins.push(
96+
new RSCWebpackPlugin({
97+
isServer: true,
98+
clientReferences: [
99+
{ directory: path.resolve(__dirname, '../../client/app'), recursive: true, include: /\.(js|ts|jsx|tsx)$/ },
100+
],
101+
}),
102+
);
91103
}
92104

93105
// Custom output for the server-bundle.
94-
// libraryTarget: 'commonjs2' is required by the Pro Node renderer so it can
95-
// `require()` the evaluated bundle.
106+
// - libraryTarget: 'commonjs2' is required by the Pro Node renderer so it
107+
// can `require()` the evaluated bundle.
108+
// - No publicPath: the server bundle is loaded by the Node renderer via the
109+
// filesystem, never served over HTTP, so asset URLs would go unused.
96110
serverWebpackConfig.output = {
97111
filename: 'server-bundle.js',
98112
globalObject: 'this',
99113
libraryTarget: 'commonjs2',
100114
path: path.resolve(__dirname, '../../ssr-generated'),
101-
publicPath: config.publicPath,
102115
};
103116

104117
// Don't hash the server bundle b/c would conflict with the client manifest

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"test:client": "yarn jest",
3131
"build:test": "rm -rf public/packs-test && RAILS_ENV=test NODE_ENV=test bin/shakapacker",
3232
"build:dev": "rm -rf public/packs && RAILS_ENV=development NODE_ENV=development bin/shakapacker",
33-
"build:clean": "rm -rf public/packs || true"
33+
"build:clean": "rm -rf public/packs || true",
34+
"node-renderer": "node renderer/node-renderer.js"
3435
},
3536
"dependencies": {
3637
"@babel/cli": "^7.21.0",
@@ -82,7 +83,7 @@
8283
"react-intl": "^6.4.4",
8384
"react-on-rails-pro": "16.6.0",
8485
"react-on-rails-pro-node-renderer": "16.6.0",
85-
"react-on-rails-rsc": "^19.0.4",
86+
"react-on-rails-rsc": "19.0.4",
8687
"react-redux": "^8.1.0",
8788
"react-router": "^6.13.0",
8889
"react-router-dom": "^6.13.0",

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8796,7 +8796,7 @@ react-on-rails-pro@16.6.0:
87968796
dependencies:
87978797
react-on-rails "16.6.0"
87988798

8799-
react-on-rails-rsc@^19.0.4:
8799+
react-on-rails-rsc@19.0.4:
88008800
version "19.0.4"
88018801
resolved "https://registry.npmjs.org/react-on-rails-rsc/-/react-on-rails-rsc-19.0.4.tgz#a605fbaa82a0bece504de1ef0b8d5c6fae5d6be3"
88028802
integrity sha512-KtHYz0opcXJk+Zw5aabjNiaszzpTdFgs1YfSLIZJSzU5SpddUw7b08epkxeJq/TCpR60Q9vsjxX3Q3OWJ97tMg==

0 commit comments

Comments
 (0)