跳到主内容
版本:11.x

pnpm fetch

获取锁文件中列出的包到虚拟存储中,包清单将被忽略。

使用场景

此命令专门用于改进构建 Docker 镜像。

你可能已经阅读了如何为 Node.js 应用程序编写 Dockerfile 的 官方指南,如果你还没有阅读,你可能需要先阅读它。

从该指南中,我们学会了如何为使用 pnpm 的项目编写优化的 Dockerfile ,这将类似于

FROM node:20

WORKDIR /path/to/somewhere

RUN corepack enable pnpm && corepack install -g pnpm@next-11

# Files required by pnpm install
COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml .pnpmfile.mjs ./

# If you patched any package, include patches before install too
COPY patches patches

RUN pnpm install --frozen-lockfile --prod

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

As long as there are no changes to .npmrc, package.json, pnpm-lock.yaml, pnpm-workspace.yaml, .pnpmfile.mjs, docker build cache is still valid up to the layer of RUN pnpm install --frozen-lockfile --prod, which cost most of the time when building a docker image.

但是,对 package.json 的修改可能比我们预期的 频繁得多,因为它不仅包含依赖,而且还可能包含版本号,脚本和其他工具的任意配置。

维护构建 monorepo 项目的 Dockerfile 也很困难,它可能看起来像

FROM node:20

WORKDIR /path/to/somewhere

RUN corepack enable pnpm && corepack install -g pnpm@next-11

# Files required by pnpm install
COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml .pnpmfile.mjs ./

# If you patched any package, include patches before install too
COPY patches patches

# for each sub-package, we have to add one extra step to copy its manifest
# to the right place, as docker have no way to filter out only package.json with
# single instruction
COPY packages/foo/package.json packages/foo/
COPY packages/bar/package.json packages/bar/

RUN pnpm install --frozen-lockfile --prod

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

如你所见,当你添加或删除子软件包时,必须更新 Dockerfile。

pnpm fetch 通过提供仅使用锁文件和配置文件(pnpm-workspace.yaml)中的信息向虚拟存储中加载软件包的能力来完美地解决上述问题。

FROM node:20

WORKDIR /path/to/somewhere

RUN corepack enable pnpm && corepack install -g pnpm@next-11

# pnpm fetch does require only lockfile
COPY pnpm-lock.yaml pnpm-workspace.yaml ./

# If you patched any package, include patches before running pnpm fetch
COPY patches patches

RUN pnpm fetch --prod


ADD . ./
RUN pnpm install -r --offline --prod


EXPOSE 8080
CMD [ "node", "server.js" ]

它既适用于简单项目,也适用于 monorepo 项目, --offline 会强制 pnpm 不与包注册源通信,因为所有需要的软件包都应该已经存在于虚拟存储中。

只要锁文件没有改变,构建缓存直到层都有效,所以 RUN pnpm install -r --offline --prod,将为你节省大量时间。

注意

Local file: protocol dependencies are skipped during pnpm fetch, since they reference directories that may not be available at fetch time (e.g. in Docker builds).

配置项

--dev, -D

只会获取开发软件包

--prod, -P

不会获取开发软件包