Skip to content

Build packages with unbuild to improve CJS support #2310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/itchy-turkeys-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-fetch": minor
---

Build package with unbuild. Also remove the minified version (openapi-fetch is only useful in a TypeScript/bundler environment, so there’s no sense in loading it from a CDN clientside).
7 changes: 7 additions & 0 deletions .changeset/shy-cars-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"openapi-react-query": minor
"openapi-typescript": minor
"swr-openapi": minor
---

Build package with unbuild to improve CJS support
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,23 @@
"version": "pnpm run build && changeset version && pnpm i"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.18.1",
"@biomejs/biome": "^1.9.4",
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.29.2",
"@playwright/test": "^1.52.0",
"@size-limit/preset-small-lib": "^11.2.0",
"@types/node": "^22.15.3",
"del-cli": "^6.0.0",
"prettier": "^3.5.3",
"size-limit": "^11.2.0",
"turbo": "^2.5.2",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"vitest": "^3.1.3"
},
"size-limit": [
{
"path": "packages/openapi-fetch/dist/index.min.js",
"path": "packages/openapi-fetch/dist/index.mjs",
"limit": "7 kB",
"brotli": false
}
Expand Down
1 change: 1 addition & 0 deletions packages/openapi-fetch/.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.turbo
*.config.*
examples
test
test-results
Expand Down
12 changes: 12 additions & 0 deletions packages/openapi-fetch/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["./src/index.js"],
declaration: "compatible",
clean: true,
sourcemap: true,
rollup: {
// Ship CommonJS-compatible bundle
emitCJS: true,
},
});
1 change: 0 additions & 1 deletion packages/openapi-fetch/examples/vue-3/tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"composite": true,
"noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",

"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
Expand Down
34 changes: 12 additions & 22 deletions packages/openapi-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@
},
"license": "MIT",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"module" has never been standardized, but was just a common community convention—common enough it started to sneak into some bundle setups. All Node LTS versions and all bundlers I’m aware of now respect "exports", which means this is no longer needed.

"main" is still standard. And technically it’s superceded by exports, but we’ll just keep it around for safety. But "module" is safe to remove at this point.

"types": "./dist/index.d.ts",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for "types"—at this point TypeScript can now just locate the types due to unbuild’s careful handling

"main": "./dist/index.mjs",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/cjs/index.d.cts",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With separate .d.cts and .d.mts declarations generated, we don’t need to declare types separately. This was a little bit of a hack from previous builds that stuck around. With unbuild’s better generation in general, TypeScript can automatically locate types.

"default": "./dist/cjs/index.cjs"
}
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
},
"./*": "./*"
},
Expand All @@ -47,19 +40,18 @@
"svelte"
],
"scripts": {
"build": "pnpm run build:clean && pnpm run build:js && pnpm run build:js-min && pnpm run build:cjs",
"build:clean": "del-cli dist",
"build:js": "mkdir -p dist && cp src/* dist",
"build:js-min": "esbuild --bundle src/index.js --format=esm --minify --outfile=dist/index.min.js && cp dist/index.d.ts dist/index.min.d.ts",
"build:cjs": "esbuild --bundle src/index.js --format=cjs --outfile=dist/cjs/index.cjs && cp dist/index.d.ts dist/cjs/index.d.cts",
"build": "unbuild",
"format": "biome format . --write",
"lint": "biome check .",
"lint": "pnpm run lint:js && pnpm run lint:ts && pnpm run lint:ts-no-strict",
"lint:js": "biome check .",
"lint:ts": "tsc --noEmit",
"lint:ts-no-strict": "tsc --noEmit -p test/no-strict-null-checks/tsconfig.json",
"generate-types": "openapi-typescript -c test/redocly.yaml",
"prepack": "pnpm run build",
"pretest": "pnpm run generate-types",
"test": "pnpm run \"/^test:/\"",
"test": "pnpm run test:js && pnpm run test:exports",
"test:js": "vitest run",
"test:ts": "tsc --noEmit",
"test:ts-no-strict": "tsc --noEmit -p test/no-strict-null-checks/tsconfig.json",
"test:exports": "pnpm run build && attw --pack .",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the “are the types wrong” type tests, so added to all packages. We were also able to remove the cjs-resolves-to-esm rule 😎

"test-e2e": "playwright test",
"bench:js": "vitest bench",
"e2e-vite-build": "vite build test/e2e/app",
Expand All @@ -71,8 +63,6 @@
},
"devDependencies": {
"axios": "^1.9.0",
"del-cli": "^6.0.0",
"esbuild": "^0.25.3",
"execa": "^9.5.2",
"express": "^5.0.0",
"feature-fetch": "^0.0.43",
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-fetch/test/bench/index.bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Fetcher } from "openapi-typescript-fetch";
import { createApiFetchClient } from "feature-fetch";
import superagent from "superagent";
import { afterAll, bench, describe, vi } from "vitest";
import createClient, { createPathBasedClient } from "../../dist/index.js";
import createClient, { createPathBasedClient } from "../../dist/index.mjs";
import * as openapiTSCodegen from "./openapi-typescript-codegen.min.js";

const BASE_URL = "https://api.test.local";
Expand Down
1 change: 1 addition & 0 deletions packages/openapi-metadata/.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.turbo
*.config.*
test
tsconfig*.json
vitest.config.ts
Expand Down
20 changes: 20 additions & 0 deletions packages/openapi-metadata/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: [
"./src/index.ts",
"./src/decorators/index.ts",
"./src/metadata/index.ts",
"./src/errors/index.ts",
"./src/ui/index.ts",
],
declaration: "compatible",
clean: true,
sourcemap: true,
rollup: {
// Ship CommonJS-compatible bundle
emitCJS: true,
// Don’t bundle .js files together to more closely match old exports (can remove in next major)
output: { preserveModules: true },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openapi-metadata was already using unbuild! But adding this config just shores it up more closely with the other packages without changing output too much.

},
});
1 change: 0 additions & 1 deletion packages/openapi-metadata/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
"@vitest/coverage-v8": "^3.1.3",
"reflect-metadata": "^0.2.2",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"unplugin-swc": "^1.5.2"
}
}
4 changes: 0 additions & 4 deletions packages/openapi-metadata/tsconfig.build.json

This file was deleted.

1 change: 1 addition & 0 deletions packages/openapi-react-query/.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.turbo
*.config.*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore build.config.ts configs for unbuild in package publishing

test
vitest.config.ts
tsconfig*.json
Expand Down
12 changes: 12 additions & 0 deletions packages/openapi-react-query/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["./src/index.ts"],
declaration: "compatible",
clean: true,
sourcemap: true,
rollup: {
// Ship CommonJS-compatible bundle
emitCJS: true,
},
});
32 changes: 11 additions & 21 deletions packages/openapi-react-query/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@
},
"license": "MIT",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"main": "./dist/index.mjs",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
}
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
},
"./*": "./*"
},
Expand All @@ -47,18 +40,17 @@
"tanstack"
],
"scripts": {
"build": "pnpm run build:clean && pnpm run build:esm && pnpm run build:cjs",
"build:clean": "del-cli dist",
"build:esm": "tsc -p tsconfig.build.json",
"build:cjs": "esbuild --bundle --platform=node --target=es2019 --outfile=dist/index.cjs --external:typescript src/index.ts",
"build": "unbuild",
"dev": "tsc -p tsconfig.build.json --watch",
"format": "biome format . --write",
"lint": "biome check .",
"lint": "pnpm run lint:js && pnpm run lint:ts",
"lint:js": "biome check .",
"lint:ts": "tsc --noEmit",
"generate-types": "openapi-typescript test/fixtures/api.yaml -o test/fixtures/api.d.ts",
"pretest": "pnpm run generate-types",
"test": "pnpm run \"/^test:/\"",
"prepack": "pnpm run build",
"test": "pnpm run generate-types && pnpm run test:js && pnpm run test:exports",
"test:js": "vitest run",
"test:ts": "tsc --noEmit",
"test:exports": "pnpm run build && attw --pack .",
"version": "pnpm run prepare && pnpm run build"
},
"dependencies": {
Expand All @@ -69,8 +61,6 @@
"@testing-library/react": "^16.3.0",
"@types/react": "18.3.21",
"@vitejs/plugin-react": "^4.4.1",
"del-cli": "^6.0.0",
"esbuild": "^0.25.0",
"execa": "^9.0.0",
"msw": "^2.7.5",
"openapi-fetch": "workspace:^",
Expand Down
4 changes: 0 additions & 4 deletions packages/openapi-react-query/tsconfig.build.json

This file was deleted.

2 changes: 2 additions & 0 deletions packages/openapi-typescript-helpers/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.turbo
*.config.*
biome.json
src
tsconfig*.json
14 changes: 14 additions & 0 deletions packages/openapi-typescript-helpers/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["./src/index.ts"],
declaration: "compatible",
clean: true,
sourcemap: true,
rollup: {
// Ship CommonJS-compatible bundle
emitCJS: true,
// Don’t bundle .js files together to more closely match old exports (can remove in next major)
output: { preserveModules: true },
},
});
4 changes: 0 additions & 4 deletions packages/openapi-typescript-helpers/index.cjs

This file was deleted.

4 changes: 0 additions & 4 deletions packages/openapi-typescript-helpers/index.js

This file was deleted.

29 changes: 9 additions & 20 deletions packages/openapi-typescript-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,15 @@
},
"license": "MIT",
"type": "module",
"main": "./index.js",
"types": "./index.d.ts",
"main": "./dist/index.mjs",
"exports": {
".": {
"import": {
"types": "./index.d.ts",
"default": "./index.js"
},
"require": {
"types": "./index.d.cts",
"default": "./index.cjs"
}
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
},
"./*": "./*"
},
"files": [
"index.js",
"index.cjs",
"index.d.ts",
"index.d.cts"
],
"homepage": "https://openapi-ts.dev",
"repository": {
"type": "git",
Expand All @@ -39,10 +27,11 @@
"url": "https://github.com/openapi-ts/openapi-typescript/issues"
},
"scripts": {
"build": "cp index.d.ts index.d.cts",
"format": "biome format . --write",
"lint": "biome check .",
"test": "tsc --noEmit"
"build": "unbuild",
"format": "biome format src --write",
"lint": "pnpm run lint:js && pnpm run lint:ts",
"lint:js": "biome check src",
"lint:ts": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.8.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export type SuccessResponse<
Media extends MediaType = MediaType,
> = GetResponseContent<T, Media, OkStatus>;

type GetResponseContent<
export type GetResponseContent<
T extends Record<string | number, any>,
Media extends MediaType = MediaType,
ResponseCode extends keyof T = keyof T,
Expand Down
3 changes: 1 addition & 2 deletions packages/openapi-typescript-helpers/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"skipLibCheck": false
},
"include": ["."]
"include": ["src"]
}
1 change: 1 addition & 0 deletions packages/openapi-typescript/.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.turbo
*.config.*
examples/
scripts/
test/
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-typescript/bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fs from "node:fs";
import path from "node:path";
import { performance } from "node:perf_hooks";
import parser from "yargs-parser";
import openapiTS, { COMMENT_HEADER, astToString, c, error, formatTime, warn } from "../dist/index.js";
import openapiTS, { COMMENT_HEADER, astToString, c, error, formatTime, warn } from "../dist/index.mjs";

const HELP = `Usage
$ openapi-typescript [input] [options]
Expand Down
14 changes: 14 additions & 0 deletions packages/openapi-typescript/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["./src/index.ts"],
declaration: "compatible",
clean: true,
sourcemap: true,
rollup: {
// Ship CommonJS-compatible bundle
emitCJS: true,
// Don’t bundle .js files together to more closely match old exports (can remove in next major)
output: { preserveModules: true },
},
});
Loading