Encontre pacotes npm não utilizados em package.json

231

Existe uma maneira de determinar se você possui pacotes no seu arquivo package.json que não são mais necessários?

Por exemplo, ao experimentar um pacote e depois comentar ou excluir código, mas esquecendo de desinstalá-lo, acabo com alguns pacotes que podem ser excluídos.

Qual seria uma maneira eficiente de determinar se um pacote poderia ser excluído com segurança?

Josh C
fonte

Respostas:

258

Você pode usar um módulo npm chamado depcheck (requer pelo menos a versão 10 do Node).

  1. Instale o módulo:

    npm install depcheck -g
    
    or
    
    yarn global add depcheck
  2. Execute-o e encontre as dependências não utilizadas:

    depcheck

O lado bom dessa abordagem é que você não precisa se lembrar do comando findou grep.

Para executar sem instalar, use npx:

npx depcheck
Attanasio alemão
fonte
11
depcheck-ES6 está agora incorporada pela depcheck
cyberwombat
47
não parece útil. Estou usando a configuração angular2 cli padrão e depchecklista todos os pacotes como unusederrados #
phil294
5
NB não depcheck não levam em conta os pacotes usados em scripts especificado no package.json
Javier Arias
17
Para executá-lo apenas uma vez (sem a instalação) - use npx :npx depcheck
Kiril
6
Não funcionou para mim. Ele listou todos os pacotes como não utilizados.
dev27 20/05/19
131

Há também um pacote chamado npm-check:

npm-check

Verifique se há dependências desatualizadas, incorretas e não utilizadas.

insira a descrição da imagem aqui

É bastante poderoso e desenvolvido ativamente. Um de seus recursos é a verificação de dependências não utilizadas - para esta parte, ele usa o depcheckmódulo mencionado na outra resposta.

alecxe
fonte
8
Parece me dar os mesmos resultados que depcheck. Parece que ele usa o depcheck para encontrar as dependências não utilizadas.
Alex K
3
npm outdatedverifica e lista as versões atuais, desejadas e mais recentes dos pacotes. Nenhuma lista de pacotes não utilizados.
Mgarde 25/10
1
não parece útil também. Eu estou usando a configuração angular padrão e isso também lista todos os pacotes como não utilizado, que é tão errado
Kyle Burkett
5

Se você estiver usando um sistema operacional Unix como o OS (Linux, OSX, etc), poderá usar uma combinação de finde egrepprocurar instruções de solicitação que contenham o nome do seu pacote:

find . -path ./node_modules -prune -o -name "*.js" -exec egrep -ni 'name-of-package' {} \;

Se você pesquisar a require('name-of-package')declaração inteira , lembre-se de usar o tipo correto de aspas:

find . -path ./node_modules -prune -o -name "*.js" -exec egrep -ni 'require("name-of-package")' {} \;

ou

find . -path ./node_modules -prune -o -name "*.js" -exec egrep -ni "require('name-of-package')" {} \;

A desvantagem é que não é totalmente automático, ou seja, não extrai os nomes dos pacotes package.jsonnem os verifica. Você precisa fazer isso para cada pacote. Como package.jsoné apenas JSON, isso pode ser remediado escrevendo um pequeno script usado child_process.execpara executar este comando para cada dependência. E faça disso um módulo. E adicione-o ao repositório do NPM ...

fiskeben
fonte
E quanto a .jsxarquivos e .tsarquivos, etc: D
OZZIE
1
Aparentemente, usando essa abordagem, não estamos usando o módulo
react
4

fiskeben escreveu:

A desvantagem é que não é totalmente automático, ou seja, não extrai os nomes dos pacotes do package.json e os verifica. Você precisa fazer isso para cada pacote.

Vamos automatizar a resposta da Fiskeben se, por qualquer motivo, depchecknão estiver funcionando corretamente! (Por exemplo, eu tentei com o Typecript e deu erros de análise desnecessários)

Para análise package.json, podemos usar o software jq. O script de shell abaixo requer um nome de diretório por onde começar.

#!/bin/bash
DIRNAME=${1:-.}
cd $DIRNAME

FILES=$(mktemp)
PACKAGES=$(mktemp)

find . \
    -path ./node_modules -prune -or \
    -path ./build -prune -or \
    \( -name "*.ts" -or -name "*.js" -or -name "*.json" \) -print > $FILES

function check {
    cat package.json \
        | jq "{} + .$1 | keys" \
        | sed -n 's/.*"\(.*\)".*/\1/p' > $PACKAGES

    echo "--------------------------"
    echo "Checking $1..."
    while read PACKAGE
    do
        RES=$(cat $FILES | xargs -I {} egrep -i "(import|require).*['\"]$PACKAGE[\"']" '{}' | wc -l)
        if [ $RES = 0 ]
        then
            echo -e "UNUSED\t\t $PACKAGE"
        else
            echo -e "USED ($RES)\t $PACKAGE"
        fi
    done < $PACKAGES
}

check "dependencies"
check "devDependencies"
check "peerDependencies"

Primeiro, ele cria dois arquivos temporários onde podemos armazenar em cache nomes e arquivos de pacotes.

Começa com o findcomando A primeira e a segunda linha fazem com que ignore as pastas node_modulese build(ou o que você quiser). A terceira linha contém extensões permitidas, você pode adicionar mais aqui, por exemplo, arquivos JSX ou JSON.

Uma função lerá tipos dependentes.

Primeiro caté o package.json. Em seguida, jqobtém o grupo de dependência necessário. ( {} +existe para que ele não gere um erro se, por exemplo, não houver dependências entre pares no arquivo.)

Depois disso, sedextrai as partes entre as aspas, o nome do pacote. -ne .../pdiz para imprimir as partes correspondentes e nada mais da jqsaída JSON de. Em seguida, lemos esta lista de nomes de pacotes em um whileloop.

RESé o número de ocorrências do nome do pacote entre aspas. Agora é import/ require... 'package'/ "package". Ele faz o trabalho na maioria dos casos.

Então, simplesmente contamos o número de linhas de resultado e depois imprimimos o resultado.

Ressalvas:

  • Não encontrará arquivos em diferentes importações, por exemplo, tsconfig.jsonarquivos ( libopção)
  • Você precisa grepmanualmente apenas ^USEDe UNUSEDarquivos.
  • É lento para grandes projetos - os scripts de shell geralmente não escalam bem. Mas espero que você não esteja executando tantas vezes.
gombosg
fonte
1
Às vezes, os editores fazem com que as importações sejam agrupadas em várias linhas. Esse script capturaria instruções em que 'import' ou 'require' estariam em uma linha diferente da 'de “PACKAGE_NAME”'? Em outras palavras, ele ignora o espaço em branco na importação ou requer instruções?
vdiaz1130 11/03
1

Podemos usar o módulo npm abaixo para esta finalidade:

https://www.npmjs.com/package/npm-check-unused

user11403389
fonte
ele revelou alguns queridos não utilizados, mas aqueles também utilizados, ainda útil eu acho :-) Ele não entende Webpack carregadores ;-)
Ozzie
1

muitas das respostas aqui são como encontrar itens não utilizados.

Eu queria removê-los automaticamente .

  1. Instale este projeto de nó.

    $ npm install -g typescript tslint tslint-etc


  1. No diretório raiz, adicione um novo arquivo tslint-imports.json

    { "extends": [ "tslint-etc" ], "rules": { "no-unused-declaration": true } }


  1. Execute isso por sua conta e risco, faça um backup :)

    $ tslint --config tslint-imports.json --fix --project .

transformador
fonte
Mas isso vai remover apenas dos arquivos js. Mas você ainda é bom.
Ayon Nahiyan
que talnpx depcheck --json | jq '.dependencies[]' | xargs -L1 npm rm
alex