-
-
Notifications
You must be signed in to change notification settings - Fork 638
docs: Improve file-system-based bundle generation guide #1766
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
docs: Improve file-system-based bundle generation guide #1766
Conversation
Caution Review failedThe pull request is closed. WalkthroughExpands docs/guides/file-system-based-automated-bundle-generation.md with a comprehensive guide on layout integration for auto-loading bundles, including examples, configuration, SSR/client variants, troubleshooting, and debug mode. The added content is duplicated in the document. No code changes or public API alterations. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant View as Rails View
participant ROR as react_component(...)
participant Tags as append_*_pack_tag
participant Layout as Layout (empty pack tags)
participant Bundler as Bundles (per-component)
participant Client as Browser
participant SSR as Server Renderer
User->>View: Request page
View->>ROR: render react_component(name, auto_load_bundle: true)
ROR->>Tags: append_javascript_pack_tag / append_stylesheet_pack_tag
View->>Layout: yield to layout with empty pack tags
Layout->>Tags: render accumulated pack tags
Tags->>Bundler: Resolve per-component JS/CSS bundles
alt SSR enabled
View->>SSR: Server render component
SSR-->>View: HTML with markup
end
Layout-->>Client: HTML + pack tags
Client->>Bundler: Load JS/CSS bundles
Bundler-->>Client: Initialize/mount component
note over Client,Bundler: If a component is excluded from auto-load,<br/>manual pack tags must be present.
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests
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 |
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: 4
🧹 Nitpick comments (7)
LICENSES/README.md (1)
12-14
: Clarify “Production Use” scope and examples.To avoid ambiguity, explicitly state that any live deployment (including internal staff-only portals and non-profits) is “Production Use,” and provide a contact or link for licensing. This prevents misinterpretation by OSS users and AI agents.
- - **Production Use** (including by non-profits) requires a paid subscription + - **Production Use** (any live deployment, including internal/staff-only and non-profits) requires a paid subscription. + For questions, contact ShakaCode or see the Pro license for details.LICENSE.md (1)
10-12
: Year range formatting nit.Use ASCII hyphen
-
instead of an en dash–
for better compatibility with license scanners.-Copyright (c) 2015–2025 ShakaCode, LLC +Copyright (c) 2015-2025 ShakaCode, LLCREACT-ON-RAILS-PRO-LICENSE.md (1)
58-67
: Attribution requirement: note operational caveats.Consider noting that HTML comment attribution may be stripped by some minifiers/CDNs. Provide guidance on verifying its presence in production and acceptable alternatives if tooling removes comments.
docs/guides/file-system-based-automated-bundle-generation.md (4)
246-269
: Accuracy on where bundles render across modes.Confirm that in HMR/dev, CSS may not be extracted and JS/CSS injection behavior differs. A short note here avoids confusion.
Proposed addendum:
2. **Layout renders appended bundles**: ... 3. **No manual bundle management**: ... +Note: In HMR/dev, CSS is typically in JS via style-loader and may not emit separate CSS files. Injection behavior differs from static/production.
281-289
: Avoid recommendingcache_manifest: false
globally.This can hurt production performance and caching. Consider omitting it from the sample or adding a note to enable it in production.
- cache_manifest: false +# cache_manifest: true # recommended for production
448-454
: Mention running via Bundler.Use
bundle exec
for consistency with most Rails setups.-bundle exec rake react_on_rails:generate_packs +bundle exec rake react_on_rails:generate_packs(If you intentionally support both, ignore.)
590-593
: Great debug tip. Add note about environment.Clarify these helpers render only when content is present; advise checking logs in dev vs prod.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
LICENSE.md
(2 hunks)LICENSES/README.md
(1 hunks)REACT-ON-RAILS-PRO-LICENSE
(0 hunks)REACT-ON-RAILS-PRO-LICENSE.md
(1 hunks)docs/guides/file-system-based-automated-bundle-generation.md
(2 hunks)
💤 Files with no reviewable changes (1)
- REACT-ON-RAILS-PRO-LICENSE
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
Applied to files:
docs/guides/file-system-based-automated-bundle-generation.md
🪛 GitHub Actions: Lint JS and Ruby
docs/guides/file-system-based-automated-bundle-generation.md
[error] 1-1: Prettier formatting issues detected in this file. Run 'prettier --write' to fix.
⏰ 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). (4)
- GitHub Check: dummy-app-integration-tests (newest)
- GitHub Check: dummy-app-integration-tests (oldest)
- GitHub Check: rspec-package-tests (newest)
- GitHub Check: rspec-package-tests (oldest)
🔇 Additional comments (3)
docs/guides/file-system-based-automated-bundle-generation.md (3)
222-273
: No duplicate “Layout Integration with Auto-Loading” section found.
Only one occurrence at line 222; no deduplication needed.
1-596
: Prettier formatting applied to docs/guides/file-system-based-automated-bundle-generation.md
CI formatting errors have been resolved.
3-3
: No changes needed for version pins or upgrade guide links
- React on Rails v13.1.0 introduced the file-system-based automated bundle generation feature requiring Shakapacker ≥ v6.5.1 (shakacode.com)
- Latest Shakapacker release is v8.3.0 (Apr 29, 2025) (rubygems.org)
When using `auto_load_bundle: true`, your Rails layout needs to include empty pack tag placeholders where React on Rails will inject the component-specific CSS and JavaScript bundles automatically: | ||
|
||
```erb | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<!-- Your regular head content --> | ||
<%= csrf_meta_tags %> | ||
<%= csp_meta_tag %> | ||
|
||
<!-- Empty pack tags - React on Rails injects component CSS/JS here --> | ||
<%= stylesheet_pack_tag %> | ||
<%= javascript_pack_tag %> | ||
</head> | ||
<body> | ||
<%= yield %> | ||
</body> | ||
</html> | ||
``` |
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
Place JS placeholder before for consistency and performance.
The text later claims JS renders “before ,” but the example shows it in . Move javascript_pack_tag
to just before and keep CSS in .
<!-- Empty pack tags - React on Rails injects component CSS/JS here -->
- <%= stylesheet_pack_tag %>
- <%= javascript_pack_tag %>
+ <%= stylesheet_pack_tag %>
</head>
<body>
<%= yield %>
+ <!-- JS placeholder at the end of body -->
+ <%= javascript_pack_tag %>
</body>
🤖 Prompt for AI Agents
In docs/guides/file-system-based-automated-bundle-generation.md around lines 224
to 242, the example shows the javascript_pack_tag in the head but the text
states JS renders "before </body>"; move the javascript_pack_tag out of the head
and place it just before the closing </body> tag while leaving the
stylesheet_pack_tag in the head, and update the example markup accordingly so
the JS placeholder appears immediately before </body>.
LICENSE.md
Outdated
--- | ||
|
||
## Disclaimer | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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 the canonical MIT license text (legal correctness).
The last sentence was changed from “THE SOFTWARE.” to “SOFTWARE.” and a “Disclaimer” header was inserted into the license block. The MIT text should remain exactly verbatim. Please revert the wording and move any headings or separators outside the license block.
-## Disclaimer
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
...
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+THE SOFTWARE.
And place “## Disclaimer” (if you want it) above/below the MIT block, not inside it. Also consider replacing the en dash in the year range with a hyphen for portability in tooling.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In LICENSE.md around lines 23 to 33, the canonical MIT license block was
altered: a "## Disclaimer" header was inserted inside the license text and the
final sentence was changed from "THE SOFTWARE." to "SOFTWARE."; revert the
license block to the exact, unmodified MIT wording (restore "THE SOFTWARE." as
the final words), remove the "## Disclaimer" header from inside the license
block and place any header or separator outside the block, and if there is a
year range use a plain hyphen (-) instead of an en dash for portability.
REACT-ON-RAILS-PRO-LICENSE.md
Outdated
## 15. Governing Law; Venue | ||
|
||
Choose one: **State of Hawaii**, USA. Exclusive jurisdiction and venue lie in the courts located therein. | ||
|
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 placeholder text in Governing Law.
“Choose one:” looks like a template artifact. Remove it so the clause is enforceable.
-Choose one: **State of Hawaii**, USA. Exclusive jurisdiction and venue lie in the courts located therein.
+**State of Hawaii**, USA. Exclusive jurisdiction and venue lie in the courts located therein.
📝 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.
## 15. Governing Law; Venue | |
Choose one: **State of Hawaii**, USA. Exclusive jurisdiction and venue lie in the courts located therein. | |
## 15. Governing Law; Venue | |
**State of Hawaii**, USA. Exclusive jurisdiction and venue lie in the courts located therein. |
🤖 Prompt for AI Agents
In REACT-ON-RAILS-PRO-LICENSE.md around lines 121 to 124, remove the template
placeholder text "Choose one:" so the Governing Law clause reads cleanly and
enforceably; replace the lines with a single definitive sentence stating the
chosen governing law (for example: "State of Hawaii, USA. Exclusive jurisdiction
and venue lie in the courts located therein.") without any bracketed or
instructional text.
Add comprehensive improvements to the file-system-based automated bundle generation documentation to address gaps that cause confusion for both human developers and AI coding agents. ## Key improvements: ### 1. Layout Integration Clarification - Added detailed section explaining empty pack tag placeholders in Rails layouts - Clarified how react_component helper automatically calls append_javascript_pack_tag - Explained the connection between component usage and automatic bundle injection - Showed the complete flow from component rendering to CSS/JS loading ### 2. Complete Working Example - Added step-by-step setup guide from scratch - Included real component implementations with CSS modules and dynamic imports - Provided complete Rails controller, view, and layout code examples - Demonstrated proper directory structure with concrete file paths - Showed bundle splitting benefits with actual size comparisons (50KB vs 2.7MB) ### 3. Comprehensive Troubleshooting Section - Documented all common issues encountered during implementation - Added solutions for FOUC handling across different development modes - Covered SSR compatibility issues with dynamic imports - Included installation order requirements (Shakapacker before React on Rails) - Provided debug techniques for troubleshooting bundle loading - Addressed bundle size optimization and development vs production differences ### 4. Enhanced Developer Experience - Clear explanations of "why" behind configuration choices - Explicit file naming conventions and patterns - Debug mode instructions for investigating bundle loading issues - Common failure modes and their solutions These improvements make the documentation significantly more practical and reduce the likelihood of implementation errors. The additions are based on real-world implementation experience and address the most common stumbling blocks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/guides/file-system-based-automated-bundle-generation.md (2)
197-202
: Avoid double-including the Special component bundle.Layout already loads
SpecialComponentNotToAutoLoadBundle
explicitly (Lines 170–173). The additionalappend_javascript_pack_tag
here will duplicate JS inclusion.<%= react_component("BarComponentOne", {}, auto_load_bundle: true) %> - <% append_javascript_pack_tag('SpecialComponentNotToAutoLoadBundle') %> <%= react_component("SpecialComponentNotToAutoLoadBundle", {}) %>
Alternative: remove the named pack tags from the layout and use both
append_stylesheet_pack_tag
andappend_javascript_pack_tag
from the view for the Special component (pick one approach, not both).
3-3
: Clarify minimum versions for automated bundle generation and auto-registration
In docs/guides/file-system-based-automated-bundle-generation.md (line 3), update to:
“Both file-system-based automated bundle generation and component auto-registration were introduced in React on Rails v13.1.0 and require Shakapacker ≥ 6.5.1 (current stable versions: React on Rails v14.2.1, Shakapacker v8.3.0).”
♻️ Duplicate comments (2)
docs/guides/file-system-based-automated-bundle-generation.md (2)
226-242
: Place JS placeholder before (keep CSS in ).The example shows
javascript_pack_tag
in the head, but later text implies JS renders before</body>
. Move the JS placeholder to the end of body for consistency and better loading.<!-- Empty pack tags - React on Rails injects component CSS/JS here --> - <%= stylesheet_pack_tag %> - <%= javascript_pack_tag %> + <%= stylesheet_pack_tag %> </head> <body> <%= yield %> + <!-- JS placeholder at the end of body --> + <%= javascript_pack_tag %> </body> </html>
394-411
: Apply the same head/body placement in the full layout example.Mirror the head/body placement used above: keep CSS in
<head>
, move JS to just before</body>
.<!-- Empty pack tags - React on Rails injects component CSS/JS here --> - <%= stylesheet_pack_tag %> - <%= javascript_pack_tag %> + <%= stylesheet_pack_tag %> </head> <body> <%= yield %> + <%= javascript_pack_tag %> </body> </html>
🧹 Nitpick comments (2)
docs/guides/file-system-based-automated-bundle-generation.md (2)
525-531
: Soften the categorical FOUC claim.FOUC can occur outside HMR depending on extraction order, third-party CSS, or late-loaded styles. Recommend softer phrasing.
-**Important**: FOUC (Flash of Unstyled Content) **only occurs with HMR (Hot Module Replacement)**. Static and production modes work perfectly without FOUC. +**Important**: FOUC (Flash of Unstyled Content) most commonly occurs with HMR (Hot Module Replacement). Static and production modes usually avoid FOUC by extracting CSS, but if you still see it, verify CSS extraction and loading order.
1-620
: Run Prettier to fix formatting warnings.CI flagged Prettier failures on this Markdown file.
#!/bin/bash npx prettier --write docs/guides/file-system-based-automated-bundle-generation.md
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
docs/images/bundle-splitting-heavy-markdown.png
is excluded by!**/*.png
📒 Files selected for processing (1)
docs/guides/file-system-based-automated-bundle-generation.md
(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
PR: shakacode/react_on_rails#1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
Applied to files:
docs/guides/file-system-based-automated-bundle-generation.md
🪛 GitHub Actions: Lint JS and Ruby
docs/guides/file-system-based-automated-bundle-generation.md
[warning] 1-1: Prettier formatting check failed for this file. Run 'prettier --write' to fix code style issues in this file.
⏰ 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). (2)
- GitHub Check: dummy-app-integration-tests (newest)
- GitHub Check: dummy-app-integration-tests (oldest)
🔇 Additional comments (1)
docs/guides/file-system-based-automated-bundle-generation.md (1)
503-506
: No update required for version reference
The automatic registration feature for bundles underconfig.components_subdirectory
was introduced in v13.3.4, so the stated lower bound is correct.
**Bundle sizes in this example (measured from browser dev tools):** | ||
- **HelloWorld**: 1.1MB total resources (50KB component-specific code + shared React runtime) | ||
- HelloWorld.js: 10.0 kB | ||
- HelloWorld.css: 2.5 kB | ||
- Shared runtime: ~1.1MB (React, webpack runtime) | ||
- **HeavyMarkdownEditor**: 2.2MB total resources (2.7MB with markdown libraries) | ||
- HeavyMarkdownEditor.js: 26.5 kB | ||
- HeavyMarkdownEditor.css: 5.5 kB | ||
- Markdown libraries: 1,081 kB additional | ||
- Shared runtime: ~1.1MB (React, webpack runtime) | ||
|
||
**Bundle splitting benefit**: Each page loads only its required components - the HelloWorld page doesn't load the heavy markdown libraries, saving ~1.1MB (50% reduction)! | ||
|
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.
Bundle size numbers are inconsistent; re-measure or generalize.
Values listed (e.g., “HelloWorld 1.1MB total” vs per-file sizes; “HeavyMarkdownEditor 2.2MB total (2.7MB with markdown libraries)”) conflict. This can mislead readers.
Proposed simplification:
-**Bundle sizes in this example (measured from browser dev tools):**
- - **HelloWorld**: 1.1MB total resources (50KB component-specific code + shared React runtime)
- - HelloWorld.js: 10.0 kB
- - HelloWorld.css: 2.5 kB
- - Shared runtime: ~1.1MB (React, webpack runtime)
- - **HeavyMarkdownEditor**: 2.2MB total resources (2.7MB with markdown libraries)
- - HeavyMarkdownEditor.js: 26.5 kB
- - HeavyMarkdownEditor.css: 5.5 kB
- - Markdown libraries: 1,081 kB additional
- - Shared runtime: ~1.1MB (React, webpack runtime)
-
-**Bundle splitting benefit**: Each page loads only its required components - the HelloWorld page doesn't load the heavy markdown libraries, saving ~1.1MB (50% reduction)!
+**Example bundle size guidance (varies by app and build settings):**
+- HelloWorld: small component bundle + shared runtime.
+- HeavyMarkdownEditor: larger component bundle + markdown libs + shared runtime.
+
+Tip: Measure with a production build and your browser’s Network panel; avoid quoting exact sizes unless measured in this repo/revision.
To re-measure precisely in your app:
#!/bin/bash
RAILS_ENV=production NODE_ENV=production bundle exec rails assets:precompile
echo "Bundle sizes under public/packs:"
# List top bundles and sizes
find public/packs -type f -maxdepth 2 -print0 | xargs -0 du -h | sort -h | tail -n 30
8d96353
to
b5f692f
Compare
#### Performance Screenshots | ||
|
||
**HelloWorld (Lightweight Component):** | ||
 |
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.
Seems that this image is missing
Summary
This PR significantly improves the file-system-based automated bundle generation documentation to address critical gaps that have been causing confusion for developers and AI coding agents implementing React on Rails v15+ auto-registration.
The improvements are based on real-world implementation experience working through the complete setup process, including troubleshooting all the common issues that arise.
Key Improvements
🎯 Layout Integration Clarification
<%= stylesheet_pack_tag %>
and<%= javascript_pack_tag %>
work as placeholdersreact_component
automatically injects bundles📖 Complete Working Example
🔧 Comprehensive Troubleshooting
🤖 AI Agent Friendly
Technical Details
The documentation now covers the complete flow:
app/javascript/src/ComponentName/ror_components/ComponentName.jsx
rake react_on_rails:generate_packs
createspacks/generated/ComponentName.js
ReactOnRails.register()
callsreact_component("ComponentName", auto_load_bundle: true)
callsappend_javascript_pack_tag
<%= javascript_pack_tag %>
renders appended bundlesTesting Done
Files Changed
docs/guides/file-system-based-automated-bundle-generation.md
: Added ~360 lines of comprehensive improvementsBenefits
This addresses feedback about the feature being "hard to understand" and "poorly documented" by providing the missing context and examples needed for successful implementation.
This change is
Summary by CodeRabbit