Skip to content

Commit 7a6dc89

Browse files
authored
feat: bundle esm + cjs variants of runtime packages using tsdown (#452)
adopts the use of https://tsdown.dev/ to bundle the runtime packages as distinct CJS and ESM distributions. increasingly, we've run into issues where mixing and matching ESM/CJS creates annoying build errors, such as the `axios` type-mismatches between their CJS and ESM typings that we had to patch out. similar issues occurred whilst updating `@koa/router` to v15, and so decided it was time to address. the primary downside, is that the `dist` files will no longer mirror the `src` structure. this will require careful testing of package publishing and installation to ensure there are no regressions prior to release.
1 parent b2ad05e commit 7a6dc89

23 files changed

Lines changed: 767 additions & 405 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ jobs:
2727

2828
- run: pnpm install --frozen-lockfile
2929

30-
- run: node ./scripts/generate-ajv-validator.js
31-
- run: pnpm tsc -b tsconfig.json
30+
- run: pnpm run build
31+
3232
- run: pnpm ci-lint
3333

3434
- name: Check for uncommitted changes
@@ -84,7 +84,7 @@ jobs:
8484
8585
- run: pnpm install --frozen-lockfile
8686

87-
- run: pnpm --filter @nahkies/openapi-code-generator-documentation build
87+
- run: pnpm run build:docs
8888

8989
unit:
9090
needs: build

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"docs:generate": "node ./scripts/generate-toc.mjs",
2222
"refresh": "./scripts/refresh-data.sh",
2323
"lint": "biome check --fix .",
24-
"build": "node ./scripts/generate-ajv-validator.js && tsc -b tsconfig.json",
24+
"build": "node ./scripts/generate-ajv-validator.js && pnpm -r --workspace-concurrency=4 run bundle && tsc -b tsconfig.json",
2525
"build:docs": "pnpm --filter @nahkies/openapi-code-generator-documentation build",
2626
"build:watch": "tsc -b tsconfig.json -w",
2727
"test": "jest",

packages/typescript-axios-runtime/package.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,20 @@
1818
},
1919
"exports": {
2020
"./main": {
21-
"require": "./dist/main.js",
22-
"import": "./dist/main.js",
23-
"types": "./dist/main.d.ts"
21+
"import": {
22+
"types": "./dist/esm/main.d.mts",
23+
"default": "./dist/esm/main.mjs"
24+
},
25+
"require": {
26+
"types": "./dist/cjs/main.d.cts",
27+
"default": "./dist/cjs/main.cjs"
28+
}
2429
}
2530
},
2631
"scripts": {
2732
"clean": "rm -rf ./dist && rm tsconfig.tsbuildinfo",
2833
"build": "tsc -p ./tsconfig.json",
34+
"bundle": "tsdown",
2935
"test": "jest"
3036
},
3137
"dependencies": {
@@ -39,6 +45,7 @@
3945
"@jest/globals": "^30.3.0",
4046
"axios": "^1.15.2",
4147
"jest": "^30.3.0",
48+
"tsdown": "^0.21.10",
4249
"typescript": "^6.0.3"
4350
},
4451
"files": [

packages/typescript-axios-runtime/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "../../tsconfig.base.json",
33
"compilerOptions": {
44
"outDir": "./dist",
5-
"rootDir": "./src"
5+
"rootDir": "./src",
6+
"emitDeclarationOnly": true
67
},
78
"include": ["src/**/*"],
89
"references": [
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {defineConfig} from "tsdown"
2+
import packageJson from "./package.json" with {type: "json"}
3+
4+
export default defineConfig({
5+
name: packageJson.name,
6+
entry: ["./src/main.ts"],
7+
8+
target: "esnext",
9+
dts: true,
10+
sourcemap: true,
11+
12+
format: {
13+
esm: {
14+
outDir: "./dist/esm",
15+
},
16+
cjs: {
17+
outDir: "./dist/cjs",
18+
},
19+
},
20+
})

packages/typescript-common-runtime/package.json

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,60 @@
1818
},
1919
"exports": {
2020
"./errors": {
21-
"require": "./dist/errors.js",
22-
"import": "./dist/errors.js",
23-
"types": "./dist/errors.d.ts"
21+
"import": {
22+
"types": "./dist/esm/errors.d.mts",
23+
"default": "./dist/esm/errors.mjs"
24+
},
25+
"require": {
26+
"types": "./dist/cjs/errors.d.cts",
27+
"default": "./dist/cjs/errors.cjs"
28+
}
2429
},
2530
"./validation": {
26-
"require": "./dist/validation.js",
27-
"import": "./dist/validation.js",
28-
"types": "./dist/validation.d.ts"
31+
"import": {
32+
"types": "./dist/esm/validation.d.mts",
33+
"default": "./dist/esm/validation.mjs"
34+
},
35+
"require": {
36+
"types": "./dist/cjs/validation.d.cts",
37+
"default": "./dist/cjs/validation.cjs"
38+
}
2939
},
3040
"./types": {
31-
"require": "./dist/types.js",
32-
"import": "./dist/types.js",
33-
"types": "./dist/types.d.ts"
41+
"import": {
42+
"types": "./dist/esm/types.d.mts",
43+
"default": "./dist/esm/types.mjs"
44+
},
45+
"require": {
46+
"types": "./dist/cjs/types.d.cts",
47+
"default": "./dist/cjs/types.cjs"
48+
}
3449
},
3550
"./query-parser": {
36-
"require": "./dist/query-parser.js",
37-
"import": "./dist/query-parser.js",
38-
"types": "./dist/query-parser.d.ts"
51+
"import": {
52+
"types": "./dist/esm/query-parser.d.mts",
53+
"default": "./dist/esm/query-parser.mjs"
54+
},
55+
"require": {
56+
"types": "./dist/cjs/query-parser.d.cts",
57+
"default": "./dist/cjs/query-parser.cjs"
58+
}
3959
},
4060
"./request-bodies": {
41-
"require": "./dist/request-bodies/index.js",
42-
"import": "./dist/request-bodies/index.js",
43-
"types": "./dist/request-bodies/index.d.ts"
61+
"import": {
62+
"types": "./dist/esm/request-bodies/index.d.mts",
63+
"default": "./dist/esm/request-bodies/index.mjs"
64+
},
65+
"require": {
66+
"types": "./dist/cjs/request-bodies/index.d.cts",
67+
"default": "./dist/cjs/request-bodies/index.cjs"
68+
}
4469
}
4570
},
4671
"scripts": {
4772
"clean": "rm -rf ./dist && rm tsconfig.tsbuildinfo",
4873
"build": "tsc -p ./tsconfig.json",
74+
"bundle": "tsdown",
4975
"test": "jest"
5076
},
5177
"dependencies": {
@@ -68,6 +94,7 @@
6894
"@jest/globals": "^30.3.0",
6995
"jest": "^30.3.0",
7096
"joi": "^18.1.2",
97+
"tsdown": "^0.21.10",
7198
"typescript": "^6.0.3",
7299
"zod": "^3.25.76"
73100
},

packages/typescript-common-runtime/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "../../tsconfig.base.json",
33
"compilerOptions": {
44
"rootDir": "./src",
5-
"outDir": "./dist"
5+
"outDir": "./dist",
6+
"emitDeclarationOnly": true
67
},
78
"include": ["src/**/*"],
89
"references": []
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {defineConfig} from "tsdown"
2+
import packageJson from "./package.json" with {type: "json"}
3+
4+
export default defineConfig({
5+
name: packageJson.name,
6+
entry: [
7+
"./src/errors.ts",
8+
"./src/validation.ts",
9+
"./src/types.ts",
10+
"./src/query-parser.ts",
11+
"./src/request-bodies/index.ts",
12+
],
13+
target: "esnext",
14+
15+
format: {
16+
esm: {
17+
outDir: "./dist/esm",
18+
},
19+
cjs: {
20+
outDir: "./dist/cjs",
21+
},
22+
},
23+
24+
dts: true,
25+
sourcemap: true,
26+
})

packages/typescript-express-runtime/package.json

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,61 @@
1818
},
1919
"exports": {
2020
"./errors": {
21-
"require": "./dist/errors.js",
22-
"import": "./dist/errors.js",
23-
"types": "./dist/errors.d.ts"
21+
"import": {
22+
"types": "./dist/esm/errors.d.mts",
23+
"default": "./dist/esm/errors.mjs"
24+
},
25+
"require": {
26+
"types": "./dist/cjs/errors.d.cts",
27+
"default": "./dist/cjs/errors.cjs"
28+
}
2429
},
2530
"./server": {
26-
"require": "./dist/server.js",
27-
"import": "./dist/server.js",
28-
"types": "./dist/server.d.ts"
31+
"import": {
32+
"types": "./dist/esm/server.d.mts",
33+
"default": "./dist/esm/server.mjs"
34+
},
35+
"require": {
36+
"types": "./dist/cjs/server.d.cts",
37+
"default": "./dist/cjs/server.cjs"
38+
}
2939
},
3040
"./joi": {
31-
"require": "./dist/joi.js",
32-
"import": "./dist/joi.js",
33-
"types": "./dist/joi.d.ts"
41+
"import": {
42+
"types": "./dist/esm/joi.d.mts",
43+
"default": "./dist/esm/joi.mjs"
44+
},
45+
"require": {
46+
"types": "./dist/cjs/joi.d.cts",
47+
"default": "./dist/cjs/joi.cjs"
48+
}
3449
},
3550
"./zod-v3": {
36-
"require": "./dist/zod-v3.js",
37-
"import": "./dist/zod-v3.js",
38-
"types": "./dist/zod-v3.d.ts"
51+
"import": {
52+
"types": "./dist/esm/zod-v3.d.mts",
53+
"default": "./dist/esm/zod-v3.mjs"
54+
},
55+
"require": {
56+
"types": "./dist/cjs/zod-v3.d.cts",
57+
"default": "./dist/cjs/zod-v3.cjs"
58+
}
3959
},
4060
"./zod-v4": {
41-
"require": "./dist/zod-v4.js",
42-
"import": "./dist/zod-v4.js",
43-
"types": "./dist/zod-v4.d.ts"
61+
"import": {
62+
"types": "./dist/esm/zod-v4.d.mts",
63+
"default": "./dist/esm/zod-v4.mjs"
64+
},
65+
"require": {
66+
"types": "./dist/cjs/zod-v4.d.cts",
67+
"default": "./dist/cjs/zod-v4.cjs"
68+
}
4469
}
4570
},
4671
"scripts": {
4772
"clean": "rm -rf ./dist && rm tsconfig.tsbuildinfo",
4873
"dev": "nodemon --watch ./src -e ts --delay 2 --exec 'pnpm build'",
4974
"build": "tsc -p ./tsconfig.json",
75+
"bundle": "tsdown",
5076
"test": "jest"
5177
},
5278
"dependencies": {
@@ -80,6 +106,7 @@
80106
"body-parser": "^2.2.2",
81107
"jest": "^30.3.0",
82108
"joi": "^18.1.2",
109+
"tsdown": "^0.21.10",
83110
"typescript": "^6.0.3",
84111
"zod": "^3.25.76"
85112
},

packages/typescript-express-runtime/src/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type {Server} from "node:http"
22
import type {AddressInfo, ListenOptions} from "node:net"
33
import type {Res, StatusCode} from "@nahkies/typescript-common-runtime/types"
4-
import {ExpressRuntimeError} from "@nahkies/typescript-express-runtime/errors"
54
import type {OptionsJson, OptionsText, OptionsUrlencoded} from "body-parser"
65
import Cors, {type CorsOptions, type CorsOptionsDelegate} from "cors"
76
import type {Response} from "express"
@@ -13,6 +12,7 @@ import express, {
1312
type RequestHandler,
1413
type Router,
1514
} from "express"
15+
import {ExpressRuntimeError} from "./errors"
1616

1717
export {parseQueryParameters} from "@nahkies/typescript-common-runtime/query-parser"
1818

0 commit comments

Comments
 (0)