-
-
Notifications
You must be signed in to change notification settings - Fork 632
Improve fresh Pro install docs and generator defaults #2494
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -542,6 +542,22 @@ describe('buildVM and runInVM', () => { | |
| expect(vmContext1).toBe(vmContext2); | ||
| }); | ||
|
|
||
| test('buildVM recovers after failure for nonexistent bundle', async () => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test doesn't call Adding test('buildVM recovers after failure for nonexistent bundle', async () => {
resetVM(); // start with a clean slate
const config = getConfig();
config.supportModules = true;
config.stubTimers = false;
const nonExistentPath = path.resolve(__dirname, './tmp/nonexistent-bundle.js');
// First call should fail because the bundle file does not exist
await expect(buildVM(nonExistentPath)).rejects.toThrow();
// After failure, the vmCreationPromises map should be cleaned up,
// allowing a retry with the correct path to succeed
await buildVM(serverBundlePath);
expect(hasVMContextForBundle(serverBundlePath)).toBeTruthy();
}); |
||
| const config = getConfig(); | ||
| config.supportModules = true; | ||
| config.stubTimers = false; | ||
|
|
||
| const nonExistentPath = path.resolve(__dirname, './tmp/nonexistent-bundle.js'); | ||
|
|
||
| // First call should fail because the bundle file does not exist | ||
| await expect(buildVM(nonExistentPath)).rejects.toThrow(); | ||
|
|
||
| // After failure, the vmCreationPromises map should be cleaned up, | ||
| // allowing a retry with the correct path to succeed | ||
| await buildVM(serverBundlePath); | ||
| expect(hasVMContextForBundle(serverBundlePath)).toBeTruthy(); | ||
| }); | ||
|
|
||
| test('running runInVM before buildVM', async () => { | ||
| resetVM(); | ||
| void prepareVM(true); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -130,6 +130,10 @@ def copy_packer_config | |
| # Always ensure precompile_hook is configured (Shakapacker 9.0+ only) | ||
| # This handles all scenarios: fresh install, pre-installed Shakapacker, or user declined overwrite | ||
| configure_precompile_hook_in_shakapacker | ||
|
|
||
| # For SSR bundles, configure Shakapacker private_output_path (9.0+ only) | ||
| # This keeps Shakapacker and React on Rails server bundle paths in sync. | ||
| configure_private_output_path_in_shakapacker | ||
| end | ||
|
|
||
| def add_base_gems_to_gemfile | ||
|
|
@@ -362,6 +366,38 @@ def configure_precompile_hook_in_shakapacker | |
|
|
||
| puts Rainbow("✅ Configured precompile_hook in shakapacker.yml").green | ||
| end | ||
|
|
||
| def configure_private_output_path_in_shakapacker | ||
| # private_output_path is only supported in Shakapacker 9.0+ | ||
| return unless ReactOnRails::PackerUtils.shakapacker_version_requirement_met?("9.0.0") | ||
|
|
||
| shakapacker_config_path = "config/shakapacker.yml" | ||
| return unless File.exist?(shakapacker_config_path) | ||
|
|
||
| content = File.read(shakapacker_config_path) | ||
|
|
||
| # Already configured? Do nothing. | ||
| return if content.match?(/^\s*private_output_path:\s*\S+/) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Suggest broadening the guard to cover any existing key (regardless of value): return if content.match?(/^\s*private_output_path:/)If you need to distinguish "set to a real value" from "set to null / empty", handle that case explicitly rather than silently re-inserting. |
||
|
|
||
| # First try: uncomment an existing private_output_path placeholder line. | ||
| updated_content = content.sub( | ||
| /^(\s*)#\s*private_output_path:\s*.*$/, | ||
| "\\1private_output_path: ssr-generated" | ||
| ) | ||
|
|
||
| # Fallback: insert directly after public_output_path in the default section. | ||
| if updated_content == content | ||
| updated_content = content.sub( | ||
| /^(\s*)public_output_path:\s*.*\n/, | ||
| "\\0\\1private_output_path: ssr-generated\n" | ||
| ) | ||
| end | ||
|
|
||
| return if updated_content == content | ||
|
|
||
| File.write(shakapacker_config_path, updated_content) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using Consider restructuring as two separate # Step 1: try to uncomment the placeholder line
gsub_file shakapacker_config_path,
/^(\s*)#\s*private_output_path:\s*.*$/,
"\\1private_output_path: ssr-generated"
# Step 2: if the placeholder wasn't there, insert after public_output_path
unless File.read(shakapacker_config_path).match?(/^\s*private_output_path: ssr-generated/)
insert_into_file shakapacker_config_path,
"\\1private_output_path: ssr-generated\n",
after: /^(\s*)public_output_path:.*\n/
endThis keeps the logic consistent with the rest of the generator. |
||
| puts Rainbow("✅ Configured private_output_path in shakapacker.yml").green | ||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # Procfile for development | ||
| # You can run these commands in separate shells | ||
| rails: bundle exec rails s -p 3000 | ||
| rails: bundle exec rails s -p ${PORT:-3000} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Procfile PORT default never used via process managersMedium Severity The Additional Locations (2) |
||
| dev-server: bin/shakapacker-dev-server | ||
| server-bundle: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| web: bin/rails server -p 3000 | ||
| web: bin/rails server -p ${PORT:-3000} | ||
| js: bin/shakapacker --watch |


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.
The
.catch(() => {}).finally(...)chain is the right pattern here — the.catchis necessary to prevent an unhandled rejection on thevoid-ed chain (since.finally()on a rejected promise propagates the rejection through the tail). The comment could be a touch more explicit about this:No functional change needed — just a suggestion for clarity.