Um guia para npm: o gerenciador de pacotes Node.js
Publicados: 2022-03-11JavaScript é facilmente a linguagem mais utilizada quando se trata de desenvolvimento de websites e aplicações web. A multiplicidade de recursos é surpreendente e, mais ainda, o número de bibliotecas disponíveis.
A princípio, essas bibliotecas são poucas e fáceis de manter; no entanto, logo o inferno da dependência se instala e uma solução mais madura é necessária.
Entre no Node Package Manager (npm) – um gerenciador de pacotes JavaScript mais usado em conjunto com o Node.js, embora também possa ser usado independentemente. Ele oferece controle excepcional sobre as dependências do seu projeto e fornece uma ótima maneira de contribuir para o mundo de código aberto.
Você pode começar simplesmente executando npm install <package name>
e injetando-o em seu arquivo JavaScript.
Quer instalar uma versão específica? Sem problemas. Execute npm install <package name>@1.2.3
.
Deseja instalar um pacote globalmente (como Mocha ou Angular-CLI)? Basta adicionar um -g
assim: npm install -g angular-cli mocha
.
É certo que a maioria dos casos de uso para em uma instalação do npm e não há necessidade de mais nada. No entanto, o npm tem muitos recursos adicionais, pelos quais vou orientá-lo, destacando aqueles que considero essenciais, realmente úteis ou simplesmente incríveis.
Comandos CLI
A CLI é onde os usuários passam a maior parte do tempo interagindo com o npm, e sua interface de ajuda é realmente útil.
Consultar a ajuda ( npm help
) gera uma série inteira de opções, e executar npm help-search <searchText>
fornece uma lista de resultados de pesquisa direto do markdown do npm.
Aqui estão os comandos principais que se destacam.
install
: É mencionado aqui por causa de sua necessidade absoluta ao trabalhar com npm. Usado para instalar um novo pacote local ou globalmente (ao adicionar-g
) ou para instalar dependências listadas no arquivopackage.json
(mais sobre isso posteriormente).uninstall
: Isso também é essencial. É usado para limpar um pacote específico do diretórionode_modules
local ou globalmente (ao adicionar-g
).access
: Este é o playground dos administradores de permissão de usuário npm dentro do contexto npm-organizations e pacotes com escopo (privado). Coisas seriamente poderosas. Usado em conjunto comadduser
,owner
,team
, etc, ele oferece um controle refinado sobre quem tem acesso a quê.bin
: Onde diabos os pacotes estão instalados? Execute este comando para ver o caminho absoluto do arquivo.cache
: Se você começar a instalar pacotes do npm left, right e center, este comando é bastante útil. Chame-o com o subcomandols
para ver uma lista de pacotes armazenados em cache local ou com o subcomandoclean
para limpar todos os pacotes que estão no cache. Quando o registro npm ainda estava um pouco instável, isso era essencial para voltar a um ambiente estável ou redefinir as coisas quando você não configurava corretamente as permissões npm.config
: Entraremos nas diferentes opções de configuração mais tarde, mas este comando lida principalmente com propriedades de configuração persistentes no arquivo de configuração local ou global usando os subcomandosset
,get
oudelete
.dedupe
ouddp
: Ao trabalhar em um projeto por um longo período de tempo e instalar pacotes diretamente do npm, este comando percorrerá a árvore de pacotes local e tentará simplificar as dependências.link
: Quando você está desenvolvendo seu próprio pacote npm, isso permite que você crie um link simbólico para o contexto global para que possa ser testado como se fosse instalado globalmente a partir do registro npm. Por exemplo, se você estiver escrevendo uma ferramenta de montagem em um nó que tenha uma CLI instalada globalmente, poderá executar este comando e testar o comportamento da CLI sem precisar implantá-la primeiro.ls
: É usado para visualizar dependências de pacotes e suas dependências, em uma estrutura de árvore. É legal de ver e também é útil para comparações com outros projetos.outdated
: Isso é usado para avaliar o estado atual das dependências instaladas e se elas estão desatualizadas ou não. Em projetos em que a lista de dependências raiz tem centenas de linhas, uma verificação manual dos pacotes é quase impossível. Adicionar-g --depth=0
a este comando permite que você também verifique seus pacotes instalados globalmente.publish
: Este comando é essencial ao desenvolver seu próprio pacote para npm. Ele faz exatamente como o nome sugere; ele publica seu pacote no registro npm.search
: Use isso para pesquisar no registro todos os pacotes que contêm o texto fornecido no terceiro argumento.shrinkwrap
: Em resumo, este comando permite que você bloqueie versões de dependência específicas em um pacote em ordem, para que um número semver (versão semântica) relaxado não quebre o código de produção.star
: Você realmente gosta de um pacote que está usando? Use este comando para mostrar sua apreciação diretamente do terminal, que reflete na página do pacote no registro npm.update
: Isso geralmente segue o comandooutdated
para atualizar quaisquer pacotes desatualizados.version
: Isso lhe dá uma abreviação para aumentar a propriedade de versãopackage.json
e fazer uma tag git tudo em um.
Observe que a maioria desses comandos pode receber subcomandos e/ou configurações, e esta lista não é de forma alguma uma discussão final na CLI.
npm-config
A configuração é uma parte importante do npm e há várias maneiras de definir as variáveis de configuração.
Configuração via CLI e variáveis ambientais
Primeiro, a configuração pode ser definida via CLI do terminal.
Normalmente, seria algo assim: npm <command> --<configuration option> [<optional value>]
.
Se o valor não for especificado, a opção será definida como true por padrão.
Por exemplo, digamos que você esteja trabalhando em um pacote npm com escopo (privado) e decida publicá-lo como um pacote público.
Isso é feito facilmente anexando --access=public
ao seu comando de publish
. Se não especificarmos a propriedade como pública, o padrão seria restrito (privado).
A configuração anexada a outros comandos como esse não persiste em todos os lugares, portanto, pode se tornar cansativo definir uma série de configurações por meio da CLI.
Nesses casos, pode ser melhor definir a configuração usando variáveis ambientais.
Qualquer variável de ambiente definida com o prefixo npm_config_
será usada para configurar o npm.
Por exemplo: export npm_config_registry=localhost:4321
a opção de configuração do registro globalmente e, quando o npm for executado, ele usará o registro npm localizado em localhost na porta 4321.
Configuração através do arquivo npmrc
Você também pode definir opções de configuração usando o arquivo .npmrc
especial, que pode ser definido em diferentes níveis, dependendo de seus requisitos:
- Nível do projeto: na raiz do código de um projeto junto com seu arquivo
package.json
, normalmentepath/to/project/.npmrc
- Nível de usuário: o diretório que configura a conta de um usuário específico, normalmente
~/.npmrc
- Nível global: O diretório onde o npm procura por configurações globais, normalmente
$PREFIX/etc/npmrc
- Nível embutido: Seja cauteloso. Essa configuração não é apenas global, mas também faz parte do código-fonte do npm, e a melhor prática recomenda (na verdade, exige) que não alteremos o código que não somos responsáveis pela manutenção. Ele normalmente pode ser encontrado em
/path/to/npm/npmrc
.
As definições de configuração no arquivo .npmrc
podem ser modificadas e mantidas usando a CLI executando um comando neste formato: npm config set <key> <value>
.
Por exemplo, você pode executar npm config set access public
para tornar a configuração de publicação de um pacote com escopo (privado) persistentemente público.
Por padrão, esse comando persistiria a configuração localmente (a configuração de nível de usuário conforme descrito acima), mas você pode adicionar -g
para persistir globalmente.
Quando a configuração persistente precisa acontecer no nível do projeto ou no nível interno, o arquivo .npmrc
deve ser modificado usando um editor de texto.
Configuração via package.json
Finalmente, a configuração pode ser definida a partir do arquivo package.json
. No entanto, isso raramente é usado (e deve ser usado apenas se explicitamente necessário), porque um arquivo .npmrc
no nível do projeto é o local convencionalmente preferido para definir a configuração do pacote.
Definições de configuração notáveis
access
: Conforme discutido acima, é usado para definir permissões.always-auth
: é importante observar que essa configuração padrão é false. Quando definido como true, o npm sempre exigirá autenticação ao entrar em contato com o registro.ca
: O padrão é a autoridade de certificação (CA) npm. Ele pode ser alterado para null para permitir acesso apenas a registradores conhecidos ou a um certificado CA específico para conceder acesso apenas a esse específico. Essa configuração, juntamente comcafile
,cert
estrict-ssl
, raramente são usadas, mas falam sobre o aspecto de segurança e confiabilidade do npm, permitindo a tranquilidade de saber que o pacote que você está instalando vem da fonte que você espera.color
: O padrão é true, dando a você uma quebra da desolação padrão do terminal, colorindo ostdout
que é permitido pelos descritores de arquivo tty. Se definido como falso, o terminal permanece sem brilho. Quando definido comoalways
, ele sempre sai em cores.depth
: essa configuração permite controle granular sobre o que você vê com comandos recursivos, comols
eoutdated
, atribuindo a profundidade com que eles são executados. Um valor de 0 avaliará apenas o primeiro nível de dependências, enquanto infinito (o padrão) fará com que todos os níveis de dependências sejam avaliados. A exceção a esta regra é ao usá-lo comoutdated
; nesse caso, infinito é interpretado como 0 para garantir uma saída mais relevante.dev
: Isso é definido como false por padrão, mas quando definido como true (ao fazer umnpm install
) todas as dependências de desenvolvimento no arquivopackage.json
serão instaladas junto com as dependências normais.dry-run
: Quando esta configuração é definida como true, o npm não fará nenhuma alteração no seu pacote, mas informará o que teria feito. Isso pode ser muito útil ao executar determinados comandos, comodedupe
ouupdate
.git-tag-version
: é definido como true por padrão. Essa configuração marca uma versão no git ao executar o comandonpm version
. Se você estiver usando o npm como gerenciador de pacotes para um projeto grande que tem versões marcadas no git, isso pode economizar seu tempo e lembre-se de atualizar o arquivopackage.json
para você.loglevel
: Por padrão, isso é definido como warning , que fornece um erro e uma saída dewarn
ao executar comandos npm. Outras configurações incluemsilent
, que não fornece saída;error
, que registra apenas erros na saída;http
, que apenas anuncia erros de solicitação de http;info
, para saída informativa);verbose
, que registra quase tudo; esilly
, que, como o nome sugere, dá uma quantidade boba de saída e mais um pouco.production
: Quando definido como true, o npm age de acordo e executa todos os comandos no modo de produção. Isso significa que as dependências de desenvolvimento ou opcionais não serão instaladas, nem quaisquer tarefas relacionadas ao desenvolvimento serão executadas.rollback
: Quando definido como true, todas as instalações com falha são removidas. Isso é útil quando uma instalação de dependências falha. Dependendo do seu nível de registro, você poderá ver quais instalações falharam, anote-as e execute o comandonpm install
com a opção rollback definida como true. Em seguida, com suas notas e uma instalação de execução a seco (conforme descrito acima), você pode depurar o problema.save
: When installing a package directly from the registry, you can append
–saveto the command which will add the installed package to the dependencies option in the
file. For example,
file. For example,
npm install lodash` adicionará lodash às suas dependências.save-dev
: Semelhante à opção de configuração de salvamento, adicione--save-dev
ao instalar um pacote e ele será adicionado à opção devDependencies no arquivopackage.json
.save-optional
: Semelhante à opção save configuration, adicione--save-optional
ao instalar um pacote, e ele será adicionado à opção optionalDependencies no arquivopackage.json
.save-exact
: Ao instalar pacotes, as opçõessave
,save-dev
esave-optional
modificam o arquivopackage.json
inserindo o pacote instalado em sua respectiva propriedade com um operador semver range. Ao invocar a configuração 'save-exact' com um valor true, em conjunto com uma das configurações mencionadas acima, um número de versão específico é usado, ignorando o intervalo semver.save-prefix
: Isso define o operador de intervalo semver ao usarsave
,save-dev
ousave-optional
. O padrão é^
, permitindo que pequenas atualizações nos pacotes aconteçam na instalação. Isso pode ser definido para qualquer operador de intervalo semver prefixado válido.tag-version-prefix
: O padrão convencional év
, especificando o que é anexado à versão da tag git ao executarnpm version
.
Atualizando o npm usando o npm
Você também pode usar o npm para se atualizar.
Basta executar npm install -g npm@latest
e o npm será atualizado para a versão estável mais recente. É importante observar que cada versão do Node.js é fornecida com uma versão específica do npm e, na minha experiência, você não deve mexer muito com esse emparelhamento.
No final do dia, minha recomendação é manter o emparelhamento como eles se destinam.
Ao usar o npm como uma ferramenta autônoma, certifique-se de entender as implicações de usar qualquer versão que você escolher. Existe uma ótima ferramenta para gerenciar diferentes versões do Node.js (e, por sua vez, versões do npm) no mesmo sistema chamado nvm.
O arquivo package.json
O arquivo package.json
é o elemento crucial que une tudo.
É um requisito para publicar um pacote no registro npm e é onde a parte de gerenciamento de dependências ganha vida.
Ele tem dois campos obrigatórios, a saber, “nome” e “versão”, e juntas essas propriedades devem ser um identificador exclusivo.
O campo de nome deve seguir certas regras, conforme definido pela documentação do npm sobre nomenclatura, e o campo de versão está sujeito às especificações do semver.
Além disso, você pode ter uma lista de dependências com uma milha de extensão e definir uma versão específica a ser usada para cada uma delas, usando as versões semver e os operadores de intervalo. Aqui está uma lista de outras propriedades notáveis.
"a Principal"
“main” define o ponto de entrada para seu aplicativo, cujo padrão é index.js
. Dependendo da convenção ou da sua estrutura, pode ser app.js
ou main.js
. Você pode, é claro, fazer o que quiser.
“roteiros”
Esta é uma propriedade subestimada.
Primeiro, ele pode ser usado para fazer coisas na pré-publicação.
Em segundo lugar, ele fornece um local onde você pode criar um alias de comandos usados com frequência, desde tarefas de compilação (definidas em gulp ou grunt), acionando a instalação de outras dependências (com algo como bower), iniciando um servidor de desenvolvimento com webpack ou executando um conjunto de comandos bash.
“dependências”
Essa propriedade é uma lista de pacotes necessários para seu aplicativo, juntamente com o número de semver compatível. É uma propriedade notável porque pode ser modificada a partir do terminal quando você instala pacotes locais.
Isso é feito adicionando --save
(ou a abreviação -S
) no final do comando npm install
.
Quando você faz isso, os pacotes recém-instalados são adicionados à lista de dependências em seu arquivo package.json
.
Da mesma forma, uma dependência também pode ser removida adicionando --save
ao executar o comando npm uninstall
.
É importante estar ciente dos padrões de versão semver de cada uma das dependências e o que eles significam.
Se a regra semver for muito rígida, você perderá novos recursos e melhorias, enquanto que se a regra semver for muito relaxada, uma versão quebrada de um pacote pode ser instalada ao longo da linha.
Uma instalação de pacote quebrada pode ser bastante difícil de resolver, especialmente quando a versão minificada do pacote é usada.
“devDependências”
Separada da propriedade de dependências, a propriedade “devDependencies” permite definir dependências que são usadas apenas durante a fase de desenvolvimento e não são necessárias para a compilação de produção (como ESLint, pacotes grunt-contrib e Protractor). Assim como com as dependências, essa propriedade pode ser modificada no terminal adicionando --save-dev
(ou a abreviação -D
) ao final do comando npm install
ou o comando npm uninstall
. O mesmo cuidado se aplica ao controle de versão, conforme mencionado em dependências.
"caixote"
É aqui que você pode especificar o(s) arquivo(s) executável(is) do seu pacote, como o caminho para um utilitário CLI. Esta propriedade diz ao npm para criar links simbólicos locais ou globais para seus executáveis quando seu pacote for instalado.
“configurar”
Conforme discutido anteriormente, é aqui que você define as definições de configuração por meio do arquivo package.json
.
"privado"
Quando definido como true, o npm se recusará a publicar o pacote.
Isso não deve ser confundido com a definição de configuração de acesso.
Essa é uma configuração útil quando você tem um projeto que utiliza npm junto com seu package.json
, mas não se destina a ser publicado no registro npm, seja com escopo ou público.
Se sua intenção mudar, basta alterar a configuração para false e você poderá publicar seu pacote.
Propriedades personalizadas
O arquivo package.json
também aceita propriedades customizadas, desde que o nome ainda não esteja definido ou reservado.
Desenvolvendo seu próprio pacote npm
O ecossistema npm está repleto de pacotes, escritos por milhares de desenvolvedores diferentes em todo o mundo. Cada um resolve algum tipo de problema, fornecendo uma abstração ou apresentando uma implementação de algo.
É provável que, em algum momento, você também queira desenvolver seu próprio pacote para compartilhar.
Primeiro, você precisa criar um arquivo package.json
com as propriedades mínimas exigidas de “name” e “version” e, em seguida, a propriedade “main” para especificar o ponto de entrada, por exemplo index.js.
Escreva seu código nesse arquivo index.js, faça login com sua conta de usuário npm ou crie um novo usuário a partir do terminal e você estará pronto para publicá-lo no registro npm.
Os pacotes podem ser públicos ou privados.
Os pacotes públicos são gratuitos para publicação e estão disponíveis para todos utilizarem.
Pacotes privados, chamados de pacotes com escopo, só podem ser publicados se você pagou o usuário de módulos privados, e eles podem ser identificados pelo @username/
distinto que é prefixado ao nome do pacote.
Os pacotes com escopo também podem ser publicados publicamente chamando o comando de publish
com --access=public
.
Além disso, se você gastar mais tempo expandindo e melhorando a base de código do seu pacote, e é hora de uma nova versão ser publicada, basta alterar a versão (de acordo com as regras e convenção semver) do pacote no package.json
file e digite npm publish
.
Você também pode usar a interface de linha de comando e chamar npm version <update_type>
, em que update_type é patch
, minor
ou major
, conforme descrito por semver, e isso incrementa automaticamente o número da versão no arquivo package.json
.
npm Organizações
Novamente, a documentação do npm para isso é excelente, e seria inútil apenas repetir suas palavras.
O que pode ser dito sobre as organizações no contexto do npm é que ele é extremamente refinado e, quando gerenciado corretamente, grandes equipes e indivíduos, trabalhando em pacotes públicos ou com escopo sob um nome, podem ser muito bem gerenciados e restritos.
Embora seja complexo de dominar, é muito gratificante.
O poder do npm
Em última análise, a documentação que o npm fornece é extensa e deve ser consultada para detalhes, mas este artigo fornece uma visão geral útil das funcionalidades envolvidas básicas e mais avançadas, transmitindo a grandiosidade do npm.
Como em todas as coisas, existem opiniões fortes e muitas falhas podem ser encontradas. Mas se você nunca experimentou o npm (ou node, por falar nisso), mergulhe e explore por si mesmo. As chances são de que você vai gostar mais do que pensa.
Para artigos mais interessantes sobre npm, considere ler Using Scala.js with npm and Browserify.