Saltar al contenido principal
Version: Próxima versión

pnpm fetch

Descargar paquetes indicados en un lockfile a la tienda virtual, el manifiesto de paquetes es ignorado.

Escenario de uso

Este comando está específicamente diseñado para mejorar la construcción de una imagen Docker.

Puede haber leído la guía oficial para escribir un archivo Dockerfile para una aplicación de Node.js, si aún no la ha leído, puede que quiera leerla primero.

De esa guía, aprendemos a escribir un Dockerfile optimizado para proyectos que usan pnpm, puede parecerse a algo tal que

FROM node:14

WORKDIR /path/to/somewhere

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

# Archivos requeridos por pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Si has parcheado algún paquete, incluye los parches antes de instalarlo también
COPY patches patches

RUN pnpm install --frozen-lockfile --prod

# Origen de aplicación del paquete
COPY . .

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

Siempre que no haya cambios en .npmrc, package.json, pnpm-lock.yaml, .pnpmfile.cjs, la caché de compilación de Docker sigue siendo válida hasta la capa de RUN pnpm install --frozen-lockfile --prod, que cuesta la mayor parte del tiempo al crear una imagen Docker.

Sin embargo, la modificación de package.json puede ocurrir con mucha más frecuencia de lo que esperamos, porque no solo contiene dependencias, sino que también puede contener el número de versión, los scripts y la configuración arbitraria de cualquier otra herramienta.

También es difícil mantener un Dockerfile que crea un proyecto monorepo, puede parecerse a algo tal que

FROM node:14

WORKDIR /path/to/somewhere

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

# Archivos requeridos por pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Si has parcheado algún paquete, incluye los parches antes de instalarlo también
COPY patches patches

# para cada subpaquete, debemos de agregar un paso más para copiar su manifest
# al lugar correcto, ya que Docker no tiene forma de filtrar package.json con
# una única instrucción
COPY packages/foo/package.json packages/foo/
COPY packages/bar/package.json packages/bar/

RUN pnpm install --frozen-lockfile --prod

# Origen de aplicación del paquete
COPY . .

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

Como puede ver, el archivo Dockerfile tiene que ser actualizado cuando agregue o elimine sub-paquetes.

pnpm fetch resuelve perfectamente el problema anterior al brindar la capacidad de cargar paquetes en la tienda virtual usando solo información de un lockfile.

FROM node:14

WORKDIR /path/to/somewhere

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

# pnpm fetch requiere solo un lockfile
COPY pnpm-lock.yaml ./

# Si has parcheado algún paquete, incluye los parches antes de ejecutar pnpm fetch
COPY patches patches

RUN pnpm fetch --prod


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


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

Funciona tanto para proyectos simples como monorepo, --offline obliga a pnpm a no comunicarse con el registro de paquetes, ya que todos los paquetes necesarios ya están presentes en la tienda virtual.

Siempre que no se cambie el lockfile, la caché de compilación es válida hasta la capa, por lo que RUN pnpm install -r --offline --prod, le ahorrará mucho tiempo.

Opciones

--dev, -D

Sólo se descargarán los paquetes de desarrollo

--prod, -P

Los paquetes de desarrollo no se descargarán