build: migrate from Rollup/Babel/Terser to tsdown#829
Merged
Conversation
Collapse the hand-rolled Rollup orchestrator (scripts/configs.cjs +
config-types.cjs + build.main.cjs, 373 lines) and 8 build devDeps into one
tsdown.config.ts (rolldown engine + built-in dts). Chosen over tsup after a
problem-blind Codex assessment and a spike: tsdown emits constructor-direct
CJS (require('fuse.js') === Fuse) and named worker CJS automatically, no
footer hacks.
Behavior-preserving on the public surface:
- identical 15-file dist set (12 runtime + 3 dts)
- CJS require() contract unchanged; named fuse-worker.cjs export preserved
- feature-flag DCE intact (basic build strips logical/extended/token)
- dev/prod default-export split preserved
- Fuse.version injected via define (bare __VERSION__ + ambient declare;
honors process.env.VERSION for releases)
Worker-URL resolution no longer depends on a bundler's import.meta.url
codegen: a per-format __WORKER_IS_CJS__ define routes browser-CJS to a
document base while ESM keeps the literal new URL('./fuse.worker.mjs',
import.meta.url) so bundlers still detect and rewrite the worker asset.
test/worker-url.test.js gates node-ESM, node-CJS, browser-ESM (Vite), and
browser-CJS. test/cjs-interop.test.js gates require() === constructor for
every lib cjs plus the named worker cjs.
Sizes: minified artifacts are 287-313 bytes smaller raw; gzip is +8..+28
bytes (<=0.4%, accepted) since rolldown's minifier compresses marginally
worse than Terser.
Build/release now requires Node >=22.18 (tsdown engines): CI builds on 22/24
and runs the Node 20 leg against the committed dist. docs-deploy
reconciliation is descoped (deploy-docs.sh is the only path that bumps docs
before deploy; needs a release-ordering fix first).
Removed devDeps: rollup, @rollup/plugin-babel, @rollup/plugin-node-resolve,
@rollup/plugin-replace, @babel/core, @babel/preset-typescript, terser,
rollup-plugin-dts. Added: tsdown.
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
Replaces the hand-rolled Rollup build (
scripts/configs.cjs+config-types.cjs+build.main.cjs, 373 lines + 8 devDeps) with a singletsdown.config.ts(rolldown engine + built-in dts).Why tsdown (not tsup, not consolidated Rollup)
A problem-blind Codex assessment leaned against an esbuild-class tool swap over CJS-interop and worker-
import.meta.urlrisk. A spike then showed tsdown clears every gate that tsup would have needed hacks for:require('fuse.js') === Fuse(constructor-direct CJS) — automatic, no footer hackfuse-worker.cjsexport — automaticBehavior-preserving
dist/set (12 runtime + 3 dts), verified againstmainrequire()contract + named worker export unchangedFuse.versioninjected viadefine(bare__VERSION__+ ambient declare; honorsprocess.env.VERSION)cjs-interop+worker-urltests gate the contractsWorker-URL resolution
Reworked so it no longer depends on a bundler's
import.meta.urlcodegen: a per-format__WORKER_IS_CJS__define routes browser-CJS to adocumentbase while ESM keeps the literalnew URL('./fuse.worker.mjs', import.meta.url)for bundler asset detection.test/worker-url.test.jsgates node-ESM, node-CJS, browser-ESM (Vite), and browser-CJS.Sizes (accepted tradeoff)
Min artifacts are 287–313 bytes smaller raw; gzip is +8 to +28 bytes (≤0.4%) because rolldown's minifier compresses marginally worse than Terser. Accepted in favor of the dependency reduction.
engines)CI builds on Node 22/24 and runs the Node 20 leg against the committed
dist/(the library runtime still supports Node ≥10)..nvmrcbumped to 22; DEVELOPERS.md + release docs updated. This CI matrix change is the main thing to watch in this PR's checks — it is the part that can't be validated locally.Review
Plan 017 and the implementation were both reviewed cross-model (Codex): plan APPROVED (round 3) plus a cold-read fresh-pass (0 CRITICAL/HIGH); implementation review APPROVED with only the LOW gzip note above.
Out of scope
docs-deploy reconciliation is descoped:
deploy-docs.shis currently the only path that bumps docs before deploy, so deleting it needs a release-ordering fix first. Tracked separately in the roadmap.