diff --git a/lib/react_on_rails/configuration.rb b/lib/react_on_rails/configuration.rb index 3ef7332d2..7c51accfb 100644 --- a/lib/react_on_rails/configuration.rb +++ b/lib/react_on_rails/configuration.rb @@ -320,15 +320,20 @@ def configure_generated_assets_dirs_deprecation end def ensure_webpack_generated_files_exists - return unless webpack_generated_files.empty? - - self.webpack_generated_files = [ + all_required_files = [ "manifest.json", server_bundle_js_file, rsc_bundle_js_file, react_client_manifest_file, react_server_client_manifest_file ].compact_blank + + if webpack_generated_files.empty? + self.webpack_generated_files = all_required_files + else + missing_files = all_required_files.reject { |file| webpack_generated_files.include?(file) } + self.webpack_generated_files += missing_files if missing_files.any? + end end def configure_skip_display_none_deprecation diff --git a/spec/react_on_rails/configuration_spec.rb b/spec/react_on_rails/configuration_spec.rb index 4d79e0e6d..d4e25a29f 100644 --- a/spec/react_on_rails/configuration_spec.rb +++ b/spec/react_on_rails/configuration_spec.rb @@ -525,6 +525,152 @@ module ReactOnRails end end end + + describe "#ensure_webpack_generated_files_exists" do + let(:config) { described_class.new } + + before do + # Reset to test defaults + config.server_bundle_js_file = "server-bundle.js" + config.rsc_bundle_js_file = nil + config.react_client_manifest_file = "react-client-manifest.json" + config.react_server_client_manifest_file = "react-server-client-manifest.json" + end + + context "when webpack_generated_files has default manifest.json only" do + it "automatically includes server bundle when configured" do + config.webpack_generated_files = %w[manifest.json] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).to eq(%w[ + manifest.json + server-bundle.js + react-client-manifest.json + react-server-client-manifest.json + ]) + end + + it "does not duplicate manifest.json" do + config.webpack_generated_files = %w[manifest.json] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files.count("manifest.json")).to eq(1) + end + end + + context "when webpack_generated_files is empty" do + it "populates with all required files" do + config.webpack_generated_files = [] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).to eq(%w[ + manifest.json + server-bundle.js + react-client-manifest.json + react-server-client-manifest.json + ]) + end + end + + context "when server bundle already included" do + it "does not duplicate entries" do + config.webpack_generated_files = %w[manifest.json server-bundle.js] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).to eq(%w[ + manifest.json + server-bundle.js + react-client-manifest.json + react-server-client-manifest.json + ]) + expect(config.webpack_generated_files.count("server-bundle.js")).to eq(1) + end + end + + context "when custom files are configured" do + it "preserves custom files and adds missing critical files" do + config.webpack_generated_files = %w[manifest.json custom-bundle.js] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).to include("manifest.json") + expect(config.webpack_generated_files).to include("custom-bundle.js") + expect(config.webpack_generated_files).to include("server-bundle.js") + expect(config.webpack_generated_files).to include("react-client-manifest.json") + end + end + + context "when server bundle is not configured" do + it "does not add nil server bundle" do + config.server_bundle_js_file = nil + config.webpack_generated_files = %w[manifest.json] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).not_to include(nil) + expect(config.webpack_generated_files).not_to include("server-bundle.js") + expect(config.webpack_generated_files).to include("manifest.json") + end + end + + context "when RSC bundle is configured" do + it "includes RSC bundle in monitoring" do + config.rsc_bundle_js_file = "rsc-bundle.js" + config.webpack_generated_files = %w[manifest.json] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).to include("rsc-bundle.js") + expect(config.webpack_generated_files).to include("server-bundle.js") + expect(config.webpack_generated_files).to include("manifest.json") + end + end + + context "when React manifests are not configured" do + it "does not add nil React manifests" do + config.react_client_manifest_file = nil + config.react_server_client_manifest_file = nil + config.webpack_generated_files = %w[manifest.json] + + config.send(:ensure_webpack_generated_files_exists) + + expect(config.webpack_generated_files).not_to include(nil) + expect(config.webpack_generated_files).to eq(%w[manifest.json server-bundle.js]) + end + end + + context "when ensuring server bundle monitoring for RSpec optimization" do + it "ensures server bundle in private directory is monitored with default config" do + # Simulate default generator configuration + config.webpack_generated_files = %w[manifest.json] + config.server_bundle_js_file = "server-bundle.js" + config.server_bundle_output_path = "ssr-generated" + + config.send(:ensure_webpack_generated_files_exists) + + # Critical: server bundle must be included for RSpec helper optimization to work + expect(config.webpack_generated_files).to include("server-bundle.js") + end + + it "handles all files being in different directories" do + # Simulate cross-directory scenario from PR #1798 + config.webpack_generated_files = %w[manifest.json] + config.server_bundle_js_file = "server-bundle.js" + config.server_bundle_output_path = "ssr-generated" + config.generated_assets_dir = "public/packs" + + config.send(:ensure_webpack_generated_files_exists) + + # All critical files should be monitored regardless of directory + expect(config.webpack_generated_files).to include("manifest.json") + expect(config.webpack_generated_files).to include("server-bundle.js") + end + end + end end end