plone / volto

React-based frontend for the Plone Content Management System
https://demo.plone.org/
MIT License
449 stars 610 forks source link

RFC: Experimental feature flags #3896

Open davisagli opened 1 year ago

davisagli commented 1 year ago

Volto development has gone at a fast pace while Volto 16 was in the alpha stage. Now that we’re ready to release Plone 6, we need to make a stable release of Volto 16 and start to be much more careful about making breaking changes, so that organizations that have built sites with Plone do not get a bad impression of its stability. At the same time, we have lots of good ideas and don’t want to prevent moving forward. This is a proposal about how to balance these concerns, for the Volto team to discuss.

One way to do this is to create a maintenance branch for Volto 16. Then we can add new features on the main branch and only backport the fixes to the 16 branch. But, this way has some problems:

As an alternative, I’d like to explore using experimental feature flags. This is something you may have seen in other large software projects like Firefox, Chrome, and Kubernetes. The idea is that we add conditional logic to enable a new feature based on a config setting. There would be a section of the config that looks like this:

config.experimental = {
  featureName: {
    enabled: false,
  },
};

A particular volto app or addon could opt in to enabling the feature like this:

config.experimental.featureName.enabled = true;

How is this different from an add-on? Experimental features are changing how Volto’s core components work, rather than adding or overriding components. How is this different from a config setting? Experimental features are intended to become the new default behavior in the future, rather than a permanent choice.

A feature is a candidate for experimental status if there is already broad agreement in the community that we want it in core, but:

The context for why I’m thinking about this is that I’d like to implement the new add block button (#3815) as an experimental feature. There are 2 reasons:

  1. It’s time for a Plone 6 release candidate but the new add block button implementation is not ready to merge. I probably need another week or two to finish it. Implementing it as an experimental feature ensures we can make it available as soon as possible even if it doesn’t make the cut for Plone 6 release candidates.
  2. kitconcept likes the new add block button in general, but we have a big project that is nearing completion and we can’t easily change how the add button works at this stage in the project. Implementing it as an experimental feature provides a way to make it easily available for new projects but keep it disabled for projects that have been underway for a while.

Rules for experimental features:

What are the downsides?

What are the upsides?

JeffersonBledsoe commented 1 year ago

+1 for this. Next.js has been using the experimental key in it's config for a while to test new or breaking features and I've found it works pretty well. We need to make sure experimental features are still well documented though.

There’s a risk that a feature doesn’t work out but someone is depending on it

Again using Next.js as the example, they make it really clear that any experimental features don't follow semver and may change or be removed at any time. I think that as long as it's clear to users who adopt experimental features that this is the case (e.g. warning logs in the server console when experimental features are enabled), it's fair game if a feature needs to be removed or adjusted.

It adds a bit to the size of the codebase

I'm not hugely into webpack, but could it be possible to load an 'experimental' bundle alongside the main bundle to keep size down for anybody not using experimental features?

tiberiuichim commented 1 year ago

I'm not hugely into webpack, but could it be possible to load an 'experimental' bundle alongside the main bundle to keep size down for anybody not using experimental features?

We could make it a requirement to make sure that experimental features are lazy-loaded, as much as possible.

JeffersonBledsoe commented 1 year ago

We could make it a requirement to make sure that experimental features are lazy-loaded, as much as possible.

@tiberiuichim What if a feature requires server-side rendering/ customises the server config somehow? I know it's unlikely, but just trying to think of all scenarios now :)

tiberiuichim commented 1 year ago

then we don't care how big it is, as it won't impact client-side.

tiberiuichim commented 1 year ago

@davisagli I'm all for this, it's definitely something that we've wanted along the way. But it's good to have this process formalized, and maybe even documented with Volto.

stevepiercy commented 1 year ago

Where would be a good place for documenting this? Would a new page be appropriate under https://6.dev-docs.plone.org/volto/developer-guidelines/index.html?

tiberiuichim commented 1 year ago

@stevepiercy yes, there.

@plone/volto-team feedback on this proposal?

sneridagh commented 1 year ago

I'm +1 for this.

Regarding the lazy loading, might be hard, because the feature (eg. the new add button placement in #3815) could be entangled with the current behavior. Although I agree that whenever possible, we should make this happen.

Also in the same direction, we are pushing for having permanent "core" integrated add-ons. Following the 'volto-slate' integration now we are able to add them at will.

https://6.dev-docs.plone.org/volto/developer-guidelines/volto-core-addons.html

And the use case: https://github.com/plone/volto/pull/3877

I can imagine experimental features in the form of add-ons (even with customizations) that at some point get into core (or stay as core add-ons)