使用 docker 构建 Yarn 工作区

Tom*_*nka 6 node.js docker yarnpkg

考虑以下纱线工作区的文件结构:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker-compose.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 packages\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 pkg-1\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dist\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tsconfig.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 services\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 api-1\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dist\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 tsconfig.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yarn.lock\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 client-1\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yarn.lock\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 tsconfig.json\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yarn.lock\n
Run Code Online (Sandbox Code Playgroud)\n

我已经编写了 Dockerfile 来为 api-1 创建映像:

\n
ARG APP_DIR=/usr/app\n\n# Build stage\nFROM node:16.2-alpine AS build\n\nARG APP_DIR\n\nWORKDIR ${APP_DIR}\nCOPY package.json ./\nCOPY yarn.lock ./\nCOPY tsconfig.json ./\n\nWORKDIR ${APP_DIR}/packages/pkg-1\nCOPY packages/pkg-1/package.json ./\nRUN yarn --pure-lockfile --non-interactive\nCOPY packages/pkg-1/tsconfig.json ./\nCOPY packages/pkg-1/src/ ./src\nRUN yarn build\n\nWORKDIR ${APP_DIR}/services/api-1\nCOPY services/api-1/package.json ./\nCOPY services/api-1/yarn.lock ./\nRUN yarn --pure-lockfile --non-interactive\nCOPY services/api-1/tsconfig.json ./\nCOPY services/api-1/src/ ./src\nRUN yarn build\n\n# Production stage\nFROM node:16.2-alpine AS prod\n\nARG APP_DIR\n\nWORKDIR ${APP_DIR}\nCOPY --from=build ${APP_DIR}/package.json ./\nCOPY --from=build ${APP_DIR}/yarn.lock ./\n\nWORKDIR ${APP_DIR}/packages/pkg-1\nCOPY --from=build ${APP_DIR}/packages/pkg-1/package.json ./\nRUN yarn --pure-lockfile --non-interactive --production\nCOPY --from=build ${APP_DIR}/packages/pkg-1/dist ./dist\n\nWORKDIR ${APP_DIR}/services/api-1\nCOPY --from=build ${APP_DIR}/services/api-1/package.json ./\nCOPY --from=build ${APP_DIR}/services/api-1/yarn.lock ./\nRUN yarn --pure-lockfile --non-interactive --production\nCOPY --from=build ${APP_DIR}/services/api-1/dist ./dist\n\nCMD ["node", "dist"]\n
Run Code Online (Sandbox Code Playgroud)\n

构建从根 docker-compose.yaml 运行以获得正确的上下文:

\n
services:\n  api-1:\n    image: project/api-1\n    container_name: api-1\n    build:\n      context: ./\n      dockerfile: ./services/api-1/Dockerfile\n      target: prod\n    ports:\n      - 3000:3000\n
Run Code Online (Sandbox Code Playgroud)\n

它是有效的,但这样随着应用程序的增长,将会出现大量的重复。问题在于包的构建方式。

\n

例如,包可以是客户端服务中使用的规范化组件集合或 API 服务中使用的规范化错误集合。

\n

每当我要构建一些服务时,我需要首先构建其依赖的包,这是不必要的重复任务。更不用说各个包的构建步骤在使用该包的每个服务的 Dockerfile 中一遍又一遍地定义。

\n

所以我的问题是。有没有办法创建例如将用于构建服务的包的映像,以避免在服务 Dockerfile 中定义包的构建步骤?

\n

Mau*_*ino 0

似乎您正在寻找一种可以让您选择拥有“父”package.json 的东西,因此您只需在其中调用“build”即可构建整个依赖关系树。

例如:

- package.json // root package
  | - a
    | - package.json // module a package
  | - b
    | - package.json // module b package
Run Code Online (Sandbox Code Playgroud)

您可能需要研究以下内容:

这两种支撑结构都与上面提到的一样,lerna 只是有更多的功能。要快速掌握差异,请查看此处:NPM 7.0.0 的工作区是否还需要 Lerna?