Skip to content
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

Make accommodations for component-local config #2124

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

boardfish
Copy link
Collaborator

@boardfish boardfish commented Oct 8, 2024

Explicitly declares access to current config as global where necessary, and makes it possible for us to introduce a component-local config that inherits from these global options in future.

Unsure of how this interacts with gems with engines that depend on ViewComponent, but I'm hoping in the long run it's a step in the right direction for them that'll allow them to have their own ApplicationComponent equivalents that inherit their config from ViewComponent's own defaults.

@boardfish boardfish changed the title Introduce component-local config Make accommodations for component-local config Oct 8, 2024
@boardfish boardfish marked this pull request as ready for review October 8, 2024 14:06
@boardfish boardfish force-pushed the introduce-component-local-config branch from 161cee3 to 6378768 Compare October 10, 2024 11:18
@joelhawksley
Copy link
Member

Will be a breaking change if folks still use ViewComponent::Base.config to setup their config.

Unfortunately for us, it's the first line of the API docs 😬 so I think we'll need to make this change in 4.0 or implement it in a non-breaking fashion. How do you think we should proceed?

@boardfish
Copy link
Collaborator Author

It might be possible to rename the ViewComponent::Base.config endpoint to ViewComponent::Base.default_global_config and preserve the existing interface. I suppose since the idea is that ViewComponent::Base's idea of config shouldn't change and should instead be extended internally by gems, that should be fine.

This PR needed a rebase anyway, so I'll try to address that in the process.

@boardfish boardfish force-pushed the introduce-component-local-config branch 2 times, most recently from e9592cb to 37e6d0d Compare October 20, 2024 09:37
@boardfish
Copy link
Collaborator Author

I've made it so that ViewComponent::Base.config, Rails.application.config.view_component, and ViewComponent::GlobalConfig are all equivalent. My thoughts are that from here, we should set the pattern for component-local config going forward – that's currently done by #1987, but if that gets held up by other factors it could be done in isolation.

Once we have the structure for component-local config in place, we can start looking at moving config options out of global and into local config one by one. There are a couple of ways we can go about this:

  1. Have the default for an option be sourced from global config at the same endpoint it currently exists at. So for example, Rails.application.config.component.strict_helpers_enabled = true would mean that all descendants of ViewComponent::Base have strict helpers enabled unless they opt out. We would seek to deprecate this in the next major version.
  2. Move options to component-local config in minor versions. This would be preferable in relation to the goal of making sure that engines that consume ViewComponent aren't subject to global config options in a way that would be detrimental for them, and would also mean that for particular minor versions we'd need to advise folks to set this config on, say, ApplicationComponent if they have it.

@boardfish boardfish force-pushed the introduce-component-local-config branch from 37e6d0d to 2dcc88d Compare October 21, 2024 08:34
Introduces a `ViewComponent::GlobalConfig` object that will be the source for global configuration going forward. Ideally in the future, this will only house options that universally affect ViewComponent regardless of whether components are sourced from an engine or not (e.g. enabling the capture compatibility patch), and more options can move to a component-local config. For these options, classes inheriting from `ViewComponent::Base` will want to override configuration themselves.

This was initially written to support extracting the incoming strict_helpers_enabled? option, but applies to everything.
@boardfish boardfish force-pushed the introduce-component-local-config branch from 2dcc88d to 62e0960 Compare October 21, 2024 10:31
@joelhawksley
Copy link
Member

@boardfish sorry for the delay in reviewing your PR, I was on vacation last week and am just now getting to it!

Having seen this set of changes and #1987, I feel like I'm missing a clear sense of exactly the end state we're hoping to migrate for. What would be helpful for me is something like this:

Option Old API New API
test_controller TBD TBD
render_monkey_patch_enabled TBD TBD

For all of our configuration API. Do you think you could put together that list for us to discuss? I think we need to make sure we agree on the proposed API changes and that they are even feasible to make.

@joelhawksley
Copy link
Member

@boardfish I took a first crack at listing them all out. Here they are with my notes:

Setting name Description Proposed changes for v4
capture_compatibility_patch_enabled Enables the experimental capture compatibility patch that makes ViewComponent compatible with forms, capture, and other built-ins. previews. Defaults to false. None - This setting mokey-patches ActionView::Base, which we can only be done globally
component_parent_class The parent class from which generated components will inherit. Defaults to nil. If this is falsy, generators will use "ApplicationComponent" if defined, "ViewComponent::Base" otherwise. Move - This shoule be moved to be under `generate`
config Returns the value of attribute config. Move - Currently set on Base, I think this should be stored in the Rails application config, right?
current Returns the current ViewComponent::Config. This is persisted against this class so that config options remain accessible before the rest of ViewComponent has loaded. Defaults to an instance of ViewComponent::Config with all other documented defaults set. Move - Currently set on Base, I think this should be stored in the Rails application config, right?
default_preview_layout A custom default layout used for the previews index page and individual previews. Defaults to nil. If this is falsy, "component_preview" is used. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
generate.* The subset of configuration options relating to generators.

All options under this namespace default to false unless otherwise stated.
Move - Currently set on Base, I think this should be stored in the Rails/Engine application config, right?
instrumentation_enabled Whether ActiveSupport notifications are enabled. Defaults to false. Move - Currently set on Base, I think this should be stored in the Rails/Engine application config, right?
preview_controller The controller used for previewing components. Defaults to ViewComponentsController. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
preview_paths The locations in which component previews will be looked up. Defaults to ['test/components/previews'] relative to your Rails root. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
preview_route The entry route for component previews. Defaults to "/rails/view_components". Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
render_monkey_patch_enabled If this is disabled, use #render_component or #render_component_to_string instead. Defaults to true. Remove (already done in v4 branch)
show_previews Whether component previews are enabled. Defaults to true in development and test environments. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
show_previews_source Whether to display source code previews in component previews. Defaults to false. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
test_controller The controller used for testing components. Can also be configured on a per-test basis using #with_controller_class. Defaults to ApplicationController. Move - Currently set on Base, I think this should be stored in the Rails application config, right? I also think we could nest preview-related config under a `preview` key.
use_deprecated_instrumentation_name Whether ActiveSupport Notifications use the private name "!render.view_component" or are made more publicly available via "render.view_component". Will default to false in next major version. Defaults to true. Remove - This should be done in v4 IMO
view_component_path The path in which components, their templates, and their sidecars should be stored. Defaults to "app/components". Modify - Wouldn't we want this to be view_component_paths?

If it's easier, I shared a Google Doc with you we can collaborate on 🤷🏻

@boardfish
Copy link
Collaborator Author

@joelhawksley Thanks for putting that together! A cursory look through seems to suggest that's all right, but generate jumps out at me as something that's both global within an app and could be configurable within an engine. I figure we'd handle this in a similar way to component-local config using inheritance. I'll have a more thorough look soon.

On reflection, the implementation of GlobalConfig shouldn't change behaviour right this second, but I could do with understanding how that might need to change depending on whether we're in an engine or not. It might be possible for us to roll that out as opt-in before v4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants