You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Monorepo中用ESBuild构建TypeScript Node.js应用:本地成功Docker失败

问题

在Docker中构建Node.js monorepo应用时出现以下错误:

2.830 /app/packages/api/node_modules/.bin/esbuild: line 1: syntax error: unexpected "("
2.837 npm error Lifecycle script `build` failed with error:
2.838 npm error code 2
2.838 npm error path /app/packages/api
2.838 npm error workspace @dispono/api@1.0.0
2.838 npm error location /app/packages/api
2.838 npm error command failed
2.838 npm error command sh -c tsc && esbuild dist/index.js --bundle --sourcemap --platform=node --outfile=dist/index.minified

使用的Dockerfile内容:

FROM node:alpine AS base

RUN apk update && apk add bash

FROM base AS deps
WORKDIR /app
COPY package*.json ./
COPY packages/database/package.json ./packages/database/
COPY packages/api/package.json ./packages/api/
COPY packages/api/tsconfig.json ./packages/api/
RUN npm ci -w @dispono/database -w @dispono/api

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build -w @dispono/api

FROM base AS runner
WORKDIR /app

COPY package*.json ./
COPY packages/ ./packages/
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/packages/api/dist/ ./dist

COPY run-docker.sh ./run-docker.sh
RUN chmod +x ./run-docker.sh

EXPOSE 3000
CMD [ "./run-docker.sh" ]

本地(monorepo根目录或包内)构建正常,仅Docker环境报错,已尝试:

  • 使用ESBuild构建Node.js应用
  • 修改tsconfig.json

预期:应用完成构建压缩,可在Docker中与数据库一同运行
实际:出现Bash语法错误

解决方法

原因分析

错误根源是node:alpine镜像中,npm默认使用sh执行脚本,而esbuild的CLI启动脚本使用了Bash专属语法(比如括号相关写法),即使安装了Bash,npm仍会用默认的sh执行,导致语法解析失败。

具体解决方案

  1. 强制npm用Bash执行脚本
    在Dockerfile的builder阶段添加环境变量,指定shell为bash:
FROM base AS builder
WORKDIR /app
ENV SHELL=/bin/bash  # 添加这一行
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build -w @dispono/api

或者直接修改package.json中的build脚本,显式用bash执行esbuild命令:

{
  "scripts": {
    "build": "tsc && bash -c \"esbuild dist/index.js --bundle --sourcemap --platform=node --outfile=dist/index.minified\""
  }
}
  1. 使用ESBuild Node API替代CLI
    避免shell环境差异,编写一个Node脚本执行构建:
    在packages/api目录下创建build-esbuild.js:
const esbuild = require('esbuild');

esbuild.build({
  entryPoints: ['dist/index.js'],
  bundle: true,
  sourcemap: true,
  platform: 'node',
  outfile: 'dist/index.minified.js',
}).catch(() => process.exit(1));

然后修改package.json的build脚本:

{
  "scripts": {
    "build": "tsc && node build-esbuild.js"
  }
}
  1. 确认ESBuild依赖安装完整
    在builder阶段补充安装包依赖(虽然npm ci已处理,但monorepo场景可额外确保):
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm install -w @dispono/api  # 添加这一行
RUN npm run build -w @dispono/api

内容的提问来源于stack exchange,提问作者dvdkwei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:33:18