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

Docker构建时ESBuild无法解析Monorepo工作空间包的问题

问题

我尝试用Docker镜像编译并运行Monorepo里的应用,用ESBuild把所有依赖打包成单个文件。手动执行打包命令一切正常,但在Docker环境里运行失败,报错无法解析应用依赖的其他工作空间包,错误示例如下:

#10 1.443 ✘ [ERROR] Could not resolve "@platform/bar"
#10 1.443 
#10 1.443     src/app/logger.ts:1:29:
#10 1.443       1 │ import { createBar } from '@platform/bar'
#10 1.443         ╵                           ~~~~~~~~~~~~~~~
#10 1.443 
#10 1.443   You can mark the path "@platform/bar" as external to exclude it from the bundle, which will remove this error.

相关配置文件

Dockerfile

FROM node:18
ENV NODE_ENV=production

COPY . /app
WORKDIR /app

RUN yarn install

RUN yarn workspace @platform/foo bundle

WORKDIR /platform/packages/apps/foo/dist

EXPOSE 8181

CMD ["node", "app.js"]

package.json(@platform/foo)

{
  "name": "@platform/foo",
  "scripts": {
    "bundle": "node bundle.mjs"
  },
  "dependencies": {
    "@platform/bar": "workspace:*",
    "@platform/xyz": "workspace:*"
  }
}

bundle.mjs

import * as esbuild from 'esbuild'
import { copy } from 'esbuild-plugin-copy'

await esbuild.build({
  entryPoints: ['src/main.ts'],
  bundle: true,
  outfile: 'dist/app.js',
  plugins: [
    copy({
      resolveFrom: 'cwd',
      verbose: true,
      assets: [
        {
          from: ['../../../node_modules/couchbase/build/**/*.node'],
          to: ['./dist'],
        },
      ],
    }),
  ],
  platform: 'node',
  target: 'node18',
  loader: {
    '.node': 'copy',
  },
})
解决方案

问题根源

  1. Docker里提前设置了NODE_ENV=production,Yarn在生产模式下会跳过工作空间内部依赖的本地关联,试图从npm仓库拉取@platform/bar这类不存在的包,导致ESBuild找不到依赖。
  2. ESBuild默认不识别Monorepo的工作空间路径映射,需要手动配置才能解析内部包别名。
  3. Dockerfile最后设置的工作目录路径错误,实际代码在/app下,却指向了/platform。

修复步骤

1. 调整Docker的依赖安装逻辑

取消提前设置生产环境变量,先完整安装所有依赖(包括工作空间包),再打包,最后设置生产环境:

FROM node:18

COPY . /app
WORKDIR /app

# 先安装所有依赖(含工作空间包)
RUN yarn install --production=false
# 执行打包
RUN yarn workspace @platform/foo bundle

# 打包完成后再设置生产环境
ENV NODE_ENV=production

# 修正工作目录路径
WORKDIR /app/packages/apps/foo/dist

EXPOSE 8181
CMD ["node", "app.js"]

或者保留NODE_ENV=production,安装时强制包含工作空间:

RUN yarn install --production --workspaces

2. 给ESBuild添加内部包路径映射

在bundle.mjs中配置alias,让ESBuild能找到工作空间内的包(路径根据你的Monorepo目录结构调整):

await esbuild.build({
  entryPoints: ['src/main.ts'],
  bundle: true,
  outfile: 'dist/app.js',
  plugins: [/* 原有copy插件 */],
  platform: 'node',
  target: 'node18',
  loader: { '.node': 'copy' },
  // 添加路径解析配置
  resolve: {
    extensions: ['.ts', '.js', '.mjs'],
    alias: {
      '@platform/bar': '../../bar/src',
      '@platform/xyz': '../../xyz/src'
    }
  }
})

如果你的Monorepo根目录有tsconfig.json并配置了paths,也可以用@esbuild-plugins/tsconfig-paths插件自动读取路径映射,不用手动写alias。

3. 修正Docker工作目录路径

原Dockerfile中WORKDIR /platform/packages/apps/foo/dist路径错误,改为/app/packages/apps/foo/dist,确保启动时能找到打包后的app.js。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:21:01