Skip to content

Commit 2c8b5a2

Browse files
committed
fix(core): vendor superjson to fix ESM/CJS compatibility
Bundle superjson and its dependency (copy-anything) during build to avoid ERR_REQUIRE_ESM errors on Node.js versions that don't support require(ESM) by default (< 22.12.0) and AWS Lambda which intentionally disables it. - Add scripts/bundle-superjson.mjs to bundle superjson with esbuild - Update build script to bundle vendor files before tshy compilation - Move superjson from dependencies to devDependencies - Update imports to use vendored bundles Fixes #2937
1 parent eeab6bd commit 2c8b5a2

File tree

5 files changed

+94
-11
lines changed

5 files changed

+94
-11
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ out/
1515
dist
1616
packages/**/dist
1717

18+
# vendored bundles (generated during build)
19+
packages/**/src/**/vendor
20+
1821
# Tailwind
1922
apps/**/styles/tailwind.css
2023
packages/**/styles/tailwind.css

packages/core/package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,12 @@
157157
},
158158
"sideEffects": false,
159159
"scripts": {
160-
"clean": "rimraf dist .tshy .tshy-build .turbo",
160+
"clean": "rimraf dist .tshy .tshy-build .turbo src/v3/vendor",
161161
"update-version": "tsx ../../scripts/updateVersion.ts",
162-
"build": "tshy && pnpm run update-version",
163-
"dev": "tshy --watch",
162+
"bundle-vendor": "node scripts/bundle-superjson.mjs",
163+
"copy-vendor": "mkdir -p dist/commonjs/v3/vendor dist/esm/v3/vendor && cp src/v3/vendor/*.cjs dist/commonjs/v3/vendor/ && cp src/v3/vendor/*.mjs dist/esm/v3/vendor/",
164+
"build": "pnpm run bundle-vendor && tshy && pnpm run copy-vendor && pnpm run update-version",
165+
"dev": "pnpm run bundle-vendor && tshy --watch",
164166
"typecheck": "tsc --noEmit -p tsconfig.src.json",
165167
"test": "vitest",
166168
"check-exports": "attw --pack ."
@@ -193,7 +195,6 @@
193195
"socket.io": "4.7.4",
194196
"socket.io-client": "4.7.5",
195197
"std-env": "^3.8.1",
196-
"superjson": "^2.2.1",
197198
"tinyexec": "^0.3.2",
198199
"uncrypto": "^0.1.3",
199200
"zod": "3.25.76",
@@ -212,6 +213,7 @@
212213
"defu": "^6.1.4",
213214
"esbuild": "^0.23.0",
214215
"rimraf": "^3.0.2",
216+
"superjson": "^2.2.1",
215217
"ts-essentials": "10.0.1",
216218
"tshy": "^3.0.2",
217219
"tsx": "4.17.0"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* This script bundles superjson and its dependency (copy-anything) into
5+
* vendored CJS and ESM bundles to avoid the ERR_REQUIRE_ESM error.
6+
*
7+
* superjson v2.x is ESM-only, which causes issues on:
8+
* - Node.js versions before 22.12.0 (require(ESM) not enabled by default)
9+
* - AWS Lambda (intentionally disables require(ESM))
10+
*
11+
* Run this script after updating the superjson dependency:
12+
* node scripts/bundle-superjson.mjs
13+
*
14+
* The output files are committed to git so the build doesn't need esbuild at runtime.
15+
*/
16+
17+
import * as esbuild from "esbuild";
18+
import { dirname, join } from "node:path";
19+
import { fileURLToPath } from "node:url";
20+
import { readFileSync } from "node:fs";
21+
22+
const __dirname = dirname(fileURLToPath(import.meta.url));
23+
const packageRoot = join(__dirname, "..");
24+
const vendorDir = join(packageRoot, "src", "v3", "vendor");
25+
26+
// Get the installed superjson version for the banner
27+
const superjsonPkg = JSON.parse(
28+
readFileSync(join(packageRoot, "node_modules", "superjson", "package.json"), "utf-8")
29+
);
30+
const banner = `/**
31+
* Bundled superjson v${superjsonPkg.version}
32+
*
33+
* This file is auto-generated by scripts/bundle-superjson.mjs
34+
* Do not edit directly - run the script to regenerate.
35+
*
36+
* Original package: https://github.com/flightcontrolhq/superjson
37+
* License: MIT
38+
*/`;
39+
40+
async function bundle() {
41+
// Bundle for CommonJS
42+
await esbuild.build({
43+
entryPoints: [join(packageRoot, "node_modules", "superjson", "dist", "index.js")],
44+
bundle: true,
45+
format: "cjs",
46+
platform: "node",
47+
target: "node18",
48+
outfile: join(vendorDir, "superjson.cjs"),
49+
banner: { js: banner },
50+
// Don't minify to keep it debuggable
51+
minify: false,
52+
});
53+
54+
// Bundle for ESM
55+
await esbuild.build({
56+
entryPoints: [join(packageRoot, "node_modules", "superjson", "dist", "index.js")],
57+
bundle: true,
58+
format: "esm",
59+
platform: "node",
60+
target: "node18",
61+
outfile: join(vendorDir, "superjson.mjs"),
62+
banner: { js: banner },
63+
minify: false,
64+
});
65+
66+
console.log("Bundled superjson v" + superjsonPkg.version);
67+
console.log(" -> src/v3/vendor/superjson.cjs (CommonJS)");
68+
console.log(" -> src/v3/vendor/superjson.mjs (ESM)");
69+
}
70+
71+
bundle().catch((err) => {
72+
console.error(err);
73+
process.exit(1);
74+
});
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
// Use vendored superjson bundle to avoid ESM/CJS compatibility issues
2+
// See: https://github.com/triggerdotdev/trigger.dev/issues/2937
13
// @ts-ignore
2-
const { default: superjson } = require("superjson");
4+
const superjson = require("../vendor/superjson.cjs");
35

46
// @ts-ignore
5-
superjson.registerCustom<Buffer, number[]>(
7+
superjson.default.registerCustom<Buffer, number[]>(
68
{
79
isApplicable: (v: unknown): v is Buffer => typeof Buffer === "function" && Buffer.isBuffer(v),
810
serialize: (v: Buffer) => [...v],
@@ -12,4 +14,4 @@ superjson.registerCustom<Buffer, number[]>(
1214
);
1315

1416
// @ts-ignore
15-
module.exports.default = superjson;
17+
module.exports.default = superjson.default;

packages/core/src/v3/imports/superjson.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
// Use vendored superjson bundle to avoid ESM/CJS compatibility issues
2+
// See: https://github.com/triggerdotdev/trigger.dev/issues/2937
13
// @ts-ignore
2-
import superjson from "superjson";
4+
import superjson from "../vendor/superjson.mjs";
35

46
superjson.registerCustom<Buffer, number[]>(
57
{
6-
isApplicable: (v): v is Buffer => typeof Buffer === "function" && Buffer.isBuffer(v),
7-
serialize: (v) => [...v],
8-
deserialize: (v) => Buffer.from(v),
8+
isApplicable: (v: unknown): v is Buffer => typeof Buffer === "function" && Buffer.isBuffer(v),
9+
serialize: (v: Buffer) => [...v],
10+
deserialize: (v: number[]) => Buffer.from(v),
911
},
1012
"buffer"
1113
);

0 commit comments

Comments
 (0)