Перейти до основного змісту
Версія: 8.x

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

# Файли, необхідні для pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Якщо ви пропатчили якийсь пакунок, включіть патчі перед встановленням
COPY patches patches

RUN pnpm install --frozen-lockfile --prod

# Зібрати вихідний код
COPY . .

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

Поки немає змін у .npmrc, package.json, pnpm-lock.yaml, .pnpmfile.cjs, кеш збірки docker буде чинним до рівня RUN 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

# Файли, необхідні для pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Якщо ви пропатчили якийсь пакунок, включіть патчі перед встановленням
COPY patches patches

# для кожного підпакета, ми повинні додати додатковий крок щоб копіювати їх маніфести
# в правильне місце, бо docker не має можливості фільтрувати кожен package.json з
# власною інструкцією
COPY packages/foo/package.json packages/foo/
COPY packages/bar/package.json packages/bar/

RUN pnpm install --frozen-lockfile --prod

# Зібрати вихідний код
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 не спілкуватись з реєстром пакунків, бо усі потрібні пакунки вже присутні в віртуальному сховищі.

Поки файл блокування не змінено, кеш збірки чинний, тому RUN pnpm install -r --offline --prod, збереже багато часу.

Параметри

--dev, -D

Будуть завантажені лише пакунки для розробки

--prod, -P

Пакунки для розробки не будуть завантажені