Перейти к основному содержимому
Версия: Будущая

pnpm fetch

Загрузка пакетов из заблокированного файла в виртуальное хранилище, манифест пакета игнорируется.

Сценарий использования

Эта команда специально предназначена для сборки образа в docker.

Возможно, вы прочитали официальное руководство по написанию Dockerfile для Node.js приложения, если вы еще не читали его, возможно, будет полезно ознакомиться с ним.

По этому руководству мы научимся писать оптимизированный Dockerfile для проектов с помощью pnpm, который выглядит как

FROM node:14

WORKDIR /path/to/somewhere

RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

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

# 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" ]

Пока в .npmrc, package.json, pnpm-lock.yaml, .pnpmfile.cjs нет изменений, кэш сборки docker останется действителен до слоя pnpm install --frozen-lockfile --prod, который занимает значительную часть времени при создании образа в docker.

Однако, модификация package.json может происходить гораздо чаще, чем мы ожидаем, так как он может содержать не только зависимости, но и версию пакета, скрипты и конфигурацию для других инструментов.

Также сложно поддерживать Dockerfile, который создает проект из монорепозитория, он может выглядеть так

FROM node:14

WORKDIR /path/to/somewhere

RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

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

# 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 отлично решает вышеуказанную проблему, предоставляя возможность для загрузки пакетов в виртуальное хранилище, используя только информацию из lockfile.

FROM node:14

WORKDIR /path/to/somewhere

RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

# pnpm fetch does require only lockfile
COPY pnpm-lock.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" ]

Он работает как для простых проектов, так и для монорепозиториев, --offline заставляет pnpm не связываться с реестром пакетов, так как все необходимые пакеты уже есть в виртуальном хранилище.

As long as the lockfile is not changed, the build cache is valid up to the layer, so RUN pnpm install -r --offline --prod, will save you much time.

Опции

--dev, -D

Будут загружены только пакеты разработки

--prod, -P

Пакеты разработки не будут загружены