🎉 Our long awaited Bundled Content Delivery Network is here!
We're happy to announce that our Bundled Content Delivery Network is live and ready to be used across our products. It's an interesting idea that, with the great help of our Infrastructure team, we've been able to turn into a working solution.
How we do it now
So you may wonder what BCDN is and why we even created it?! Let's first go through a couple key points to understand what we do now.
The frontends of our products are quite complex most of the time, and require a lot of dependencies. This allows the team to write simpler code, providing a better developer experience and a smaller surface area for bugs.
Some of the dependencies we rely on are external libraries/frameworks, internal plugins, and tools and components that implement Causeway. So even though its simple on the
surface, complexity is still buried inside package.json dependencies. BCDN is all about causeway components
and their delivery.
Disadvantages of current solution
Currently we're building and bundling our components in a separate repository, and publish separate packages which are imported individually. This comes with a couple disadvantages.
Package size
Every package is built in isolation, so there is no way to tree-shake duplicated (between components) dependencies. Everything is bundled up and these kilobytes add up over time.
Amount of dependencies
Every component is a separate dependency in package.json which brings a whole myriad of challenges:
- install time - downloading each dependency during build take some time
- build time - besides downloading, every package has to be bundled up with the product itself
- package-lock - maintaining/updating this file is especially challenging with docker setup
- updating version - tedious process of deploying a package, waiting for publish, updating the version in a product's
package.json, and pushing changes, for each dependency - dependabot - no comment required
Example
signet-ui currently has 10 component dependencies
"@infotechfl/causeway-icon": "^0.2.0-alpha.56",
"@infotechfl/cw-alert": "^5.0.7",
"@infotechfl/cw-autocomplete": "^3.0.8",
"@infotechfl/cw-datetime-picker": "^4.0.7",
"@infotechfl/cw-form": "^3.1.12",
"@infotechfl/cw-full-overlay": "^2.0.4",
"@infotechfl/cw-modal": "^6.0.1",
"@infotechfl/cw-shell": "^7.1.0",
"@infotechfl/cw-tag": "^6.0.0",
"@infotechfl/cw-tooltip": "^1.0.0",
Build stack
At some point the decision was made to package our components with everything necessary for production. This allowed the product to use a component without requiring changes to a product's build stack/pipeline. Causeway components don't care if a given product uses
webpack, rollup or vite. The only requirement is that it has to use npm to install requested component and have some sort of pipeline
that pushes that component into a .js asset on a page. No loaders, no CLIs in package.json, nothing.
This was a nice step forward considering the previous polymer implementation had a lot of requirements, complicating product's
build stack significantly. In some cases, this was the main frustration while working with these components. Even though current
requirements are minimal, they are still there, so it's quite challenging to simply "drop-in" components on static pages, documentation, CMS etc.
Our vision and dream from many years ago to "drop-in" components everywhere was still not achieved.
What's up with BCDN
So what is BCDN? It's quite simply a Bundled CDN — a Delivery Network for Bundled Content. Rather than static assets (common case), it's a sort of API that delivers bundled packages that you've requested. Take our terminology with a grain of salt. We're probably mixing up multiple networking terms!
The main responsibility of the BCDN is simple - take a repository at a given version, select packages that the user is interested in, and bundle them up in a single file. To better explain the process, let's take a look at the typical flow with our causeway repository.
💡 Causeway is a monorepo that's why we are talking about multiple packages in a single repository.
- resource request comes to BCDN
- lambda parses the url and gets 3 key pieces of information
- project/repository (causeway only for now)
- version
- components/features/packages
- lambda checks if resource for given project/version/features combination already exists on
S3 - if yes, it will simply redirect request to
S3file - if that's not the case it will kick off
codebuildwith provided informations and respondNew build startedfor the time being. The build currently takes about 3 minutes. codebuildhas abuildspecfile created specifically for each project/repository so it knows how to build the assets- once build is ready it will push files to
S3 - another request for that resource should result in response that contains bundled resource
This is simplified version. There are a couple minor details here and there but you should get the general flow.
One of the concerns you may have is "A page requests a resource and now has to wait 3, 5 , N minutes for a response?!".
The simple answer is no. Actually, lambda will return right after starting the build, but won't return the requested
resources until the build finishes. Does that mean your page won't work? The page may work, but components on that page most certainly won't work.
Since resources are versioned by repository and bundled assets are generally publicly available, BCDN doesn't need to have multiple
environments like dev, demo, prod - its simply a single environment (prod) and once they are built, resources are never removed from S3.
It's safe to assume that these resources will be bundled during development and be ready for production long before
a product change will be deployed to that environment.
Advantages of BCDN
We talked a little bit about how it works, so let's dive into why.
Package size
Since every requested component is bundled into a single file, it's a great spot to tree-shake any duplicated imports and deliver the most
optimal package possible. On top of that, this allows us to use Vuejs under the hood without worrying about the packaging runtime
multiple times in every causeway component (16kb vs 10x16kb).
No npm dependencies
Since npm is not required from a product to use BCDN's bundles, it removes these dependencies in package.json entirely. That eliminates
all the headaches we mentioned in Amount of dependencies:
- install time - not part of npm, zero install time
- build time - build is not concerned about these bundles
- package-lock - not part of npm - no merge conflicts
- updating version - just update URL and it's done
- dependabot - not part of npm - dependabot won't bother product's repo
Toggle between versions
Since you're not required to reinstall packages, or even publish them, you can easily swap versions of selected components inside
index.html file and troubleshoot, test, or verify that everything works great (or was broken already 😱 ).
Build stack
With this solution there are zero requirements on product's build stack or the stack as a whole. You can use it on Rails,
statically generated sites, an index.html on S3, or anything that's rendered in a browser! Just slap a <script>
tag on your page and you're good to go.
How
Finally, let's talk about how to use this thing! Example BCDN's URL:
https://bcdn.infotechinc.com/causeway/v0.4.0-beta.16/badge,tag,icon-clear.umd.js
The path is really important and follows this format:
/project/version/coma,separated,features.extension
- project - project/repository name, for now only
causewayis supported - version - tag on a selected repository on which
codebuildshould checkout - features - comma separated feature list that will be passed into the build process
- extension -
causewaysupportses.jsandumd.jsatm
Once you figure out what you want, just put a <script> tag on your page:
<script src="https://bcdn.infotechinc.com/causeway/v0.4.0-beta.16/badge,tag,icon-add.umd.js" defer></script>
Let that page run in the browser, wait a couple minutes for codebuild to finish (if necessary) and have fun playing with Causeway components on your page 🔥
💡 At the time of writing,
causewayhas onlybadge,tagand icons (plenty of icons) available.
This blog is using the BCDN right now to bring in the nav open/close icons in the top-right of your screen!
Thank you
BCDN wouldn't be possible without our Infrastructure Team, so big thanks to Matt's team ❤️
← Back to blog