You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add automatic precompile hook coordination in bin/dev (#2092)
## Summary
Adds automatic precompile hook coordination to `bin/dev`, eliminating
the need for manual coordination, sleep hacks, and duplicate task calls
in `Procfile.dev`.
**This PR is focused solely on the bin/dev coordination feature.** The
complementary idempotent locale generation feature is in PR #2093.
## How It Works
When you configure a `precompile_hook` in `config/shakapacker.yml`:
```yaml
default: &default
precompile_hook: 'bundle exec rake react_on_rails:locale'
```
`bin/dev` will now:
1. ✅ Run the hook **once** before starting development processes
2. ✅ Set `SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true` environment variable
3. ✅ Pass the env var to all spawned processes (Rails, webpack, etc.)
4. ✅ Prevent webpack processes from re-running the hook independently
## Before & After
**Before (manual coordination with sleep hacks):**
```procfile
# Procfile.dev
wp-server: sleep 15 && bundle exec rake react_on_rails:locale && bin/shakapacker --watch
```
**After (automatic coordination via bin/dev):**
```procfile
# Procfile.dev
wp-server: bin/shakapacker --watch
```
```yaml
# config/shakapacker.yml
default: &default
precompile_hook: 'bundle exec rake react_on_rails:locale'
```
Clean, simple, reliable - no sleep hacks required!
## Key Features
**Shakapacker Version Detection**
- Checks if you're using Shakapacker < 9.4.0
- Displays friendly warning about `SHAKAPACKER_SKIP_PRECOMPILE_HOOK`
support
- Recommends upgrading to 9.4.0+ to avoid duplicate hook execution
**Error Handling**
- Exits immediately if precompile hook fails
- Shows clear error message with the failed command
- Suggests fixing or removing the hook from config
**Smart Skipping**
- Skips hook execution for `bin/dev kill` and `bin/dev help` commands
- Only runs hook for actual development modes (hmr, static, prod)
**Help Flag Handling**
- Detects `-h`/`--help` flags early
- Prevents hook execution when user just wants help
- Maintains clean separation between help and runtime logic
## Use Cases
**Locale generation (with PR #2093):**
```yaml
precompile_hook: 'bundle exec rake react_on_rails:locale'
```
**ReScript compilation:**
```yaml
precompile_hook: 'yarn rescript'
```
**Multiple tasks:**
```yaml
precompile_hook: 'bundle exec rake react_on_rails:locale && yarn rescript'
```
Any expensive build task that needs to run before webpack starts!
## Implementation Details
**Modified Files:**
- `lib/react_on_rails/dev/server_manager.rb` - Core coordination logic
- `spec/react_on_rails/dev/server_manager_spec.rb` - Comprehensive test
coverage (161 lines)
- `docs/building-features/process-managers.md` - Feature documentation
- `docs/building-features/i18n.md` - Usage example with locale
generation
**Test Coverage:**
- ✅ Hook execution for all modes (development, static, prod)
- ✅ Environment variable setting across all modes
- ✅ Skipping for kill/help commands
- ✅ Help flag handling (-h/--help)
- ✅ Shakapacker version warning (< 9.4.0)
- ✅ Error handling when hook fails
- ✅ No-hook configuration scenario
## Shakapacker Version Requirements
- **9.3.0+**: `precompile_hook` configuration support
- **9.4.0+**: `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` env var support
(prevents duplicate execution)
If you're on Shakapacker < 9.4.0, `bin/dev` will warn you that the hook
may run multiple times.
## Related PRs
- PR #2093 - Idempotent locale generation (makes `react_on_rails:locale`
safe to call multiple times)
- Issue #2091 - Original feature request
## Breaking Changes
None - this is purely additive functionality.
## Testing
Run the test suite:
```bash
bundle exec rspec spec/react_on_rails/dev/server_manager_spec.rb
```
Manual testing:
```bash
# Configure a precompile_hook in config/shakapacker.yml
echo 'default: &default\n precompile_hook: "echo Running hook..."' >> config/shakapacker.yml
# Run bin/dev and verify:
bin/dev
# Should see: "🔧 Running Shakapacker precompile hook..."
# Should see: "Running hook..."
# Should see: "✅ Precompile hook completed successfully"
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,15 @@ After a release, please make sure to run `bundle exec rake update_changelog`. Th
23
23
24
24
Changes since the last non-beta release.
25
25
26
+
#### Improved
27
+
28
+
-**Automatic Precompile Hook Coordination in bin/dev**: The `bin/dev` command now automatically runs Shakapacker's `precompile_hook` once before starting development processes and sets `SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true` to prevent duplicate execution in spawned webpack processes.
29
+
- Eliminates the need for manual coordination, sleep hacks, and duplicate task calls in Procfile.dev
30
+
- Users can configure expensive build tasks (like locale generation or ReScript compilation) once in `config/shakapacker.yml` and `bin/dev` handles coordination automatically
31
+
- Includes warning for Shakapacker versions below 9.4.0 (the `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable is only supported in 9.4.0+)
32
+
- The `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable is set for all spawned processes, making it available for custom scripts that need to detect when `bin/dev` is managing the precompile hook
33
+
- Addresses [2091](https://github.com/shakacode/react_on_rails/issues/2091) by [justin808](https://github.com/justin808)
Copy file name to clipboardExpand all lines: docs/building-features/i18n.md
+24-3Lines changed: 24 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,10 +21,31 @@ You can use [Rails internationalization (i18n)](https://guides.rubyonrails.org/i
21
21
22
22
3. The locale files must be generated before `yarn build` using `rake react_on_rails:locale`.
23
23
24
-
For development, you should adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any Webpack watch process (`yarn run build:development`).
24
+
**Recommended: Use Shakapacker's precompile_hook with bin/dev** (React on Rails 16.2+, Shakapacker 9.3+)
25
25
26
-
If you are not using the React on Rails test helper,
27
-
you may need to configure your CI to run `bundle exec rake react_on_rails:locale` before any Webpack process as well.
26
+
The locale generation task is idempotent and can be safely called multiple times. Configure it in Shakapacker's `precompile_hook` and `bin/dev` will handle coordination automatically:
27
+
28
+
```yaml
29
+
# config/shakapacker.yml
30
+
default: &default
31
+
# Run locale generation before webpack compilation
32
+
# Safe to run multiple times - will skip if already built
- Run the precompile hook **once** before starting development processes
39
+
- Set `SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true` to prevent duplicate execution
40
+
- Pass the environment variable to all spawned processes (Rails, webpack, etc.)
41
+
42
+
This eliminates the need for sleep hacks and manual coordination in `Procfile.dev`. See the [Process Managers documentation](./process-managers.md#precompile-hook-integration) for details.
43
+
44
+
**Alternative: Manual coordination**
45
+
46
+
For development, you can adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any Webpack watch process (`yarn run build:development`).
47
+
48
+
If you are not using the React on Rails test helper, you may need to configure your CI to run `bundle exec rake react_on_rails:locale` before any Webpack process as well.
28
49
29
50
> [!NOTE]
30
51
> If you try to lint before running tests, and you depend on the test helper to build your locales, linting will fail because the translations won't be built yet.
Copy file name to clipboardExpand all lines: docs/building-features/process-managers.md
+40-3Lines changed: 40 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,9 +16,46 @@ React on Rails includes `bin/dev` which automatically uses Overmind or Foreman:
16
16
17
17
This script will:
18
18
19
-
1. Try to use Overmind (if installed)
20
-
2. Fall back to Foreman (if installed)
21
-
3. Show installation instructions if neither is found
19
+
1. Run Shakapacker's `precompile_hook` once (if configured in `config/shakapacker.yml`)
20
+
2. Set `SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true` to prevent duplicate execution
21
+
3. Try to use Overmind (if installed)
22
+
4. Fall back to Foreman (if installed)
23
+
5. Show installation instructions if neither is found
24
+
25
+
### Precompile Hook Integration
26
+
27
+
If you have configured a `precompile_hook` in `config/shakapacker.yml`, `bin/dev` will automatically:
28
+
29
+
- Execute the hook **once** before starting development processes
30
+
- Set the `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable
31
+
- Pass this environment variable to all spawned processes (Rails, webpack, etc.)
32
+
- Prevent webpack processes from re-running the hook independently
33
+
34
+
**Note:** The `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable is supported in Shakapacker 9.4.0 and later. If you're using an earlier version, `bin/dev` will display a warning recommending you upgrade to avoid duplicate hook execution.
35
+
36
+
This eliminates the need for manual coordination in your `Procfile.dev`. For example:
37
+
38
+
**Before (manual coordination with sleep hacks):**
0 commit comments