Znajdź nieużywane pakiety npm w package.json

231

Czy istnieje sposób, aby ustalić, czy w pliku package.json znajdują się pakiety, które nie są już potrzebne?

Na przykład podczas wypróbowywania pakietu, a następnie komentowania lub usuwania kodu, ale zapominając o jego odinstalowaniu, otrzymuję kilka pakietów, które można usunąć.

Jaki byłby skuteczny sposób ustalenia, czy pakiet można bezpiecznie usunąć?

Josh C.
źródło

Odpowiedzi:

258

Możesz użyć modułu npm o nazwie depcheck (wymaga co najmniej wersji 10 Węzła).

  1. Zainstaluj moduł:

    npm install depcheck -g
    
    or
    
    yarn global add depcheck
  2. Uruchom go i znajdź nieużywane zależności:

    depcheck

Zaletą tego podejścia jest to, że nie musisz pamiętać polecenia findlub grep.

Aby uruchomić bez instalacji użyj npx:

npx depcheck
Niemiecki Attanasio
źródło
11
depcheck-ES6 jest teraz połączone w depcheck
cyberwombat
47
nie wygląda na przydatne. Używam standardowej konfiguracji angular2 cli i depcheckwyświetla każdą paczkę, unusedktóra jest po prostu zła
phil294
5
NB depcheck nie bierze pod uwagę pakietów używanych w skryptach określonych w package.json
Javier Arias,
17
Aby uruchomić go tylko raz (bez instalacji) - użyj npx :npx depcheck
Kiril
6
Nie działało dla mnie. Wymienił wszystkie pakiety jako nieużywane.
dev27
131

Istnieje również pakiet o nazwie npm-check:

sprawdź npm

Sprawdź, czy istnieją nieaktualne, niepoprawne i nieużywane zależności.

wprowadź opis zdjęcia tutaj

Jest dość potężny i aktywnie rozwijany. Jedną z jego funkcji jest sprawdzanie nieużywanych zależności - w tej części wykorzystuje depcheckmoduł wymieniony w drugiej odpowiedzi.

alecxe
źródło
8
Wydaje mi się, że daje takie same wyniki jak usuwanie. Wygląda na to, że nawet używa Depcheck, aby znaleźć nieużywane zależności.
Alex K
3
npm outdatedsprawdza i wyświetla aktualne, poszukiwane i najnowsze wersje pakietów. Brak listy nieużywanych pakietów.
mgarde
1
też nie wygląda na użyteczny. Korzystam ze standardowej konfiguracji kątowej, co powoduje również, że każda paczka jest nieużywana, co jest równie złe
Kyle Burkett
5

Jeśli używasz systemu operacyjnego typu Unix (Linux, OSX itp.), Możesz użyć kombinacji findi, egrepaby wyszukać instrukcje wymagane zawierające nazwę pakietu:

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

Jeśli szukasz całej require('name-of-package')instrukcji, pamiętaj, aby używać poprawnego rodzaju znaków cudzysłowu:

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

lub

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

Minusem jest to, że nie jest w pełni automatyczny, tzn. Nie wyodrębnia nazw pakietów package.jsoni nie sprawdza ich. Musisz to zrobić sam dla każdego pakietu. Ponieważ package.jsonjest to po prostu JSON, można temu zaradzić, pisząc mały skrypt, który używa child_process.execdo uruchomienia tego polecenia dla każdej zależności. I uczyń z niego moduł. I dodaj go do repozytorium NPM ...

fiskeben
źródło
Co z .jsxplikami i .tsplikami itp .: D
OZZIE
1
Najwyraźniej przy takim podejściu nie używamy modułu reagowania w naszej aplikacji React: D
OZZIE
4

fiskeben napisał:

Minusem jest to, że nie jest w pełni automatyczny, tzn. Nie wyodrębnia nazw pakietów z package.json i nie sprawdza ich. Musisz to zrobić sam dla każdego pakietu.

Zróbmy automatyczną odpowiedź Fiskeben, jeśli z jakiegokolwiek powodu depchecknie działa poprawnie! (Np. Próbowałem z Typescript i dało to niepotrzebne błędy analizy)

Do parsowania package.jsonmożemy użyć oprogramowania jq. Poniższy skrypt powłoki wymaga nazwy katalogu, od którego ma się zacząć.

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

Najpierw tworzy dwa pliki tymczasowe, w których możemy buforować nazwy pakietów i pliki.

Zaczyna się od findpolecenia. Pierwszy i drugi wiersz powodują, że ignoruje foldery node_modulesi build(lub cokolwiek chcesz). Trzeci wiersz zawiera dozwolone rozszerzenia, możesz dodać tutaj więcej, np. Pliki JSX lub JSON.

Funkcja odczytuje typy zależne.

Najpierw cats package.json. Następnie jqpobiera wymaganą grupę zależności. ( {} +czy istnieje, aby nie zgłaszał błędu, jeśli np. w pliku nie ma zależności równorzędnych).

Następnie sedwyodrębnia części między cudzysłowami, nazwę pakietu. -ni .../pkaże mu wydrukować pasujące części i nic więcej z jqwyjścia JSON. Następnie czytamy listę nazw pakietów w whilepętli.

RESto liczba wystąpień nazwy pakietu w cudzysłowie. W tej chwili jest to import/ require... 'package'/ "package". W większości przypadków spełnia swoje zadanie.

Następnie po prostu zliczamy liczbę linii wyniku, a następnie drukujemy wynik.

Ostrzeżenia:

  • Nie znajdzie plików w różnych importach, np. tsconfig.jsonPlikach (lib opcja)
  • Musisz grepręcznie tylko dla plików ^USEDi UNUSEDplików.
  • Jest duży w przypadku dużych projektów - skrypty powłoki często nie skalują się dobrze. Ale miejmy nadzieję, że nie uruchomisz tego wiele razy.
gombosg
źródło
1
Redaktorzy czasami powodują zawijanie importu do wielu wierszy. Czy ten skrypt przechwytywałby instrukcje, w których „import” lub „wymagają” byłyby w innym wierszu niż „z” PACKAGE_NAME ”? Innymi słowy, czy ignoruje białe znaki w imporcie, czy wymaga instrukcji?
vdiaz1130
1

wiele odpowiedzi tutaj to jak znaleźć nieużywane przedmioty.

Chciałem je usunąć automatycznie .

  1. Zainstaluj ten projekt węzła.

    $ npm install -g typescript tslint tslint-etc


  1. W katalogu głównym dodaj nowy plik tslint-imports.json

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


  1. Uruchom to na własne ryzyko, wykonaj kopię zapasową :)

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

transformator
źródło
Ale to usunie tylko z plików js. Ale nadal jesteś dobry.
Ayon Nahiyan
co powiesz nanpx depcheck --json | jq '.dependencies[]' | xargs -L1 npm rm
alex