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
Fix legacy JS binstub dispatch and NODE_ENV default in helper binstubs (#1127)
## Summary
Address the **high-priority bug fixes** from the [PR #1104 follow-up
review](#1123) on
ESM-safe config binstubs.
This is **PR 1 of 3** for #1123 — focused on user-visible regressions.
Test-coverage and polish items will follow in separate PRs to keep
review scope tight.
### Fixes
- **#1 — rake task crash for upgraded apps with a legacy JS binstub.**
`shakapacker:export_bundler_config` previously invoked
`bin/shakapacker-config` via `RbConfig.ruby` unconditionally. Apps
upgraded from older Shakapacker versions still carry a `#!/usr/bin/env
node` JavaScript binstub that this gem did not rewrite — running it
through Ruby would try to parse JS as Ruby and crash. The task now
detects the shebang and dispatches: Ruby binstubs keep the
version-manager protection from #1104; legacy JS binstubs are exec'd
directly so their shebang resolves Node, and the user is nudged to run
`rake shakapacker:binstubs` to upgrade. A new
`Shakapacker::Utils::Misc.js_binstub?` helper makes the detection
unit-testable.
- **#2 — `NODE_ENV` default ignored `RAILS_ENV` in helper binstubs.**
The helper binstubs hard-coded `ENV["NODE_ENV"] ||= "development"`,
which diverged from `Shakapacker.ensure_node_env!`. Concretely,
`RAILS_ENV=production bin/shakapacker-config show-config` with
`NODE_ENV` unset spawned Node with `NODE_ENV=development` and produced
the development bundler config. The default now mirrors the Ruby logic
(`DEV_ENVS = %w[development test]`): only development and test default
to `NODE_ENV=development`; everything else defaults to `production`.
Applied in all four sync'd copies: `lib/install/bin/shakapacker-config`,
`lib/install/bin/diff-bundler-config`,
`spec/dummy/bin/shakapacker-config`, and the `createBinStub` template in
`package/configExporter/cli.ts`.
- **#6 — `error.message` guard.** `package/bin/shakapacker-config.cjs`
and `bin/shakapacker-config` now stringify non-`Error` throws (`error
instanceof Error ? error.message : String(error)`) instead of printing
`undefined`, matching the existing `formatError` pattern in
`diff-bundler-config.cjs`.
- **#7 — `NODE_ENV` default in `diff-bundler-config`.** Resolved by #2's
fix: kept the default (now using the corrected logic) with a comment
explaining why it stays consistent with `shakapacker-config`.
### Follow-up PRs
Items deferred to keep this PR focused:
- **PR 2** — test-coverage gaps: dummy binstub sync coverage (#3),
`createBinStub` template sync spec (#4), fallback-warning assertion
(#5), "Keep in sync" comments updated to list all four locations (#8),
`binstub_sync_spec` test rename (#9).
- **PR 3** — polish: replace `system(node, "--version")` probe with a
no-fork PATH walk (#10).
Refs #1123.
## Test plan
- [x] `bundle exec rspec spec/shakapacker/utils_misc_spec.rb` — new unit
tests for `js_binstub?` (8 examples)
- [x] `bundle exec rspec spec/shakapacker/helper_binstubs_spec.rb` —
existing helper binstub specs still pass (8 examples)
- [x] `bundle exec rspec spec/shakapacker/binstub_sync_spec.rb` — sync
spec still passes
- [x] `bundle exec rspec spec/shakapacker/doctor_spec.rb` — doctor specs
(147 examples) still pass
- [x] `bundle exec rubocop` — no offenses on changed Ruby files
- [x] `yarn eslint` — no errors on changed JS/TS files
- [x] `ruby -c` on all modified Ruby binstubs/rake task — syntax OK
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Medium risk because it changes how rake tasks and binstubs choose
interpreters and default environment variables, which can affect
build/config export behavior across environments.
>
> **Overview**
> **Fixes config-export helper regressions for upgraded apps.**
`shakapacker:export_bundler_config` now detects legacy `#!/usr/bin/env
node` `bin/shakapacker-config` shims and execs them directly (while
still running modern Ruby binstubs via `RbConfig.ruby`), avoiding
crashes and prompting users to regenerate binstubs.
>
> **Aligns environment defaults across helper binstubs.**
`shakapacker-config`/`diff-bundler-config` now default `NODE_ENV` to
`development` only for `RAILS_ENV` in `development|test`, otherwise
`production`, and both Node shims now stringify non-`Error` throws for
clearer stderr. Adds a unit-tested
`Shakapacker::Utils::Misc.js_binstub?` helper and updates the changelog.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
08c3c39. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed a regression when exporting bundler config after upgrades from
older installations.
* Improved detection of legacy JavaScript helper scripts (including
`env`-style shebangs) and now runs the appropriate Node or Ruby
interpreter.
* Enhanced error handling and messages when the JavaScript or Ruby
runtime can’t be executed, including upgrade guidance to refresh helper
scripts.
* **Tests**
* Expanded coverage for helper-script interpreter detection, guidance
output, and failure scenarios (including missing runtimes and varied
shebang formats).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,7 @@
22
22
### Fixed
23
23
24
24
-**Fixed dev-server passthrough argument validation messages**. [PR #1180](https://github.com/shakacode/shakapacker/pull/1180) by [justin808](https://github.com/justin808). `bin/shakapacker-dev-server -- --host ...` or `--port ...` now fails with a clearer Shakapacker message instead of forwarding the separator to the bundler; set `dev_server.host` and `dev_server.port` in `config/shakapacker.yml` instead.
25
+
-**Fixed `shakapacker:export_bundler_config` regression on apps upgraded from older Shakapacker versions**. [PR #1127](https://github.com/shakacode/shakapacker/pull/1127) by [justin808](https://github.com/justin808). The task previously invoked `bin/shakapacker-config` unconditionally via `RbConfig.ruby`, which crashed when the file was still the legacy JavaScript binstub (`#!/usr/bin/env node`) left over from earlier installs. The task now inspects the shebang and exec's the file directly when it points at Node, while keeping the Ruby+`RbConfig.ruby` path for the current Ruby binstub. Affected users are also nudged to run `bundle exec rake shakapacker:binstubs` to refresh their helper binstub. Refs [#1123](https://github.com/shakacode/shakapacker/issues/1123).
25
26
-**Fixed `shakapacker:doctor` Sass implementation detection for `sass-embedded` apps**. [PR #1178](https://github.com/shakacode/shakapacker/pull/1178) by [justin808](https://github.com/justin808). The doctor now accepts either modern Sass implementation package (`sass` or `sass-embedded`) when Sass files are present, matching Shakapacker's default modern Sass API instead of incorrectly requiring Dart Sass. New installs also include `sass` alongside `sass-loader`. Fixes [#1172](https://github.com/shakacode/shakapacker/issues/1172).
26
27
-**Fixed compiler strategies ignoring the instance config of custom `Shakapacker::Instance` objects.**[PR #1147](https://github.com/shakacode/shakapacker/pull/1147) by [justin808](https://github.com/justin808). Ports [#976](https://github.com/shakacode/shakapacker/pull/976) by [brunodccarvalho](https://github.com/brunodccarvalho). Strategies now read the instance-specific config and watch both webpack and rspack config directories.
0 commit comments