Modern software development often calls for innovative approaches to managing dependencies, especially in large-scale JavaScript projects. One such approach is using multiple versions of the same package in a single project. This method, while seemingly unconventional, addresses various needs such as ensuring legacy system support, conducting feature toggling, or facilitating A/B testing.
In this blog post, we’ll delve into the reasons behind using multiple versions of a package, with a focus on feature toggling and A/B testing, and explore how Bit can simplify this complex process.
Why Use Multiple Versions of the Same Package?
- Legacy Code and Gradual Updates
Legacy systems often rely on older versions of dependencies. Introducing a new version may cause incompatibilities. Using multiple versions ensures new features can leverage updated libraries while older systems remain stable.
- Feature Toggling
Feature toggling enables developers to control the availability of specific features without modifying the codebase. This approach is especially useful when releasing features incrementally or testing their impact.
-
Release Toggles: Delay the public release of a feature while ensuring its code is merged and tested within the main branch.
-
Experiment Toggles:(A/B Testing): Allow testing features with different user segments to determine the optimal implementation.
-
Ops Toggles: Provide operational teams with the ability to enable or disable features without deploying new code.
Feature toggling may require multiple versions of a package or component when toggling involves significant changes, such as upgrading a library or altering a core component.
Tagging Bit components with Pre-Release Versions
Bit offers the bit snap
command to version your component with a hash instead of a Semantic Version, to indicate the version is no ready for release (the command also executes a slightly different build pipeline, accordingly).
For example:
'bit snap' => package-name@5475049d02fafa0eaf6885a06d36e42e0ffdc4a3
'bit tag' => package-name@1.2.3
However, having a hash as the component’s version does not give any information about its purpose, its parent release version, or whether this “branch” of the component’s history has additional iterations.
A bit snap
is useful as a Bit analogy for git commit
but not for experimental release versions that should be integrated into production.
To provide more information, it’s recommended to use the prerelease
option. For example:
bit tag forms/sign-in -m "add SSO option" --increment prerelease --prerelease-id beta
Managing Multiple Versions of a Package
When using multiple versions of a package/Bit component, dependency aliasing is key. This approach allows teams to maintain multiple package versions within the same project.
{
"dependencies": {
"@my-org/my-scope.forms.sign-in": "0.0.1",
"@my-org/my-scope.forms.sign-in-sso": "npm:@my-org/my-scope.forms/sign-in@0.0.2-beta.0",
}
Alias names make it easy to differentiate between versions:
import { SignInForm } from "@my-org/my-scope.forms.sign-in";
import { SignInForm as SignInFormWithSso } from "@my-org/my-scope.forms.sign-in-sso"
export function SignInPage() {
if (features.flags.sso.enabled) return <SignInFormWithSso />;
return <SignInForm />
);
}
Learn more