Feature/cdn considerations - #13
Merged
Merged
Conversation
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.
Description
sibujs-uihad no no-build story. The package shipped ESM and CJS only, so a page using SibuJS from a<script>tag — islands, most often — could reach the runtime but none of these components. This adds a CDN build, and the stylesheet that makes it actually usable.The bundle
Three new export paths:
sibujs-ui/cdn,sibujs-ui/cdn-dev,sibujs-ui/cdn-css.SibuJS is not bundled in. It stays a peer dependency in this artifact too: an esbuild plugin resolves
sibujsto thewindow.Sibuthe runtime tag installed, so a page that already loaded the framework does not download it again. All 59 imports insrc/are baresibujs, so the plugin's filter covers every one — verified against the built bytes, which contain no framework internals and do readglobalThis.Sibu.That is also why tag order matters. Loading
sibujs-uiwithout the runtime throws a message naming the problem and the fix, rather than surfacing later as an undefined property inside whichever component ran first.The stylesheet, which is the part that was missing
Every component carries Tailwind utility classes — 29 on a single
Button— and the shipped themes are custom properties only. A page that loaded just the script tags got correct behaviour and raw browser defaults. Nothing threw, which makes that harder to diagnose, not easier:sibujs-ui.cssdisplayinline-blockinline-flexrgb(240,240,240)oklch(0.205 0 0)A no-build consumer has no build step by definition, so
dist/sibujs-ui.cssis now compiled from the components' actual class usage plus the base and default themes — 113.7 KB, 17.7 KB gzip. One<link>, no separate theme import. Thedestructivevariant renders distinctly and dark mode inverts correctly viaclass="dark".It includes Tailwind's Preflight, matching what bundler consumers already get from
@import "tailwindcss"— the components are designed against that reset, and without it buttons keep their native chrome and borders default tocurrentColor. It therefore restyles the host page, which the README states plainly.tw-animate-cssturned out to be unnecessary:base.cssalready defines the keyframes and--animate-*tokens the components name, so the only new dependencies aretailwindcssand@tailwindcss/cli, both dev-only.Fix: the dev gate could not be folded
components/types.tstestedglobalThis.__SIBU_DEV__first. A member expression is not adefinetarget, so no bundler could replace it: the branch stayed live and its warning text rode into builds that could never print it. It now leads with a bare__SIBU_DEV__, mirroring the framework's own convention, sodefine: { __SIBU_DEV__: "false" }folds it away. The fallbacks it consulted before are still consulted, in the same order, so behaviour is unchanged wherever the flag was already correct.Sizes
dist/cdn.global.jsdist/cdn.dev.global.jsdist/sibujs-ui.cssThe JS carries the whole package — every component and the ~1900-icon set — because a
<script>tag cannot tree-shake, and the icons are roughly 79 KB gzip of that total. Bundler consumers are unaffected: the ESM/CJS entry points are untouched and still tree-shake per import.Related Issue
Closes #
Type of Change
Checklist
Verification
npm run build— clean; produces both IIFEs, the stylesheet, and the ESM/CJS entry pointsnpm run lint— clean, 66 filestsc --noEmit— cleannpx vitest run— 432 passingnpm pack --dry-run— 23 files, 659.3 kB; confirmsdist/cdn.global.js,dist/cdn.dev.global.js,dist/sibujs-ui.css, every theme, andstyles/cdn.cssall ship.prepublishOnlyruns the full build, so a stale artifact cannot be published.tests/cdn-artifacts.test.ts(12 tests) asserts against the built files what source cannot show: SibuJS absent from the bytes, the ordering guard firing,SibuUIregistered without disturbingSibu, diagnostics compiled out of production and present in dev, and the stylesheet carrying both the utilities and the theme tokens.One test-design note worth recording: the stylesheet tests first used
skipIf(!existsSync(cssPath)), which skipped instead of failing — precisely the behaviour that would let this gap reappear unnoticed. They now gate on the samebuiltflag as the JS bundles, so a built package with a missing stylesheet is a failure. Verified red before implementing.Verified in a browser
Beyond the unit tests, the actual use case was exercised in Chromium: components built inside a
registerIslandsetup, appended to server-rendered markup, with a click on a SibuUIButtondriving the island's own signal (0 → 1) — one shared runtime, no wiring. Confirmed against bothcdn.global.jsandcdn.full.global.js, and the load-order guard confirmed firing when the tags are reversed.Not addressed here
The JS bundle is 131.3 KB gzip, ~79 KB of which is the icon set that no
<script>tag can tree-shake. Splitting icons into a second optional artifact would put the base near 54 KB gzip — worth doing, but it changes the public artifact layout and belongs in its own PR.