From c7af7ef14156dc44b0852156b85ffa00962ebdac Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 25 Nov 2025 21:18:39 -1000 Subject: [PATCH 1/3] Add suppress_unused_component_warnings config option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ability to suppress console.warn messages about registered components that are not used on a page. This is useful in production environments where many React components are registered globally but only a subset are used on each page. Configuration: config.suppress_unused_component_warnings = true Changes: - Add suppress_unused_component_warnings config option (default: false) - Pass option to railsContext as suppressUnusedComponentWarnings - Update CallbackRegistry to check the option before logging warnings - Update TypeScript types and RBS signatures - Update documentation and tests Closes #2117 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CHANGELOG.md | 2 ++ docs/api-reference/configuration.md | 15 +++++++++++++++ .../react-on-rails-pro/src/CallbackRegistry.ts | 15 ++++++++++----- packages/react-on-rails/src/types/index.ts | 1 + .../react-on-rails/tests/ClientRenderer.test.ts | 4 ++++ .../lib/react_on_rails/configuration.rb | 10 ++++++++-- react_on_rails/lib/react_on_rails/helper.rb | 1 + .../sig/react_on_rails/configuration.rbs | 2 ++ 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9349e3a348..4b655b26cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ Changes since the last non-beta release. #### Added +- **Suppress Unused Component Warnings**: Added `suppress_unused_component_warnings` configuration option to disable console warnings about registered components that are not used on a page. This is useful for production environments where many components are registered globally but only a subset are used on each page. Set `config.suppress_unused_component_warnings = true` in your React on Rails initializer. Note: This only affects React on Rails Pro users. [PR 2125](https://github.com/shakacode/react_on_rails/pull/2125) by [justin808](https://github.com/justin808). + - **Service Dependency Checking for bin/dev**: Added optional `.dev-services.yml` configuration to validate required external services (Redis, PostgreSQL, Elasticsearch, etc.) are running before `bin/dev` starts the development server. Provides clear error messages with start commands and install hints when services are missing. Zero impact if not configured - backwards compatible with all existing installations. [PR 2098](https://github.com/shakacode/react_on_rails/pull/2098) by [justin808](https://github.com/justin808). #### Changed diff --git a/docs/api-reference/configuration.md b/docs/api-reference/configuration.md index 2675624460..010c6b3696 100644 --- a/docs/api-reference/configuration.md +++ b/docs/api-reference/configuration.md @@ -710,6 +710,21 @@ config.component_registry_timeout = 5000 # default (5 seconds) Set to `0` to wait indefinitely (not recommended for production). +#### suppress_unused_component_warnings + +**Type:** Boolean +**Default:** `false` + +Suppress console warnings about registered components that are not used on a page: + +```ruby +config.suppress_unused_component_warnings = true +``` + +When many React components are registered globally but only a subset are used on each page, React on Rails Pro will emit console warnings suggesting the unused components may be cleaned up. Set this option to `true` to suppress these warnings, which is useful in production environments where such warnings can be noisy. + +> **Note:** This configuration option only affects React on Rails Pro users, as the warnings are generated by the Pro package's component registry timeout feature. + ### I18n Configuration These options are for applications using [react-intl](https://formatjs.io/docs/react-intl/) or similar internationalization libraries. If your application doesn't need i18n, you can skip this section. diff --git a/packages/react-on-rails-pro/src/CallbackRegistry.ts b/packages/react-on-rails-pro/src/CallbackRegistry.ts index c3015d7355..a0fa8dfaaa 100644 --- a/packages/react-on-rails-pro/src/CallbackRegistry.ts +++ b/packages/react-on-rails-pro/src/CallbackRegistry.ts @@ -53,11 +53,16 @@ export default class CallbackRegistry { this.waitingPromises.forEach((waitingPromiseInfo, itemName) => { waitingPromiseInfo.reject(this.createNotFoundError(itemName)); }); - this.notUsedItems.forEach((itemName) => { - console.warn( - `Warning: ${this.registryType} '${itemName}' was registered but never used. This may indicate unused code that can be removed.`, - ); - }); + + // Only log warnings if not suppressed via configuration + const suppressWarnings = getRailsContext()?.suppressUnusedComponentWarnings; + if (!suppressWarnings) { + this.notUsedItems.forEach((itemName) => { + console.warn( + `Warning: ${this.registryType} '${itemName}' was registered but never used. This may indicate unused code that can be removed.`, + ); + }); + } }; onPageLoaded(() => { diff --git a/packages/react-on-rails/src/types/index.ts b/packages/react-on-rails/src/types/index.ts index 22f5b962bd..32d23e29be 100644 --- a/packages/react-on-rails/src/types/index.ts +++ b/packages/react-on-rails/src/types/index.ts @@ -20,6 +20,7 @@ type ReactComponent = ComponentType | string; // Keep these in sync with method lib/react_on_rails/helper.rb#rails_context export type RailsContext = { componentRegistryTimeout: number; + suppressUnusedComponentWarnings: boolean; railsEnv: string; inMailer: boolean; i18nLocale: string; diff --git a/packages/react-on-rails/tests/ClientRenderer.test.ts b/packages/react-on-rails/tests/ClientRenderer.test.ts index 21ad1cee26..1fc1dcf0ae 100644 --- a/packages/react-on-rails/tests/ClientRenderer.test.ts +++ b/packages/react-on-rails/tests/ClientRenderer.test.ts @@ -59,6 +59,7 @@ describe('ClientRenderer', () => { httpAcceptLanguage: 'en', serverSide: false, componentRegistryTimeout: 0, + suppressUnusedComponentWarnings: false, }); document.body.appendChild(railsContextElement); @@ -116,6 +117,7 @@ describe('ClientRenderer', () => { httpAcceptLanguage: 'en', serverSide: false, componentRegistryTimeout: 0, + suppressUnusedComponentWarnings: false, }); document.body.appendChild(railsContextElement); @@ -145,6 +147,7 @@ describe('ClientRenderer', () => { httpAcceptLanguage: 'en', serverSide: false, componentRegistryTimeout: 0, + suppressUnusedComponentWarnings: false, }); document.body.appendChild(railsContextElement); @@ -195,6 +198,7 @@ describe('ClientRenderer', () => { httpAcceptLanguage: 'en', serverSide: false, componentRegistryTimeout: 0, + suppressUnusedComponentWarnings: false, }); document.body.appendChild(railsContextElement); diff --git a/react_on_rails/lib/react_on_rails/configuration.rb b/react_on_rails/lib/react_on_rails/configuration.rb index 2f8d66ff97..e524b9fdc7 100644 --- a/react_on_rails/lib/react_on_rails/configuration.rb +++ b/react_on_rails/lib/react_on_rails/configuration.rb @@ -64,6 +64,10 @@ def self.configuration # If exceeded, an error will be thrown for server-side rendered components not registered on the client. # Set to 0 to disable the timeout and wait indefinitely for component registration. component_registry_timeout: DEFAULT_COMPONENT_REGISTRY_TIMEOUT, + # Set to true to suppress warnings about registered components not being used on a page. + # This can be useful in production environments where many components are registered globally + # but only a subset are used on each page. + suppress_unused_component_warnings: false, generated_component_packs_loading_strategy: nil, server_bundle_output_path: DEFAULT_SERVER_BUNDLE_OUTPUT_PATH, enforce_private_server_bundles: false @@ -82,7 +86,7 @@ class Configuration :same_bundle_for_client_and_server, :rendering_props_extension, :make_generated_server_bundle_the_entrypoint, :generated_component_packs_loading_strategy, - :component_registry_timeout, + :component_registry_timeout, :suppress_unused_component_warnings, :server_bundle_output_path, :enforce_private_server_bundles # Class instance variable and mutex to track if deprecation warning has been shown @@ -144,7 +148,8 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, i18n_yml_safe_load_options: nil, random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil, components_subdirectory: nil, auto_load_bundle: nil, - component_registry_timeout: nil, server_bundle_output_path: nil, enforce_private_server_bundles: nil) + component_registry_timeout: nil, suppress_unused_component_warnings: nil, + server_bundle_output_path: nil, enforce_private_server_bundles: nil) self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root self.generated_assets_dirs = generated_assets_dirs self.generated_assets_dir = generated_assets_dir @@ -169,6 +174,7 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender self.skip_display_none = skip_display_none self.rendering_props_extension = rendering_props_extension self.component_registry_timeout = component_registry_timeout + self.suppress_unused_component_warnings = suppress_unused_component_warnings || false # Server rendering: self.server_bundle_js_file = server_bundle_js_file diff --git a/react_on_rails/lib/react_on_rails/helper.rb b/react_on_rails/lib/react_on_rails/helper.rb index ec883db173..e98954171f 100644 --- a/react_on_rails/lib/react_on_rails/helper.rb +++ b/react_on_rails/lib/react_on_rails/helper.rb @@ -274,6 +274,7 @@ def rails_context(server_side: true) @rails_context ||= begin result = { componentRegistryTimeout: ReactOnRails.configuration.component_registry_timeout, + suppressUnusedComponentWarnings: ReactOnRails.configuration.suppress_unused_component_warnings, railsEnv: Rails.env, inMailer: in_mailer?, # Locale settings diff --git a/react_on_rails/sig/react_on_rails/configuration.rbs b/react_on_rails/sig/react_on_rails/configuration.rbs index 961270141f..6d31d67c79 100644 --- a/react_on_rails/sig/react_on_rails/configuration.rbs +++ b/react_on_rails/sig/react_on_rails/configuration.rbs @@ -32,6 +32,7 @@ module ReactOnRails attr_accessor generated_component_packs_loading_strategy: Symbol? attr_accessor immediate_hydration: bool attr_accessor component_registry_timeout: Integer + attr_accessor suppress_unused_component_warnings: bool attr_accessor server_bundle_output_path: String? attr_accessor enforce_private_server_bundles: bool @@ -68,6 +69,7 @@ module ReactOnRails ?auto_load_bundle: bool?, ?immediate_hydration: bool?, ?component_registry_timeout: Integer?, + ?suppress_unused_component_warnings: bool?, ?server_bundle_output_path: String?, ?enforce_private_server_bundles: bool? ) -> void From 60885767f027665e6abbd49deabaf936df99457b Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 25 Nov 2025 21:51:20 -1000 Subject: [PATCH 2/3] Address review feedback: fix PR number and add unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix CHANGELOG PR reference (was 2125, now correct 2136) - Add unit tests for suppress_unused_component_warnings configuration - Test default value is false - Test can be set to true - Test can be set to false explicitly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CHANGELOG.md | 2 +- .../spec/react_on_rails/configuration_spec.rb | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b655b26cf..a01c4adc52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ Changes since the last non-beta release. #### Added -- **Suppress Unused Component Warnings**: Added `suppress_unused_component_warnings` configuration option to disable console warnings about registered components that are not used on a page. This is useful for production environments where many components are registered globally but only a subset are used on each page. Set `config.suppress_unused_component_warnings = true` in your React on Rails initializer. Note: This only affects React on Rails Pro users. [PR 2125](https://github.com/shakacode/react_on_rails/pull/2125) by [justin808](https://github.com/justin808). +- **Suppress Unused Component Warnings**: Added `suppress_unused_component_warnings` configuration option to disable console warnings about registered components that are not used on a page. This is useful for production environments where many components are registered globally but only a subset are used on each page. Set `config.suppress_unused_component_warnings = true` in your React on Rails initializer. Note: This only affects React on Rails Pro users. [PR 2136](https://github.com/shakacode/react_on_rails/pull/2136) by [justin808](https://github.com/justin808). - **Service Dependency Checking for bin/dev**: Added optional `.dev-services.yml` configuration to validate required external services (Redis, PostgreSQL, Elasticsearch, etc.) are running before `bin/dev` starts the development server. Provides clear error messages with start commands and install hints when services are missing. Zero impact if not configured - backwards compatible with all existing installations. [PR 2098](https://github.com/shakacode/react_on_rails/pull/2098) by [justin808](https://github.com/justin808). diff --git a/react_on_rails/spec/react_on_rails/configuration_spec.rb b/react_on_rails/spec/react_on_rails/configuration_spec.rb index a0357fa25f..9fe394fdae 100644 --- a/react_on_rails/spec/react_on_rails/configuration_spec.rb +++ b/react_on_rails/spec/react_on_rails/configuration_spec.rb @@ -506,6 +506,27 @@ module ReactOnRails end end + describe ".suppress_unused_component_warnings" do + it "defaults to false" do + ReactOnRails.configure {} # rubocop:disable Lint/EmptyBlock + expect(ReactOnRails.configuration.suppress_unused_component_warnings).to be(false) + end + + it "can be set to true" do + ReactOnRails.configure do |config| + config.suppress_unused_component_warnings = true + end + expect(ReactOnRails.configuration.suppress_unused_component_warnings).to be(true) + end + + it "can be set to false explicitly" do + ReactOnRails.configure do |config| + config.suppress_unused_component_warnings = false + end + expect(ReactOnRails.configuration.suppress_unused_component_warnings).to be(false) + end + end + describe "enforce_private_server_bundles validation" do context "when enforce_private_server_bundles is true" do before do From 76a642990b567e9b277036d67785c52cd15a4fbf Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 25 Nov 2025 22:05:09 -1000 Subject: [PATCH 3/3] Fix Pro spec fixture for rails_context test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add suppressUnusedComponentWarnings to the rails_context fixture in the Pro helper spec to match the updated rails_context structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb b/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb index e8b90fd01f..6af2d66d89 100644 --- a/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb +++ b/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb @@ -323,7 +323,7 @@ def response; end end let(:rails_context_tag) do <<-SCRIPT.strip_heredoc - + SCRIPT end let(:react_component_div_with_initial_chunk) do