Existem três atores principais no espaço do gerenciador de pacotes:
npm
Yarn
High-Performance npm (pnpm)
Na verdade, temos funcionalidades basicamente semelhantes implementadas em todos os gerenciadores de pacotes, então você provavelmente decidirá qual deles usar com base em requisitos não funcionais Gerenciador de pacotes , como velocidade de instalação, consumo de armazenamento ou praticidade.
É claro que a forma como você escolhe usar cada gerenciador de pacotes será diferente, mas todos eles têm conceitos basicamente consistentes. Todos os gerenciadores de pacotes acima podem executar os seguintes comandos:
No entanto, apesar disso, os gerenciadores de pacotes são diferentes nos bastidores. Tradicionalmente, npm
e Yarn
instalavam dependências em uma pasta node_modules simples. (Preste atenção na ordem aqui, yarn
é colocado lado a lado primeiro e npm
era recursivo antes). Mas os ladrilhos também podem causar uma série de problemas de segurança.
Incerteza da estrutura de dependência.
O algoritmo de nivelamento em si é muito complexo e demorado.
Pacotes com dependências declaradas
ainda podem ser acessados ilegalmente no projeto.
Portanto, pnpm
introduziu alguns novos conceitos na pasta node_modules
para armazenar dependências de forma mais eficiente. Yarn Berry
vai ainda mais longe ao abandonar totalmente o modo (PnP) de node_modules
(mais sobre isso em outro artigo).
O primeiro gerenciador de pacotes lançado foi npm
, em janeiro de 2010. Ele estabeleceu os princípios básicos de como os gerenciadores de pacotes funcionam hoje. Mas como npm
existe há mais de 10 anos, por que existe outra opção? Aqui estão alguns dos principais motivos pelos quais isso pode ser o caso:
node_modules
possui diferentes algoritmos de resolução de dependência (aninhados e lado a lado, node_modules
vs. modo PnP) ehoisting
).locking
(desempenho diferente, como aquele escrito pelo próprio yarn
)workspaces
) que afetam a capacidade de manutenção e a velocidade dos monorepos
Vamos mergulhar em a história de como esses aspectos foram determinados após a ascensão do npm
, como Yarn Classic
resolveu alguns desses problemas, como pnpm
estendeu esses conceitos e como Yarn Berry
, como sucessor do Yarn Classic
quebra esses conceitos e processos tradicionais.
npm
é o criador dos gerenciadores de pacotes. Muitas pessoas acreditam erroneamente que npm
é um acrônimo para "Gerenciador de pacotes do Node", mas não é o caso.
Seu lançamento constituiu uma revolução porque antes as dependências do projeto eram baixadas e gerenciadas manualmente. npm
introduziu coisas como arquivos e seus campos de metadados, armazenamento de dependências em node_modules
, scripts personalizados, pacotes públicos e privados e muito mais.
Em 2020, o GitHub adquiriu o npm, então, em princípio, npm
agora é gerenciado pela Microsoft. No momento em que este artigo foi escrito, a versão principal mais recente era a v8, lançada em outubro de 2021.
Em outubro de 2016, o Facebook anunciou uma parceria com o Google e uma série de outras empresas para desenvolver um novo gerenciador de pacotes (engineering.fb.com/2016/10/11/…) para abordar a consistência então existente do npm, questões de segurança e desempenho. Eles nomearam o fio substituto.
Embora Yarn
ainda seja arquitetado e projetado com base em muitos conceitos e processos do npm
, Yarn
teve um impacto significativo no campo do gerenciador de pacotes. Comparado ao npm
, Yarn
paraleliza as operações para acelerar o processo de instalação, o que tem sido um grande problema nas versões anteriores do npm
.
Yarn
estabeleceu padrões mais elevados para leitura e gravação, segurança e desempenho, e inventou muitos conceitos (mais tarde npm
também fez muitas melhorias para isso), incluindo:
monorepo
suportaLocking
Yarn v1 em Entrando no modo de manutenção em 2020. Desde então, a série v1.x é considerada legada e renomeada como Yarn Classic
. Seu sucessor, Yarn v2 (Berry), é agora o ramo de desenvolvimento mais ativo.
pnpm
mais eficienteA versão 1 do pnpm
foi lançada em 2017 por Zoltan Kochan. É um substituto para npm
, então se você tiver um projeto npm
, poderá usar pnpm
imediatamente!
A principal razão pela qual pnpm
foi criado é que npm
e Yarn
são muito redundantes em termos de estruturas de armazenamento de dependência usadas em projetos. Embora Yarn Classic
tenha uma vantagem de velocidade sobre npm
, ele usa o mesmo método de resolução de dependência que pnpm
não usa: npm
e Yarn Classic
usam hoisting
para nivelar seus node_modules
,
em vez de otimizar a estrutura anterior, pnpm
apresenta Outra estratégia de resolução de dependência é proposta: uma. estrutura de armazenamento endereçada ao conteúdo. A pasta node_modules
gerada por este método, na verdade, depende do diretório ~/.pnpm-store/
que é armazenado globalmente na pasta principal. Cada versão das dependências é armazenada fisicamente uma vez nesta pasta de diretório, formando um único endereço de origem para economizar espaço em disco considerável.
A estrutura node_modules
é uma estrutura aninhada de dependências criadas usando symlinks
(onde cada arquivo/pacote dentro de uma pasta é armazenado por meio de um link físico). (Imagens a serem preenchidas: links físicos e virtuais)
A influência do pnpm
é visível no relatório de 2021: Devido às suas inovações em armazenamento endereçável de conteúdo, os concorrentes procuram adotar conceitos pnpm
, como a estrutura de links simbólicos e o gerenciamento eficiente de pacotes em disco.
Yarn 2 foi lançado em janeiro de 2020 e foi anunciado como uma grande atualização do Yarn
original. A equipe Yarn
o chama de Yarn Berry
para deixar mais óbvio que é essencialmente um novo gerenciador de pacotes com uma nova base de código e novos princípios.
A principal inovação do Yarn Berry
é sua abordagem plug-and-play (PnP) como estratégia para reparar node_modules. Em vez da estratégia de gerar node_modules
, gere um arquivo .pnp.cjs
com uma tabela de consulta de dependências, que permite um tratamento mais eficiente das dependências, pois é um arquivo único em vez de uma estrutura de pastas aninhadas. Além disso, cada pacote é armazenado em uma pasta na forma de um arquivo zip em vez de .yarn/cache/
e ocupa menos espaço em disco que node_modules
.
Todas essas mudanças aconteceram tão rapidamente que causaram muita polêmica após serem lançadas. Essas mudanças radicais no PnP exigem que os mantenedores atualizem seus pacotes existentes para serem compatíveis com ele. Usar a nova abordagem PnP por padrão e reverter para node_modules
não foi simples inicialmente, o que fez com que muitos desenvolvedores conhecidos não a considerassem e criticassem publicamente o Yarn 2.
Desde então, a equipe Yarn Berry
abordou muitos problemas em seus lançamentos subsequentes. Para resolver problemas de incompatibilidade de PnP, a equipe forneceu uma maneira de alterar facilmente o modo operacional padrão. Com a ajuda do plugin node_modules, voltar para a abordagem tradicional node_modules
requer apenas uma linha de configuração.
Além disso, o ecossistema JavaScript tem fornecido suporte crescente ao PnP ao longo do tempo e, como você pode ver nesta tabela de compatibilidade, alguns grandes projetos começaram a adotar Yarn Berry
.
Embora Yarn Berry
ainda seja jovem, já está causando impacto no espaço do gerenciador de pacotes – pnpm
adotou a abordagem PnP no final de 2020.
O gerenciador de pacotes deve primeiro ser instalado nos sistemas locais e de CI/CD de cada desenvolvedor.
npm
vem com Node.js
, portanto, nenhuma etapa extra é necessária. Além de baixar o instalador Node.js para o seu sistema operacional, tornou-se uma prática comum usar ferramentas CLI para gerenciar versões de software. No contexto do Node, o Node Version Manager (nvm) ou Volta se tornou um utilitário muito conveniente.
Você pode instalar o Yarn 1 de diferentes maneiras, por exemplo, como um pacote npm
: .$ npm i -g yarn
Para migrar do Yarn Classic para o Yarn Berry, o método recomendado é:
Instalar ou atualizar Yarn Classic
para
versão
use o comando
yarn set version berry.
No entanto, a maneira recomendada de instalar o Yarn Berry aqui é através do Corepack.
Corepack foi criado pelos desenvolvedores do Yarn Berry. A iniciativa foi originalmente chamada de Package Manager Manager (pmm) e foi mesclada com o Node no LTS v16.
Com a ajuda do Corepack, o Node é um gerenciador de pacotes alternativo ao npm
que você não precisa instalar “separadamente”, pois inclui os binários Yarn Classic
, Yarn Berry
e pnpm
. Esses shims permitem que os usuários executem comandos Yarn e pnpm sem instalá-los explicitamente primeiro e sem atrapalhar a distribuição do Node.
Corepack vem pré-instalado com Node.js ≥ v16.9.0. No entanto, para versões mais antigas do Node, você pode usar ⬇️
npm install -g corepack
para habilitar o Corepack antes de usá-lo. Este exemplo mostra como ativá-lo no Yarn Berry v3.1.1.
# você precisa ativar primeiro $ corepack ativar # shim instalado mas a versão concreta precisa ser ativada $ corepack prepare [email protected] --activate
Você pode instalar pnpm
como um pacote npm
: $ npm i -g pnpm
. Você também pode instalar o pnpm usando Corepack:
$ corepack prepare [email protected] --activate
Nesta seção você verá rapidamente os principais recursos dos diferentes gerenciadores de pacotes. Você pode descobrir facilmente quais arquivos estão envolvidos na configuração de um gerenciador de pacotes específico e quais arquivos são gerados pela etapa de instalação.
Todos os gerenciadores de pacotes armazenam todas as metainformações importantes no arquivo de manifesto do projeto package.json. Além disso, os arquivos de configuração de nível raiz podem ser usados para configurar diferentes pacotes privados ou diferentes configurações de resolução de dependências.
Durante a etapa de instalação, dependencies
são armazenadas em uma estrutura de arquivo como node_modules
e um arquivo locking
é gerado. Esta seção não considera as configurações do espaço de trabalho, portanto, todos os exemplos mostram apenas um único local onde as dependências são armazenadas.
usando $ npm install
ou o $ npm i
mais curto, gerarei um arquivo package-lock.json
e uma pasta node_modules
. Existem também arquivos configuráveis como .npmrc
que podem ser colocados no diretório de nível raiz. Consulte a próxima seção para obter mais informações sobre locking
arquivos.
. ├── node_modules/ ├── .npmrc ├── pacote-lock.json └── package.json
executando $ yarn
criará um arquivo yarn.lock
e uma pasta node_modules
. Arquivos .yarnrc
também podem ser opções de configuração, e Yarn Classic
também oferece suporte a arquivos .npmrc
. Alternativamente, você pode usar a pasta de cache .yarn/cache/
e a versão mais recente Yarn Classic
armazenada localmente em .yarn/releases/
.
. ├── .fio/ │ ├──cache/ │ └── libera/ │ └── fio-1.22.17.cjs ├── node_modules/ ├── .yarnrc ├── pacote.json └── yarn.lock
Por causa deste modo de instalação especial, você tem que lidar com mais arquivos e pastas em seu projeto Yarn Berry
do que com outros gerenciadores de pacotes. Alguns são opcionais e outros são obrigatórios.
Yarn Berry
não suporta mais .npmrc
ou .yarnrc
, ele requer um .yarnrc.yml. Para o fluxo de trabalho tradicional de geração de pastas node_modules
, você deve fornecer a configuração nodeLinker
para usar a configuração node_modules
ou pnpm
(não entendo esta parte).
#.yarnrc.yml nodeLinker: node-modules # ou pnpm
executando $ yarn
instalará todas as dependências em uma pasta node_modules
. E um arquivo yarn.lock
é gerado, que é mais recente, mas não é compatível com Yarn Classic
. Além disso, uma pasta .yarn/cache/
é gerada para instalação offline. Esta pasta é opcional e serve para armazenar a versão do Yarn Berry
utilizada pelo projeto.
. ├── .fio/ │ ├──cache/ │ └── libera/ │ └── fio-3.1.1.cjs ├── node_modules/ ├──.yarnrc.yml ├── pacote.json └── Yarn.lock
Seja no modo estrito ou no modo solto para PnP, executar $ yarn
com .pnp.cjs
e yarn.lock
gerará um .yarn/cache/
e .yarn/unplugged
. PnP estrito é o modo padrão. Se você deseja configurar o modo flexível, você precisa habilitá-lo no seguinte formato⬇️:
# .yarnrc.yml. nodeLinker:pnp pnpMode: loose
Em um projeto PnP, além da pasta releases
, a pasta .yarn
provavelmente também conterá uma pasta sdk/
que fornece suporte IDE. Dependendo do seu caso de uso, .yarn
pode até conter mais pastas.
. ├── .fio/ │ ├──cache/ │ ├── libera/ │ │ └── fio-3.1.1.cjs │ ├── SDK/ │ └── desconectado/ ├── .pnp.cjs ├── .pnp.loader.mjs ├──.yarnrc.yml ├── pacote.json └── yarn.lock`O estado inicial do
package.json
o mesmo do projeto npm
ou Yarn Classic
e também requer o arquivo pnpm
. Depois de instalar dependências usando $ pnpm i
resulta em uma pasta node_modules
, mas sua estrutura é completamente diferente já que seu conteúdo é um armazenamento endereçável.
pnpm
também gera seu próprio arquivo de bloqueio pnp-lock.yml
. Você pode fornecer configuração adicional usando o arquivo .npmrc
opcional.
. ├── node_modules/ │ └── .pnpm/ ├── .npmrc ├── pacote.json └── arquivo de bloqueio pnpm-lock.yml
Conforme mencionado na seção anterior, todo gerenciador de pacotes cria arquivos de bloqueio.
O arquivo lock
armazena a versão exata de cada dependência instalada pelo seu projeto, permitindo uma instalação mais previsível e determinística. Este arquivo lock
é importante porque as versões dependentes provavelmente serão declaradas com um intervalo de versões (por exemplo, ≥ v1.2.5) e se você não "bloquear" sua versão, a versão real instalada poderá ser diferente.
Às vezes, os arquivos de bloqueio também armazenam somas de verificação (um hash, pelo que me lembro), que abordaremos com mais detalhes na seção de segurança.
A partir do npm
v5+, o bloqueio de arquivos sempre foi a principal função do npm
yarn.lock
package-lock.json
). No pnpm
pnpm-lock.yaml
, Yarn Berry
aparece no novo formato YAML.
Na seção anterior vimos a abordagem tradicional de instalação de dependências na estrutura de pastas node_modules
. Esta é a solução utilizada por npm
, Yarn Classic e pnpm ( pnpm
é mais eficiente que as outras).
Yarn Berry
faz as coisas de maneira diferente no modo PnP. Em vez da pasta node_modules
, as dependências são armazenadas em arquivos zip como uma combinação de arquivos .yarn/cache/
e .pnp.cjs
.
É melhor colocar esses arquivos de bloqueio sob controle de versão, já que cada membro da equipe instala a mesma versão, então isso resolve o problema "funciona na sua máquina e na minha".
A tabela a seguir compara os diferentes comandos CLI disponíveis em npm
, Yarn Classic
, Yarn Berry
e pnpm
. Esta não é de forma alguma uma lista completa, mas sim uma folha de dicas. Esta seção não aborda comandos relacionados ao fluxo de trabalho.
npm
e pnpm
têm muitos aliases de comandos e opções ad hoc, o que significa que os comandos podem ter nomes diferentes, ou seja, $ $ npm add
$ npm install
vs. Além disso, muitas opções de comando têm versões abreviadas, como -D
em vez de --save-dev
. Na tabela, chamo todas as versões abreviadas de aliases. Usando cada um desses gerenciadores de pacotes, você pode adicionar, atualizar ou remover diversas dependências.
Esta tabela cobre os comandos de gerenciamento de dependências usados para instalar ou atualizar todas as dependências especificadas em package.json
.
Ação | npm | Yarn Classic | Yarn Berry | pnpm | |
---|---|---|---|---|---|
install deps em package.json | npm install alias: eu, adiciono | a instalação do fio ou o fio | como Classic | pnpm install alias: eu | |
atualizo os deps em package.json semver | npm update alias: up, atualize | o fio, atualize | o fio. semver up (via plugin) | pnpm update alias: up | |
update deps em package.json para o mais recente | N/A | yarn upgrade --latest | yarn up | pnpm update --latest alias: -L | |
update | deps | acc | . | semver up reagir | pnpm up reagir |
atualizar deps para última | atualização npm react@latest | Yarn upgrade react --latest | wire up reagir | pnpm up -L reagir | |
atualizar deps interativamente | N/A | yarn upgrade-interactive | wire upgrade-interactive (via plugin) | $ pnpm up --interactive alias: -i | |
adiciono runtime deps | npm i reajo | yarn add reage | como Classic | pnpm add react | |
add dev deps | npm i -D babel alias: --save-dev | alias add -D babel alias: --dev | like Classic | pnpm add -D babel alias: --save-dev | |
adiciona deps a package.json sem semver | npm i -E alias de reação: --save-exact | fio add -E alias de reação: --exato | como Classic | pnpm add -E alias de reação: - -save-exact | |
desinstalar deps e remover do pacote.json | npm desinstalar reagir alias: remover, rm, r, un, desvincular | o fio remover reagir | como clássico | pnpm remover reagir alias: rm, un, desinstalar | |
desinstalar deps sem atualização do pacote. json | npm desinstalar --no-save | N/D | N/D | N/D |
O exemplo a seguir mostra como gerenciar pacotes durante o desenvolvimento. Termos usados na tabela:
- Pacote: dependência ou binário
- Binário: Uma ferramenta de execução de
node_modules/.bin/
ou.yarn/cache/
(PnP)
É importante entender que Yarn Berry
só nos permite executar em package.json
ou Expose os arquivos binários especificados no arquivo bin/
.
Ação | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
instala pacotes globalmente | npm i -g ntl alias: --global | yarn global add ntl | N/A (global removido) | pnpm add --global ntl |
atualiza pacotes globalmente | npm update -g ntl | yarn global upgrade ntl | N /A | atualização pnpm --global ntl |
remove pacotes globalmente | npm desinstalar -g ntl | yarn global remove ntl | N/A | pnpm remove --global ntl |
executa binários do terminal | npm exec ntl | yarn ntl | yarn ntl | pnpm ntl |
executa binários do script | ntl | ntl | ntl | ntl |
execução dinâmica de pacote | npx ntl | N/A | yarn dlx ntl | pnpm dlx ntl |
add runtime deps | npm i react | fio add react | like Clássico | pnpm add react |
add dev deps | npm i -D babel alias: --save-dev | yarn add -D babel alias: --dev | como Classic | pnpm add -D babel alias: --save-dev |
adiciona deps a package.json sem semver | npm i -E react alias: --save-exact | Yarn add -E react alias: --exact | como Classic | pnpm add -E alias de reação: --save-exact |
desinstalar deps e remover do pacote.json | npm desinstalar alias de reação: remover, rm, r, un, desvincular | o fio remover reagir | como clássico | pnpm remover alias de reação: rm, un, desinstalar |
desinstalar deps sem atualização de package.json | npm desinstalar --no-save | N/D | N/D | N/D |
Esta tabela cobre alguns comandos integrados úteis. Se não houver um comando oficial, comandos de terceiros geralmente podem ser usados por meio de pacotes npm
ou plug-ins Yarn Berry
.
Ação | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
publicar | npm publicar | fio publicar | fio npm publicar | pnpm publicar |
lista instalada deps | npm ls alias: lista, la, ll | lista de fios | alias da lista pnpm: ls | |
lista desatualizado deps | npm desatualizado | fio desatualizado | fio atualização-interativo | pnpm desatualizado |
imprimir informações sobre deps | npm explicar alias ntl: por que | fio por que ntl | como Clássico | pnpm por que ntl |
init projeto | npm init -y npm init (interativo) alias: - -yes | Yarn init -y Yarn init (interativo) alias: --yes | Yarn init | pnpm init -y pnpm init (interativo) alias: --yes |
imprimir informações de licenças | N/A (via pacote de terceiros) | lista de licenças de fios | N/ A (ou via plug-in, outro plug-in) | N/A (via pacote de terceiros) |
atualizar a versão do gerenciador de pacotes | N/A (com ferramentas de terceiros, por exemplo, nvm) | com npm: conjunto de políticas de fio-versão 1.13.0 | com Corepack : wire set versão 3.1.1 | N/A (com npm, Corepack) |
realizar auditoria de segurança | npm audit | wire audit | wire npm audit | pnpm audit |
add deps to package.json sem semver | npm i -E react alias: --save-exact | yarn add -E alias de reação: --exato | como clássico | pnpm add -E alias de reação: --save-exact |
desinstalar deps e remover do pacote.json | npm desinstalar alias de reação: remover, rm, r, un, desvincular | o fio remover reagir | como o clássico | pnpm remover alias de reação: rm, un, desinstalar |
deps de desinstalação sem atualização de package.json | npm desinstalar --no-save | N/A | N/A | N/A |
A configuração do gerenciador de pacotes ocorre em seu package.json
e em arquivos de configuração dedicados.
monorepo
A maioria das configurações ocorre no arquivo de configuração privado .npmrc
.
Se quiser usar o recurso workspaces
do npm
, você deve adicionar o campo de metadados de espaços de trabalho em package.json
para informar ao npm onde encontrar o subprojeto ou a pasta do espaço de trabalho.
// ... "espaços de trabalho": [ "ganchos", "utilitários" ] }
Todo gerenciador de pacotes pode usar o registro npm
público. Você provavelmente desejará reutilizá-los sem publicá-los em um registro público. Você pode configurar isso para tornar privado o registro em seu arquivo .npmrc
. (Basicamente todos têm fontes privadas agora)
# .npmrc @doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/
Existem muitas opções de configuração para npm
, é melhor verificá-las na documentação.
Você pode definir workspaces
do yarn
em package.json
(deve ser um pacote privado).
{ // ... "privado": verdadeiro, "espaços de trabalho": ["espaço de trabalho-a", "espaço de trabalho-b"] }
Qualquer configuração opcional vai para um arquivo .yarnrc
. Uma opção de configuração comum é definir um yarn-path:
força cada membro da equipe a usar uma versão binária especificada. yarn-path
aponta para a pasta que contém uma versão específica Yarn
(por exemplo, .yarn/releases/
). Você pode instalar a versão unificada Yarn Classic
usando o comando (classic.yarnpkg.com/en/docs/cli…).
A configuração de workspaces
no Yarn Berry
é semelhante à configuração no Yarn Classic
( package.json
). A maior parte da configuração Yarn Berry
ocorre em .yarnrc.yml
e há muitas opções de configuração disponíveis.
#.yarnrc.yml YarnPath: .yarn/releases/yarn-3.1.1.cjs
yarn berry
pode usar o método de importação $> yarn plugin import <name>
para estender o plug-in (yarnpkg.com/cli/plugin/…), este comando irá também ser atualizado .yarnrc.yml
.
#.yarnrc.yml plug-ins: - caminho: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs especificação: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"
Conforme mencionado na seção de histórico, devido a motivos de compatibilidade, Pode haver alguns problemas com dependências no modo estrito PnP. Existe uma solução típica para este tipo de problema PnP: política de configuração de extensão de pacotes.
#.yarnrc.yml extensões de pacote: "componentes estilizados@*": dependências: react-is: "*"
pnpm
usa o mesmo mecanismo de configuração que npm
, então você pode usar arquivos .npmrc
. Configurar um registro privado também funciona da mesma forma que usar npm
. Projetos de vários pacotes podem ser suportados com o recurso de espaço de trabalho do pnpm. Para inicializar monorepo
, você deve especificar o local do pacote no arquivo pnpm-workspace.yaml
.
# pnpm-workspace.yaml pacotes: - 'pacotes/**'
(Na verdade, existem três conceitos aqui: armazém único e vários projetos, armazém único e projeto único e vários armazéns e vários projetos)
monorepo
é um workspace
que contém vários projetos. Manter tudo em um só lugar em vez de usar vários repositórios é uma estratégia de organização do projeto.
É claro que isto introduz uma complexidade adicional. Yarn Classic
foi o primeiro a habilitar esse recurso, mas agora todos os principais gerenciadores de pacotes oferecem funcionalidade de espaço de trabalho. Esta seção mostra como configurar seu espaço de trabalho usando cada um dos diferentes gerenciadores de pacotes.
A equipe npm
lançou o tão aguardado recurso de espaço de trabalho npm na v7. Ele contém muitos comandos CLI para ajudar a gerenciar projetos de vários pacotes a partir do pacote raiz. A maioria dos comandos pode ser usada com opções relacionadas workspace
para informar npm
se ele deve ser executado em um espaço de trabalho específico, em vários ou em todos os espaços de trabalho.
# Instalando todas as dependências para todos os espaços de trabalho $ npm i --workspaces. # executa em um pacote $ npm executar teste --workspace=hooks # executa vários pacotes $ npm executar teste --workspace=hooks --workspace=utils #correr contra todos $ npm executar teste --workspaces #ignore todos os pacotes faltando teste $ npm run test --workspaces --if-present
dicas: Comparado a outros gerenciadores de pacotes, npm
v8 atualmente não oferece suporte a filtragem avançada ou execução paralela de vários comandos relacionados ao espaço de trabalho.
Em agosto de 2017, a equipe Yarn
anunciou suporte monorepo
para funcionalidade de espaço de trabalho. Anteriormente, os gerenciadores de pacotes só podiam ser usados em projetos de vários pacotes com software de terceiros, como o Lerna. Esta nova adição ao Yarn
também abre caminho para outros gerenciadores de pacotes implementarem tal funcionalidade.
Se estiver interessado, você pode consultar como usar a função de espaço de trabalho do Yarn Classic com e sem Lerna. Mas este artigo apresentará apenas alguns comandos necessários para ajudá-lo a gerenciar dependências na configuração Yarn Classic
.
# Instala todas as dependências $yarn para todos os espaços de trabalho # Mostra a árvore de dependências $ informações dos espaços de trabalho do fio # Execute outro pacote para iniciar $ Yarn Workspace Awesome - Package Start # Adicione o Webpack ao pacote $ Yarn Workspace Awesome - Package Add - D Webpack # add React para todos os pacotes $ yarn add react -W
Yarn Berry
apresenta espaços de trabalho desde o início, pois sua implementação é construída sobre os conceitos do Yarn Classic
. Em um comentário no Reddit, o desenvolvedor líder do Yarn Berry forneceu uma breve visão geral dos recursos orientados ao espaço de trabalho, incluindo:
Yarn Berry
usa vários protocolos que podem ser usados no campo dependencies
ou devDependencies
do arquivo package.json
. Entre eles está o protocolo workspace
.
Em contraste com o espaço de trabalho do Yarn Classic
, Yarn Berry
define claramente que uma dependência deve ser um dos pacotes neste monorepo
. Caso contrário, se as versões não corresponderem, Yarn Berry
poderá tentar obter sua versão do registro remoto.
{ // ... "dependências": { "@doppelmutzi/hooks": "espaço de trabalho:*", "servidor http": "14.0.0", // ... } }
Através do protocolo workspace
, pnpm
contribuiu para um projeto monorepo
semelhante ao Yarn Berry
. Muitos comandos pnpm
aceitam opções --recursive (-r)
ou --filter que são particularmente úteis no contexto monorepo
. Seus comandos de filtragem nativos também são um ótimo complemento para Lerna
.
#remove todos os espaços de trabalho pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml # executa todos os testes para todos os espaços de trabalho com escopo @doppelmutzi teste de execução recursiva pnpm --filter @doppelmutzi/`
O desempenho é uma parte fundamental da decisão de seleção. Esta seção apresenta benchmarks baseados em projetos de pequeno e médio porte. Aqui estão algumas notas sobre o projeto de amostra:
Medi cada uma de nossas variantes de gerenciador de pacotes uma vez usando três casos de uso (UC). Para avaliação e explicação detalhadas, consulte os resultados do Projeto 1 (P1) e do Projeto 2 (P2).
node_modules
ou .pnp.cjs
node_modules
ou .pnp.cjs
node_modules
ou .pnp.cjs
usei a ferramenta gnomon para medir o tempo consumido pela instalação ( yarn
| gnomon
). Além disso, medi o tamanho dos arquivos gerados $ du -sh node_modules
.
Resultados de desempenho do Projeto 1 | |||||||
---|---|---|---|---|---|---|---|
Método | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP solto v3.1.1 | Yarn Berry PnP estrito v3.1.1 | Yarn Berry node_modules v3.1.1 | Yarn Berry pnpm v3.1.1 |
UC 1 | 86,63s | 108,89s | 43,58s | 31,77s | 30,13s | 56,64s | 60,91s |
UC 2 | 41,54s | 65,49s | 26,43s | 12,46s | 12,66s | 46,36s | 40,74s |
UC 3 | 23,59s | 40,35s | 20,32s | 1,61s | 1,36s | 28,72s | 31,8 |
Arquivos 9s e tamanho | package-lock.json: 1,3M node_modules : 467M | node_modules: 397M Yarn.lock: 504K | pnpm-lock.yaml: 412K node_modules: 319M | Yarn.lock: 540K cache: 68M desconectado: 29M .pnp.cjs: 1,6M | Yarn.lock: 540K cache: 68M desconectado: 29M . pnp.cjs: 1,5M | node_modules: 395M Yarn.lock: 540K cache: 68M | node_modules: 374M Yarn.lock: 540K cache: 68M |
Resultados de desempenho para o Projeto 2 | |||||||
---|---|---|---|---|---|---|---|
Método | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP solto v3.1.1 | Yarn Berry PnP estrito v3.1.1 | Yarn Berry node_modules v3.1.1 | Yarn Berry pnpm v3.1.1 |
UC 1 | 34,91s | 43,26s | 15,6s | 13,92s | 6,44s | 23,62s | 20,09s |
UC 2 | 7,92s | 33,65s | 8,86s | 7,09s | 5,63s | 15,12s | 14,93s |
UC 3 | 5,09s | 15,64s | 4,73s | 0,93s | 0,79s | 8,18s | 6,02s |
Arquivos e tamanho | de bloqueio de pacote .json: 684K node_modules: 151M | fios.lock: 268K node_modules: 159M | pnpm-lock.yaml: 212K node_modules: 141M | .pnp.cjs: 1,1M .pnp.loader.mjs: 8,0K fios.lock: 292K .yarn: 38M | .pnp.cjs: 1,0 M .pnp.loader.mjs: 8,0K Yarn.lock: 292K .yarn: 38M | Yarn.lock: 292K node_modules: 164M cache: 34M | Yarn.lock: 292K node_modules: 156M cache: 34M |
npm
é um pouco tolerante quando se trata de lidar com pacotes ruins e encontrou algumas vulnerabilidades de segurança que afetaram diretamente muitos projetos. Por exemplo, na versão 5.7.0, ao executar o comando sudo npm
em um sistema operacional Linux, você pode alterar a propriedade dos arquivos do sistema, inutilizando o sistema operacional.
Outro incidente ocorreu em 2018 envolvendo roubo de Bitcoins. O pacote Node.js EventStream adicionou uma dependência maliciosa em sua versão 3.3.6. Este pacote malicioso contém um método criptográfico que tenta roubar Bitcoins da máquina do desenvolvedor.
Para ajudar a resolver esses problemas, as novas versões npm
usam algoritmos criptográficos para verificar a integridade dos pacotes instalados. SHA-512.
Yarn Classic
e Yarn Berry
usam somas de verificação para verificar a integridade de cada pacote desde o início. Yarn
também tenta impedir que você recupere pacotes maliciosos que não estejam declarados em package.json
: se uma incompatibilidade for encontrada, a instalação será abortada.
Yarn Berry
no modo PnP não apresenta os problemas de segurança do método node_modules
tradicional. Comparado com Yarn Classic
, Yarn Berry
melhora a segurança da execução de comandos. Você só pode executar pacotes que foram declarados em package.json
. Esse recurso de segurança é semelhante ao pnpm
, que descrevo abaixo.
pnpm
ainda usa checksums para verificar a integridade de cada pacote instalado antes de executar seu código.
Como mencionamos acima, tanto npm
quanto Yarn Classic
apresentam problemas de segurança devido à promoção. pnpm
evita essa situação porque seu modelo de gerenciamento não utiliza elevação, em vez disso gera pastas node_modules
aninhadas, eliminando assim o risco de acesso ilegal a dependências; Isso significa que as dependências são declaradas em .package.json
.
Como discutimos, isso é especialmente importante em um cenário monorepo
, uma vez que o reforço de algoritmos às vezes pode levar ao não-determinismo de dependência.
npm | Yarn Classic | Yarn Berry | pnpm |
Svelte | React | Jest (com node_modules) | Vue 3 |
Preact | Angular | Storybook (com node_modules) | Browserlist |
Express.js | Ember | Babel (com node_modules) | Prisma |
Meteor | Next.js | Redux Toolkit (com node_modules) | SvelteKit |
Apollo Server | Gatsby | ||
Nuxt | |||
Criar aplicativo React | |||
webpack-cli | |||
Emoção |
Na verdade, existem grandes diferenças nos princípios dos diferentes gerenciadores de pacotes.
pnpm
inicialmente se parece com npm
, pois o uso da CLI é pnpm
, mas o gerenciamento de dependências é muito diferente; Yarn Classic
ainda é popular, mas é considerado software legado e o suporte pode ser descartado em um futuro próximo. Yarn Berry PnP
é novo, mas seu potencial para revolucionar o mundo do gerente de pacotes ainda não foi realizado.
Ao longo dos anos, muitos usuários perguntaram a quem usa quais gerentes de pacotes e as pessoas em geral parecem estar particularmente interessadas na maturidade e adoção do Yarn Berry PnP
.
O objetivo deste artigo é fornecer várias perspectivas para decidir qual gerente de pacotes usar para si mesmo. Gostaria de ressaltar que não recomendo um gerenciador de pacotes específico. Depende de como você pesa os diferentes requisitos - para que você ainda possa escolher o que quiser!
Endereço original em inglês: https://blog.logrocket.com/javascript-package-managers-compared/