Pular para o conteúdo principal
Versão: Next

pnpm fetch

Buscar pacotes a partir de um arquivo lockfile em lojas virtuais, o manifesto do pacote é ignorado.

Casos de uso

Esse comando é focado para melhorar o building de uma imagem Docker.

Talvez você tenha que ler a documentação para escrever um Dockerfile para uma aplicação Node.js, se você ainda não a leu, você deveria ler primeiro.

Com a leitura de tal documentação, aprendemos como escrever um Dockerfile otimizado para projetos que utilizam pnpm, que parece como

FROM node:14

WORKDIR /path/to/somewhere

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

# Arquivos necessários para o pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Se você atualizou algum pacote, inclua eles antes de instalar
COPY patches patches

RUN pnpm install --frozen-lockfile --prod

# Copia o código-fonte do aplicativo para dentro do contêiner
COPY . .

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

Enquanto não houver mudanças aos arquivos .npmrc, package.json, pnpm-lock.yaml e .pnpmfile.cjs, o cache de compilação do docker ainda será valido na camada de execução do comando pnpm install --frozen-lockfile --prod, no qual custa o maior tempo quando se está compilando uma imagem do docker.

Contudo, modificações no arquivo package.json costumam acontecer com mais frequência do que nós esperamos, pois o arquivo não contém somente as dependências, mas também contém o número de versão, scripts e configurações arbitrárias de outras ferramentas.

Também é difícil manter um arquivo Dockerfile que compila um projeto monorepo. Ele provavelmente se parecerá com

FROM node:14

WORKDIR /path/to/somewhere

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

# Arquivos necessários para o pnpm install
COPY .npmrc package.json pnpm-lock.yaml .pnpmfile.cjs ./

# Se você corrigiu algum pacote, inclua os patches antes de instalar
COPY patches patches

# Para cada sub-pacote, nós temos que adicionar um passo extra para copiar seu manifesto para o lugar certo, pois no docker não existe um comando único para filtrar apenas o package.json.
COPY packages/foo/package.json packages/foo/
COPY packages/bar/package.json packages/bar/

RUN pnpm install --frozen-lockfile --prod

# Empacote o código-fonte do aplicativo
COPY . .

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

Como você pode ver, o Dockerfile tem que ser atualizado quando você adiciona ou remove sub-pacotes.

O comando pnpm fetch resolve o problema acima perfeitamente, fornecendo a possibilidade de carregar pacotes na loja virtual usando apenas informações de um lockfile.

FROM node:14

WORKDIR /path/to/somewhere

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

# pnpm fetch só precisa do lockfile
COPY pnpm-lock.yaml ./

# Se você corrigiu algum pacote, inclua as correções antes de rodar o comando pnpm fetch
COPY patches patches

RUN pnpm fetch --prod


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


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

Isso funciona para ambos os projetos simples quanto para os monorepos, --offline garante que o pnpm não vai se comunicar com nenhum gerenciador de pacotes, pois todos os pacotes necessários já estão presentes na loja virtual.

Enquanto o arquivo lockfile não for modificado, o cache de compilação será valido para a camada, então RUN pnpm install -r --offline --prod vai lhe salvar muito tempo.

Opções

--dev, -D

Apenas pacotes de desenvolvimento serão buscados

--prod, -P

Pacotes de desenvolvimento não serão buscados