Addresses the suppressed review comment on #2099, which was the sharpest of the three rounds: the guard stopped looking at a package the moment its `external` entry was removed — so deleting `"undici"` from the web config would have made the pre-fix bundle pass. That is self-referential, and #2067 was precisely a MISSING declaration, so the guard covered its regression but not the bug. Candidates are now the union of two independently-derived lists: each client's `external` array, and the root manifest's `dependencies` — root-declared by rule, reached through `core/`, and required to be external in every client bundle. Removing a package from an `external` list can no longer remove it from scrutiny. That immediately surfaced one latent instance of the same rule violation: `@modelcontextprotocol/ext-apps` is root-declared and reached through `core/mcp/apps.ts`, but was absent from the CLI's `external` list and was being inlined into `index.js` — dragging the transitive v1 SDK and zod-to-json-schema in with it. It is ESM, so it was not failing the way `undici` did; what it violated was the rule. Adding it drops the CLI bundle from 590KB to 518KB. It is also a real example of the shape the previous revision could not see: it was inlined into the entry, emitting no `<pkg>-HASH.js` chunk at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTHVxSu8AUgHRLvo1ntZ8H Signed-off-by: cliffhall <cliff@futurescale.com>
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
import { defineConfig } from "tsup";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = path.resolve(dirname, "../..");
|
|
|
|
export default defineConfig({
|
|
entry: {
|
|
index: "src/index.ts",
|
|
},
|
|
format: ["esm"],
|
|
outDir: "build",
|
|
clean: true,
|
|
// No source maps in the published bundle — they roughly double the on-disk
|
|
// size and aren't needed at runtime (debug via `npm run dev` on the source).
|
|
sourcemap: false,
|
|
target: "node22",
|
|
platform: "node",
|
|
// Bundle core source; leave npm deps external.
|
|
noExternal: [/^@inspector\/core/],
|
|
external: [
|
|
// `undici` MUST stay external. It is CommonJS, so inlining it rewrites
|
|
// `import("undici")` to a relative chunk whose `require("assert")` hits
|
|
// esbuild's ESM `__require` shim and throws "Dynamic require of \"assert\"
|
|
// is not supported" — and because the specifier was rewritten at build time,
|
|
// no user-side install can ever satisfy it (#2067). It is declared in the
|
|
// ROOT manifest only, so tsup cannot infer this from a nearest-manifest
|
|
// lookup; the entry has to be explicit.
|
|
"undici",
|
|
"@napi-rs/keyring",
|
|
// Root-declared (see the repo's dependency-placement rule) and CJS, which
|
|
// is the combination that bites: tsup externalizes what the *client's*
|
|
// package.json declares, so a root-only dependency is bundled unless named
|
|
// here — and inlining a CJS module into an ESM bundle leaves esbuild's
|
|
// `Dynamic require of "path" is not supported` shim, which throws at
|
|
// import time and takes the whole binary down before it parses a flag.
|
|
"proper-lockfile",
|
|
"@modelcontextprotocol/client",
|
|
"@modelcontextprotocol/core",
|
|
// Root-declared and reached through `core/mcp/apps.ts`, so it must be
|
|
// external here like every other root runtime dependency — it was being
|
|
// inlined (dragging the transitive v1 SDK and zod-to-json-schema with it),
|
|
// which the #2067 guard surfaced. ESM, so it was not failing the way
|
|
// `undici` did; the rule is what it violated.
|
|
"@modelcontextprotocol/ext-apps",
|
|
"commander",
|
|
"pino",
|
|
],
|
|
esbuildOptions(options) {
|
|
options.alias = {
|
|
"@inspector/core": path.join(repoRoot, "core"),
|
|
};
|
|
},
|
|
});
|