pnpm vs npm: armazenamento, lockfiles, workspaces e comandos | We.Inc
Como pnpm e npm armazenam pacotes, travam versões e rodam monorepos, um tradutor pesquisável de comandos npm para pnpm e os passos exatos para migrar um projeto com segurança.
O npm copia cada pacote para o node_modules de cada projeto e os eleva em uma estrutura plana. O pnpm mantém um único store endereçado por conteúdo no disco, cria hard links dos arquivos a partir dele e coloca só as suas dependências diretas no topo do node_modules. Isso economiza espaço em disco e impede que o código importe pacotes que nunca declarou. A maioria dos comandos tem equivalente direto.
Principais diferenças
Tema
Onde ficam os arquivos dos pacotes
Uma cópia dentro de cada projeto
Um store compartilhado, com hard links para os projetos
Estrutura do node_modules
Plana, tudo elevado
Só as dependências diretas, o resto em node_modules/.pnpm
Lockfile
Workspaces declarados em
Instalação estrita no CI
npm ci
pnpm install (frozen lockfile é o padrão no CI)
Rodar um pacote sem instalar
pnpm dlx (também pnx, pnpx)
As duas ferramentas leem o mesmo package.json e instalam do mesmo registry, então a escolha depende da estrutura, da velocidade das instalações repetidas, das ferramentas para monorepo e do nível de rigor. Abaixo está como cada uma armazena os pacotes, um tradutor para os comandos que você já conhece e os passos para levar um projeto existente do npm para o pnpm.
Digite um comando npm no tradutor, ou clique em um dos exemplos, para ver o equivalente em pnpm.
Leia a seção sobre armazenamento para entender por que as instalações do pnpm usam menos disco e pegam imports não declarados.
Siga os passos de migração se decidir trocar e faça commit do novo lockfile.
Escolha um único gerenciador de pacotes por repositório e apague o outro lockfile, para que ninguém instale a partir de um desatualizado.
No CI, o pnpm install se recusa a mexer em um lockfile desatualizado, então faça commit do pnpm-lock.yaml sempre que o package.json mudar.
Se um pacote quebra no pnpm porque importa algo que nunca declarou, reporte ao projeto de origem; esse import só funcionava por acaso no npm.
O pnpm roda scripts sem a palavra run, então pnpm dev funciona, desde que o nome do script não conflite com um comando nativo do pnpm.
Perguntas frequentes
O pnpm é mais rápido que o npm?
O pnpm muitas vezes reaproveita arquivos que já estão no seu store, o que ajuda nas instalações repetidas na mesma máquina. A velocidade depende do estado do cache, da rede e do tamanho do projeto, então meça os dois no seu próprio projeto em vez de confiar em um benchmark publicado.
Posso usar o pnpm em um projeto que tem package-lock.json?
Sim. Rode pnpm import para gerar um pnpm-lock.yaml a partir de package-lock.json, npm-shrinkwrap.json ou yarn.lock, depois apague o lockfile antigo e o node_modules e rode pnpm install.
Por que o meu app não encontra um módulo depois de mudar para o pnpm?
O seu código, ou uma dependência, importa um pacote que não está listado no próprio package.json. A estrutura plana do npm escondia esse erro. Adicione o pacote que falta como dependência de quem o importa.
O pnpm precisa do Node.js instalado?
A documentação de instalação do pnpm descreve o pnpm 12 como um executável nativo que não precisa do Node.js para rodar. Os scripts do seu projeto, claro, continuam precisando do Node.js.
Qual deles um iniciante deve usar?
O npm, porque vem com o Node.js e quase todo tutorial o usa. Passe para o pnpm quando tiver um monorepo, muitos projetos na mesma máquina ou quiser a estrutura de node_modules mais rigorosa.
Como cada ferramenta armazena os pacotes
O npm grava uma cópia completa de cada dependência no node_modules do projeto e eleva as dependências aninhadas para o nível de cima sempre que possível. Dez projetos que usam a mesma biblioteca guardam dez cópias.
O pnpm baixa cada arquivo uma única vez para um store global endereçado por conteúdo. Os projetos recebem hard links para esses arquivos, então um segundo projeto com as mesmas versões quase não ocupa espaço extra, e uma versão nova só acrescenta os arquivos que mudaram.
Dentro do projeto, o pnpm coloca symlinks para as suas dependências diretas no node_modules e mantém todo o resto em node_modules/.pnpm. Um pacote só consegue alcançar o que declarou.
Workspaces e monorepos
Os workspaces do npm são listados no package.json da raiz e executados com -w name ou --workspaces. O pnpm os lista no pnpm-workspace.yaml e os seleciona com --filter, que também entende grafos de dependência, por exemplo um pacote mais tudo de que ele depende.
O protocolo workspace: do pnpm fixa uma dependência no pacote local e se recusa a recorrer ao registry. Ele é convertido em um intervalo de versões normal quando você publica.
Migrar um projeto do npm para o pnpm
Passos da migração
O pnpm import lê o lockfile do npm, então você mantém as versões que já testou. Rode os seus testes antes de fazer commit.
Cada pasta que corresponder aqui vira um pacote do workspace. Coloque o arquivo na raiz do repositório.
Dependendo de um pacote local
workspace:* sempre resolve para a cópia local de ui em vez de uma versão do registry.
Tradutor de comandos npm para pnpm
Digite um comando npm
npm install -D vite
Equivalente em pnpm
Nenhuma correspondência direta. A maioria dos outros comandos do npm mantém o mesmo nome no pnpm.