ext-apps/build.bun.ts
Olivier Chafik 22205e6d03
fix: bundle SDK+zod in react-with-deps (was byte-identical to ./react) (#539)
* chore: remove dead ./react-with-deps export (copy-paste bug from #221)

The react-with-deps build entry was introduced in PR #221 (e078250a) as a
sibling to app-with-deps for CDN/unpkg no-bundler use. But its external
array was duplicated without editing — it never dropped @modelcontextprotocol/sdk
from externals, so it has shipped byte-identical to ./react for 10 releases
(v0.3.1 → v1.2.0).

After #534 merged, both entries use ['react', 'react-dom', ...PEER_EXTERNALS]
— still identical, just smaller.

Delete rather than fix: React apps always use a bundler; the CDN/unpkg
use case (HTML-string apps like qr-server) doesn't apply to React hooks.
Zero consumers verified (examples/docs/tests/plugins).

* fix: bundle SDK+zod in react-with-deps (keep React external)

Reverts the deletion from the previous commit and applies the actual fix.

The react-with-deps external array was copy-pasted in PR #221 without
dropping PEER_EXTERNALS — now it mirrors app-with-deps: bundles
@modelcontextprotocol/sdk + zod for CDN/import-map consumers.

React and react-dom MUST remain external — bundling them would cause
dual-React-instance hooks errors. Consumer provides them via import map.

Before: index.js 26KB == react-with-deps.js 26KB (identical MD5)
After:  index.js 26KB != react-with-deps.js 323KB (SDK+zod bundled)
2026-03-10 17:33:49 +00:00

64 lines
1.7 KiB
TypeScript

#!/usr/bin/env bun
import { $ } from "bun";
import { cpSync, mkdirSync } from "node:fs";
// Run TypeScript compiler for type declarations
await $`tsc`;
// Copy schema.json (tsc is emitDeclarationOnly, Bun.build doesn't emit JSON assets).
// Needed for the "./schema.json" package export.
mkdirSync("dist/src/generated", { recursive: true });
cpSync("src/generated/schema.json", "dist/src/generated/schema.json");
const isDevelopment = Bun.env.NODE_ENV === "development";
// Build all JavaScript/TypeScript files
function buildJs(
entrypoint: string,
opts: Partial<Parameters<(typeof Bun)["build"]>[0]> = {},
) {
return Bun.build({
entrypoints: [entrypoint],
outdir: "dist",
target: "browser",
minify: !isDevelopment,
...(isDevelopment
? {
sourcemap: "inline",
}
: {}),
...opts,
});
}
// zod is a peerDependency — keep it external so consumers share a single
// zod instance (instanceof ZodError / schema.extend() break with duplicate copies).
const PEER_EXTERNALS = ["@modelcontextprotocol/sdk", "zod"];
await Promise.all([
buildJs("src/app.ts", {
outdir: "dist/src",
external: PEER_EXTERNALS,
}),
buildJs("src/app.ts", {
outdir: "dist/src",
naming: { entry: "app-with-deps.js" },
}),
buildJs("src/app-bridge.ts", {
outdir: "dist/src",
external: PEER_EXTERNALS,
}),
buildJs("src/react/index.tsx", {
outdir: "dist/src/react",
external: ["react", "react-dom", ...PEER_EXTERNALS],
}),
buildJs("src/react/index.tsx", {
outdir: "dist/src/react",
external: ["react", "react-dom"],
naming: { entry: "react-with-deps.js" },
}),
buildJs("src/server/index.ts", {
outdir: "dist/src/server",
external: PEER_EXTERNALS,
}),
]);