Skip to content

Commit 6d14926

Browse files
stubbiclaude
authored andcommitted
feat: precompile workspace packages, remove tsx from production runtime (#10)
* feat: precompile all workspace packages — eliminate tsx from runtime Switch all workspace package exports from src/*.ts to dist/*.js so the server runs on precompiled JavaScript without needing tsx as a runtime transpiler. Changes: - All package.json exports fields now point to dist/ (previously pointed to src/ for development convenience, with publishConfig overriding for npm publish) - Dockerfile CMD changed from node --import tsx/loader to node directly - Dockerfile now prunes devDependencies (tsx no longer needed at runtime) - Selective dist-only COPY in production stage works correctly now Benefits: - Faster startup (no runtime transpilation) - Smaller image (no tsx, no TypeScript source in production) - No devDependencies shipped - More secure (no source code in production image) - Reproducible (compiled output is deterministic) Verified: server starts and runs correctly with node server/dist/index.js without tsx loader. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use conditional exports — types from src/, import from dist/ TypeScript resolves types via the "types" condition (pointing to src/*.ts for zero-build typechecking), while Node resolves runtime imports via the "import" condition (pointing to dist/*.js). This lets pnpm -r typecheck work without building first, while the runtime still uses precompiled output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use custom "production" condition for dist/ exports Use Node's --conditions flag to switch between source and compiled output: - "default" → ./src/*.ts (dev, tests, typecheck — no build needed) - "production" → ./dist/*.js (Docker, deployed environments) Dockerfile CMD uses --conditions=production so Node resolves workspace imports to precompiled dist/ output. Dev tools (vitest, tsx, tsc) use the default condition and resolve to source. Verified: typecheck passes, 569 tests pass, server starts with --conditions=production without tsx. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 82b0029 commit 6d14926

12 files changed

Lines changed: 179 additions & 38 deletions

File tree

Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ COPY . .
4747
RUN pnpm -r build \
4848
&& test -f server/dist/index.js || (echo "ERROR: server build output missing" && exit 1)
4949

50-
# Note: no prod prune — tsx is in devDependencies but needed at runtime
51-
# as the Node ESM loader. Image size is controlled by selective COPY below.
50+
# Prune dev dependencies — tsx is no longer needed at runtime
51+
# since all workspace packages export precompiled dist/ output.
52+
RUN pnpm prune --prod --no-optional
5253

5354
# ── Stage 4: production ───────────────────────────────────────
5455
# Distroless-style minimal image. No shell, no package manager,
@@ -142,4 +143,4 @@ HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
142143
CMD curl -fsS http://localhost:3100/api/health || exit 1
143144

144145
ENTRYPOINT ["tini", "--"]
145-
CMD ["node", "--import", "./server/node_modules/tsx/dist/loader.mjs", "server/dist/index.js"]
146+
CMD ["node", "--conditions=production", "server/dist/index.js"]

packages/adapter-utils/package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./*": "./src/*.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./*": {
22+
"types": "./src/*.ts",
23+
"production": "./dist/*.js",
24+
"default": "./src/*.ts"
25+
}
1826
},
1927
"publishConfig": {
2028
"access": "public",

packages/adapters/claude-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/codex-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/cursor-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/gemini-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/openclaw-gateway/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/opencode-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/adapters/pi-local/package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./server": "./src/server/index.ts",
18-
"./ui": "./src/ui/index.ts",
19-
"./cli": "./src/cli/index.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./server": {
22+
"types": "./src/server/index.ts",
23+
"production": "./dist/server/index.js",
24+
"default": "./src/server/index.ts"
25+
},
26+
"./ui": {
27+
"types": "./src/ui/index.ts",
28+
"production": "./dist/ui/index.js",
29+
"default": "./src/ui/index.ts"
30+
},
31+
"./cli": {
32+
"types": "./src/cli/index.ts",
33+
"production": "./dist/cli/index.js",
34+
"default": "./src/cli/index.ts"
35+
}
2036
},
2137
"publishConfig": {
2238
"access": "public",

packages/db/package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@
1313
},
1414
"type": "module",
1515
"exports": {
16-
".": "./src/index.ts",
17-
"./*": "./src/*.ts"
16+
".": {
17+
"types": "./src/index.ts",
18+
"production": "./dist/index.js",
19+
"default": "./src/index.ts"
20+
},
21+
"./*": {
22+
"types": "./src/*.ts",
23+
"production": "./dist/*.js",
24+
"default": "./src/*.ts"
25+
}
1826
},
1927
"publishConfig": {
2028
"access": "public",

0 commit comments

Comments
 (0)