feat: flat output layout (clean break, no src/ wrapper)#10
Open
brainkim wants to merge 3 commits into
Open
Conversation
Modules now publish at the package root (dist/index.js) instead of
nested under src/ (dist/src/index.js), so direct CDN file URLs like
cdn.jsdelivr.net/npm/<pkg>/index.js resolve. CDNs serve literal paths
and never consult the exports map, so the src/ wrapper 404'd every
copy-pasted file URL.
Layout:
- src/<entry> -> dist/<entry>.{js,cjs,d.ts}
- bin/<entry> -> dist/bin/<entry>.js (unchanged)
- chunks -> dist/_chunks/ (was dist/src/_chunks/)
- internal modules -> relocated with the tree (relative imports intact)
dist/src/ now holds compatibility stubs - tiny re-export shims (plus a
full UMD copy) - so <pkg>/src/<entry>.js paths from packages published
with older libuild versions keep resolving. Stubs re-export `default`
only when the entry has one, detected via the esbuild metafile. Node
consumers are unaffected either way: exports-map keys never contained
src/.
Also fixes discovered along the way:
- UMD plugin wrapped (and corrupted) every sibling .js in its outdir;
it now wraps only the UMD output file
- --save root bin could point at a path that exists but is not the
built executable; paths are normalized to the real artifact
- --save is idempotent again for ambient .d.ts exports and for
multi-entry discovery with flat saved export values
Fixes #9
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The src/ layout only existed for packages published with libuild since 0.1.x, a small set. The crank-ecosystem CDN URLs that motivated #9 are already flat - flat output restores them. Carrying a stub layer in every future tarball to protect a handful of /src/ deep links wasn't worth it: literal <pkg>/src/* URLs 404 once a package republishes. Node consumers are unaffected (exports keys never contained src/). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Never let a breaking change go to waste: - deps: esbuild ^0.19 -> ^0.28.1 (nine esbuild-breaking minors), commander 15, glob/expect patch bumps. Zero API fallout. - .tsx entry points discovered and built; tsconfig jsx settings honored for declarations (fallback: preserve). Fixes #6 - --save no longer drops the import/require conditions from a types-only "." export (broke bundler resolution of symlinked packages). Fixes #7 - restore npm flag whitelist on `libuild publish`: the security validation from 47a93bb was silently dropped in the commander rewrite (60d24e7); unknown/unsafe flags are warned and stripped again. The 4 "failing" security tests were correct all along - the suite is now fully green (139 pass, 0 fail) - dead code: unreachable src/bin entry flavor, unused params, deprecated substr, untyped catches Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.
Closes #9.
What this does
Modules publish at the tarball root (
<pkg>/index.js) instead of nested undersrc/. jsDelivr/unpkg serve literal paths and never consult the exports map, so the old layout 404'd every copy-pasted CDN file URL. This is the default behavior — no config flag — and a clean break: no compatibility layer ships.cdn.jsdelivr.net/npm/<pkg>/index.jscdn.jsdelivr.net/npm/<pkg>/src/index.jssrc/)npm linkroot/dist symmetrydist/prefix strip unchanged)The accepted break is small by construction: the
src/layout only ever existed for packages published with libuild 0.1.x (~9 months). The crank-ecosystem URLs that motivated #9 are already flat — this restores them.Layout
Design notes from the issue discussion:
{in, out}entry points), not B — keepingbin/as a subdir at build time is what per-entry output mapping gives natively.bin/a subdir and outputs carrying.js/.cjs/.d.tsextensions, no reachable collision with copied metadata files exists. (Thesrc/bin/entry flavor in the old code is dead — nothing producessource: 'src'.)dist/src/for old URLs; dropped in the second commit per discussion — band-aid off.Bugs found & fixed along the way
.jsin its outdir, so any package withsrc/umd.tsplus other entries shipped UMD-mangled ESM files. Now wraps only its own output; regression test included.--savebin kept stale nested paths (caught by test-update agent):bin: "src/cli.js"saved as./dist/src/cli.js; now flattened to the real executable.--saveidempotency (caught by agents): the ambient.d.tsexport whitelist and the multi-entry discovery heuristic both assumed/src/-shaped saved values; both now accept flat forms.Verification
main.test/flat-output.test.ts: flat layout + nosrc/in output, root-module runtime resolution (CDN-literal simulation), P1: Module augmentation and .d.ts paths broken in published package #1-style guard (internal-module.d.ts+declare modulerelocate together, relative imports intact), UMD non-corruption,npm packtarball shape (asserts nothing ships undersrc/),--savebin regression.tsc(nodenext) through the exports map — typechecks; runtime imports work.dist/srcgone), CLI executes,--saveround-trips.Also in this release (maintenance batch)
Per "never let a breaking change go to waste", commit 26b6723 folds in:
^0.19→^0.28.1(nine esbuild-breaking minors; zero API fallout), commander 15, patch bumps--saveno longer dropsimport/requireconditions from a types-only.exportBreaking-change notes (0.2.0)
<pkg>/src/*URLs into previously published packages 404 once those packages republish. Node/bundler consumers unaffected.--savepaths change shape (./dist/index.js); old saved paths migrate automatically on the next--save.filesfield is dropped when it only contained layout dirs (npm packs the whole dist dir); author extras keep the field with module patterns appended.🤖 Generated with Claude Code