Skip to content

Commit

Permalink
Always generate append_X_pack calls if not in development (#1545)
Browse files Browse the repository at this point in the history
* always generate append_X_pack calls if not in development
  • Loading branch information
Judahmeek authored Jun 14, 2023
1 parent 631ca55 commit 43efef2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Changes since last non-beta release.

*Please add entries here for your pull requests that are not yet released.*

### Removed
- Removed a requirement for autoloaded pack files to be generated as part of CI or deployment separate from initial Shakapacker bundling. [PR 1545](https://github.com/shakacode/react_on_rails/pull/1545) by [judahmeek](https://github.com/judahmeek).

### [13.3.5] - 2022-05-31
#### Fixed
- Fixed race condition where a react component could attempt to initialize before it had been registered. [PR 1540](https://github.com/shakacode/react_on_rails/pull/1540) by [judahmeek](https://github.com/judahmeek).
Expand Down
10 changes: 0 additions & 10 deletions docs/guides/file-system-based-automated-bundle-generation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
Attention! If you are visiting this doc because you are encountering new failures on CI while implementing this feature, be sure to read [our section specifically for CI integration](#integrating-auto-bundling-into-ci-workflows)!

# File-System-Based Automated Bundle Generation

To use the automated bundle generation feature introduced in React on Rails v13.1.0, please upgrade to use [Shakapacker v6.5.1](https://github.com/shakacode/shakapacker/tree/v6.5.1) at least. If you are currently using webpacker, please follow the migration steps available [here](https://github.com/shakacode/shakapacker/blob/master/docs/v6_upgrade.md).
Expand Down Expand Up @@ -196,12 +194,4 @@ Once generated, all server entrypoints will be imported into a file named `[Reac

As of version 13.3.4, bundles inside of directories that match `config.components_subdirectory` will be automatically added as entrypoints, while bundles outside of those directories will have to be manually added to the Shakapacker.config.source_entry_path or Webpack's `entry` rules.

### Integrating auto-bundling into CI workflows

Currently, ReactOnRails contains conditional logic that checks for the existence of generated entrypoint files whenever `react_component` or one of its derivative methods are called. If a generated entrypoint of the same name as provided to `react_component` or `react_component_hash` exists, then an `append_javascript_pack` call is made automatically.

This means that `rake react_on_rails:generate_packs` or its programmatic equivalent must be run as a prerequisite to any sort of test or spec that would result in `react_component` or `react_component_hash` being called, even if the generated entrypoint files have already been bundled in a previous workflow/job.

Caching of the generated entrypoints between workflow/jobs should also resolve this issue.


34 changes: 23 additions & 11 deletions lib/react_on_rails/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,20 +313,25 @@ def rails_context(server_side: true)
@rails_context.merge(serverSide: server_side)
end

def load_pack_for_generated_component(component_name)
ReactOnRails::WebpackerUtils.raise_nested_entries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
def load_pack_for_generated_component(react_component_name, render_options)
return unless render_options.auto_load_bundle

append_javascript_pack_tag("generated/#{component_name}",
ReactOnRails::WebpackerUtils.raise_nested_entries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
if Rails.env.development?
is_component_pack_present = File.exist?(generated_components_pack_path(react_component_name))
raise_missing_autoloaded_bundle(react_component_name) unless is_component_pack_present
end
append_javascript_pack_tag("generated/#{react_component_name}",
defer: ReactOnRails.configuration.defer_generated_component_packs)
append_stylesheet_pack_tag("generated/#{component_name}")
append_stylesheet_pack_tag("generated/#{react_component_name}")
end

# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity

private

def generated_components_pack_path(component_name)
"#{ReactOnRails::WebpackerUtils.webpacker_source_entry_path}/generated/#{component_name}.js"
def generated_components_pack_path(react_component_name)
"#{ReactOnRails::WebpackerUtils.webpacker_source_entry_path}/generated/#{react_component_name}.js"
end

def build_react_component_result_for_server_rendered_string(
Expand Down Expand Up @@ -439,11 +444,7 @@ def internal_react_component(react_component_name, options = {})
# Create the HTML rendering part
result = server_rendered_react_component(render_options)

if render_options.auto_load_bundle
is_component_pack_present = File.exist?(generated_components_pack_path(react_component_name))

load_pack_for_generated_component(react_component_name) if is_component_pack_present
end
load_pack_for_generated_component(react_component_name, render_options)

{
render_options: render_options,
Expand Down Expand Up @@ -564,6 +565,17 @@ def in_mailer?
instrument_method :react_component, type: "ReactOnRails", name: "react_component"
instrument_method :react_component_hash, type: "ReactOnRails", name: "react_component_hash"
end

def raise_missing_autoloaded_bundle(react_component_name)
msg = <<~MSG
**ERROR** ReactOnRails: Component "#{react_component_name}" is configured as "auto_load_bundle: true"
but the generated component entrypoint, which should have been at #{generated_components_pack_path(react_component_name)},
is missing. You might want to check that this component is in a directory named "#{ReactOnRails.configuration.components_subdirectory}"
& that "bundle exec rake react_on_rails:generate_packs" has been run.
MSG

raise ReactOnRails::Error, msg
end
end
end
# rubocop:enable Metrics/ModuleLength
Expand Down
13 changes: 12 additions & 1 deletion spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,24 @@ class PlainReactOnRailsHelper
end

describe "#load_pack_for_generated_component" do
let(:render_options) do
ReactOnRails::ReactComponent::RenderOptions.new(react_component_name: "component_name",
options: {})
end

it "appends js/css pack tag" do
allow(helper).to receive(:append_javascript_pack_tag)
allow(helper).to receive(:append_stylesheet_pack_tag)
expect { helper.load_pack_for_generated_component("component_name") }.not_to raise_error
expect { helper.load_pack_for_generated_component("component_name", render_options) }.not_to raise_error
expect(helper).to have_received(:append_javascript_pack_tag).with("generated/component_name", { defer: true })
expect(helper).to have_received(:append_stylesheet_pack_tag).with("generated/component_name")
end

it "throws an error in development if generated component isn't found" do
allow(Rails.env).to receive(:development?).and_return(true)
expect { helper.load_pack_for_generated_component("nonexisting_component", render_options) }
.to raise_error(ReactOnRails::Error, /the generated component entrypoint/)
end
end

describe "#json_safe_and_pretty(hash_or_string)" do
Expand Down

0 comments on commit 43efef2

Please sign in to comment.