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
refactor: unify renderer cache staging under PreSeedRendererCache#call(mode:)
Collapse the copy-based PreSeedRendererCache and the symlink-based
PrepareNodeRenderBundles into a single entry point with a `mode:` keyword
argument. Both modes produce the identical <cache>/<hash>/<hash>.js layout;
only the file operation differs (FileUtils.cp vs relative symlink).
Changes:
- ReactOnRailsPro::PreSeedRendererCache.call now accepts mode: :copy
(default, for Docker/image builds) or mode: :symlink (same-filesystem
workflows). Rejects unknown modes with ArgumentError.
- mode: :copy now raises a clear error when neither
RENDERER_SERVER_BUNDLE_CACHE_PATH nor RENDERER_BUNDLE_PATH is set in
non-dev/test environments. The Node renderer's default lookup can
differ from the Ruby side (falling back to /tmp when cwd is outside
the app tree), so silent fallback is unsafe for production-like
deploys and was a silent-misconfig footgun.
- `react_on_rails_pro:pre_seed_renderer_cache` rake task accepts
MODE=copy (default) or MODE=symlink.
- ReactOnRailsPro::PrepareNodeRenderBundles is now a thin deprecated
shim that emits a once-per-process warning and delegates to
PreSeedRendererCache.call(mode: :symlink). Public class and the
`pre_stage_bundle_for_node_renderer` rake task remain for backward
compatibility.
- AssetsPrecompile.call invokes the unified API with mode: :symlink
after precompile (no behavior change for existing users).
- react_on_rails:doctor scans common deploy-script locations
(Procfile*, Dockerfile, bin/*) for references to the deprecated
pre_stage_bundle_for_node_renderer task and surfaces a migration
warning.
- Docs: docs/pro/node-renderer.md describes the unified API, both
modes, the non-dev env-var requirement for copy mode, and the
deprecation story.
- CHANGELOG: new Changed entry describing the unification.
- Tests: mode validation, raise-in-non-dev guard (including symlink
opt-out), deprecation warning on the shim, and a doctor check test.
Context: stacked on PR #3124 (jg/3122-preseed-renderer-cache).
Refs: #3122
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,10 @@ After a release, run `/update-changelog` in Claude Code to analyze commits, writ
28
28
29
29
-**[Pro]****Pre-seed renderer cache for Docker builds**: New `react_on_rails_pro:pre_seed_renderer_cache` rake task copies compiled server bundles into the Node Renderer's bundle-hash cache directory structure during Docker image builds, eliminating the 410→retry cold-start latency (200ms–1s+) on the first SSR request after deployment. Supports `RENDERER_SERVER_BUNDLE_CACHE_PATH`, RSC bundles, and rolling-deploy guidance centered on current and previous bundle hashes. The legacy `pre_stage_bundle_for_node_renderer` task now stages the same cache layout via symlinks for same-filesystem workflows. **Note:**`RENDERER_BUNDLE_PATH` is now deprecated in favor of `RENDERER_SERVER_BUNDLE_CACHE_PATH` across both tasks. Existing users with `RENDERER_BUNDLE_PATH` set will see a deprecation warning on stderr. [PR 3124](https://github.com/shakacode/react_on_rails/pull/3124) by [justin808](https://github.com/justin808).
30
30
31
+
#### Changed
32
+
33
+
-**[Pro]****Unified renderer cache staging**: `ReactOnRailsPro::PreSeedRendererCache.call(mode: :copy | :symlink)` is now the single entry point for staging the Node Renderer cache. Both modes produce the same `<cache>/<bundleHash>/<bundleHash>.js` layout. The `react_on_rails_pro:pre_seed_renderer_cache` rake task accepts `MODE=copy` (default; Docker/image builds) or `MODE=symlink` (same-filesystem). `MODE=copy` now raises a clear error when neither `RENDERER_SERVER_BUNDLE_CACHE_PATH` nor `RENDERER_BUNDLE_PATH` is set in non-dev/test environments, because the Node renderer's default lookup can differ from the Ruby side and would silently drop pre-seeded bundles in the wrong directory. The legacy `react_on_rails_pro:pre_stage_bundle_for_node_renderer` task and `ReactOnRailsPro::PrepareNodeRenderBundles` class remain as deprecated shims that emit a once-per-process warning and delegate to `mode: :symlink`. `react_on_rails:doctor` flags deploy scripts that still reference the deprecated task.
34
+
31
35
#### Fixed
32
36
33
37
-**Doctor accepts TypeScript server bundle entrypoints**: `react_on_rails:doctor` now resolves common source entrypoint suffixes (`.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs`) before warning that the server bundle is missing, preventing false positives when apps use `server-bundle.ts`. [PR 3111](https://github.com/shakacode/react_on_rails/pull/3111) by [justin808](https://github.com/justin808).
Copy file name to clipboardExpand all lines: docs/pro/node-renderer.md
+15-6Lines changed: 15 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -119,26 +119,35 @@ When a new container starts, the Node Renderer has an empty bundle cache. The fi
119
119
120
120
### Pre-seeding the bundle cache
121
121
122
-
The `pre_seed_renderer_cache` rake task copies compiled server bundles directly into the renderer's cache directory during your Docker build, so the renderer finds them immediately on startup:
122
+
The `pre_seed_renderer_cache` rake task stages compiled server bundles directly into the renderer's cache directory, so the renderer finds them immediately on startup.
123
+
124
+
It supports two modes, both producing the same on-disk cache layout (`<cache>/<bundleHash>/<bundleHash>.js`):
125
+
126
+
-**`MODE=copy`** (default) — copies files. Use in Docker/image builds so the cache is baked into an immutable artifact.
RUN bundle exec rake react_on_rails_pro:pre_seed_renderer_cache
127
133
```
128
134
129
-
This copies the bundle into the renderer's expected directory structure (`<cache>/<bundleHash>/<bundleHash>.js`), including any configured `assets_to_copy` and RSC bundles when RSC support is enabled.
135
+
Both modes stage the server bundle, any configured `assets_to_copy`, and (when RSC is enabled) the RSC bundle and its companion manifests.
130
136
131
-
This is the preferred path for Docker and other image-build workflows. React on Rails Pro has long supported runtime bundle uploads and the older `react_on_rails_pro:pre_stage_bundle_for_node_renderer` task for same-filesystem deployments; `pre_seed_renderer_cache` is the copy-based variant that fits immutable artifacts while using the same bundle-hash cache layout.
137
+
The `pre_seed_renderer_cache` task is also invoked automatically at the end of `assets:precompile` with `MODE=symlink`, so the local/CI/Heroku path has zero new configuration.
138
+
139
+
> [!NOTE]
140
+
> The older `react_on_rails_pro:pre_stage_bundle_for_node_renderer` rake task and `ReactOnRailsPro::PrepareNodeRenderBundles` class are deprecated in favor of the unified API. Both remain available as thin shims that emit a deprecation warning and delegate to `MODE=symlink`. `react_on_rails:doctor` flags deploy scripts that still reference the deprecated task.
132
141
133
142
### Configuration
134
143
135
144
The task follows the same environment-variable precedence as the Node Renderer, while the default fallback can differ between Ruby and standalone Node environments:
2.`RENDERER_BUNDLE_PATH` environment variable (deprecated — emits a warning)
139
-
3.`Rails.root.join(".node-renderer-bundles")` (Rails-side default when env vars are unset)
148
+
3.`Rails.root.join(".node-renderer-bundles")` (Rails-side default when env vars are unset, only accepted for `MODE=symlink` and in dev/test)
140
149
141
-
Set `RENDERER_SERVER_BUNDLE_CACHE_PATH` in your Dockerfile to match the renderer's configuration:
150
+
In **`MODE=copy`** (Docker image builds) the task requires one of the env vars above to be set in non-dev/test environments. Because the Node renderer's own default can differ (e.g., falling back to `/tmp/react-on-rails-pro-node-renderer-bundles` when its `cwd` sits outside the app tree), relying on the silent fallback risks pre-seeded bundles landing in a directory the renderer never reads. The task raises a clear error if the env var is missing:
0 commit comments