Skip to content

Commit ce30d89

Browse files
authored
🚀 Enhance bin/dev with configurable routes and improved production asset handling (#1790)
* 🚀 Enhance bin/dev script with configurable routes and improved error handling ## Major Improvements ### 🎯 Configurable Route Support - Add `--route` parameter to bin/dev for custom URL display - Default to root URL (/) instead of hardcoded /hello_world - Generators pass specific routes (hello_world) when creating demo apps - Clean abstraction in ReactOnRails::Dev::ServerManager ### 🛠️ Enhanced Error Handling - Comprehensive error messages for `bin/dev prod` failures - Specific guidance for missing secret_key_base, database issues, dependencies - Suggest `bin/dev static` as alternative for development with production-like assets - Color-coded, actionable error messages with specific commands ### 🏗️ Architecture Cleanup - Remove duplicate bin/dev files - single source of truth in templates/ - Abstract command-line logic into ServerManager.run_from_command_line() - Eliminate complex route detection - simple generator-based approach - Update install generator to copy directly from templates ### 🔧 Configuration Fixes - Add nil-safe operators for PackerUtils.packer_type calls - Improve handling when Shakapacker is not available - Better deprecation warnings with fallback values ## Benefits - ✅ Cleaner development workflow with configurable URLs - ✅ Better error messages guide users to solutions - ✅ Reduced code duplication and maintenance overhead - ✅ More robust configuration handling - ✅ Preserved backwards compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * 🔍 Capture and display precompile error output for better debugging ## Improvement - Use Open3.capture3 to capture both stdout and stderr from asset precompilation - Display actual error output when bin/dev prod fails - Provide contextual fixes based on error content analysis - Smart detection of specific issues (secret_key_base, database, webpack, gems) ## Benefits - ✅ Users see the actual error message instead of generic failure - ✅ Contextual guidance based on error type - ✅ Better debugging experience for production asset compilation - ✅ No more hidden error output 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * ✨ Add --rails-env option for configurable asset precompilation environment ## New Feature - Add `--rails-env` option to `bin/dev prod` for custom Rails environment during assets:precompile - Default: NODE_ENV=production, RAILS_ENV=development (avoids credentials complexity) - Option: `--rails-env=production` for full production Rails environment - Clear documentation that option only affects assets:precompile, not server processes ## Enhanced Documentation - Comprehensive help text with examples and environment explanations - Clear runtime messaging about environment configuration - Separation of asset precompilation vs server process environments - Guidance on when to use each option ## Usage Examples ```bash bin/dev prod # Default: production webpack, development Rails bin/dev prod --rails-env=production # Full production environment bin/dev prod --route=dashboard # Custom route in URLs ``` ## Benefits - ✅ Production webpack optimizations without production Rails complexity by default - ✅ Option for full production environment when needed (testing credentials, etc.) - ✅ Clear documentation prevents confusion about scope - ✅ Better error handling with environment-specific guidance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * Fix test failures: restore PackerUtils logic and update bin/dev tests - Restore proper PackerUtils.using_packer? logic from master branch - Fix precompile? method to handle missing shakapacker properly - Update bin/dev tests to match new simplified template structure - Update server_manager_spec to expect Open3.capture3 instead of system 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * Fix RuboCop violations in server_manager_spec.rb - Use instance_double instead of double for Process::Status - Break long line for readability 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * Fix shell injection vulnerability in server_manager.rb Security improvements: - Replace string interpolation with env hash and argv array for Open3.capture3 - Add rails_env validation with allowlist pattern (/^[a-z0-9_]+$/i) - Update error handling to use safe command display - Add tests for rails_env validation and custom environment usage - Prevent arbitrary shell command execution via --rails-env parameter 🤖 Generated with [Claude Code](https://claude.ai/code)
1 parent 6415a58 commit ce30d89

File tree

14 files changed

+283
-135
lines changed

14 files changed

+283
-135
lines changed

docs/contributor-info/coding-agents-guide.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This guide provides structured instructions for AI coding agents working with Re
1616
### Version Compatibility Matrix
1717

1818
| react_on_rails | Shakapacker | Webpack | Node.js | Ruby |
19-
|----------------|-------------|---------|---------|------|
19+
| -------------- | ----------- | ------- | ------- | ---- |
2020
| v16.x | >= 6.0 | v5 | 20-22 | 3.2+ |
2121
| v14.x | >= 6.0 | v5 | 18-20 | 2.7+ |
2222
| v13.x | >= 6.0 | v5 | 16-18 | 2.7+ |
@@ -206,25 +206,29 @@ fix_webpack_cache() {
206206
#### 1. Missing Routes File (js-routes gem)
207207

208208
**Detection:**
209+
209210
```regex
210211
/Cannot read properties of undefined.*reading 'module'/
211212
/ProvidedDependencyTemplate\.apply/
212213
```
213214

214215
**Auto-fix:**
216+
215217
```bash
216218
bundle exec rails js:export
217219
```
218220

219221
#### 2. ProvidePlugin Module Missing
220222

221223
**Detection:**
224+
222225
```regex
223226
/Error: Can't resolve.*\$app/
224227
/Module not found.*utils\/routes/
225228
```
226229

227230
**Auto-fix:**
231+
228232
```bash
229233
# Check if file exists, generate if missing
230234
[ -f "app/javascript/utils/routes.js" ] || bundle exec rails js:export
@@ -236,12 +240,14 @@ grep -q "\$app" config/webpack/*.js || echo "⚠️ Missing webpack alias"
236240
#### 3. Version Incompatibility
237241

238242
**Detection:**
243+
239244
```regex
240245
/webpack.*incompatible/
241246
/peer dep.*react-on-rails/
242247
```
243248

244249
**Auto-fix:**
250+
245251
```bash
246252
# Update to compatible versions
247253
npm install react-on-rails@^16.0.0
@@ -370,18 +376,21 @@ After successful upgrades, suggest:
370376
### If Build Completely Breaks
371377

372378
1. **Rollback immediately:**
379+
373380
```bash
374381
git checkout HEAD~1 -- Gemfile package.json Gemfile.lock package-lock.json
375382
bundle install
376383
npm install
377384
```
378385

379386
2. **Identify the issue:**
387+
380388
```bash
381389
npm run build 2>&1 | tee build-error.log
382390
```
383391

384392
3. **Apply targeted fixes:**
393+
385394
- Missing routes: `rails js:export`
386395
- Cache issues: `rm -rf node_modules/.cache tmp/cache`
387396
- Dependencies: `bundle update && npm install`
@@ -391,6 +400,7 @@ After successful upgrades, suggest:
391400
### If Rails Environment Unavailable
392401

393402
Use minimal commands:
403+
394404
```bash
395405
# Skip database operations
396406
DATABASE_URL=sqlite3:tmp/minimal.db rails js:export
@@ -401,4 +411,4 @@ RAILS_ENV=test rails js:export
401411

402412
---
403413

404-
This guide ensures consistent, reliable React on Rails operations for coding agents while providing clear error recovery paths.
414+
This guide ensures consistent, reliable React on Rails operations for coding agents while providing clear error recovery paths.

docs/guides/upgrading-react-on-rails.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ rails generate react_on_rails:install
8888
**Symptoms:** Webpack cannot find modules referenced in your configuration
8989

9090
**Solutions:**
91+
9192
1. Clear webpack cache: `rm -rf node_modules/.cache`
9293
2. Verify all ProvidePlugin modules exist
9394
3. Check webpack alias configuration

docs/javascript/troubleshooting-build-errors.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,80 +15,96 @@ This guide covers common webpack build errors encountered when using react_on_ra
1515
**Note:** This error only occurs if you're using the optional `js-routes` gem to access Rails routes in JavaScript.
1616

1717
### Error Message
18+
1819
```
1920
Cannot read properties of undefined (reading 'module')
2021
TypeError: Cannot read properties of undefined (reading 'module')
2122
at ProvidedDependencyTemplate.apply
2223
```
2324

2425
### Root Cause
26+
2527
This error occurs when:
28+
2629
1. Your webpack config references Rails routes via ProvidePlugin
2730
2. The `js-routes` gem hasn't generated the JavaScript routes file
2831
3. You're using `js-routes` integration but missing the generated file
2932

3033
### When You Need js-routes
34+
3135
`js-routes` is **optional** and typically used when:
36+
3237
- Rails-heavy apps with React components that need to navigate to Rails routes
3338
- Server-side rendered apps mixing Rails and React routing
3439
- Legacy Rails apps migrating ERB views to React
3540
- Apps using Rails routing patterns for RESTful APIs
3641

3742
### When You DON'T Need js-routes
43+
3844
Most modern React apps use:
45+
3946
- Client-side routing (React Router) instead of Rails routes
4047
- Hardcoded API endpoints or environment variables
4148
- SPA (Single Page App) architecture with API-only Rails backend
4249

4350
### Solution (if using js-routes)
51+
4452
1. **Generate JavaScript routes file:**
53+
4554
```bash
4655
bundle exec rails js:export
4756
```
4857

4958
2. **Verify the routes file was created:**
59+
5060
```bash
5161
ls app/javascript/utils/routes.js
5262
```
5363

5464
3. **Check webpack configuration includes ProvidePlugin:**
5565
```javascript
5666
new webpack.ProvidePlugin({
57-
Routes: "$app/utils/routes"
58-
})
67+
Routes: '$app/utils/routes',
68+
});
5969
```
6070

6171
### Alternative Solution (if NOT using js-routes)
72+
6273
Remove the Routes ProvidePlugin from your webpack configuration:
74+
6375
```javascript
6476
// Remove this line if you don't use js-routes
6577
new webpack.ProvidePlugin({
66-
Routes: "$app/utils/routes" // ← Remove this
67-
})
78+
Routes: '$app/utils/routes', // ← Remove this
79+
});
6880
```
6981

7082
## ProvidePlugin Module Resolution Errors
7183

7284
### Common Error Patterns
85+
7386
- `Cannot read properties of undefined (reading 'module')`
7487
- `Module not found: Error: Can't resolve 'module_name'`
7588
- `ERROR in ./path/to/file.js: Cannot find name 'GlobalVariable'`
7689

7790
### Debugging Steps
7891

7992
1. **Check file existence:**
93+
8094
```bash
8195
find app/javascript -name "routes.*" -type f
8296
find app/javascript -name "*global*" -type f
8397
```
8498

8599
2. **Verify webpack aliases:**
100+
86101
```javascript
87102
// In your webpack config
88103
console.log('Webpack aliases:', config.resolve.alias);
89104
```
90105

91106
3. **Test module resolution:**
107+
92108
```bash
93109
# Run webpack with debug output
94110
bin/shakapacker --debug-shakapacker
@@ -109,6 +125,7 @@ new webpack.ProvidePlugin({
109125
## Environment Setup Dependencies
110126

111127
### Rails Environment Required
128+
112129
Some operations require a working Rails environment:
113130

114131
- `rails js:export` (generates routes - **only needed if using js-routes gem**)
@@ -118,17 +135,20 @@ Some operations require a working Rails environment:
118135
### Common Issues
119136

120137
1. **Database Connection Errors:**
138+
121139
```
122140
MONGODB | Error checking localhost:27017: Connection refused
123141
```
124142

125143
**Solution:** These are usually warnings and don't prevent operation. To silence:
144+
126145
```bash
127146
# Run with minimal environment
128147
RAILS_ENV=development bundle exec rails js:export
129148
```
130149

131150
2. **Missing Dependencies:**
151+
132152
```
133153
sidekiq-pro is not installed
134154
```
@@ -138,6 +158,7 @@ Some operations require a working Rails environment:
138158
### Workarounds
139159

140160
1. **Skip database initialization:**
161+
141162
```bash
142163
DATABASE_URL=sqlite3:tmp/db.sqlite3 rails js:export
143164
```
@@ -152,14 +173,15 @@ Some operations require a working Rails environment:
152173
### Version Compatibility Matrix
153174

154175
| react_on_rails | Shakapacker | Webpack | Node.js |
155-
|----------------|-------------|---------|---------|
176+
| -------------- | ----------- | ------- | ------- |
156177
| v16.x | >= 6.0 | v5 | 20-22 |
157178
| v14.x | >= 6.0 | v5 | 18-20 |
158179
| v13.x | >= 6.0 | v5 | 16-18 |
159180

160181
### Common Upgrade Issues
161182

162183
1. **Webpacker to Shakapacker migration incomplete:**
184+
163185
```bash
164186
# Remove webpacker references
165187
grep -r "webpacker" config/
@@ -172,6 +194,7 @@ Some operations require a working Rails environment:
172194
```
173195

174196
### Migration Steps
197+
175198
1. Follow the [Shakapacker upgrade guide](https://github.com/shakacode/shakapacker/blob/main/docs/v6_upgrade.md)
176199
2. Update webpack configurations
177200
3. Regenerate configurations with `rails generate react_on_rails:install`
@@ -254,4 +277,4 @@ fi
254277

255278
- Check the [general troubleshooting guide](./troubleshooting-when-using-shakapacker.md)
256279
- Review [webpack configuration docs](./webpack.md)
257-
- Contact [[email protected]](mailto:[email protected]) for professional support
280+
- Contact [[email protected]](mailto:[email protected]) for professional support

lib/generators/react_on_rails/bin/dev

Lines changed: 0 additions & 46 deletions
This file was deleted.

lib/generators/react_on_rails/generator_messages.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def clear
3838
@output = []
3939
end
4040

41-
def helpful_message_after_installation(component_name: "HelloWorld")
41+
def helpful_message_after_installation(component_name: "HelloWorld", route: "hello_world")
4242
process_manager_section = build_process_manager_section
4343
testing_section = build_testing_section
4444
package_manager = detect_package_manager
@@ -62,7 +62,7 @@ def helpful_message_after_installation(component_name: "HelloWorld")
6262
./bin/dev prod # Production-like mode for testing
6363
./bin/dev help # See all available options
6464
65-
3. Visit: #{Rainbow('http://localhost:3000/hello_world').cyan.underline}
65+
3. Visit: #{Rainbow(route ? "http://localhost:3000/#{route}" : 'http://localhost:3000').cyan.underline}
6666
✨ KEY FEATURES:
6767
─────────────────────────────────────────────────────────────────────────
6868
• Auto-registration enabled - Your layout only needs:

lib/generators/react_on_rails/install_generator.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,13 @@ def shakapacker_in_gemfile?
136136
end
137137

138138
def add_bin_scripts
139-
directory "#{__dir__}/bin", "bin"
139+
# Copy bin scripts from templates
140+
template_bin_path = "#{__dir__}/templates/base/base/bin"
141+
directory template_bin_path, "bin"
140142

141143
# Make these and only these files executable
142144
files_to_copy = []
143-
Dir.chdir("#{__dir__}/bin") do
145+
Dir.chdir(template_bin_path) do
144146
files_to_copy.concat(Dir.glob("*"))
145147
end
146148
files_to_become_executable = files_to_copy.map { |filename| "bin/#{filename}" }
@@ -149,7 +151,14 @@ def add_bin_scripts
149151
end
150152

151153
def add_post_install_message
152-
GeneratorMessages.add_info(GeneratorMessages.helpful_message_after_installation)
154+
# Determine what route will be created by the generator
155+
route = "hello_world" # This is the hardcoded route from base_generator.rb
156+
component_name = options.redux? ? "HelloWorldApp" : "HelloWorld"
157+
158+
GeneratorMessages.add_info(GeneratorMessages.helpful_message_after_installation(
159+
component_name: component_name,
160+
route: route
161+
))
153162
end
154163

155164
def shakapacker_loaded_in_process?(gem_name)

lib/generators/react_on_rails/react_with_redux_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def add_redux_specific_messages
6868
require_relative "generator_messages"
6969
GeneratorMessages.output.clear
7070
GeneratorMessages.add_info(
71-
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp")
71+
GeneratorMessages.helpful_message_after_installation(component_name: "HelloWorldApp", route: "hello_world")
7272
)
7373
end
7474
end

lib/generators/react_on_rails/templates/base/base/bin/dev

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,4 @@ rescue LoadError
2828
end
2929

3030
# Main execution
31-
case ARGV[0]
32-
when "production-assets", "prod"
33-
ReactOnRails::Dev::ServerManager.start(:production_like)
34-
when "static"
35-
ReactOnRails::Dev::ServerManager.start(:static, "Procfile.dev-static-assets")
36-
when "kill"
37-
ReactOnRails::Dev::ServerManager.kill_processes
38-
when "help", "--help", "-h"
39-
ReactOnRails::Dev::ServerManager.show_help
40-
when "hmr", nil
41-
ReactOnRails::Dev::ServerManager.start(:development, "Procfile.dev")
42-
else
43-
puts "Unknown argument: #{ARGV[0]}"
44-
puts "Run 'bin/dev help' for usage information"
45-
exit 1
46-
end
31+
ReactOnRails::Dev::ServerManager.run_from_command_line(ARGV)

0 commit comments

Comments
 (0)