Simplify and modernise tsdown build configuration#1492
Open
smorimoto wants to merge 3 commits intoworkos:mainfrom
Open
Simplify and modernise tsdown build configuration#1492smorimoto wants to merge 3 commits intoworkos:mainfrom
smorimoto wants to merge 3 commits intoworkos:mainfrom
Conversation
Contributor
Greptile OverviewGreptile SummaryConsolidated and modernized the build configuration by upgrading tsdown from 0.17 to 0.20, replacing two separate build configs with a unified approach that reduces output from 566 to 12 files while maintaining full compatibility across Node.js, Deno, Bun, and Worker runtimes. Key changes:
Confidence Score: 5/5
Important Files Changed
Flowchartflowchart TD
A[Source Files] --> B[tsdown 0.20]
B --> C{Build Format}
C -->|ESM| D[index.mjs<br/>index.worker.mjs]
C -->|CJS| E[index.cjs<br/>index.worker.cjs]
C -->|Types| F[index.d.cts<br/>index.worker.d.mts]
G[Dependencies] --> H{Bundling Strategy}
H -->|inlineOnly| I[iron-webcrypto<br/>jose]
H -->|External| J[Other deps]
I --> D
I --> E
J --> D
J --> E
D --> K[package.json exports]
E --> K
F --> K
K --> L{Runtime Condition}
L -->|workerd/edge-light/convex| M[worker entry]
L -->|import| N[main ESM]
L -->|require| O[main CJS]
P[publint] --> K
P --> Q[Validation]
Last reviewed commit: d771b19 |
Upgrade tsdown from 0.17 to 0.20 and consolidate the build configuration from two separate objects (one for ESM, one for CJS) into a single unified configuration object. Key changes to tsdown.config.ts: - Merge ESM and CJS into one config with `format: ['esm', 'cjs']`. The previous setup maintained two independent configuration objects with duplicated entry, outDir, target, sourcemap, and dts options. A single object eliminates this repetition entirely. - Remove `target: 'es2022'` because tsdown 0.20 automatically reads the `engines.node` field from package.json (currently `>=20.15.0`) to determine the compilation target, making an explicit target redundant. - Remove `unbundle: true` because the package only exports two entry points (`.` and `./worker`), so preserving the full source file structure in the output is unnecessary. This reduces the output from 566 files to 12 files with automatic code splitting for shared modules. - Remove `outExtensions` because tsdown 0.20 automatically derives the correct file extensions (`.mjs`/`.d.mts` for ESM, `.cjs`/`.d.cts` for CJS) based on the output format. - Replace `noExternal` with `inlineOnly`, the recommended option in tsdown 0.20 for explicitly marking which ESM-only dependencies should be bundled into the CJS output. Unlike `noExternal`, `inlineOnly` prevents unintended bundling of other dependencies. - Replace `uint8array-extras` with `jose` in the inlined dependencies list. `uint8array-extras` was a transitive dependency of `iron-webcrypto` and is automatically inlined recursively when its parent is inlined, so listing it explicitly was unnecessary. `jose` is a direct ESM-only dependency that was previously missing from the inline list. - Add `exports` option with `customExports` to let tsdown automatically manage the package.json exports field, keeping it in sync with the build output. The custom function adds the runtime-specific conditions (workerd, edge-light, convex) that route to the worker entry point for environments without `process` global. - Remove `deno` and `bun` export conditions from package.json because both runtimes correctly resolve through the standard `import`/`require` fallback conditions, making dedicated conditions redundant. - Remove explicit `types` fields from export conditions because the declaration files (`.d.mts`/`.d.cts`) are co-located with their corresponding JS files, allowing TypeScript to resolve them automatically. - Add `publint: true` to validate the package.json configuration against the actual build output on every build, catching export mismatches early. - Add `publint` as a devDependency to support the built-in validation. - Update ecosystem-check.ts to reference `.mjs` extensions instead of `.js` to match the new tsdown 0.20 output naming convention.
…script
Add `attw: { profile: 'node16' }` to tsdown.config.ts so that Are The
Types Wrong validation runs automatically on every build alongside
publint. This makes the separate `check:types` npm script redundant,
as the same validation (with a clearer `node16` profile instead of
`--ignore-rules no-resolution`) now runs as part of `npx tsdown`.
981ba60 to
380dfb4
Compare
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.
Summary
target— auto-inferred fromengines.nodeunbundle— unnecessary as only two entry points are exported, reducing output from 566 to 12 filesoutExtensions— auto-derived by tsdown 0.20noExternalwithinlineOnly, the recommended tsdown 0.20 option that prevents unintended dependency bundling. Also fix the dependency list: removeuint8array-extras(recursively inlined viairon-webcrypto) and add the missingjose(direct ESM-only dependency)exportsoption withcustomExportsto auto-manage package.json exports, keeping them in sync with build output. Runtime-specific conditions (workerd,edge-light,convex) route to the worker entry for environments withoutprocessglobaldenoandbunexport conditions as both runtimes resolve correctly through the standardimport/requirefallbacktypesfields from export conditions as co-located.d.mts/.d.ctsfiles are resolved automatically by TypeScriptpublintvalidation to catch export mismatches on every buildattwvalidation withnode16profile to verify type declarations on every build, replacing the separatecheck:typesnpm script which used--ignore-rules no-resolution.mjsextensions matching tsdown 0.20 outputPackage size comparison
lib/file countlib/disk sizeBreaking change note
Removing
unbundlemeans individual source files are no longer emitted tolib/. Deep imports such as@workos-inc/node/lib/common/net/node-clientthat previously worked (despite never being officially supported via theexportsmap) will no longer resolve. Only the documented entry points (.and./worker) are available. This aligns the actual output with the package's public API surface.Housekeeping
sort-package-jsonfor consistent field orderingTest plan
npx tsdownbuilds successfully with no warningspublintreports no issuesattwreports no problems (node16 CJS/ESM, bundler all green)npm run check:runtimespasses all 6 runtime tests (node-cjs, node-esm, deno, bun-cjs, bun-esm, worker)