在package.json中找到未使用的npm软件包


231

有没有办法确定您的package.json文件中是否有不再需要的软件包?

例如,当试用一个程序包,后来注释或删除代码但忘记卸载它时,我最终得到了几个可以删除的程序包。

确定包是否可以安全删除的有效方法是什么?

Answers:


258

您可以使用称为depcheck的npm模块(至少需要Node版本10)。

  1. 安装模块:

    npm install depcheck -g
    
    or
    
    yarn global add depcheck
    
  2. 运行它并找到未使用的依赖项:

    depcheck

这种方法的好处是您不必记住findor grep命令。

要运行而不安装,请使用npx:

npx depcheck

11
depcheck-es6现在已合并为depcheck
cyberwombat

47
看起来没有用。我正在使用标准的angular2 cli设置,并depcheck列出了每个软件包unused都是错误的
phil294

5
注意 depcheck不考虑在package.json中指定的脚本中使用的软件包
Javier Arias

17
要运行一次(不进行安装),请使用npxnpx depcheck
Kiril

6
没为我工作。它列出了所有未使用的软件包。
dev27

131

还有一个名为的软件包npm-check

npm检查

检查过时,不正确和未使用的依赖项。

在此处输入图片说明

它功能强大且积极开发。它的功能之一是检查未使用的依赖关系-对于这一部分,它使用depcheck另一个答案中提到的模块。


8
似乎给我的结果与depcheck相同。看起来它甚至使用depcheck来查找未使用的依赖项。
亚历克斯K

3
npm outdated检查并列出当前,需要和最新的软件包版本。没有未使用的软件包列表。
mgarde '18 -10-25

1
看起来也没有用。我使用的是标准角度设置,它还会列出每个未使用的包裹,这同样是错误的
Kyle Burkett

5

如果您使用的是类Unix操作系统(Linux操作系统,OSX等),那么你可以使用的组合findegrep搜索需要您的包名的语句:

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

如果搜索整个require('name-of-package')语句,请记住使用正确的引号类型:

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

要么

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

缺点是它不是全自动的,即不会从中提取软件包名称package.json并进行检查。您需要自己为每个程序包执行此操作。由于package.json只是JSON,因此可以通过编写一个小的脚本child_process.exec针对每个依赖项运行此命令来解决。并使其成为一个模块。并将其添加到NPM存储库中...


.jsx文件和.ts文件等呢:D
OZZIE

1
显然,使用这种方法时,我们并未在React应用中使用react模块:D
OZZIE,

4

fiskeben写道:

缺点是它不是全自动的,即它不会从package.json中提取包名称并进行检查。您需要自己为每个程序包执行此操作。

如果由于某种原因depcheck无法正常工作,让我们让菲斯克本的答案自动化!(例如,我用Typescript尝试过,它给出了不必要的解析错误)

为了进行解析,package.json我们可以使用该软件jq。下面的Shell脚本需要一个目录名称(从此处开始)。

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

首先,它创建两个临时文件,我们可以在其中缓存程序包名称和文件。

它从find命令开始。第一和第二行使其忽略node_modulesbuild文件夹(或任何您想要的文件)。第三行包含允许的扩展名,您可以在此处添加更多扩展名,例如JSX或JSON文件。

一个函数将读取依赖类型。

首先catpackage.json。然后,jq获取所需的依赖项组。({} +在那里,如果文件中没有对等项依赖关系,它将不会引发错误。)

之后,sed提取引号之间的部分,即软件包名称。-n.../p告诉它打印匹配的部分,而不会jq输出JSON输出中的其他内容。然后,我们将此软件包名称列表读入while循环。

RES是用引号引起的包名称的出现次数。现在是import/ require... 'package'/ "package"。在大多数情况下,它都能胜任。

然后,我们只计算结果行的数量,然后打印结果。

注意事项:

  • 找不到其他导入中的文件,例如tsconfig.json文件(lib选项)
  • 您只需要grep手动输入^USEDUNUSED文件。
  • 对于大型项目而言,这很慢-Shell脚本通常无法很好地扩展。但是希望您不会运行很多次。

1
编辑器有时会导致导入包装成多行。此脚本会捕获“导入”或“需要”与“来自“ PACKAGE_NAME””的行不同的语句吗?换句话说,它会忽略导入中的空白还是需要语句?
vdiaz1130


1

这里的许多答案是如何找到未使用的物品。

我想自动删除它们

  1. 安装此节点项目。

    $ npm install -g typescript tslint tslint-etc


  1. 在根目录下,添加一个新文件tslint-imports.json

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


  1. 运行此程序需您自担风险,进行备份:)

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


但这只会从js文件中删除。但是你仍然很好。
Ayon Nahiyan

怎么样npx depcheck --json | jq '.dependencies[]' | xargs -L1 npm rm
亚历克斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.