fix(build): production tsc + Next.js workspace root resolution

Three small build-time fixes surfaced when the Docker images first ran
their full production build (previously only dev mode via tsx):

- packages/shared: exclude *.test.ts from tsc (vitest types not needed
  for shipped output), add @types/node dep so node:crypto resolves
- packages/db: add @types/node dep for the same reason
- apps/web: pin Next.js Turbopack root to the workspace root via
  next.config.ts so the bundler doesn't fail to detect the monorepo
  layout from inside the Docker image
This commit is contained in:
yiekheng 2026-05-09 22:54:51 +08:00
parent 8e37beb76b
commit 499bcf22ed
5 changed files with 21 additions and 140 deletions

View File

@ -1,12 +1,22 @@
import type { NextConfig } from "next";
import { join } from "node:path";
// In a pnpm workspace + Turbopack setup, Next can't always infer the monorepo
// root (it walks up looking for next/package.json). Pin it explicitly so both
// dev and production builds resolve files correctly inside the Docker image.
const workspaceRoot = join(import.meta.dirname, "..", "..");
const nextConfig: NextConfig = {
reactStrictMode: true,
output: "standalone",
outputFileTracingRoot: workspaceRoot,
transpilePackages: ["@cmbot/db", "@cmbot/shared"],
experimental: {
typedRoutes: true,
},
turbopack: {
root: workspaceRoot,
},
};
export default nextConfig;

View File

@ -24,6 +24,7 @@
"pg": "^8.13.0"
},
"devDependencies": {
"@types/node": "^22.7.0",
"@types/pg": "^8.11.10",
"drizzle-kit": "^0.28.0",
"tsx": "^4.19.0",

View File

@ -21,6 +21,7 @@
},
"devDependencies": {
"@types/luxon": "^3.4.2",
"@types/node": "^22.7.0",
"typescript": "^5.5.0",
"vitest": "^2.1.0"
}

View File

@ -4,5 +4,6 @@
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"exclude": ["src/**/*.test.ts"]
}

146
pnpm-lock.yaml generated
View File

@ -182,6 +182,9 @@ importers:
specifier: ^8.13.0
version: 8.20.0
devDependencies:
'@types/node':
specifier: ^22.7.0
version: 22.19.18
'@types/pg':
specifier: ^8.11.10
version: 8.20.0
@ -207,12 +210,15 @@ importers:
'@types/luxon':
specifier: ^3.4.2
version: 3.7.1
'@types/node':
specifier: ^22.7.0
version: 22.19.18
typescript:
specifier: ^5.5.0
version: 5.9.3
vitest:
specifier: ^2.1.0
version: 2.1.9(@types/node@25.6.2)(lightningcss@1.32.0)(msw@2.14.5(@types/node@25.6.2)(typescript@5.9.3))
version: 2.1.9(@types/node@22.19.18)(lightningcss@1.32.0)(msw@2.14.5(@types/node@22.19.18)(typescript@5.9.3))
packages:
@ -2298,9 +2304,6 @@ packages:
'@types/node@22.19.18':
resolution: {integrity: sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==}
'@types/node@25.6.2':
resolution: {integrity: sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw==}
'@types/pg@8.20.0':
resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==}
@ -4229,9 +4232,6 @@ packages:
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici-types@7.19.2:
resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==}
unicorn-magic@0.3.0:
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
engines: {node: '>=18'}
@ -5117,14 +5117,6 @@ snapshots:
optionalDependencies:
'@types/node': 22.19.18
'@inquirer/confirm@6.0.12(@types/node@25.6.2)':
dependencies:
'@inquirer/core': 11.1.9(@types/node@25.6.2)
'@inquirer/type': 4.0.5(@types/node@25.6.2)
optionalDependencies:
'@types/node': 25.6.2
optional: true
'@inquirer/core@11.1.9(@types/node@22.19.18)':
dependencies:
'@inquirer/ansi': 2.0.5
@ -5137,30 +5129,12 @@ snapshots:
optionalDependencies:
'@types/node': 22.19.18
'@inquirer/core@11.1.9(@types/node@25.6.2)':
dependencies:
'@inquirer/ansi': 2.0.5
'@inquirer/figures': 2.0.5
'@inquirer/type': 4.0.5(@types/node@25.6.2)
cli-width: 4.1.0
fast-wrap-ansi: 0.2.0
mute-stream: 3.0.0
signal-exit: 4.1.0
optionalDependencies:
'@types/node': 25.6.2
optional: true
'@inquirer/figures@2.0.5': {}
'@inquirer/type@4.0.5(@types/node@22.19.18)':
optionalDependencies:
'@types/node': 22.19.18
'@inquirer/type@4.0.5(@types/node@25.6.2)':
optionalDependencies:
'@types/node': 25.6.2
optional: true
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@ -6257,11 +6231,6 @@ snapshots:
dependencies:
undici-types: 6.21.0
'@types/node@25.6.2':
dependencies:
undici-types: 7.19.2
optional: true
'@types/pg@8.20.0':
dependencies:
'@types/node': 22.19.18
@ -6304,15 +6273,6 @@ snapshots:
msw: 2.14.5(@types/node@22.19.18)(typescript@5.9.3)
vite: 5.4.21(@types/node@22.19.18)(lightningcss@1.32.0)
'@vitest/mocker@2.1.9(msw@2.14.5(@types/node@25.6.2)(typescript@5.9.3))(vite@5.4.21(@types/node@25.6.2)(lightningcss@1.32.0))':
dependencies:
'@vitest/spy': 2.1.9
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
msw: 2.14.5(@types/node@25.6.2)(typescript@5.9.3)
vite: 5.4.21(@types/node@25.6.2)(lightningcss@1.32.0)
'@vitest/pretty-format@2.1.9':
dependencies:
tinyrainbow: 1.2.0
@ -7368,32 +7328,6 @@ snapshots:
transitivePeerDependencies:
- '@types/node'
msw@2.14.5(@types/node@25.6.2)(typescript@5.9.3):
dependencies:
'@inquirer/confirm': 6.0.12(@types/node@25.6.2)
'@mswjs/interceptors': 0.41.8
'@open-draft/deferred-promise': 3.0.0
'@types/statuses': 2.0.6
cookie: 1.1.1
graphql: 16.14.0
headers-polyfill: 5.0.1
is-node-process: 1.2.0
outvariant: 1.4.3
path-to-regexp: 6.3.0
picocolors: 1.1.1
rettime: 0.11.11
statuses: 2.0.2
strict-event-emitter: 0.5.1
tough-cookie: 6.0.1
type-fest: 5.6.0
until-async: 3.0.2
yargs: 17.7.2
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- '@types/node'
optional: true
music-metadata@11.12.3:
dependencies:
'@borewit/text-codec': 0.2.2
@ -8313,9 +8247,6 @@ snapshots:
undici-types@6.21.0: {}
undici-types@7.19.2:
optional: true
unicorn-magic@0.3.0: {}
universalify@2.0.1: {}
@ -8373,24 +8304,6 @@ snapshots:
- supports-color
- terser
vite-node@2.1.9(@types/node@25.6.2)(lightningcss@1.32.0):
dependencies:
cac: 6.7.14
debug: 4.4.3
es-module-lexer: 1.7.0
pathe: 1.1.2
vite: 5.4.21(@types/node@25.6.2)(lightningcss@1.32.0)
transitivePeerDependencies:
- '@types/node'
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
vite@5.4.21(@types/node@22.19.18)(lightningcss@1.32.0):
dependencies:
esbuild: 0.21.5
@ -8401,16 +8314,6 @@ snapshots:
fsevents: 2.3.3
lightningcss: 1.32.0
vite@5.4.21(@types/node@25.6.2)(lightningcss@1.32.0):
dependencies:
esbuild: 0.21.5
postcss: 8.5.14
rollup: 4.60.3
optionalDependencies:
'@types/node': 25.6.2
fsevents: 2.3.3
lightningcss: 1.32.0
vitest@2.1.9(@types/node@22.19.18)(lightningcss@1.32.0)(msw@2.14.5(@types/node@22.19.18)(typescript@5.9.3)):
dependencies:
'@vitest/expect': 2.1.9
@ -8446,41 +8349,6 @@ snapshots:
- supports-color
- terser
vitest@2.1.9(@types/node@25.6.2)(lightningcss@1.32.0)(msw@2.14.5(@types/node@25.6.2)(typescript@5.9.3)):
dependencies:
'@vitest/expect': 2.1.9
'@vitest/mocker': 2.1.9(msw@2.14.5(@types/node@25.6.2)(typescript@5.9.3))(vite@5.4.21(@types/node@25.6.2)(lightningcss@1.32.0))
'@vitest/pretty-format': 2.1.9
'@vitest/runner': 2.1.9
'@vitest/snapshot': 2.1.9
'@vitest/spy': 2.1.9
'@vitest/utils': 2.1.9
chai: 5.3.3
debug: 4.4.3
expect-type: 1.3.0
magic-string: 0.30.21
pathe: 1.1.2
std-env: 3.10.0
tinybench: 2.9.0
tinyexec: 0.3.2
tinypool: 1.1.1
tinyrainbow: 1.2.0
vite: 5.4.21(@types/node@25.6.2)(lightningcss@1.32.0)
vite-node: 2.1.9(@types/node@25.6.2)(lightningcss@1.32.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 25.6.2
transitivePeerDependencies:
- less
- lightningcss
- msw
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
web-streams-polyfill@3.3.3: {}
whatsapp-rust-bridge@0.5.3: {}