Repository navigation
Feature: bundle KibaIcon icons at build time - #259
Merged
Merged
Conversation
…e per page registerKibaIcons adds bundled svgs that KibaIcon renders on its first render. Other icons are still fetched, now shared between KibaIcons (one request per url), retried once, and a stale response can't replace a newer icon.
…at build time The plugin finds icon ids in the app's source and ui-react's own build, reads them from the installed icon packages (now optional peer dependencies) and registers them before the app's entry runs.
…ts-cdn.kiba.dev Each badge is its own lazily loaded chunk, so apps only download the ones they show.
A separate module made rolldown move all of ui-react into a shared chunk instead of keeping it in dist/index.js.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What/why:
KibaIconfetched every icon fromassets-cdn.kiba.devon every mount (no cache, no retry, stale responses could win). This bundles the icons an app uses at build time so we can retire that proxy. TheKibaIcon iconId='ion-home'API is unchanged.How apps enable it (
config.build.js, and install the icon packages they use; they're optional peer deps, ui-react's own components only needionicons):dist/vitePlugin, imports onlynode:fs/path/url).src(ts/tsx/js/jsx/mdx) and ui-react's owndistfor quoted ids like'ion-home'. It reads the svgs straight from the installed packages:ionicons/dist/svg,@material-design-icons/svg/{filled,outlined,…}(mui-account-boxisfilled/account_box.svg, and a-outlined/-round/-sharp/-two-tonesuffix picks that style),bootstrap-icons/icons,feather-icons/dist/iconsandremixicon/icons/<Category>. Ids that don't resolve are skipped. If an id's package isn't installed you get one warning.registerKibaIconsfrom an inline module script it adds before the app's entry (and from non-html entries such as the ssr build).ionicons/iconsdata uris because those uris style outlines with ion-icon's css classes.Fallback: ids it can't see (e.g.
`ion-${name}`, ids from an api) and apps without the plugin still fetch from the CDN, now once per url per page, with one retry, ignoring responses for an oldiconId. ThepreconnectinKibaAppstays for now because that fallback still uses the CDN.Also:
AppDownloadButtonbadges are bundled (each in its own lazy chunk, 7-20kb) instead of loaded from the CDN.Carouselusesion-chevron-back/forward(wasmui-chevron-left/right).Tested:
ioniconsinstalled: 49 icons bundled (24.4kb raw / 5.8kb gzip).Fonts (
kibaFontsPlugin), a separate plugin from the same@kibalabs/ui-react/vite-pluginentry, works like next/font for Google Fonts. Apps keep their@import url('https://fonts.googleapis.com/css2?...')(or anindex.html<link>) and addviteConfig.plugins.push(kibaFontsPlugin());.vite:css, so@imports in sass partials are found too. It downloads the stylesheet (with a Chrome UA, so it gets woff2 + unicode-range subsets) and each font file. The fonts are emitted as hashed assets and the@importis replaced by@font-facerules rebuilt from an allowlist of descriptors. Font urls go into the css through a content-hash placeholder that's resolved ingenerateBundle, so the css hash changes when a font does.https://fonts.googleapis.com/https://fonts.gstatic.com, with no redirects. It checks content-type/extension plus woff2/woff/ttf magic bytes, caps sizes at 512kb for css and 5mb per font, and uses a 20s timeout. There are no new dependencies (Node's fetch/crypto).node_modules/.cache/kiba-fonts(keyed by url hash and validated on read). Offline or failed downloads leave the@importas is with one warning, and the build never fails. In dev the@importis left alone (fonts load from Google).document.fonts.check('16px "Host Grotesk"')is true and body text computes to Host Grotesk. There were 0 requests to Google and no font-related console errors. The text regions are pixel-identical to the same build without the plugin loaded with Google reachable. A cached rebuild with the network blocked works, an offline uncached build falls back with a warning, andmake startstill works. A fixture also covered an html<link>, a sass partial, a lazy css chunk,base: './'andcssCodeSplit: false.