Versioning and Releasing PIE Web Components #432
Replies: 8 comments 5 replies
-
Thanks for setting this up @ashleynolan! This is definitely a nuanced subject with no single answer being correct. That said, I would like to add a few thoughts to your suggestions: Component versionsI think that versioning all the components as one version in a combined package, whilst tempting, could ultimately be harder for people to adopt into their projects. Given that teams will have to fit component adoption into their own priorities, I think the more we can reduce the overhead, the better our chance of seeing adoption. In this instance, I believe adopting an entire component library would be harder than individual components. Design and Engineering versioningDesign and Engineering have different philosophies and standards when it comes to versioning. In engineering, we use SemVer. Breaking changes can result in a major version bump that wouldn't make sense in a design context. For example, design may bump a button version from version 1 to version 2 because of a big visual change. On the other hand, we might bump a package major version due to an API change that has no visual change. Rather than shoehorn both disciplines into the same versioning approach in an attempt to synchronise versions between design tooling and component package versions (which I think would be unnatural to both sides and potentially not even possible), I think we should respect the differences and version component packages and designs at their own cadences and simply reference the design version in package versions. This would mean both engineers and designers can use their own versioning methodologies, but still have a way to quickly reference designs easily. An example of this in practice could be having Then we get a new design, and eventually have something like Hopefully, this makes some sense. We might be able to leverage tagging/labelling to achieve this and also reference in changelogs. I would advocate for option 1 or 2 also. I think they are the simplest solutions and give us the most flexibility, which should help with adoption. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the write-up @ashleynolan! Fully agree with @jamieomaguire's point about the separation between design / engineering versioning too. I'll bring another option to the table regarding the repo versioning 👀. 4. Version Components under a single version & also provide individual Components After looking at some other design systems, mainly https://github.com/chakra-ui/chakra-ui and https://github.com/adobe/react-spectrum, I believe it's possible to provide both capabilities, and leave it down to the consumer to decide which approach works for their use-case. There's potentially a bit more complexity on our side, and is probably worth doing a spike into, but I personally believe this approach would address most, if not all of our concerns. The idea is as follows... Creating a @justeattakeaway/pie-web-components packageThis package would be a new package in the monorepo, that is both versioned by changesets and published to npm. This package would define all web components in the monorepo as a package.json dependency, either targeting Continue to have individually versioned componentsWe would continue to individually version and publish our components, giving us the flexibility we currently have. The main difference, is because the @justeat/pie-web-components package defines these as dependencies, whenever a semver bump is applied to a web-component via changesets, the dependency would also get bumped in the main @justeat/pie-web-components package, and a new version the the whole component library would be available. Example Implementations@adobe/react-spectrum - In our case, this would be @justeattakeaway/pie-web-components and serve as a versioned / publishable package of the entire component library. You'll notice that all components are defined as dependencies. Another example here for chakra-ui - https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/react/package.json. @chakraui/popover - https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/popover/package.json I'll outline pros/cons tomorrow :) |
Beta Was this translation helpful? Give feedback.
-
Thank you, @ashleynolan for putting this up, and for the rest for sharing your thoughts on this. ❤️ As someone who has only worked with one bundled package before, I can definitely relate to the pros and cons you mentioned. One issue I particularly resonate with is the fact that if we roll back, all the consumers of the package will be affected, even if the bug was introduced by a specific piece of work they don't actually need. For example, if we update the button component, but the modal component introduces a bug, users who only need the button component will also need to wait for the fix. While this approach is simpler and I don't see the bundle size as a big issue as we can delegate bundle size management to our consumers by ensuring they have proper tree shaking (this step is done in L-Takeaway CW), I am inclined to explore other options to gain a fuller understanding. I do believe that individual versioning and releasing components might be the way since we can adopt a gradual improvement approach when we roll out to our consumers, however, the Individually Version approach can introduce complexity for both us and our users in terms of figuring out version numbers. This may not be a big issue in the beginning but could become more challenging as versions diverge and breaking changes based on business logic become harder to track. For example, if we had to make changes such as icing, it would be clear that all components with version 1.x.x are prior to icing changes and 2.xx is post-icing. and, if each component had its own version, the version numbers would lose their contextual meaning and become more difficult to manage. Also as a side note just in case I forget, we probably need to maintain metadata to reference which PIE version in design the current version is based on. |
Beta Was this translation helpful? Give feedback.
-
Development process vs public APIA lot depends on your rationale on how you want your users to consume your public API, and how your development process is designed. For example, when going for 1 or 2, there will be those who always upgrade to latest (using Dependabot or similar) and there will be those who’ll eventually not stay on top of this, especially if upgrades happen often or if different packages have different manual steps for upgrading in case of deprecations and breaking changes. This frequency is also especially important to consider for option 2, after all this is not just about your publication process but also about the perceived ease of use of your library. Amount of packagesFor options 1 and 2 it also depends a bit on how many components you plan on publishing. I don’t think people would be happy to use it if the number gets above 60, as it will blow up package.json and make manual operations more tedious when needed. Shared codeYou’ll probably still want a core package that holds shared code, so that it does not need to be duplicated across all components. This could also give the flexibility of say “quickly updating a colour” or broken style in a non-breaking way: There is a flexibility vs complexity question here as well: if you require a core package (sooner or later I think you would), then what is the cost of maintaining that compared to having a single package altogether (option 3). And how happy are you with the flexibility that it gives you? Option 4You could consider doing a hybrid of options 1 and 3, where you have some cohesive packages of which their scope makes sense from a technical / development point of view. Personally I was happily surprised by the quality and great separation and cohesion of the modules of TailwindCSS. Not quite the same thing, but they seem to have things under control quite well. See plugins in the left menu at the very bottom of their docs. Ultimately I'd go with whatever works best in practice and decide when to split off a package on a case by case basis, and evaluate the pros and cons of that package as opposed to having it included in the main package. |
Beta Was this translation helpful? Give feedback.
-
Regarding the second approach, I'm wondering how can we make the consumer life easier after version updates. Let's say we have a breaking change in |
Beta Was this translation helpful? Give feedback.
-
The flexibility and convenience provided by the approach suggested by Ben seems to be a good option. I understand the concern of bundle size, though I wouldn't agree that the package size necessarily corresponds to what is bundled in the consumer application. Treeshaking is used in CW in order to get rid of Snacks unused components in the app production build. I'd suggest doing some sort of experiment for checking how much of a web components bundle can be treeshaken before discarding this approach. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the write up @ashleynolan . Another thing is it might be beneficial for us to reach out to consumers (or future consumers) to get their input earlier on, which might help make a decision. Below are my personal thoughts: Around one bundled library: Based purely off personal experience, individually versioned components from a consumer standpoint can be frustrating: Each component needs to be independently installed, and maintained. As you pointed out, it adds additional complexity when components are dependent on each other. Ultimately, I really like @siggerzz write up around both approaches. This seems to be a very good solution as we are leaving the option to consumers. |
Beta Was this translation helpful? Give feedback.
-
I just wanted to sum up our findings and conversations on bundling so far – I'll keep this discussion open as it's useful to help track any progress on this topic. SummaryAfter discussions both in this thread and through conversations we've had, it seems like our preferred approach will be to follow @siggerzz suggestion which is to Version and release components individually while also providing a bundled version of these components which provides more identifiable bundle version numbers across components. This should give us flexibility of letting consumers decide on what might work best for them. The main concern that we will need to address (through a spike as we build out the capability and through further discussions) around the bundle approach is around performance. Currently, it's unclear how bundling components in this way could impact performance. As mentioned in this comment, the Adobe Spectrum team do provide a similar bundle for consumers, but advise against using it in production due to performance concerns. I think it's still of benefit to maintain a versioned bundle, as it could help with prototyping, as well as enabling clear communications as to which individual component releases relate to major version bumps in the bundle package (which could be useful for larger brand updates for example). We'll initially recommend for early adopters to consume components by using the individual package releases. We can then spike out the creation of a bundle distributable of components and look into the implications of this as the number of components in PIE grows. We are shortly due to be catching up with the Adobe Spectrum team, so any learnings from that may also influence the direction we take with the component bundle. |
Beta Was this translation helpful? Give feedback.
-
This is to start discussions over how we want to handle the versioning and releasing of the PIE web components as we build out the web component library.
Below are some of my own thoughts/opinions on the subject to start things off and maybe provoke some discussion on the subject; please do feel free to reply or add your own thoughts and we can then get together to discuss it all in more detail.
Versioning
It should come as no real surprise that we'll be using semver for versioning components.
As of me writing this, I can think of three possible routes we could take with versioning our components:
pie-button
,pie-card
, andpie-modal
would all be versioned and released separately. Consumers of the components would then install each component as needed vianpm install @justeattakeaway/pie-button
for example. Components would have different version numbers from one another.This approach is common in libraries such as ESLint, Babel etc as it gives the overall release version shared meaning but also allows for components to be released independently (and rolled back independently).
pie-components
package is versioned and released. Consumers then install the component library as a single package (npm install @justeattakeaway/pie-webcomponents
) and import a specific component in their JS –import pie-button from @justeattakeaway/pie-webcomponents
The above massively simplifies the considerations and possibilities in both approaches, so I'll break down some of the considerations of each approach before giving my own opinion on which approach may be best to take.
1. Individually Version and Release Components
This is the approach that we currently use for the Fozzie Vue Components.
Essentially, each component looks after itself and is versioned and released separately from one another. So
pie-button
could be onv1.2.0
whilepie-modal
could be onv5.3.0
. Each component is installed and listed as a separate dependency in thepackage.json
. To consider the pros and cons of this approach:Pros
pie-modal
, andpie-button
also had improvements made to it, we wouldn't need to downgrade both together if they were versioned separately.pie-button
andpie-modal
gets a new breaking update, then it's of no concern to that consuming application as they don't use it anyway.Cons
pie-modal
andpie-alert
both rely onpie-button
, we need to ensure that only one version ofpie-button
is being loaded in the application to avoid page bloat.pie-button
is compatible with every version ofpie-modal
. This can be mitigated by usingpeerDependencies
to specify which version of a child component we consider compatible with a parent component.pie-button
component, but haven't updated thepie-modal
component and it is now significantly out of date. This can again be mitigated slightly by usingpeerDependencies
.2. Version Components in Sync
This approach is the same as Approach 1 with the key difference that components are versioned in sync with one another so that the package number across all components is the same.
So in a component library where
pie-button
andpie-modal
exist and are currently on versionv1.2.0
, a minor update topie-button
would mean that both packages will increment their version number tov1.3.0
, but are then released as separate packages.The Pros and Cons of this approach are essentially the same as Approach 1 but with the following considerations:
The potential pro of this approach is that it gives the whole library a shared version for consuming applications to reference. For example, it's super clear for the DS team to ask teams what version of the DS they are using (assuming they are updating their packages together). It also means the DS team can reference a more simplified version when communicating changes potentially.
A potential con of this approach is that it could mean that the component library versioning goes through a lot of major release versions, especially as the library is being built up. A breaking change for one component would mean the whole library gets bumped to the next major version. We may therefore need to be more careful with breaking changes so this doesn't get out of hand (otherwise release versions could mean less ultimately).
3. Version as one bundled component library package
This is the approach currently used by the Snacks React Component System and Skip React PIE Library.
Pros
Cons
For example, if both
pie-button
andpie-modal
had been updated in a new update but it was later found that there was an issue with the change topie-modal
, then both components would be rolled back by moving back to an older version of the library. The more components in the library, the wider this issue could become.v2.1.0
of the library has been made topie-modal
and a consuming app is usingv1.9.0
they have to update to the latest major version of the library to benefit from the change.Overall opinion on Versioning
I think due to the nature of how our library works across many teams with many applications consuming our components, flexibility and avoiding any sort of bottlenecks or blocks to releasing is really important.
The cons to the individual component versioning and releasing should be mitigated by providing upgrade tooling (through something like Scorecard) and rigid
peerDependencies
defined in our components.Therefore I'd advocate for either Approach 1 or 2, leaning potentially towards Approach 2 as it would give us the benefit of being able to communicate major version releases as a whole library version bump while also giving us the benefit of granular component releases.
Component Versioning Relationship to PIE Design Tokens
Currently, I think it makes sense to keep the
pie-design-tokens
package as a separate version, mainly as we use the tokens across other applications other than on Web (iOS and Android for instance). Therefore, I don't think it would make sense to tie the two together unless we thought there was a perceived benefit in doing so. Happy to discuss this if others feel differently though.Release cycles
One aspect that runs alongside the above is how we structure our release cycles for component releases.
Currently these are done in an ad-hoc manner, with changes made to components then released within a few days as part of our changeset release PR.
We could potentially plan our major releases much more than we currently do, working to a more regular cadence for these bigger releases. There are pros and cons to this approach, but this should probably be discussed with the team to decide if we think there are benefits (probably depending on the versioning approach we go for above).
Thoughts?
Any thoughts on the above would be great to hear and opinions on the different approaches welcomed! Likewise, if there's a versioning approach I may have missed, please write it up so we can consider it as well.
Beta Was this translation helpful? Give feedback.
All reactions