409

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

例如,当尝试一个包并随后评论或删除代码,但忘记卸载它时,我最终得到了几个可以删除的包。

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

4

11 回答 11

534

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

  1. 安装模块:

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

     depcheck
    

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

要在不安装的情况下运行,请使用npx

npx depcheck 
于 2014-12-08T16:24:27.480 回答
175

还有一个包叫做npm-check

npm-检查

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

在此处输入图像描述

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

于 2014-12-14T06:53:01.143 回答
19

检查未使用的依赖项

npm install depcheck -g
depcheck

在此处输入图像描述

检查过时的库

npm outdated

在此处输入图像描述

于 2021-01-08T06:44:37.597 回答
7

菲斯克本写道:

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

depcheck如果由于某种原因无法正常工作,让我们让 Fiskeben 的答案自动化!(例如,我使用 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_modulesandbuild文件夹(或任何你想要的)。第三行包含允许的扩展名,您可以在此处添加更多,例如 JSX 或 JSON 文件。

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

首先它catpackage.json. 然后,jq获取所需的依赖组。({} +是否存在这样如果文件中没有对等依赖项,它就不会抛出错误。)

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

RES是引号中包名称的出现次数。现在是import/ require... 'package'/ "package"。它适用于大多数情况。

然后我们简单地计算结果行的数量然后打印结果。

注意事项:

  • 不会在不同的导入中找到文件,例如tsconfig.json文件(lib选项)
  • 您必须grep手动 for only^USEDUNUSEDfiles。
  • 对于大型项目来说速度很慢 - shell 脚本通常不能很好地扩展。但希望你不会运行这么多次。
于 2018-09-17T15:25:33.637 回答
7

gombosg的脚本比 npm-check 好得多。
我稍微修改了一下,所以 node_modules 中的 devdependencies 也会被发现。
示例sass从未使用过,但需要sass-loader

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

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

# use fd
# https://github.com/sharkdp/fd

function check {
    cat package.json \
        | jq "{} + .$1 | keys" \
        | sed -n 's/.*"\(.*\)".*/\1/p' > $PACKAGES
    echo "--------------------------"
    echo "Checking $1..."
    fd '(js|ts|json)$' -t f > $FILES
    while read PACKAGE
    do
        if [ -d "node_modules/${PACKAGE}" ]; then
            fd  -t f '(js|ts|json)$' node_modules/${PACKAGE} >> $FILES
        fi
        RES=$(cat $FILES | xargs -I {} egrep -i "(import|require|loader|plugins|${PACKAGE}).*['\"](${PACKAGE}|.?\d+)[\"']" '{}' | 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"

原始脚本的结果:

--------------------------
Checking dependencies...
UNUSED           jquery
--------------------------
Checking devDependencies...
UNUSED           @types/jquery
UNUSED           @types/jqueryui
USED (1)         autoprefixer
USED (1)         awesome-typescript-loader
USED (1)         cache-loader
USED (1)         css-loader
USED (1)         d3
USED (1)         mini-css-extract-plugin
USED (1)         postcss-loader
UNUSED           sass
USED (1)         sass-loader
USED (1)         terser-webpack-plugin
UNUSED           typescript
UNUSED           webpack
UNUSED           webpack-cli
USED (1)         webpack-fix-style-only-entries

和修改:

Checking dependencies...
USED (5)         jquery
--------------------------
Checking devDependencies...
UNUSED           @types/jquery
UNUSED           @types/jqueryui
USED (1)         autoprefixer
USED (1)         awesome-typescript-loader
USED (1)         cache-loader
USED (1)         css-loader
USED (2)         d3
USED (1)         mini-css-extract-plugin
USED (1)         postcss-loader
USED (3)         sass
USED (1)         sass-loader
USED (1)         terser-webpack-plugin
USED (16)        typescript
USED (16)        webpack
USED (2)         webpack-cli
USED (2)         webpack-fix-style-only-entries
于 2020-10-27T21:21:41.090 回答
6

如果您使用的是像 OS(Linux、OSX 等)这样的 Unix,那么您可以使用find和的组合egrep来搜索包含您的包名称的 require 语句:

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 存储库中...

于 2014-03-27T09:08:46.650 回答
4

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

我想自动删除它们

选项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 .

选项 2:根据@Alex

npx depcheck --json | jq '.dependencies[]' | xargs -L1 npm rm
于 2020-04-18T22:32:20.887 回答
1

在 Yarn 2.x 及更高版本中,使用:

yarn dlx depcheck

yarn dlx 旨在执行可能已作为全局包与 yarn 1.x 一起安装的一次性脚本。管理系统范围的包超出了纱线的范围。为了反映这一点,yarn global 已被删除。

来源:https ://yarnpkg.com/getting-started/migration#use-yarn-dlx-instead-of-yarn-global

于 2021-10-12T10:16:20.933 回答
1

为此,我们可以使用以下 npm 模块:

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

于 2019-04-24T06:07:49.190 回答
0

除非我对gombosgnMo的脚本有误解。这是一个更快的nMo脚本扩展版本,默认为“查找”,但可以轻松修改为使用“fd”进行查找功能。

变化在于它首先查找所有相关文件,然后一次从所有相关文件中 grep 包,而不是逐个文件库。

并发可以控制,默认为8。

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

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

export NUMCONCURRENT=8

function findCmd {
  startPath=${1:-.}
  find "$startPath" \
    -path ./node_modules -prune -or \
    -path ./build -prune -or \
    \( -name "*.ts" -or -name "*.js" -or -name "*.json" \) -print
}

# use fd
# https://github.com/sharkdp/fd
function findCmd_fd {
  startPath=${1:-.}
  fd  -t f '(js|ts|json)$' "$startPath"
}



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

    findCmd > "$FILES"
    while read PACKAGE
    do
        #echo "node_modules/${PACKAGE}"
        if [ -d "node_modules/${PACKAGE}" ]; then
                findCmd node_modules/${PACKAGE} >> $FILES
        fi
    done < $PACKAGES
    export FILES
    export SQ="'"
    xargs -P ${NUMCONCURRENT:-1} -r -a  "$PACKAGES" -I[] bash -c '
        PACKAGE="[]"

        RES=$(cat "$FILES" | xargs -r egrep -i "(import|require|loader|plugins|${PACKAGE}).*[\"${SQ}](${PACKAGE}|.?\d+)[\"${SQ}]" | wc -l)

        if [ $RES = 0 ]
        then
            echo -e "UNUSED\t\t $PACKAGE"
        else
            echo -e "USED ($RES)\t $PACKAGE"
        fi
    '
    [ -f  "$PACKAGES" ] && rm "$PACKAGES"
    [ -f  "$FILES" ] && rm "$FILES"
}

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

于 2021-10-25T12:40:19.800 回答
-2

如果你想选择站在哪个巨人的肩膀上

这是一个生成 npm 可用选项的简短列表的链接;它过滤关键字unused packages

https://www.npmjs.com/search?q=unused%20packages

为什么我的答案只是一个链接?

通常我不会只提供一个链接。这个问题值得一个时间敏感度较低的答案。该解决方案依赖于最新的软件。推荐一个可能已经停止维护的特定软件(这里有一些建议的情况)几乎没有用。帮助人们找到最新的东西似乎是合适的。

于 2020-11-24T18:12:14.217 回答