parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.49k stars 2.27k forks source link

[RFC] Moving to trunk based development and introducing feature flags #9539

Closed marcins closed 1 month ago

marcins commented 8 months ago

💬 RFC

We have a lot of complex features / pieces of work planned for Parcel over the foreseeable future. In order to be able to meet our goals of: being able to work on features in parallel, deliver value incrementally, and provide the ability to dogfood new / risky / complex features at scale before making them generally available, we need to shift the approach to how we do feature development and releases in Parcel.

The summary of this proposal is:

Trunk based development

The main philosophy shift here is that rather than working on a feature on a branch until it is done / tested / ready for release, features are able to be released piecemeal onto the main branch and are protected by feature flags (see below for feature flags description).

This means that where changes are isolated in scope within a module, they are conditionally executed based on feature flag outcomes. Where changes are more broad and would require peppering conditionals throughout the code then a parallel implementation needs to be created and conditionally included / abstracted at a higher level. How this is achieved will be specific to particular use cases so is not prescribed by this RFC.

(Open question - what about changes that require new dependencies? Are there any issues with this? This doesn't apply to dependency bumps, those would not be possible to feature flag easily)

The advantages of this approach are that integration costs are lower - you're not needing to constantly keep a branch in sync with what's happening on the main branch. Parallel work from a baseline piece of work on the main branch is easier to achieve.

The disadvantage is additional overhead for complex changes of maintaining an abstraction or conditional code.

We believe the advantages for parallelising work and shipping changes sooner for internal usage outweigh the disadvantages.

Feature flags

We will introduce the concept of feature flags in Parcel. This will allow us to ship inert code in open source, that we are actively testing and stabilising in our internal large scale use cases. Without the ability to do this, in combination with the improvements to the development model above, it may become untenable for us to work in the open source repository as the source of truth.

Note for the purposes of this proposal feature flags will not be used to produce different binary output from Rust builds - at this stage if some new Rust feature is being developed that has a dependency on a new crate, that crate will need to be included in the build even if unused.

The main approach to feature flagging is largely inspired by other open source projects that take this approach such as React (https://legacy.reactjs.org/docs/how-to-contribute.html#feature-flags) and Relay (https://github.com/facebook/relay/blob/main/packages/relay-runtime/util/RelayFeatureFlags.js, https://github.com/facebook/relay/blob/main/compiler/crates/common/src/feature_flags.rs)

The proposed approach is:

There is a spike implementation here: https://github.com/parcel-bundler/parcel/compare/v2...spike-feature-flags

The main considerations when trying out the spike:

Next steps

jondlm commented 8 months ago

Any thoughts about how we'll manage the lifecycle of feature flags? AFAIK there's no perfect solution to the problem of feature flag atrophy but it's nice to at least consider the problem up front.

Seems like a solid proposal to me 👍

marcins commented 8 months ago

Any thoughts about how we'll manage the lifecycle of feature flags? AFAIK there's no perfect solution to the problem of feature flag atrophy but it's nice to at least consider the problem up front.

Fair point. There's definitely a risk that we might end up with features behind a flag that for whatever reason don't "graduate" to real features for a long time. I suppose it's one of those things that we'll need to address as it comes up.

We've kind of already got this to some extent with some of the unstable_ features we added during our long migration. The main one I can think of is the "async runtime" stuff. Whether that was behind a feature flag or unstable_ prefix it's still just sitting there with no current plan for what needs to be done to "graduate" it.