-
Notifications
You must be signed in to change notification settings - Fork 0
Install react_on_rails v16.1.1 and shakapacker 9.0.0.beta.3 #2
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
base: main
Are you sure you want to change the base?
Conversation
Warning Rate limit exceeded@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 16 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (35)
WalkthroughAdds React on Rails with Shakapacker: webpack/babel configs, npm manifest, bin scripts, Procfiles, ReactOnRails initializer, and a HelloWorld example (controller, route, views, React components with SSR). Also extends .gitignore and updates application layout to include the webpack pack. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant R as Rails Router
participant C as HelloWorldController
participant V as ERB View
participant RoR as ReactOnRails
participant SSR as Server Renderer (server-bundle.js)
participant B as Browser (application pack)
U->>R: GET /hello_world
R->>C: route to index
C->>V: render index.html.erb (layout: hello_world)
V->>RoR: react_component("HelloWorld", props, prerender: true)
RoR->>SSR: load `ssr-generated/server-bundle.js` and component
SSR-->>RoR: return rendered HTML
RoR-->>V: inject SSR markup + mount point
V-->>B: send HTML (includes packs)
B->>B: hydrate component using `application` pack
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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 |
4fd9bea
to
bac0985
Compare
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: 6
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
Gemfile.lock
is excluded by!**/*.lock
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (31)
.gitignore
(1 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/application.js
(1 hunks)app/javascript/packs/server-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/application.html.erb
(1 hunks)app/views/layouts/hello_world.html.erb
(1 hunks)babel.config.js
(1 hunks)bin/dev
(1 hunks)bin/setup
(1 hunks)bin/shakapacker
(1 hunks)bin/shakapacker-dev-server
(1 hunks)config/initializers/react_on_rails.rb
(1 hunks)config/routes.rb
(1 hunks)config/shakapacker.yml
(1 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
(1 hunks)config/webpack/test.js
(1 hunks)config/webpack/webpack.config.js
(1 hunks)package.json
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
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/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/production.js (2)
config/webpack/development.js (2)
generateWebpackConfigs
(6-6)require
(4-4)config/webpack/test.js (1)
generateWebpackConfigs
(4-4)
config/webpack/clientWebpackConfig.js (3)
config/webpack/commonWebpackConfig.js (2)
commonWebpackConfig
(16-16)require
(5-5)config/webpack/serverWebpackConfig.js (2)
commonWebpackConfig
(5-5)require
(4-4)config/webpack/generateWebpackConfigs.js (1)
clientConfig
(8-8)
config/webpack/commonWebpackConfig.js (2)
config/webpack/serverWebpackConfig.js (2)
require
(4-4)commonWebpackConfig
(5-5)config/webpack/clientWebpackConfig.js (1)
commonWebpackConfig
(4-4)
config/webpack/development.js (1)
config/webpack/generateWebpackConfigs.js (1)
clientWebpackConfig
(4-4)
config/webpack/serverWebpackConfig.js (3)
config/webpack/commonWebpackConfig.js (2)
require
(5-5)commonWebpackConfig
(16-16)config/webpack/clientWebpackConfig.js (1)
commonWebpackConfig
(4-4)config/webpack/generateWebpackConfigs.js (1)
serverWebpackConfig
(5-5)
babel.config.js (4)
config/webpack/commonWebpackConfig.js (1)
require
(5-5)config/webpack/development.js (1)
require
(4-4)config/webpack/serverWebpackConfig.js (1)
require
(4-4)config/webpack/webpack.config.js (3)
require
(1-1)require
(2-2)require
(3-3)
config/webpack/webpack.config.js (3)
config/webpack/commonWebpackConfig.js (1)
require
(5-5)config/webpack/development.js (1)
require
(4-4)config/webpack/serverWebpackConfig.js (1)
require
(4-4)
🔇 Additional comments (11)
bin/setup (1)
18-19
: Ensuring JavaScript deps are in placeThanks for wiring up
npm install
sobin/setup
provisions both Ruby and JS dependencies in one shot.bin/dev (1)
31-34
: Default route guard reads cleanOnly adding
--route
when it’s absent keeps the CLI flexible without surprising overrides.app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css (1)
1-4
: Scoped style looks good.The
.bright
module class gives the demo something visual without leaking to the global scope. Nicely done.app/views/hello_world/index.html.erb (1)
1-2
: Helper usage looks correct.The
react_component
call (withprerender: true
) lines up with the generator guidance for SSR, so the view should render as expected once the bundle is wired up.app/views/layouts/application.html.erb (1)
20-22
: Confirm CSS chunks are loaded as well.Because the HelloWorld component imports a CSS module, Shakapacker will emit a CSS chunk alongside the JS entrypoint for production builds. Without a corresponding
stylesheet_pack_tag
(or another mechanism that injects the link tag), that chunk never gets referenced and the.bright
styles disappear outside of HMR. Please either add<%= stylesheet_pack_tag "application" %>
here or confirm that your ReactOnRails auto-bundle setup is already inserting the CSS link tags for you. (github.com)config/routes.rb (1)
1-2
: Route addition looks good.This cleanly exposes
/hello_world
for the demo controller without touching existing routes.app/javascript/packs/application.js (1)
1-16
: ReactOnRails auto-load bundle settings confirmed
config.components_subdirectory
is set to"ror_components"
andconfig.auto_load_bundle = true
inconfig/initializers/react_on_rails.rb
, so the emptyapplication.js
pack will correctly load the generated bundles.config/webpack/production.js (1)
1-10
: Production hook setup looks goodThe env-specific hook mirrors the upstream template and keeps production overrides cleanly isolated.
config/webpack/webpack.config.js (1)
5-15
: ENV loader wiring looks solidResolving the config by
env.nodeEnv
keeps the entry tidy and the console trace will help diagnose missing configs.config/webpack/development.js (1)
8-19
: React Refresh gating looks correctConditionally loading the plugin under
WEBPACK_SERVE
lines up with the Babel guard and avoids shipping dev-only code in other modes.config/webpack/generateWebpackConfigs.js (1)
7-35
: Config splitter behaves as expectedThe helper neatly centralizes client/server creation and the env flags cover the common single-bundle workflows.
<form> | ||
<label className={style.bright} htmlFor="name"> | ||
Say hello to: | ||
<input id="name" type="text" value={name} onChange={(e) => setName(e.target.value)} /> | ||
</label> | ||
</form> |
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.
Prevent form submission reload
Submitting the form (e.g., pressing Enter) currently performs a full page reload, wiping local state and undermining the interactive demo. Add a preventDefault handler on the form submit so the component stays SPA-friendly.
- <form>
+ <form onSubmit={(event) => event.preventDefault()}>
<label className={style.bright} htmlFor="name">
📝 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.
<form> | |
<label className={style.bright} htmlFor="name"> | |
Say hello to: | |
<input id="name" type="text" value={name} onChange={(e) => setName(e.target.value)} /> | |
</label> | |
</form> | |
<form onSubmit={(event) => event.preventDefault()}> | |
<label className={style.bright} htmlFor="name"> | |
Say hello to: | |
<input | |
id="name" | |
type="text" | |
value={name} | |
onChange={(e) => setName(e.target.value)} | |
/> | |
</label> | |
</form> |
🤖 Prompt for AI Agents
In app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx around
lines 11 to 16, the <form> currently submits and reloads the page; add an
onSubmit handler to the form that calls event.preventDefault() (e.g.,
onSubmit={(e) => e.preventDefault()}) so pressing Enter won't trigger a full
reload and local React state (name) is preserved — update the JSX to include
this handler on the form element.
<%= stylesheet_pack_tag %> | ||
<%= javascript_pack_tag %> |
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 pack helper usage to avoid runtime ArgumentError.
Line 8 invokes stylesheet_pack_tag
(and Line 9 javascript_pack_tag
) with no arguments. These helpers require at least one pack name; calling them empty raises ArgumentError: wrong number of arguments (given 0, expected 1+)
, so any request using this layout will blow up before rendering. Pass the appropriate pack names (e.g., 'application'
or your HelloWorld bundle) or remove the helpers if they’re not needed.
- <%= stylesheet_pack_tag %>
- <%= javascript_pack_tag %>
+ <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
+ <%= javascript_pack_tag 'application', 'data-turbo-track': 'reload', defer: true %>
Adjust the pack name(s) to match the entries you actually build.
📝 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.
<%= stylesheet_pack_tag %> | |
<%= javascript_pack_tag %> | |
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbo-track': 'reload' %> | |
<%= javascript_pack_tag 'application', 'data-turbo-track': 'reload', defer: true %> |
🤖 Prompt for AI Agents
In app/views/layouts/hello_world.html.erb around lines 8 to 9, the layout calls
stylesheet_pack_tag and javascript_pack_tag with no arguments which raises
ArgumentError; update those calls to pass the actual pack names you build (for
example 'application' or your HelloWorld bundle) or remove the helpers if you
don't use webpacker packs, ensuring the pack names match your webpacker/webpack
entries.
#!/usr/bin/env ruby | ||
|
||
ENV["RAILS_ENV"] ||= "development" | ||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) |
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 BUNDLE_GEMFILE
path
Using File.expand_path("../../Gemfile", __FILE__)
walks up two directories and resolves to /Gemfile
, so require "bundler/setup"
raises Bundler::GemfileNotFound
. Point the lookup just one level above bin/
instead.
Apply this diff to correct the path:
-ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
📝 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.
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) | |
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) |
🤖 Prompt for AI Agents
In bin/shakapacker-dev-server around line 4, the BUNDLE_GEMFILE path is
resolving two levels up and ending at /Gemfile which causes
Bundler::GemfileNotFound; change the lookup to point one directory above bin
(e.g. use File.expand_path("../Gemfile", __FILE__) or
File.expand_path("../Gemfile", __dir__)) so BUNDLE_GEMFILE references the
correct Gemfile and require "bundler/setup" can find it.
const cssLoader = rule.use.find((item) => { | ||
let testValue; | ||
|
||
if (typeof item === 'string') { | ||
testValue = item; | ||
} else if (typeof item.loader === 'string') { | ||
testValue = item.loader; | ||
} | ||
|
||
return testValue.includes('css-loader'); | ||
}); | ||
if (cssLoader && cssLoader.options) { | ||
cssLoader.options.modules = { exportOnlyLocals: true }; | ||
} | ||
|
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.
Don't clobber CSS module options
On Line 96 we replace the entire css-loader
modules
options object with { exportOnlyLocals: true }
. That wipes out existing settings (e.g., a custom localIdentName
) defined in the shared config. The server bundle will now emit different class names than the client bundle, breaking SSR hydration for any CSS module. Please merge in exportOnlyLocals
instead of overwriting the object so the previously configured options stay intact.
- if (cssLoader && cssLoader.options) {
- cssLoader.options.modules = { exportOnlyLocals: true };
- }
+ if (cssLoader?.options?.modules) {
+ cssLoader.options.modules =
+ cssLoader.options.modules === true
+ ? { exportOnlyLocals: true }
+ : { ...cssLoader.options.modules, exportOnlyLocals: true };
+ }
📝 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 cssLoader = rule.use.find((item) => { | |
let testValue; | |
if (typeof item === 'string') { | |
testValue = item; | |
} else if (typeof item.loader === 'string') { | |
testValue = item.loader; | |
} | |
return testValue.includes('css-loader'); | |
}); | |
if (cssLoader && cssLoader.options) { | |
cssLoader.options.modules = { exportOnlyLocals: true }; | |
} | |
const cssLoader = rule.use.find((item) => { | |
let testValue; | |
if (typeof item === 'string') { | |
testValue = item; | |
} else if (typeof item.loader === 'string') { | |
testValue = item.loader; | |
} | |
return testValue.includes('css-loader'); | |
}); | |
if (cssLoader?.options?.modules) { | |
cssLoader.options.modules = | |
cssLoader.options.modules === true | |
? { exportOnlyLocals: true } | |
: { ...cssLoader.options.modules, exportOnlyLocals: true }; | |
} |
🤖 Prompt for AI Agents
In config/webpack/serverWebpackConfig.js around lines 85 to 99, the code is
overwriting css-loader's modules options with { exportOnlyLocals: true } which
discards any existing module settings; update the logic to merge
exportOnlyLocals into the existing modules configuration instead of replacing
it: read cssLoader.options.modules, if it's an object spread its properties and
add exportOnlyLocals: true, if it's undefined or a boolean convert to an object
that preserves intent (for boolean true create an object with exportOnlyLocals:
true, for undefined create { exportOnlyLocals: true }), and assign that back to
cssLoader.options.modules so existing settings like localIdentName are retained.
Gemfile
Outdated
gem "react_on_rails", "16.1.1" | ||
gem "shakapacker", "9.0.0.beta.3" |
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.
Blocker: shakapacker gem pin targets an unpublished version
RubyGems does not expose a 9.0.0.beta.3
release for shakapacker (the latest published line as of September 9, 2025 is 8.4.0), so bundle install
will fail. Please pin to an available release and keep the gem/npm versions aligned to avoid the known cross-version mismatch error shakapacker raises.(rubygems.org)
Apply this diff (or any currently published version) to restore installability:
-gem "shakapacker", "9.0.0.beta.3"
+gem "shakapacker", "8.3.0"
🤖 Prompt for AI Agents
In Gemfile around lines 9 to 10, the shakapacker gem is pinned to a
non-published version "9.0.0.beta.3" which will make bundle install fail; change
the Gemfile to pin shakapacker to a published release (e.g., "8.4.0" or any
currently available version), run bundle install (or bundle update shakapacker),
and ensure your JS package.json webpack/shakapacker-related packages are aligned
with that gem version to avoid cross-version mismatches.
"react-dom": "^19.1.1", | ||
"react-on-rails": "^16.1.1", | ||
"sass-loader": "^16.0.5", | ||
"shakapacker": "9.0.0-beta.3", |
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.
Blocker: npm shakapacker version is unavailable
The npm registry tops out at shakapacker 8.3.0
right now, so installing 9.0.0-beta.3
will fail. Keeping the npm package in lockstep with the gem avoids the runtime guard that aborts when the versions differ.(npmjs.com)
Update the dependency to a published release that matches the gem:
- "shakapacker": "9.0.0-beta.3",
+ "shakapacker": "8.3.0",
📝 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.
"shakapacker": "9.0.0-beta.3", | |
"shakapacker": "8.3.0", |
🤖 Prompt for AI Agents
In package.json at line 27, the shakapacker dependency is set to "9.0.0-beta.3"
which is not available on npm; update the version to a published release that
matches the gem (e.g., "8.3.0") and then run your package manager to refresh
lockfiles (npm install or yarn install) so the dependency resolves correctly.
- Add .ruby-version file for Ruby 3.3.4 - Configure PostgreSQL as database adapter - Add database.yml with PostgreSQL configuration - Update CI workflow to use PostgreSQL service - Fix CI test command (use bin/rails test instead of db:test:prepare) - Comment out propshaft, kamal, and thruster gems (not needed) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add shakapacker 9.0.0.beta.3 (strict version) - Add react_on_rails 16.1.1 (strict version) - Add pg gem for PostgreSQL database - Update Gemfile.lock with dependencies 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Run rails generate react_on_rails:install - Configure Shakapacker webpack integration - Add HelloWorld example component and controller - Set up webpack configuration for client and server bundles - Add Procfile.dev variants for different asset modes - Configure babel for React development - Install npm dependencies for webpack and React - Fix RuboCop linting issues in generated files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
67eb305
to
10303d5
Compare
Summary
Changes
Test plan
bin/dev
to start the development server/hello_world
to verify the React component renders correctlybundle exec rubocop
to ensure code style compliancenpm run build
to verify production builds work🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores