-
Notifications
You must be signed in to change notification settings - Fork 380
Update React on Rails to 16.1.1 and move SSR to private directory #656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughUpdates .gitignore to exclude SSR outputs and generated client files, adds a ReactOnRails configuration option for server bundle output path, and modifies the server webpack configuration to emit SSR bundles into a private ssr-generated directory. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Developer
participant WPK as Server Webpack Config
participant FS as File System (private)
participant ROR as ReactOnRails
rect rgb(230,245,255)
note over WPK: Updated output.path to "ssr-generated"
Dev->>WPK: Run server bundle build
WPK->>FS: Emit server bundle to /ssr-generated
end
FS-->>ROR: Provide bundle via server_bundle_output_path
ROR->>ROR: Load server bundle for SSR
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches and finishing touches✅ Passed checks (3 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 Quick Review App CommandsWelcome! Here are the commands you can use in this PR:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
config/webpack/serverWebpackConfig.js (1)
4-8
: Remove unused shakapacker import and hoistpath
merge
/config
fromshakapacker
are no longer used, and the inlinerequire('path')
later in the file triggersglobal-require
. Pullpath
to the top-level and drop the unused import to clear the lint errors.Apply this diff to satisfy ESLint:
-const { merge, config } = require('shakapacker'); +const path = require('path'); const commonWebpackConfig = require('./commonWebpackConfig'); const webpack = require('webpack');
🧹 Nitpick comments (1)
Procfile.dev-prod-assets (1)
6-8
: Consider documenting the service availability strategy.While the commented services provide flexibility, consider adding a brief comment explaining when to uncomment these services or referencing documentation for service dependencies.
# sidekiq: bundle exec sidekiq -C config/sidekiq.yml # redis: redis-server # mailcatcher: mailcatcher --foreground +# Uncomment services above based on your application's background job and email testing needs
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
Gemfile.lock
is excluded by!**/*.lock
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
📒 Files selected for processing (27)
.gitignore
(2 hunks)Gemfile
(1 hunks)Procfile.dev
(1 hunks)Procfile.dev-prod-assets
(1 hunks)Procfile.dev-static-assets
(1 hunks)app/controllers/hello_world_controller.rb
(1 hunks)app/javascript/packs/client-bundle.js
(1 hunks)app/javascript/packs/server-bundle.js
(1 hunks)app/javascript/packs/stimulus-bundle.js
(1 hunks)app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx
(1 hunks)app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css
(1 hunks)app/javascript/src/HelloWorld/ror_components/HelloWorld.server.jsx
(1 hunks)app/views/hello_world/index.html.erb
(1 hunks)app/views/layouts/hello_world.html.erb
(1 hunks)babel.config.js
(1 hunks)bin/dev
(2 hunks)config/initializers/react_on_rails.rb
(1 hunks)config/routes.rb
(1 hunks)config/shakapacker.yml
(2 hunks)config/webpack/clientWebpackConfig.js
(1 hunks)config/webpack/commonWebpackConfig.js
(1 hunks)config/webpack/development.js
(1 hunks)config/webpack/generateWebpackConfigs.js
(1 hunks)config/webpack/production.js
(1 hunks)config/webpack/serverWebpackConfig.js
(2 hunks)config/webpack/test.js
(1 hunks)package.json
(6 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
config/webpack/generateWebpackConfigs.js (3)
config/webpack/commonWebpackConfig.js (1)
require
(5-5)config/webpack/serverWebpackConfig.js (2)
require
(4-4)serverWebpackConfig
(14-14)config/webpack/clientWebpackConfig.js (1)
clientConfig
(7-7)
config/webpack/test.js (2)
config/webpack/development.js (2)
generateWebpackConfigs
(6-6)require
(4-4)config/webpack/production.js (1)
generateWebpackConfigs
(4-4)
config/webpack/commonWebpackConfig.js (2)
config/webpack/serverWebpackConfig.js (2)
require
(4-4)commonWebpackConfig
(5-5)config/webpack/clientWebpackConfig.js (1)
commonWebpackConfig
(4-4)
app/javascript/src/HelloWorld/ror_components/HelloWorld.server.jsx (1)
app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx (1)
HelloWorld
(4-19)
config/webpack/development.js (2)
config/webpack/generateWebpackConfigs.js (1)
clientWebpackConfig
(4-4)config/webpack/client.js (1)
ReactRefreshWebpackPlugin
(3-3)
config/webpack/production.js (2)
config/webpack/development.js (2)
generateWebpackConfigs
(6-6)require
(4-4)config/webpack/test.js (1)
generateWebpackConfigs
(4-4)
config/webpack/serverWebpackConfig.js (3)
config/webpack/commonWebpackConfig.js (1)
require
(5-5)config/webpack/generateWebpackConfigs.js (1)
serverWebpackConfig
(5-5)config/webpack/webpackConfig.js (1)
serverWebpackConfig
(5-5)
🪛 ESLint
config/webpack/generateWebpackConfigs.js
[error] 1-1: Delete ·
(prettier/prettier)
config/webpack/test.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 4-4: Insert ;
(prettier/prettier)
[error] 8-8: Insert ;
(prettier/prettier)
[error] 10-10: Insert ;
(prettier/prettier)
config/webpack/clientWebpackConfig.js
[error] 1-1: Delete ·
(prettier/prettier)
config/webpack/commonWebpackConfig.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 18-18: Insert ⏎
(prettier/prettier)
config/webpack/development.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 4-4: 'devServer' is assigned a value but never used.
(no-unused-vars)
[error] 4-4: 'inliningCss' is assigned a value but never used.
(no-unused-vars)
config/webpack/production.js
[error] 1-1: Delete ·
(prettier/prettier)
app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx
[error] 4-19: Function component is not a function declaration
(react/function-component-definition)
[error] 5-5: Must use destructuring props assignment
(react/destructuring-assignment)
[error] 5-5: 'name' is missing in props validation
(react/prop-types)
babel.config.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 5-5: Unexpected require().
(global-require)
[error] 5-5: Insert ;
(prettier/prettier)
[error] 6-6: Insert ;
(prettier/prettier)
[error] 7-7: Insert ;
(prettier/prettier)
[error] 16-16: Insert ,
(prettier/prettier)
[error] 17-17: Insert ,
(prettier/prettier)
[error] 18-18: Insert ,
(prettier/prettier)
[error] 24-24: Insert ⏎········
(prettier/prettier)
[error] 26-26: Insert ,
(prettier/prettier)
[error] 27-27: Insert ,
(prettier/prettier)
[error] 28-28: Insert ,
(prettier/prettier)
[error] 30-30: Insert ;
(prettier/prettier)
[error] 32-32: Insert ;
(prettier/prettier)
[error] 33-33: Replace ·]
with ];
(prettier/prettier)
[error] 35-35: Insert ;
(prettier/prettier)
[error] 36-36: Insert ;
(prettier/prettier)
config/webpack/serverWebpackConfig.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 4-4: 'merge' is assigned a value but never used.
(no-unused-vars)
[error] 4-4: 'config' is assigned a value but never used.
(no-unused-vars)
[error] 54-54: Unexpected require().
(global-require)
🪛 GitHub Actions: Rspec CI
app/javascript/packs/client-bundle.js
[error] 5-50: Module not found: Can't resolve '../bundles/comments/startup/App' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 6-68: Module not found: Can't resolve '../bundles/comments/startup/ClientRouterApp' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 7-105: Module not found: Can't resolve '../bundles/comments/components/SimpleCommentScreen/SimpleCommentScreen' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 8-80: Module not found: Can't resolve '../bundles/comments/store/routerCommentsStore' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 9-68: Module not found: Can't resolve '../bundles/comments/store/commentsStore' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 10-66: Module not found: Can't resolve '../bundles/comments/startup/NavigationBarApp' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 11-66: Module not found: Can't resolve '../bundles/comments/components/Footer/Footer' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 12-75: Module not found: Can't resolve '../bundles/comments/rescript/ReScriptShow.bs.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 13-38: Module not found: Can't resolve '../assets/styles/application' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
app/javascript/packs/server-bundle.js
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
app/javascript/packs/stimulus-bundle.js
[error] 6-41: Module not found: Can't resolve '../controllers' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 7-76: Module not found: Can't resolve '../bundles/comments/startup/NavigationBarApp' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
🪛 GitHub Actions: JS CI
app/javascript/packs/client-bundle.js
[error] 5-50: Module not found: Can't resolve '../bundles/comments/startup/App' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 6-68: Module not found: Can't resolve '../bundles/comments/startup/ClientRouterApp' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 7-105: Module not found: Can't resolve '../bundles/comments/components/SimpleCommentScreen/SimpleCommentScreen' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 8-80: Module not found: Can't resolve '../bundles/comments/store/routerCommentsStore' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 9-68: Module not found: Can't resolve '../bundles/comments/store/commentsStore' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 10-66: Module not found: Can't resolve ../bundles/comments/startup/NavigationBarApp in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 11-66: Module not found: Can't resolve '../bundles/comments/components/Footer/Footer' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 12-75: Module not found: Can't resolve '../bundles/comments/rescript/ReScriptShow.bs.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
[error] 13-38: Module not found: Can't resolve '../assets/styles/application' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
app/javascript/packs/server-bundle.js
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/app/javascript/packs'
🪛 RuboCop (1.80.2)
config/routes.rb
[convention] 4-4: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
(Style/StringLiterals)
[convention] 4-4: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
(Style/StringLiterals)
🪛 GitHub Actions: Lint CI
config/routes.rb
[error] 4-4: Rubocop: Style/StringLiterals offenses detected (autocorrectable). Prefer double-quoted strings in this file.
[error] 4-4: Rubocop: Style/StringLiterals offenses detected (autocorrectable). Prefer double-quoted strings in this file.
🔇 Additional comments (25)
Procfile.dev-static-assets (1)
1-2
: Procfile simplification LGTMRails server and shakapacker watcher split is clear and aligns with the new asset flow.
Procfile.dev (1)
3-5
: Dev HMR flow LGTMwebpack-dev-server gated by WEBPACK_SERVE and server-bundle watch separated. Matches the Babel/DevServer gating changes.
package.json (2)
19-32
: Generate ReactOnRails packs before webpack builds
Addbundle exec rake react_on_rails:generate_packs
to your build scripts and clean the newapp/assets/builds
directory. Unblocks CI module resolution for generated files.Apply this diff:
- "build:test": "rm -rf public/packs-test && RAILS_ENV=test NODE_ENV=test bin/shakapacker", - "build:dev": "rm -rf public/packs && RAILS_ENV=development NODE_ENV=development bin/shakapacker", - "build:clean": "rm -rf public/packs || true" + "build:test": "bundle exec rake react_on_rails:generate_packs && rm -rf public/packs-test app/assets/builds && RAILS_ENV=test NODE_ENV=test bin/shakapacker", + "build:dev": "bundle exec rake react_on_rails:generate_packs && rm -rf public/packs app/assets/builds && RAILS_ENV=development NODE_ENV=development bin/shakapacker", + "build:clean": "rm -rf public/packs public/packs-test app/assets/builds || true"Verify the rake task exists locally:
bundle exec rake -T | grep react_on_rails:generate_packs
96-99
: Version bumps look compatible webpack@5 matches ^5.0.0; react-refresh@^0.17.0 matches ≥0.10.0 <1.0.0; @pmmmwh/react-refresh-webpack-plugin@^0.6.1 compatible.Procfile.dev-prod-assets (2)
1-3
: LGTM: Clear documentation added.The header comments clearly explain the purpose of this Procfile variant, helping distinguish it from other development configurations.
5-5
: LGTM: Rails server configuration is correct.The Rails server command uses the appropriate bundle exec prefix and port configuration for this development environment.
bin/dev (3)
21-22
: LGTM: Simplified dependency management.The direct bundler/setup and react_on_rails/dev requires are cleaner than the previous rescue/fallback approach.
24-27
: LGTM: Default route configuration is well-documented.The constant is clearly documented with guidance on customization, and the default aligns with the HelloWorld example being added in this PR.
30-34
: LGTM: Default argument handling is robust.The logic correctly adds the default route only when no --route option is already provided, preserving user preferences while providing sensible defaults.
config/shakapacker.yml (5)
14-14
: LGTM: Nested entries enabled for component organization.This allows for better organization of React components in subdirectories within the source entry path.
27-27
: LGTM: Precompilation enabled for production readiness.Setting
shakapacker_precompile: true
is the correct configuration for deployment scenarios.
70-71
: LGTM: Development optimizations configured correctly.
compile: true
andcompiler_strategy: mtime
are appropriate for development environments where fast rebuilds are prioritized.
83-91
: LGTM: HMR configuration is well-documented.The detailed comments explain the trade-offs between HMR with inline CSS vs. using mini-css-extract-plugin, helping developers make informed decisions.
118-119
: LGTM: Test isolation with separate output directory.Using
packs-test
for test compilation isolates test assets from development/production assets, preventing conflicts.config/initializers/react_on_rails.rb (4)
44-44
: LGTM: Server bundle configuration aligns with private directory move.The server bundle filename matches the webpack output and the private directory structure mentioned in the PR objectives.
46-48
: LGTM: Server bundle output path configured for private directory.The
ssr-generated
path configuration supports the move to private directories as described in the PR objectives.
50-53
: LGTM: Private server bundles enforcement improves security.Enabling
enforce_private_server_bundles
prevents server-side code exposure, which is a significant security improvement mentioned in the PR benefits.
59-66
: LGTM: Component registry configuration supports the new structure.The
components_subdirectory
set to "ror_components" andauto_load_bundle: true
aligns with the HelloWorld component structure seen in other files.app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css (1)
1-4
: LGTM: Simple and functional styling.The CSS module provides clean styling for the HelloWorld component. The green color and bold weight create good visual emphasis for the demo component.
app/views/hello_world/index.html.erb (1)
1-2
: LGTM: Proper React component integration with SSR.The view correctly integrates the HelloWorld React component with server-side rendering enabled (
prerender: true
) and passes props from the controller. This demonstrates the React on Rails SSR capabilities that were moved to the private directory.app/views/layouts/hello_world.html.erb (2)
1-15
: LGTM: Clean layout structure for React integration.The layout provides a minimal, clean HTML structure appropriate for React component rendering with proper CSRF protection and pack tag integration.
7-9
: Verify emptystylesheet_pack_tag
/javascript_pack_tag
placeholders
In app/views/layouts/hello_world.html.erb (lines 8–9), these default to anapplication
pack, but there’s no application.js/css in public/packs or app/assets/builds. Ensure React on Rails injection still loads the correct assets or update to reference explicit pack names.Gemfile (1)
8-8
: Verify React on Rails 16.1.1 upstream changelog
Couldn’t locate any 16.1.1 release notes in this repo; confirm there are no breaking changes in the official changelog before merging.app/javascript/src/HelloWorld/ror_components/HelloWorld.server.jsx (1)
1-5
: Server-side re-export keeps SSR parityThe server bundle delegating to the client component keeps both render paths aligned. No issues spotted here.
app/controllers/hello_world_controller.rb (1)
3-8
: Controller setup aligns with new SSR layoutThe controller correctly selects the
hello_world
layout and exposes the props expected by the view. Looks good.
.gitignore
Outdated
**/generated/** | ||
ssr-generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'generated' ignore pattern can break builds
Ignoring /generated/ hides app/javascript/generated/server-bundle-generated.js that server-bundle.js imports. Ensure CI generates this file before webpack runs or narrow the ignore pattern.
Options:
- Keep ignore and run generator in build scripts (recommended).
- Narrow ignore to only private SSR output under app/assets/builds (do not ignore app/javascript/generated).
Would you like a PR-ready update to CI/scripts?
🤖 Prompt for AI Agents
In .gitignore around lines 58-59, the blanket "**/generated/**" ignore will
exclude app/javascript/generated/server-bundle-generated.js which breaks webpack
imports; either (A) keep the ignore but ensure CI/build scripts run the
generator step before webpack/bundling (add generator command to CI job and
local build scripts), or (B) narrow the gitignore to only private SSR output
(e.g. ignore app/assets/builds/**/generated/** or the specific SSR output
directory) while removing or excluding app/javascript/generated from the ignore
so server-bundle-generated.js is tracked; update CI scripts if choosing (A) and
update .gitignore if choosing (B).
// import statement added by react_on_rails:generate_packs rake task | ||
import "./../generated/server-bundle-generated.js" | ||
// Placeholder comment - auto-generated imports will be prepended here by react_on_rails:generate_packs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Verification inconclusive
Resolve missing generated import causing build failure
Webpack can’t resolve ../generated/server-bundle-generated.js (ignored by .gitignore and not generated in CI). Guard the import at build-time and add a CI generation step.
Apply this diff:
-// import statement added by react_on_rails:generate_packs rake task
-import "./../generated/server-bundle-generated.js"
-// Placeholder comment - auto-generated imports will be prepended here by react_on_rails:generate_packs
+// import added by react_on_rails:generate_packs rake task (guarded so CI doesn't fail if not generated)
+/* eslint-disable no-eval, global-require, import/no-dynamic-require */
+try {
+ // Using eval(require) so webpack won't statically require a file that may not exist in CI
+ eval("require('../generated/server-bundle-generated.js')");
+} catch (e) {
+ if (process.env.NODE_ENV !== "production") {
+ // eslint-disable-next-line no-console
+ console.warn("server-bundle-generated.js not found; ensure react_on_rails:generate_packs ran.");
+ }
+}
+/* eslint-enable no-eval, global-require, import/no-dynamic-require */
+// Placeholder comment - auto-generated imports will be prepended here by react_on_rails:generate_packs
Run to verify file presence during CI:
🏁 Script executed:
#!/bin/bash
# Check whether the generated file exists and where
fd -H -a --glob "server-bundle-generated.js" | sed 's/^/FOUND: /'
Length of output: 0
Guard generated import & run generation in CI
Webpack can’t resolve ../generated/server-bundle-generated.js (missing in CI). Wrap the import in a try/catch (e.g. eval(require())) so builds don’t break, and add a CI step to run react_on_rails:generate_packs before the webpack build.
🤖 Prompt for AI Agents
In app/javascript/packs/server-bundle.js around lines 1 to 3, the static import
of "./../generated/server-bundle-generated.js" breaks builds when that generated
file is missing (eg. in CI); change the import to a guarded dynamic require
executed inside a try/catch (for example using eval('require') or similar to
avoid static resolution) so missing file won’t fail the webpack build, and add a
CI pipeline step that runs the react_on_rails:generate_packs rake task before
the webpack build to ensure the generated file exists.
config/webpack/development.js
Outdated
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js | ||
|
||
process.env.NODE_ENV = process.env.NODE_ENV || 'development'; | ||
// The source code including full typescript support is available at: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the Prettier lint failure.
Line 1 still has a trailing space, which Prettier flags as an error. Please remove it so linting succeeds. Based on static analysis.
Apply this diff:
-// The source code including full typescript support is available at:
+// The source code including full typescript support is available at:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// The source code including full typescript support is available at: | |
// The source code including full typescript support is available at: |
🧰 Tools
🪛 ESLint
[error] 1-1: Delete ·
(prettier/prettier)
🤖 Prompt for AI Agents
In config/webpack/development.js around line 1, the first line contains a
trailing space causing a Prettier lint failure; remove the trailing space at the
end of that line (ensure the line ends immediately after the colon) and save the
file so the file has no trailing whitespace on line 1, then re-run linting to
verify the Prettier error is resolved.
@@ -0,0 +1,37 @@ | |||
// The source code including full typescript support is available at: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trim trailing whitespace to satisfy Prettier.
ESLint/Prettier are flagging Line 1 because of the trailing space at the end of the comment. Drop that space so the lint step passes. Based on static analysis.
Apply this diff:
-// The source code including full typescript support is available at:
+// The source code including full typescript support is available at:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// The source code including full typescript support is available at: | |
// The source code including full typescript support is available at: |
🧰 Tools
🪛 ESLint
[error] 1-1: Delete ·
(prettier/prettier)
🤖 Prompt for AI Agents
In config/webpack/generateWebpackConfigs.js around line 1, the first-line
comment contains a trailing space causing Prettier/ESLint to fail; remove the
trailing whitespace at the end of that comment so the file has no extra space on
line 1 and re-run linting to confirm the fix.
config/webpack/production.js
Outdated
// The source code including full typescript support is available at: | ||
// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prettier error: strip trailing whitespace in header
Prettier flags the trailing space at the end of this comment line, causing the lint step to fail. Please trim it.
You can fix it with:
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js
+// The source code including full TypeScript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// The source code including full typescript support is available at: | |
// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js | |
// The source code including full TypeScript support is available at: | |
// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js |
🧰 Tools
🪛 ESLint
[error] 1-1: Delete ·
(prettier/prettier)
🤖 Prompt for AI Agents
In config/webpack/production.js around lines 1 to 2, there is a trailing
whitespace at the end of the first comment line which Prettier flags; remove the
extra space at the end of that comment line (trim trailing whitespace) so the
header comment ends with no trailing space and re-run lint/Prettier to confirm
the issue is resolved.
config/webpack/test.js
Outdated
const generateWebpackConfigs = require('./generateWebpackConfigs') | ||
|
||
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => { | ||
// place any code here that is for test only | ||
}; | ||
} | ||
|
||
module.exports = webpackConfig(testOnly); | ||
module.exports = generateWebpackConfigs(testOnly) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore Prettier-approved formatting
Prettier is currently flagging this file (missing semicolons and closing punctuation), so yarn lint
/ yarn prettier
will fail. Please re-run the formatter or patch the semicolons manually.
Apply this diff to fix the formatting:
-const generateWebpackConfigs = require('./generateWebpackConfigs')
+const generateWebpackConfigs = require('./generateWebpackConfigs');
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
// place any code here that is for test only
-}
+};
-module.exports = generateWebpackConfigs(testOnly)
+module.exports = generateWebpackConfigs(testOnly);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const generateWebpackConfigs = require('./generateWebpackConfigs') | |
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => { | |
// place any code here that is for test only | |
}; | |
} | |
module.exports = webpackConfig(testOnly); | |
module.exports = generateWebpackConfigs(testOnly) | |
const generateWebpackConfigs = require('./generateWebpackConfigs'); | |
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => { | |
// place any code here that is for test only | |
}; | |
module.exports = generateWebpackConfigs(testOnly); |
🧰 Tools
🪛 ESLint
[error] 4-4: Insert ;
(prettier/prettier)
[error] 8-8: Insert ;
(prettier/prettier)
[error] 10-10: Insert ;
(prettier/prettier)
🤖 Prompt for AI Agents
In config/webpack/test.js around lines 4 to 10 the file is missing
Prettier-approved punctuation (missing semicolons and final punctuation) which
causes lint/format failures; fix by adding the missing semicolons and proper
punctuation (e.g., terminate const declarations and function definition with
semicolons where appropriate), or simply run the project's Prettier formatter
(yarn prettier --write config/webpack/test.js) to apply the standard formatting,
then re-run lint to verify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR upgrades React on Rails from a release candidate version to the stable 16.1.1 release and implements security improvements by moving server-side rendering bundles to a private directory structure following React on Rails 16 best practices.
- Updated React on Rails from 16.0.1.rc.4 to stable 16.1.1 release along with related dependencies
- Migrated SSR bundle output to private ssr-generated directory instead of public packs
- Refactored webpack configuration architecture with new generateWebpackConfigs pattern
Reviewed Changes
Copilot reviewed 25 out of 29 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
package.json | Updates React on Rails npm package and related dependencies to latest versions |
Gemfile | Updates React on Rails Ruby gem to stable 16.1.1 release |
config/webpack/*.js | Refactors webpack configuration with new architecture and private SSR bundle paths |
config/initializers/react_on_rails.rb | Configures private server bundle location and enhanced security settings |
config/shakapacker.yml | Updates configuration with new defaults and improved development settings |
babel.config.js | Improves React Refresh configuration for better HMR compatibility |
app/javascript/* | Adds new Hello World React component with SSR support |
app/controllers/hello_world_controller.rb | New controller for Hello World demo page |
Procfile.* | Simplifies development process commands |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
// libraryTarget: 'commonjs2', | ||
path: config.outputPath, | ||
publicPath: config.publicPath, | ||
path: require('path').resolve(__dirname, '../../ssr-generated'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard-coded path construction using relative paths can be fragile. Consider using Rails.root or a configurable constant to make this more maintainable and consistent with the Rails application structure.
path: require('path').resolve(__dirname, '../../ssr-generated'), | |
// Use environment variable for output path, fallback to default if not set | |
path: process.env.SSR_GENERATED_PATH || require('path').resolve(__dirname, '../../ssr-generated'), |
Copilot uses AI. Check for mistakes.
config.raise_on_prerender_error = !Rails.env.production? | ||
# Configure where server bundles are output. Defaults to "ssr-generated". | ||
# This should match your webpack configuration for server bundles. | ||
config.server_bundle_output_path = "ssr-generated" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hard-coded directory name 'ssr-generated' should be defined as a constant or configuration variable to maintain consistency with the webpack configuration and make it easier to change in the future.
Copilot uses AI. Check for mistakes.
Code Review for PR #656: Update React on Rails to 16.1.1 and move SSR to private directoryThank you for this PR! I've reviewed the changes and here's my feedback: ✅ Strengths
🔍 Areas for Consideration
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 14
🧹 Nitpick comments (5)
config/shakapacker.yml (3)
39-44
: Loader choice: Babel is fine; consider SWC/Esbuild later for build speedNo blocker—Babel keeps compatibility. Optionally evaluate swc/esbuild once the upgrade stabilizes to reduce CI and dev build times.
58-66
: Consider enabling SRI in production onlyKeep disabled by default, but turn on integrity for prod to harden CDN-delivered assets.
Apply this diff:
production: <<: *default @@ # Cache manifest.json for performance cache_manifest: true + # Enable Subresource Integrity for production assets + integrity: + enabled: true + hash_functions: ["sha384"] + cross_origin: "anonymous"
103-107
: allowed_hosts: 'auto' is safe for localhost; update if using tunnels/codespacesIf you use ngrok/GitHub Codespaces, set allowed_hosts to include those domains or use 'all' for dev-only convenience.
client/app/bundles/comments/rescript/ReScriptShow.bs.js (2)
62-67
: Harden subscription cleanup.Guard against missing
unsubscribe
to avoid runtime errors if the subscription creation ever fails or changes.React.useEffect((function () { - var scription = subscribeToCommentsChannel(); + var scription = subscribeToCommentsChannel(); return (function () { - scription.unsubscribe(); + if (scription && typeof scription.unsubscribe === "function") { + scription.unsubscribe(); + } }); }), []);
35-45
: Catch thrown fetch errors to dispatch SetFetchError.If
Actions.Fetch.fetchComments()
throws (network error), the rejection isn’t handled; dispatch the error state in a catch.var fetchData = async function () { - var comments = await Actions.Fetch.fetchComments(); - if (comments.TAG === "Ok") { - return dispatch({ - TAG: "SetComments", - _0: comments._0 - }); - } else { - return dispatch("SetFetchError"); - } + try { + var comments = await Actions.Fetch.fetchComments(); + if (comments.TAG === "Ok") { + return dispatch({ TAG: "SetComments", _0: comments._0 }); + } else { + return dispatch("SetFetchError"); + } + } catch (_) { + return dispatch("SetFetchError"); + } }; ... React.useEffect((function () { - fetchData(); + fetchData(); }), []);Also applies to: 68-70
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
client/app/bundles/comments/components/CommentBox/CommentBox.jsx
(1 hunks)client/app/bundles/comments/components/SimpleCommentScreen/SimpleCommentScreen.jsx
(1 hunks)client/app/bundles/comments/rescript/Actions/Actions.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentForm/CommentForm.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentForm/forms/HorizontalForm.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentForm/forms/InlineForm.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentForm/forms/StackedForm.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentList/AlertError/AlertError.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentList/Comment/Comment.bs.js
(1 hunks)client/app/bundles/comments/rescript/CommentList/CommentList.bs.js
(1 hunks)client/app/bundles/comments/rescript/Header/Header.bs.js
(1 hunks)client/app/bundles/comments/rescript/ReScriptShow.bs.js
(1 hunks)client/app/bundles/comments/rescript/bindings/ActionCable.bs.js
(1 hunks)client/app/bundles/comments/rescript/bindings/Axios.bs.js
(1 hunks)client/app/bundles/comments/rescript/bindings/Marked.bs.js
(1 hunks)client/app/bundles/comments/rescript/bindings/ReactTransitionGroup.bs.js
(1 hunks)client/app/libs/i18n/default.js
(1 hunks)client/app/libs/i18n/translations.js
(1 hunks)client/app/packs/server-bundle.js
(1 hunks)config/initializers/react_on_rails.rb
(1 hunks)config/shakapacker.yml
(2 hunks)config/webpack/alias.js
(1 hunks)config/webpack/commonWebpackConfig.js
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- client/app/bundles/comments/rescript/bindings/Marked.bs.js
- client/app/bundles/comments/rescript/bindings/Axios.bs.js
🧰 Additional context used
🧬 Code graph analysis (6)
config/webpack/commonWebpackConfig.js (3)
config/webpack/alias.js (1)
require
(1-1)config/webpack/serverWebpackConfig.js (2)
require
(4-4)commonWebpackConfig
(5-5)config/webpack/clientWebpackConfig.js (1)
commonWebpackConfig
(4-4)
client/app/bundles/comments/rescript/Actions/Actions.bs.js (1)
client/app/bundles/comments/actions/commentsActionCreators.js (1)
fetchComments
(51-59)
client/app/bundles/comments/rescript/CommentList/CommentList.bs.js (2)
client/app/bundles/comments/components/CommentBox/CommentList/CommentList.jsx (1)
CommentList
(17-87)client/app/bundles/comments/components/CommentBox/CommentList/CommentList.spec.jsx (1)
cssTransitionGroupClassNames
(9-14)
client/app/bundles/comments/rescript/CommentList/Comment/Comment.bs.js (1)
client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.jsx (1)
rawMarkup
(14-14)
client/app/bundles/comments/rescript/CommentList/AlertError/AlertError.bs.js (1)
client/app/bundles/comments/components/CommentBox/CommentList/CommentList.spec.jsx (1)
cssTransitionGroupClassNames
(9-14)
client/app/bundles/comments/rescript/ReScriptShow.bs.js (2)
client/app/bundles/comments/components/CommentBox/CommentList/CommentList.spec.jsx (1)
comments
(17-30)client/app/bundles/comments/components/CommentBox/CommentList/CommentList.jsx (1)
CommentList
(17-87)
🪛 GitHub Check: test (22.x, 3.3.4)
client/app/packs/server-bundle.js
[failure] 4-4:
'serverRegistration' is defined but never used
[failure] 2-2:
Unable to resolve path to module '../generated/server-bundle-generated.js'
🪛 GitHub Actions: JS CI
client/app/packs/server-bundle.js
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/client/app/packs' (tries various extensions).
client/app/bundles/comments/rescript/CommentList/CommentList.bs.js
[error] 8-32: Export 'default' (imported as 'ReScriptShowModuleScss') was not found in '../ReScriptShow.module.scss' (exports: elementEnter, elementEnterActive, elementLeave, elementLeaveActive).
client/app/bundles/comments/rescript/CommentList/AlertError/AlertError.bs.js
[error] 7-7: export 'default' (imported as 'ReScriptShowModuleScss') was not found in '../../ReScriptShow.module.scss' (possible exports: elementEnter, elementEnterActive, elementLeave, elementLeaveActive)
[error] 7-7: Error details: export 'default' not found in SCSS module; check ReScriptShow.module.scss exports.
🪛 GitHub Actions: Lint CI
client/app/packs/server-bundle.js
[error] 2-2: ESLint: Unable to resolve path to module '../generated/server-bundle-generated.js' (import/no-unresolved).
🪛 GitHub Actions: Rspec CI
client/app/packs/server-bundle.js
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/client/app/packs'
client/app/bundles/comments/rescript/CommentList/CommentList.bs.js
[error] 8-32: export 'default' (imported as 'ReScriptShowModuleScss') was not found in '../ReScriptShow.module.scss' (possible exports: elementEnter, elementEnterActive, elementLeave, elementLeaveActive)
client/app/bundles/comments/rescript/CommentList/AlertError/AlertError.bs.js
[error] 7-32: export 'default' (imported as 'ReScriptShowModuleScss') was not found in '../../ReScriptShow.module.scss' (possible exports: elementEnter, elementEnterActive, elementLeave, elementLeaveActive)
🪛 ESLint
config/webpack/commonWebpackConfig.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 6-6: path
import should occur before import of shakapacker
(import/order)
[error] 14-16: Replace ⏎······path.resolve(__dirname,·'../../client/app/assets/styles/app-variables.scss'),⏎····
with path.resolve(__dirname,·'../../client/app/assets/styles/app-variables.scss')
(prettier/prettier)
[error] 47-47: Insert ⏎
(prettier/prettier)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: claude-review
🔇 Additional comments (11)
config/webpack/commonWebpackConfig.js (1)
1-2
: Fix Prettier violations at file headerLine 1 still has the trailing space that Prettier flags, and the file is missing the newline at EOF, so the lint step keeps failing just like the earlier review noted. Please clean those up (e.g., run Prettier on the file).
-// The source code including full typescript support is available at: +// The source code including full typescript support is available at: @@ -module.exports = commonWebpackConfig; +module.exports = commonWebpackConfig;Also applies to: 47-47
config/shakapacker.yml (7)
5-15
: Confirm source_path and nested entry layout match the repo after SSR moveKeeping source_path: client/app with source_entry_path: packs and nested_entries: true is fine if the code actually lives there. Given prior churn between client/app and app/javascript, please reconfirm there are no stale imports or duplicate entry points.
Run to verify entries/imports:
#!/bin/bash # Show top-level entries and nested entries under client/app/packs fd -t f . client/app/packs -e js -e jsx -e ts -e tsx | sed -E 's#client/app/##' | head -50 # Look for lingering imports referencing app/javascript or client/app (mixed roots) rg -nP "from ['\"](app/javascript|client/app)/" -g '!**/node_modules/**' -C1
45-52
: Good defaults for freshness and hashingcompiler_strategy: digest (default) with useContentHash: false outside prod is sensible; production overrides later. No action.
127-129
: Prod hashing on—LGTMuseContentHash: true in production is correct for long-term caching.
68-94
: HMR + inline_css requirements satisfied: style-loader is installed and mini-css-extract-plugin (v2.9.4) is present.
22-24
: Manually confirm SSR bundles are excluded from public/packs
Repository doesn’t include built artifacts—verify no server bundle files are output topublic/packs
in any environment.
16-21
: Loader chain verified and dependencies present
All required loaders (style-loader and mini-css-extract-plugin) are installed and the HMR inline CSS configuration in config/shakapacker.yml aligns with their usage. No changes needed.
118-120
: No action needed forpacks-test
path
Verification shows no hardcoded/packs/
references in specs or CI workflows, Rails’ test environment already serves static files (includingpublic/packs-test
), and CI uses generic Bundler/Yarn caching. No updates required.client/app/bundles/comments/rescript/CommentList/Comment/Comment.bs.js (2)
18-35
: Verify TransitionGroup/CSSTransition usage and classNames.
- Ensure no outer CSSTransition wraps this component; double-wrapping with separate nodeRefs can break animations.
- Confirm
props.cssTransitionGroupClassNames
is always provided; otherwise class name hooks won’t apply and animations won’t run.
32-33
: Confirm timeout matches CSS animation duration.500ms should match the SCSS variable used by the transitions; please verify to avoid jitter.
client/app/bundles/comments/rescript/ReScriptShow.bs.js (1)
3-11
: Verify React version compatibility with jsx-runtime.This file imports
react/jsx-runtime
, which requires React 17+. Confirm the app’s React runtime version aligns post‑upgrade.
client/app/bundles/comments/components/CommentBox/CommentBox.jsx
Outdated
Show resolved
Hide resolved
client/app/bundles/comments/components/SimpleCommentScreen/SimpleCommentScreen.jsx
Outdated
Show resolved
Hide resolved
JsxRuntime.jsx("input", { | ||
"aria-label": "Submit comment", | ||
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | ||
type: "submit", | ||
value: "Post" | ||
}) | ||
], | ||
className: "flex flex-col gap-0 lg:gap-4 lg:flex-row" | ||
}) | ||
], | ||
"aria-label": "Comment submission form", | ||
className: "form-horizontal flex flex-col gap-4", | ||
disabled: props.disabled, | ||
onSubmit: props.handleSubmit | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabled state never reaches the controls
Setting disabled
on a <form>
is a no-op in HTML, so while the reducer sets savingStatus
to "Saving"
, the inputs and submit button stay interactive and users can resubmit repeatedly. Propagate props.disabled
to the actual controls (or wrap them in a disabled <fieldset>
) to enforce the lockout.
JsxRuntime.jsx("input", {
"aria-label": "Author name",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full",
id: "comment_author",
name: "comment_author",
placeholder: "Your Name",
type: "text",
value: props.author,
- onChange: props.handleAuthorChange
+ onChange: props.handleAuthorChange,
+ disabled: props.disabled
})
@@
JsxRuntime.jsx("input", {
"aria-label": "Comment text",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full",
id: "comment_text",
name: "comment_text",
placeholder: "Say something using markdown...",
type: "text",
value: props.text,
- onChange: props.handleTextChange
+ onChange: props.handleTextChange,
+ disabled: props.disabled
})
@@
JsxRuntime.jsx("input", {
"aria-label": "Submit comment",
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800",
type: "submit",
- value: "Post"
+ value: "Post",
+ disabled: props.disabled
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post" | |
}) | |
], | |
className: "flex flex-col gap-0 lg:gap-4 lg:flex-row" | |
}) | |
], | |
"aria-label": "Comment submission form", | |
className: "form-horizontal flex flex-col gap-4", | |
disabled: props.disabled, | |
onSubmit: props.handleSubmit | |
}); | |
// … earlier in the file, within your render: | |
JsxRuntime.jsx("input", { | |
"aria-label": "Author name", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full", | |
id: "comment_author", | |
name: "comment_author", | |
placeholder: "Your Name", | |
type: "text", | |
value: props.author, | |
onChange: props.handleAuthorChange, | |
disabled: props.disabled | |
}), | |
// … later, the comment text field | |
JsxRuntime.jsx("input", { | |
"aria-label": "Comment text", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full", | |
id: "comment_text", | |
name: "comment_text", | |
placeholder: "Say something using markdown...", | |
type: "text", | |
value: props.text, | |
onChange: props.handleTextChange, | |
disabled: props.disabled | |
}), | |
// … and finally the submit button | |
JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post", | |
disabled: props.disabled | |
}) | |
// … |
🤖 Prompt for AI Agents
In client/app/bundles/comments/rescript/CommentForm/forms/HorizontalForm.bs.js
around lines 55 to 69, the form element is receiving props.disabled but HTML
forms do not disable child controls; propagate the disabled state to the actual
controls (inputs and submit) or wrap the input controls in a <fieldset
disabled={props.disabled}> so the inputs and submit button become
non-interactive when props.disabled is true; update the JSX to either add
disabled: props.disabled to each input/textarea/button or introduce a fieldset
that takes the disabled prop and contains the existing controls, ensuring the
visual styles and aria-label remain unchanged.
JsxRuntime.jsx("div", { | ||
children: JsxRuntime.jsx("input", { | ||
"aria-label": "Submit comment", | ||
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | ||
type: "submit", | ||
value: "Post" | ||
}), | ||
className: "flex gap-2" | ||
}) | ||
], | ||
"aria-label": "Comment submission form", | ||
className: "form-inline flex flex-col lg:flex-row flex-wrap gap-4", | ||
disabled: props.disabled, | ||
onSubmit: props.handleSubmit | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propagate the disabled state to inputs
Same as the horizontal form: the disabled
prop never leaves the <form>
, so controls remain active during a save. Pass props.disabled
to the text inputs and the submit button to avoid duplicate submissions.
JsxRuntime.jsx("input", {
"aria-label": "Author name",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded",
id: "comment_author",
name: "comment_author",
placeholder: "Your Name",
type: "text",
value: props.author,
- onChange: props.handleAuthorChange
+ onChange: props.handleAuthorChange,
+ disabled: props.disabled
})
@@
JsxRuntime.jsx("input", {
"aria-label": "Comment text",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded",
id: "comment_text",
name: "comment_text",
placeholder: "Say something using markdown...",
type: "text",
value: props.text,
- onChange: props.handleTextChange
+ onChange: props.handleTextChange,
+ disabled: props.disabled
})
@@
children: JsxRuntime.jsx("input", {
"aria-label": "Submit comment",
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800",
type: "submit",
- value: "Post"
+ value: "Post",
+ disabled: props.disabled
}),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
JsxRuntime.jsx("div", { | |
children: JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post" | |
}), | |
className: "flex gap-2" | |
}) | |
], | |
"aria-label": "Comment submission form", | |
className: "form-inline flex flex-col lg:flex-row flex-wrap gap-4", | |
disabled: props.disabled, | |
onSubmit: props.handleSubmit | |
}); | |
// Updated InlineForm.bs.js – propagate `props.disabled` to each control | |
JsxRuntime.jsxs("form", { | |
children: [ | |
// Author name input | |
JsxRuntime.jsx("input", { | |
"aria-label": "Author name", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded", | |
id: "comment_author", | |
name: "comment_author", | |
placeholder: "Your Name", | |
type: "text", | |
value: props.author, | |
onChange: props.handleAuthorChange, | |
disabled: props.disabled | |
}), | |
// Comment text input | |
JsxRuntime.jsx("input", { | |
"aria-label": "Comment text", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded", | |
id: "comment_text", | |
name: "comment_text", | |
placeholder: "Say something using markdown...", | |
type: "text", | |
value: props.text, | |
onChange: props.handleTextChange, | |
disabled: props.disabled | |
}), | |
// Submit button | |
JsxRuntime.jsx("div", { | |
children: JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post", | |
disabled: props.disabled | |
}), | |
className: "flex gap-2" | |
}) | |
], | |
"aria-label": "Comment submission form", | |
className: "form-inline flex flex-col lg:flex-row flex-wrap gap-4", | |
disabled: props.disabled, | |
onSubmit: props.handleSubmit | |
}); |
🤖 Prompt for AI Agents
In client/app/bundles/comments/rescript/CommentForm/forms/InlineForm.bs.js
around lines 48-62, the form's props.disabled is only applied to the <form>
element and not passed down to the text input(s) and the submit button, allowing
controls to remain active during save; update the JSX nodes for the text
input(s) and the submit input to include disabled: props.disabled so the inputs
and the "Post" button become disabled during saving (also mirror for any
textarea or other interactive controls in this component).
JsxRuntime.jsx("div", { | ||
children: JsxRuntime.jsx("input", { | ||
"aria-label": "Submit comment", | ||
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | ||
type: "submit", | ||
value: "Post" | ||
}), | ||
className: "flex flex-col gap-0" | ||
}) | ||
], | ||
"aria-label": "Comment submission form", | ||
className: "flex flex-col gap-4", | ||
disabled: props.disabled, | ||
onSubmit: props.handleSubmit | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabled prop is dropped on the floor
Here too, the <form disabled>
attribute has no effect, so users can still interact with the fields while a save is in flight. Please wire props.disabled
into the two text inputs and the submit input (or wrap them in a disabled <fieldset>
).
JsxRuntime.jsx("input", {
"aria-label": "Author name",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full",
id: "comment_author",
name: "comment_author",
placeholder: "Your Name",
type: "text",
value: props.author,
- onChange: props.handleAuthorChange
+ onChange: props.handleAuthorChange,
+ disabled: props.disabled
})
@@
JsxRuntime.jsx("input", {
"aria-label": "Comment text",
"aria-required": true,
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full",
id: "comment_text",
name: "comment_text",
placeholder: "Say something using markdown...",
type: "text",
value: props.text,
- onChange: props.handleTextChange
+ onChange: props.handleTextChange,
+ disabled: props.disabled
})
@@
children: JsxRuntime.jsx("input", {
"aria-label": "Submit comment",
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800",
type: "submit",
- value: "Post"
+ value: "Post",
+ disabled: props.disabled
}),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
JsxRuntime.jsx("div", { | |
children: JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post" | |
}), | |
className: "flex flex-col gap-0" | |
}) | |
], | |
"aria-label": "Comment submission form", | |
className: "flex flex-col gap-4", | |
disabled: props.disabled, | |
onSubmit: props.handleSubmit | |
}); | |
/* Author name input */ | |
JsxRuntime.jsx("input", { | |
"aria-label": "Author name", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full", | |
id: "comment_author", | |
name: "comment_author", | |
placeholder: "Your Name", | |
type: "text", | |
value: props.author, | |
onChange: props.handleAuthorChange, | |
disabled: props.disabled | |
}), | |
/* Comment text input */ | |
JsxRuntime.jsx("input", { | |
"aria-label": "Comment text", | |
"aria-required": true, | |
className: "px-3 py-1 leading-4 border border-gray-300 rounded w-full", | |
id: "comment_text", | |
name: "comment_text", | |
placeholder: "Say something using markdown...", | |
type: "text", | |
value: props.text, | |
onChange: props.handleTextChange, | |
disabled: props.disabled | |
}), | |
/* Submit button wrapper */ | |
JsxRuntime.jsx("div", { | |
children: JsxRuntime.jsx("input", { | |
"aria-label": "Submit comment", | |
className: "self-start px-3 py-1 font-semibold border-0 rounded text-sky-50 bg-sky-600 hover:bg-sky-800", | |
type: "submit", | |
value: "Post", | |
disabled: props.disabled | |
}), | |
className: "flex flex-col gap-0" | |
}) | |
], | |
"aria-label": "Comment submission form", | |
className: "flex flex-col gap-4", | |
disabled: props.disabled, | |
onSubmit: props.handleSubmit | |
}); |
🤖 Prompt for AI Agents
In client/app/bundles/comments/rescript/CommentForm/forms/StackedForm.bs.js
around lines 50 to 64, the form's disabled state (props.disabled) isn't applied
to the inputs or submit button so users can still interact during save; update
the JSX so props.disabled is wired into the two text inputs and the submit input
by adding disabled: props.disabled to their props or alternatively wrap the
input elements in a <fieldset disabled={props.disabled}> so all child controls
become disabled while the form is submitting.
client/app/packs/server-bundle.js
Outdated
commentsStore, | ||
}); | ||
// import statement added by react_on_rails:generate_packs rake task | ||
import "./../generated/server-bundle-generated.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the generated bundle import path
The generated server bundle lives under client/app/packs/generated/
, but the ../
in the relative path points outside packs/
, so webpack can’t resolve it (see the broken CI job). Update the import to keep it inside the packs
directory.
-import "./../generated/server-bundle-generated.js"
+import "./generated/server-bundle-generated.js"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import "./../generated/server-bundle-generated.js" | |
// client/app/packs/server-bundle.js | |
import "./generated/server-bundle-generated.js" |
🧰 Tools
🪛 GitHub Check: test (22.x, 3.3.4)
[failure] 2-2:
Unable to resolve path to module '../generated/server-bundle-generated.js'
🪛 GitHub Actions: JS CI
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/client/app/packs' (tries various extensions).
🪛 GitHub Actions: Lint CI
[error] 2-2: ESLint: Unable to resolve path to module '../generated/server-bundle-generated.js' (import/no-unresolved).
🪛 GitHub Actions: Rspec CI
[error] 2-51: Module not found: Can't resolve './../generated/server-bundle-generated.js' in '/home/runner/work/react-webpack-rails-tutorial/react-webpack-rails-tutorial/client/app/packs'
🤖 Prompt for AI Agents
In client/app/packs/server-bundle.js around line 2, the import currently uses
"../generated/server-bundle-generated.js" which points outside the packs
directory and breaks webpack; update the import to reference the generated
bundle inside packs, e.g. change it to "./generated/server-bundle-generated.js"
so the path stays within client/app/packs and webpack can resolve the module.
client/app/packs/server-bundle.js
Outdated
// import statement added by react_on_rails:generate_packs rake task | ||
import "./../generated/server-bundle-generated.js" | ||
// Server bundle imports | ||
import serverRegistration from '../bundles/comments/startup/serverRegistration'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the unused default import
We only need the side effects from serverRegistration
, so importing it as a value leaves serverRegistration
unused and makes ESLint fail.
-import serverRegistration from '../bundles/comments/startup/serverRegistration';
+import '../bundles/comments/startup/serverRegistration';
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import serverRegistration from '../bundles/comments/startup/serverRegistration'; | |
import '../bundles/comments/startup/serverRegistration'; |
🧰 Tools
🪛 GitHub Check: test (22.x, 3.3.4)
[failure] 4-4:
'serverRegistration' is defined but never used
🤖 Prompt for AI Agents
In client/app/packs/server-bundle.js around line 4, the default import
`serverRegistration` is unused because only its side effects are needed; change
the import to a side-effect-only import by removing the identifier and importing
the module path directly (i.e. use an import that doesn't bind a name) so ESLint
no longer reports an unused variable and side effects still run.
config/shakapacker.yml
Outdated
# See https://github.com/shakacode/shakapacker#deployment | ||
shakapacker_precompile: true | ||
|
||
# Additional paths webpack should lookup modules | ||
# Location for manifest.json, defaults to {public_output_path}/manifest.json if unset | ||
# manifest_path: public/packs/manifest.json | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Precompile is enabled—ensure tasks cover both client packs and private SSR bundle
shakapacker_precompile: true covers client assets. With SSR bundle relocated to app/assets/builds, confirm the build step that emits the server bundle also runs on deploy and is not accidentally published to public/.
🏁 Script executed:
#!/bin/bash
# Verify server bundle path and absence under public/
fd -t f server-bundle .
fd -t f server-bundle public -E node_modules
fd -t f server-bundle app/assets/builds -E node_modules
# Check Procfile/CI for SSR build invocation
fd -t f 'Procfile*' .
rg -nP '(webpack|shakapacker|yarn|npm).*server' -C2
Length of output: 5427
Ensure SSR bundle builds on deploy
Add a step in your production Procfile or CI pipeline that invokes bin/shakapacker (with SERVER_BUNDLE_ONLY=yes) to emit the server bundle into ssr-generated and keep it out of public/.
🤖 Prompt for AI Agents
In config/shakapacker.yml around lines 26 to 31, there is no deployment step to
build the SSR/server bundle; add a step in your production Procfile or CI
pipeline that runs bin/shakapacker with SERVER_BUNDLE_ONLY=yes so the server
bundle is emitted into ssr-generated (not into public/) during deploy; ensure
the command runs after assets are installed, uses NODE_ENV=production, and that
shakapacker_precompile remains true so only the server bundle is produced and
placed in ssr-generated for SSR runtime.
config.module.rules.forEach((rule) => { | ||
if (rule.test && rule.test.toString().includes('scss|sass')) { | ||
if (rule.use) { | ||
rule.use.push(sassResourcesLoader); | ||
} | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the sass-loader detection logic
rule.test.toString().includes('scss|sass')
never matches the default Shakapacker regex (/\.s[ac]ss$/i
), so the new helper skips every Sass rule and the globals loader never runs. That regresses all styles relying on the injected variables/mixins. Please switch to a RegExp.test
check so both .scss
and .sass
rules are caught.
- if (rule.test && rule.test.toString().includes('scss|sass')) {
- if (rule.use) {
- rule.use.push(sassResourcesLoader);
- }
- }
+ const matchesSass =
+ rule.test instanceof RegExp &&
+ (rule.test.test('file.scss') || rule.test.test('file.sass'));
+ if (matchesSass && rule.use) {
+ rule.use.push(sassResourcesLoader);
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
config.module.rules.forEach((rule) => { | |
if (rule.test && rule.test.toString().includes('scss|sass')) { | |
if (rule.use) { | |
rule.use.push(sassResourcesLoader); | |
} | |
} | |
}); | |
config.module.rules.forEach((rule) => { | |
- if (rule.test && rule.test.toString().includes('scss|sass')) { | |
- if (rule.use) { | |
- rule.use.push(sassResourcesLoader); | |
- } | |
const matchesSass = | |
rule.test instanceof RegExp && | |
(rule.test.test('file.scss') || rule.test.test('file.sass')); | |
if (matchesSass && rule.use) { | |
rule.use.push(sassResourcesLoader); | |
} | |
}); |
🤖 Prompt for AI Agents
In config/webpack/commonWebpackConfig.js around lines 22-28, the detection using
rule.test.toString().includes('scss|sass') fails to match the default
Shakapacker regex; change the check to use a proper regular-expression test
(e.g. use /\.s[ac]ss$/i.test(rule.test.toString())) and ensure you only run it
when rule.test is present so Sass rules are correctly detected and
sassResourcesLoader is pushed onto rule.use.
Code Review for PR #656: Update React on Rails to 16.1.1 and move SSR to private directoryThank you for this PR updating React on Rails to the stable 16.1.1 release and implementing the security best practice of moving server bundles to a private directory. Here's my review: ✅ Strengths
🔍 Observations & Suggestions
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
app/javascript/packs/server-bundle.js (1)
1-2
: Use a bare import to keep the registration side effectWe only need
serverRegistration
for its side effect (the component/store registration). Importing it as a default and never referencing the symbol can triggerno-unused-vars
and risks future tree‑shaking removing the registration. Switching to a side-effect-only import keeps the intent explicit and lint-clean.-// Server bundle imports -import serverRegistration from 'bundles/comments/startup/serverRegistration'; +// Server bundle imports (execute registration side effects) +import 'bundles/comments/startup/serverRegistration';config/shakapacker.yml (1)
32-35
: Consider removing the legacyclient/app
dependency.With
source_path
now atapp/javascript
, keepingclient/app
inadditional_paths
prolongs the old layout and can hide straggler files. Once the remaining modules are migrated (or confirmed unused), please drop this path so resolution stays scoped to the new structure.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
app/javascript/packs/client-bundle.js
(1 hunks)app/javascript/packs/server-bundle.js
(1 hunks)app/javascript/packs/stimulus-bundle.js
(1 hunks)client/app/packs/client-bundle.js
(0 hunks)client/app/packs/server-bundle.js
(0 hunks)config/shakapacker.yml
(2 hunks)config/webpack/commonWebpackConfig.js
(1 hunks)package.json
(6 hunks)
💤 Files with no reviewable changes (2)
- client/app/packs/server-bundle.js
- client/app/packs/client-bundle.js
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🧬 Code graph analysis (1)
config/webpack/commonWebpackConfig.js (2)
config/webpack/serverWebpackConfig.js (2)
require
(4-4)commonWebpackConfig
(5-5)config/webpack/clientWebpackConfig.js (1)
commonWebpackConfig
(4-4)
🪛 ESLint
config/webpack/commonWebpackConfig.js
[error] 1-1: Delete ·
(prettier/prettier)
[error] 6-6: path
import should occur before import of shakapacker
(import/order)
[error] 14-16: Replace ⏎······path.resolve(__dirname,·'../../client/app/assets/styles/app-variables.scss'),⏎····
with path.resolve(__dirname,·'../../client/app/assets/styles/app-variables.scss')
(prettier/prettier)
[error] 44-44: Insert ⏎
(prettier/prettier)
🔇 Additional comments (3)
config/webpack/commonWebpackConfig.js (3)
5-6
: Reorder requires so ESLint import/order passesNode built-ins must precede external modules; keeping
path
aftershakapacker
makes the lint step fail.-const { generateWebpackConfig, merge } = require('shakapacker'); -const path = require('path'); +const path = require('path'); +const { generateWebpackConfig, merge } = require('shakapacker');
1-2
: Fix the remaining Prettier violationsThe trailing space in the header comment, the multiline single-element array, and the missing newline at EOF all trigger
prettier/prettier
. Cleaning these up (or rerunning Prettier) will unblock the lint job.-// The source code including full typescript support is available at: +// The source code including full TypeScript support is available at: @@ - resources: [ - path.resolve(__dirname, '../../client/app/assets/styles/app-variables.scss'), - ], + resources: [path.resolve(__dirname, '../../client/app/assets/styles/app-variables.scss')], @@ -module.exports = commonWebpackConfig; +module.exports = commonWebpackConfig; +Also applies to: 14-16, 44-44
23-28
: Restore Sass rule detection so globals loader runs
rule.test.toString().includes('scss|sass')
never matches Shakapacker’s default regex (/\.s[ac]ss$/i
), sosassResourcesLoader
is never appended and every Sass build loses the shared variables. This regresses all SCSS that expects those globals. Please switch to a real RegExp check so both.scss
and.sass
rules are picked up.- if (rule.test && rule.test.toString().includes('scss|sass')) { - if (rule.use) { - rule.use.push(sassResourcesLoader); - } - } + const matchesSass = + rule.test instanceof RegExp && + ['scss', 'sass'].some((ext) => new RegExp(rule.test).test(`file.${ext}`)); + if (matchesSass && rule.use) { + rule.use.push(sassResourcesLoader); + }
2c9192b
to
3e8226d
Compare
Code Review for PR #656: Update React on Rails to 16.1.1 and move SSR to private directoryThank you for this PR! I've thoroughly reviewed the changes for upgrading React on Rails to 16.1.1 and moving the SSR bundle to a private directory. Here's my feedback: ✅ Strengths
🔍 Issues & Suggestions
|
- Configure webpack to output server bundle to app/assets/builds/ - Update React on Rails config to load server bundle from private location - Add private directories to .gitignore to keep server bundles private This follows React on Rails best practices by keeping server-side rendering bundles in a private directory separate from public client assets for security.
3e8226d
to
68092cf
Compare
Code Review for PR #656✅ Overall AssessmentThis PR successfully upgrades React on Rails from a release candidate (16.0.1.rc.4) to the stable 16.1.1 version and improves the security architecture by moving SSR bundles to a private directory. The changes are well-structured and follow React on Rails 16 best practices. 🎯 Code Quality & Best PracticesExcellent:
🔒 Security ImprovementsStrong Points:
⚡ Performance ConsiderationsPositive:
|
Use the correct React on Rails 16+ config option 'server_bundle_output_path' instead of incorrect 'server_bundle_js_file_path'. The server_bundle_js_file should remain just the filename, not a full path.
Code Review for PR #656Thank you for upgrading React on Rails and improving the SSR bundle configuration! Here's my review: ✅ Strengths
🔍 Observations & Suggestions
|
Per code review, use the documented default value 'ssr-generated' for server_bundle_output_path instead of a custom path. This follows the React on Rails 16 conventions and matches the framework defaults.
Code Review: Move SSR to Private DirectoryThank you for this PR! I've reviewed the changes for moving the SSR bundle to a private directory. Here's my feedback: ✅ Strengths
🔍 Observations & Suggestions
|
/deploy-review-app |
✅ Deployment complete for PR #656, commit 7fcef62 |
Move the require('path') statement to the top of serverWebpackConfig.js with other require statements to follow proper code organization.
Code Review for PR #656Thank you for upgrading React on Rails and improving the SSR bundle configuration! Here's my review: ✅ Strengths
🔍 Code Quality Observations
|
✅ Deployment complete for PR #656, commit 71a8257 |
🚀 Deploying to Control Plane... ⏳ Waiting for deployment to be ready... |
✅ Review app for PR #656 was successfully deleted |
Code Review for PR #656✅ Overall AssessmentThis PR successfully upgrades React on Rails from a release candidate to a stable version and implements the recommended SSR bundle isolation pattern. The changes align well with React on Rails 16 best practices. 👍 Strengths
🔍 Areas for Attention1. Directory Creation & Documentation
2. Test Environment Configuration
3. Build Process Verification
💡 Suggestions
✅ Security & Performance
📝 Minor Notes
Verdict: Approved with suggestions ✅The changes are solid and follow best practices. Address the test adjustments mentioned in the PR description and consider the suggestions above for a smoother deployment experience. |
Summary
Upgrade React on Rails to stable 16.1.1 release and move server-side rendering bundle to a private directory following best practices.
Changes
1. Update React on Rails to 16.1.1
16.0.1.rc.4
to16.1.1
(stable release)2. Move SSR Bundle to Private Directory
app/assets/builds/
app/assets/builds/
to.gitignore
Benefits
Test Status
Migration Notes
The server bundle is now located in
app/assets/builds/
instead of being mixed with client assets inpublic/packs/
. This is the recommended approach for React on Rails 16.🤖 Generated with Claude Code
This change is
Summary by CodeRabbit
Chores
Refactor
Configuration