我曾经参与了一个项目,其结构类似于你们的,看起来是这样的:
project
├── package.json
├── packages
│ ├── package1
│ │ ├── package.json
│ │ └── src
│ ├── package2
│ │ ├── package.json
│ │ └── src
│ └── package3
│ ├── package.json
│ └── src
├── services
│ ├── service1
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── src
│ └── service2
│ ├── Dockerfile
│ ├── package.json
│ └── src
└── yarn.lock
services/
文件夹每个子文件夹包含一个服务。每个服务都是用node.js编写的,有自己的package.json和Dockerfile。它们通常基于Express构建Web服务器或REST API。
packages/
文件夹包含所有不属于服务的包,通常是内部库。
一个服务可以依赖于一个或多个包,但不能依赖于另一个服务。一个包可以依赖于另一个包,但不能依赖于一个服务。
主要的package.json(位于项目根目录)只包含一些devDependencies,例如eslint
,测试运行程序等。
假设service1
依赖于package1
和package3
,则单独的Dockerfile
如下:
FROM node:8.12.0-alpine AS base
WORKDIR /project
FROM base AS dependencies
COPY packages/package1 packages/package1
COPY packages/package3 packages/package3
COPY services/services1 services/services1
COPY package.json .
COPY yarn.lock .
RUN yarn install --production --pure-lockfile --non-interactive --cache-folder ./ycache; rm -rf ./ycache
我使用的实际 Dockerfile
更加复杂,因为它们需要构建子包、运行测试等等。但是你可以通过此示例了解到基本思路。
如您所见,诀窍在于仅复制特定服务所需的软件包。 yarn.lock
文件包含一个 package@version 的列表,其中包含确切版本和已解决的依赖项。 将其复制而不包括所有子包并不是问题,yarn 在安装包含包的依赖项时将使用那里解决的版本。
在您的情况下,React-Native 项目永远不会成为任何 Dockerfile 的一部分,因为它不是任何服务的依赖项,从而节省了大量空间。
为了简洁起见,在答案中省略了很多细节,如果有什么不太清楚的地方,请随时在评论中要求准确性。