cagov / design-system

State of California Design System
MIT License
79 stars 25 forks source link

Components: CDN - dynamically create multi package bundles #770

Closed aaronhans closed 6 months ago

aaronhans commented 2 years ago

Consumers of the design system who want to use several components but not all of them would benefit from the ability to create a bundle of components specific to their use case.

This will allow them to get only the code they are using and not weight their site visitors down unnecessarily.

we can create this by building a frontend tool that lets you select components that calls a backend service that builds and publishes a bundle of all these components as a publicly available CDN backed, versioned file.

Will need to review these technical implementation details with the engineering team before building.

Also need design guidance for UI

chachasikes commented 2 years ago

Breaking this down into steps might help.

Started working on a bundle to include in the "shuffled" Gutenberg repo in prep for new devs. (And yes, Drought site can use it the new code as soon as it's ready - will have PRs soon.)

But - in working on that, figured out that we need to map out the naming pattern.

Current naming pattern (PHP example):

define( 'CAGOV_DESIGN_SYSTEM_BUNDLE', "https://cdn.designsystem.webstandards.ca.gov/bundles/v1.0.0/cagov-design-system.development.js" ); // Bundle instructions
define( 'CAGOV_DESIGN_SYSTEM_BUNDLE_LOCAL', CAGOV_DESIGN_SYSTEM_GUTENBERG_URI . "/build/js/cagov-design-system.core.js"); // Bundle instructions

Some variants - Thought I saw a conversation about this on Slack, need to look for it tomorrow. bundles/v1.0.0/cagov-design-system.development.js bundles/v{versionNumber}/cagov-design-system.{branch}.js bundles/v{versionNumber}/cagov-design-system.min.js bundles/v{versionNumber}/cagov-design-system.min.es5.js

Saw this in CDN install instructions: https://github.com/import url("https://cdn.designsystem.webstandards.ca.gov/components/ds-button-grid/v2.0.2/index.css")

Got some feedback from OET engineers & CDT (Art) on HTML/CSS - we started calling them "Content Components" in Component Audit Sprint 2022 Airtable when categorizing new components to bring into the Design System.

Question: Are all the content components automate-able?

The WordPress Integration can use a package.json variable componentType - "Content component", "Web component" - and if there is a CSS only structure we can iteratively pull the correct files.

If the files are still not consistent let's prioritize fixing that next sprint while I'm Release Ranger.

xjensen commented 2 years ago

How will consumers of this service upgrade their bundle?

Other CSS/JS frameworks tend to tag all of their different components under one overall version number. In contrast, we version all of our components separately. It'll hurt adoption and/or regular updating if we leave it to the consumer to keep track of all those separate version numbers, especially if we leave them to fend for themselves with breaking changes.

I see a few possible solutions to this.

Option 1

When we compile and offer a custom download, we could also include a config file. Later, when a consumer wants to update their bundle, we could accept the config file back as an upload. This could pre-populate our tool with information about the previous version of the custom bundle: which components should be included, which components have updates with breaking changes, etc. I believe Bootstrap does something like this.

The downside is that we're asking the consumer to manage those config files; it's easy to imagine them going missing or out-of-date.

Option 2

We could start from that config file concept. But instead of offering the config file as a download, we host it. We could even keep version history of each custom bundle. Then consumers would just be given a URL/link to a page they could revisit to create a new bundle. We could embed the URL as a comment in the script itself.

The upside is that the consumer no longer needs to keep track of that config file. The downside is that we'd need to take responsibility for all those per-bundle configs and config pages ourselves. Sounds like a lot more upfront work.

Option 3

We encode the entire bundle and every component version number into the download URL. Then we build an analyzer that could parse out that URL into a configuration page. Consumers could just plug their previous script/download URL into the analyzer.

The upside is that there are the fewest assets to manage here, both for us and the consumer. No config files on either side. The downside is that I'm not confident we could get our build speeds low enough to serve a bundle just-in-time from a URL (Lambda cold starts, etc.). The CDN caching keys could potentially become very cumbersome. And we'd need to work within a URL character limit (2000?) which we wouldn't hit soon, but could eventually bite us.

Option X

I'm leaning toward option 2 here. But I wonder what others think about this problem. How do we make it as easy and as painless as possible for consumers to upgrade custom bundles?

aaronhans commented 2 years ago

I like #3 with a tool that lets design system consumers create their own bundle.

xjensen commented 2 years ago

The hashing is key. Yes, that could work.

chachasikes commented 2 years ago

Nice recommendations @xjensen.

I like option #3 & agree with Aaron's suggestions.

Also suggest some "plain" options for "all components" - possibly connected to DS release numbers & "all components" - with the caveat that we encourage folks to only use what they need.

This would fit current expectations, and also help teams understand when in time their configuration is from.

This would be useful for debugging, learning, or connecting to a CMS build output - where you don't know what content folks will eventually use.