Encuentre paquetes npm no utilizados en package.json

231

¿Hay alguna manera de determinar si tiene paquetes en su archivo package.json que ya no son necesarios?

Por ejemplo, al probar un paquete y luego comentar o eliminar código, pero olvidando desinstalarlo, termino con un par de paquetes que podrían eliminarse.

¿Cuál sería una manera eficiente de determinar si un paquete podría eliminarse de manera segura?

Josh C
fuente

Respuestas:

259

Puede usar un módulo npm llamado depcheck (requiere al menos la versión 10 de Node).

  1. Instale el módulo:

    npm install depcheck -g
    
    or
    
    yarn global add depcheck
  2. Ejecútelo y encuentre las dependencias no utilizadas:

    depcheck

Lo bueno de este enfoque es que no tiene que recordar el comando findo grep.

Para ejecutar sin instalar, use npx:

npx depcheck
Attanasio alemán
fuente
11
depcheck-es6 ahora se fusionó con depcheck
cyberwombat
47
no parece útil Estoy usando la configuración estándar angular2 cli y enumero depcheckcada paquete como unusedincorrecto
phil294
55
NÓTESE BIEN. depcheck no tiene en cuenta los paquetes utilizados en los scripts especificados en package.json
Javier Arias el
17
Para ejecutarlo solo una vez (sin instalación) - use npx :npx depcheck
Kiril
66
No funciono para mi. Enumeró todos los paquetes como no utilizados.
dev27
131

También hay un paquete llamado npm-check:

npm-check

Verifique las dependencias desactualizadas, incorrectas y no utilizadas.

ingrese la descripción de la imagen aquí

Es bastante poderoso y desarrollado activamente. Una de sus características es la comprobación de dependencias no utilizadas: para esta parte, utiliza el depcheckmódulo mencionado en la otra respuesta.

alecxe
fuente
8
Parece darme los mismos resultados que depcheck. Parece que incluso usa depcheck para encontrar las dependencias no utilizadas.
Alex K
3
npm outdatedcomprueba y enumera las versiones actuales, deseadas y más recientes del paquete. Sin embargo, no hay una lista de paquetes no utilizados.
mgarde
1
No parece útil también. Estoy usando la configuración angular estándar y esto también enumera todos los paquetes como no utilizados, lo que es igual de incorrecto
Kyle Burkett
5

Si está utilizando un Unix como SO (Linux, OSX, etc.), entonces puede usar una combinación de findy egreppara buscar declaraciones de requerimiento que contengan el nombre de su paquete:

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

Si busca la require('name-of-package')declaración completa , recuerde utilizar el tipo correcto de comillas:

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

o

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

La desventaja es que no es completamente automático, es decir, no extrae los nombres de los paquetes package.jsonni los verifica. Necesita hacer esto para cada paquete usted mismo. Dado que package.jsones solo JSON, esto podría remediarse escribiendo un pequeño script que use child_process.execpara ejecutar este comando para cada dependencia. Y que sea un módulo. Y agréguelo al repositorio de NPM ...

fiskeben
fuente
¿Qué pasa con los .jsxarchivos y .tsarchivos, etc .: D
OZZIE
1
Aparentemente, utilizando este enfoque, no estamos utilizando el módulo de reacción en nuestra aplicación React: D
OZZIE
4

fiskeben escribió:

La desventaja es que no es completamente automático, es decir, no extrae los nombres de paquetes de package.json y los verifica. Debe hacer esto para cada paquete usted mismo.

¡Hagamos que la respuesta de Fiskeben sea automática si por alguna razón depcheckno funciona correctamente! (Por ejemplo, lo probé con Typecript y me dio errores de análisis innecesarios)

Para analizar package.jsonpodemos usar el software jq. El siguiente script de shell requiere un nombre de directorio donde comenzar.

#!/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"

Primero crea dos archivos temporales donde podemos almacenar en caché los nombres de los paquetes y los archivos.

Comienza con el findcomando. La primera y segunda línea hacen que ignore las carpetas node_modulesy build(o lo que quiera). La tercera línea contiene extensiones permitidas, puede agregar más aquí, por ejemplo, archivos JSX o JSON.

Una función leerá tipos dependientes.

Primero cates el package.json. Luego, jqobtiene el grupo de dependencia requerido. ( {} +está ahí para que no arroje un error si, por ejemplo, no hay dependencias de pares en el archivo).

Después de eso, sedextrae las partes entre las comillas, el nombre del paquete. -ny .../ple dice que imprima las partes coincidentes y nada más de jqla salida JSON de. Luego leemos esta lista de nombres de paquetes en un whilebucle.

RESes el número de apariciones del nombre del paquete entre comillas. En este momento es import/ require... 'package'/ "package". Hace el trabajo para la mayoría de los casos.

Luego simplemente contamos el número de líneas de resultado y luego imprimimos el resultado.

Advertencias:

  • No encontrará archivos en diferentes importaciones, por ejemplo, tsconfig.jsonarchivos ( libopción)
  • Usted tiene que grepmanualmente por sólo ^USEDy UNUSEDarchivos.
  • Es lento para proyectos grandes: los scripts de shell a menudo no se escalan bien. Pero espero que no corras tantas veces.
gombosg
fuente
1
Los editores a veces hacen que las importaciones se agrupen en varias líneas. ¿Esta secuencia de comandos capturará las declaraciones donde 'import' o 'require' estarían en una línea diferente que 'from “PACKAGE_NAME”'? En otras palabras, ¿ignora los espacios en blanco en la importación o requiere declaraciones?
vdiaz1130
1

Podemos usar el siguiente módulo npm para este propósito:

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

usuario11403389
fuente
reveló algunos no usados ​​pero también usados, todavía útiles, supongo :-) No entiende los cargadores de paquetes web ;-)
OZZIE
1

Muchas de las respuestas aquí son cómo encontrar elementos no utilizados.

Quería eliminarlos automáticamente .

  1. Instale este proyecto de nodo.

    $ npm install -g typescript tslint tslint-etc


  1. En el directorio raíz, agregue un nuevo archivo tslint-imports.json

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


  1. Ejecute esto bajo su propio riesgo, haga una copia de seguridad :)

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

transformador
fuente
Pero esto solo se eliminará de los archivos js. Pero ya estás bien.
Ayon Nahiyan
¿qué talnpx depcheck --json | jq '.dependencies[]' | xargs -L1 npm rm
alex