From 722d06b0291357552c82ca1abd9b40441bcfac04 Mon Sep 17 00:00:00 2001 From: jo <17280917+dev-jodee@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:41:11 -0400 Subject: [PATCH] fix(generate): load dart renderer via its ESM build #8 stopped the total outage but dart itself still 500'd: its CJS build (loaded via createRequire) requires the .cjs variants of a large @codama/@solana/@noble tree that Next only bundles as .mjs, so @codama/visitors-core/dist/index.node.cjs was missing from the lambda. Load dart's real ESM build by path instead (bundler-ignored so Turbopack leaves it a runtime import, avoiding its "expression too dynamic" error), which reuses the already-bundled .mjs deps. Broaden outputFileTracingIncludes to guarantee dart's ESM closure (@codama/@solana/@noble) is present. --- lib/codama-generate.ts | 23 +++++++++++++++-------- next.config.ts | 12 +++++++++--- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/codama-generate.ts b/lib/codama-generate.ts index 5bc461c..56100c1 100644 --- a/lib/codama-generate.ts +++ b/lib/codama-generate.ts @@ -8,7 +8,7 @@ import JSZip from "jszip"; import fs from "fs"; import path from "path"; import { randomUUID } from "crypto"; -import { createRequire } from "module"; +import { pathToFileURL } from "url"; import type { Language } from "./codama-types"; import { assertLanguageSupportedForIdl } from "./codama-compat"; import { getCodamaRootNode, getIdlProgramName } from "./idl-utils"; @@ -91,13 +91,20 @@ export async function generateFromIdl( case "dart": { const dartDir = path.join(tmpDir, `${programName}-dart-client`); fs.mkdirSync(dartDir, { recursive: true }); - // codama-renderers-dart@0.4.x mispublishes its ESM entry (exports `import` -> a - // .mjs absent from the tarball); load the working CJS build lazily here so a - // resolution failure can't break the other renderers at module load time. - const renderDart = createRequire( - path.join(process.cwd(), "package.json") - )("codama-renderers-dart") - .renderVisitor as typeof import("codama-renderers-dart").renderVisitor; + // codama-renderers-dart@0.4.x mispublishes its exports map: `import` points at a + // missing .mjs, and its CJS build drags in a large @codama/@solana/.cjs tree Next + // never bundles. Import the real ESM build by path (bundler-ignored so Turbopack + // leaves it as a runtime import) so it reuses the already-bundled .mjs deps the + // other renderers rely on. Lazy so any failure only affects dart. + const dartEntry = pathToFileURL( + path.join( + process.cwd(), + "node_modules/codama-renderers-dart/dist/index.node.js" + ) + ).href; + const { renderVisitor: renderDart } = (await import( + /* webpackIgnore: true */ /* turbopackIgnore: true */ dartEntry + )) as typeof import("codama-renderers-dart"); codama.accept( renderDart(dartDir, { formatCode: false, diff --git a/next.config.ts b/next.config.ts index 0abf6f0..bd15e1b 100644 --- a/next.config.ts +++ b/next.config.ts @@ -24,10 +24,16 @@ const nextConfig: NextConfig = { "memfs", ], - // codama-renderers-dart's broken exports map defeats Next's dependency tracer, so its - // files are missing from the serverless bundle. Force-include them for the generate route. + // codama-renderers-dart's broken exports map defeats Next's dependency tracer, so it and + // its dependency closure are missing from the serverless bundle. Force-include the ESM + // build's deps (dart + the codama/solana/noble packages it imports) for the generate route. outputFileTracingIncludes: { - "/api/generate": ["./node_modules/codama-renderers-dart/**/*"], + "/api/generate": [ + "./node_modules/codama-renderers-dart/**/*", + "./node_modules/@codama/**/*", + "./node_modules/@solana/**/*", + "./node_modules/@noble/**/*", + ], }, async headers() {