如何轻松验证安装正确的npm依赖项?

时间:2014-04-07 14:44:00

标签: node.js npm

如果有任何未满足的package.json依赖项,我怎么知道何时提示用户运行npm install

我想这样做,因为如果任何require()失败,用户会收到错误的错误消息:

module.js:340
    throw err;
          ^
Error: Cannot find module 'nopt'

我以前曾尝试检查是否存在node_modules目录,但这只适用于新的git克隆。我也尝试过只需要npm并运行npm install作为加载的一部分,但这非常重要。

我希望有一个较轻的重量库,只需解析package.json并确保node_modules内容满足要求。

一个想法是使用process.on('uncaughtException')来捕获模块导入错误,但首先要查看是否存在“标准”解决方案。

6 个答案:

答案 0 :(得分:2)

今天发现了这个。不确定你是否还需要这个。

https://www.npmjs.com/package/check-dependencies

npm install check-dependencies --save-dev

安装此软件包并保存到package.json。

require('check-dependencies')(config, callback);

config是以下对象,然后传递给回调。

{
    status: number,      // 0 if successful, 1 otherwise
    depsWereOk: boolean, // true if dependencies were already satisfied
    log: array,          // array of logged messages
    error: array,        // array of logged errors
}

答案 1 :(得分:0)

不确定是否有npm方式可以做到,但只是觉得这看起来很有帮助:

博文:http://bahmutov.calepin.co/check-dependencies-in-grunt-by-default.html

项目:https://github.com/bahmutov/deps-ok

答案 2 :(得分:0)

如果你使用github,或者至少在github上托管你的project.json,你可以使用:https://david-dm.org/

替换您的用户名和回购。

https://david-dm.org/username/repo.svg

然后你可以看到像https://david-dm.org/bower/bower这样的东西来识别过时的包裹。

答案 3 :(得分:0)

您可以使用yarn并执行yarn check --verify-tree(您可以继续使用npm进行其他操作)

答案 4 :(得分:0)

npm ls从项目文件夹运行时将报告缺少的软件包。

npm-ls documentation

答案 5 :(得分:0)

另一种解决方案

function dependenciesNeedUpdating() {
  const childProcess = require('child_process');
  const result = JSON.parse(childProcess.execSync('npm install --dry-run --json').toString());
  return result.added.length > 0 || result.updated.length > 0 || result.removed > 0;
}

这样称呼

if (dependenciesNeedUpdating()) {
  console.error('dependencies need updating. Please run `npm install`');
  process.exit(1);
}

如果要将此安装为依赖项?它的5行在npm软件包here中。它添加了一个ld-check-dependencies命令(上面的4个用法行),因此您可以直接在npm脚本中使用它。示例:

  "scripts": {
    "build": "ld-check-dependencies && rollup ..."
  },

理论价格:

我了解到依赖是一个巨大的责任,只要有更简单的解决方案就应该避免。

例如,这是check-dependencies

的荒谬依赖树
└─┬ check-dependencies@1.1.0
  ├─┬ bower-config@1.4.3
  │ ├── graceful-fs@4.2.4
  │ ├── minimist@0.2.1 extraneous
  │ ├── mout@1.2.2
  │ ├─┬ osenv@0.1.5
  │ │ ├── os-homedir@1.0.2
  │ │ └── os-tmpdir@1.0.2
  │ ├─┬ untildify@2.1.0
  │ │ └── os-homedir@1.0.2 deduped
  │ └── wordwrap@0.0.3
  ├─┬ chalk@2.4.2
  │ ├─┬ ansi-styles@3.2.1
  │ │ └─┬ color-convert@1.9.3
  │ │   └── color-name@1.1.3
  │ ├── escape-string-regexp@1.0.5
  │ └─┬ supports-color@5.5.0
  │   └── has-flag@3.0.0
  ├─┬ findup-sync@2.0.0
  │ ├── detect-file@1.0.0
  │ ├─┬ is-glob@3.1.0
  │ │ └── is-extglob@2.1.1
  │ ├─┬ micromatch@3.1.10
  │ │ ├── arr-diff@4.0.0
  │ │ ├── array-unique@0.3.2
  │ │ ├─┬ braces@2.3.2
  │ │ │ ├── arr-flatten@1.1.0
  │ │ │ ├── array-unique@0.3.2 deduped
  │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ ├─┬ fill-range@4.0.0
  │ │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ │ ├─┬ is-number@3.0.0
  │ │ │ │ │ └── kind-of@3.2.2 extraneous
  │ │ │ │ ├── repeat-string@1.6.1
  │ │ │ │ └─┬ to-regex-range@2.1.1
  │ │ │ │   ├── is-number@3.0.0 deduped
  │ │ │ │   └── repeat-string@1.6.1 deduped
  │ │ │ ├── isobject@3.0.1
  │ │ │ ├── repeat-element@1.1.3
  │ │ │ ├── snapdragon@0.8.2 deduped
  │ │ │ ├─┬ snapdragon-node@2.1.1
  │ │ │ │ ├── define-property@1.0.0 extraneous
  │ │ │ │ ├── isobject@3.0.1 deduped
  │ │ │ │ └─┬ snapdragon-util@3.0.1
  │ │ │ │   └── kind-of@3.2.2 extraneous
  │ │ │ ├─┬ split-string@3.1.0
  │ │ │ │ └── extend-shallow@3.0.2 deduped
  │ │ │ └── to-regex@3.0.2 deduped
  │ │ ├─┬ define-property@2.0.2
  │ │ │ ├── is-descriptor@1.0.2 extraneous
  │ │ │ └── isobject@3.0.1 deduped
  │ │ ├─┬ extend-shallow@3.0.2
  │ │ │ ├── assign-symbols@1.0.0
  │ │ │ └── is-extendable@1.0.1 extraneous
  │ │ ├─┬ extglob@2.0.4
  │ │ │ ├── array-unique@0.3.2 deduped
  │ │ │ ├── define-property@1.0.0 extraneous
  │ │ │ ├─┬ expand-brackets@2.1.4
  │ │ │ │ ├── debug@2.6.9 deduped
  │ │ │ │ ├── define-property@0.2.5 extraneous
  │ │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ │ ├── posix-character-classes@0.1.1
  │ │ │ │ ├── regex-not@1.0.2 deduped
  │ │ │ │ ├── snapdragon@0.8.2 deduped
  │ │ │ │ └── to-regex@3.0.2 deduped
  │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ ├── fragment-cache@0.2.1 deduped
  │ │ │ ├── regex-not@1.0.2 deduped
  │ │ │ ├── snapdragon@0.8.2 deduped
  │ │ │ └── to-regex@3.0.2 deduped
  │ │ ├─┬ fragment-cache@0.2.1
  │ │ │ └── map-cache@0.2.2
  │ │ ├── kind-of@6.0.3
  │ │ ├─┬ nanomatch@1.2.13
  │ │ │ ├── arr-diff@4.0.0 deduped
  │ │ │ ├── array-unique@0.3.2 deduped
  │ │ │ ├── define-property@2.0.2 deduped
  │ │ │ ├── extend-shallow@3.0.2 deduped
  │ │ │ ├── fragment-cache@0.2.1 deduped
  │ │ │ ├── is-windows@1.0.2
  │ │ │ ├── kind-of@6.0.3 deduped
  │ │ │ ├── object.pick@1.3.0 deduped
  │ │ │ ├── regex-not@1.0.2 deduped
  │ │ │ ├── snapdragon@0.8.2 deduped
  │ │ │ └── to-regex@3.0.2 deduped
  │ │ ├─┬ object.pick@1.3.0
  │ │ │ └── isobject@3.0.1 deduped
  │ │ ├─┬ regex-not@1.0.2
  │ │ │ ├── extend-shallow@3.0.2 deduped
  │ │ │ └─┬ safe-regex@1.1.0
  │ │ │   └── ret@0.1.15
  │ │ ├─┬ snapdragon@0.8.2
  │ │ │ ├─┬ base@0.11.2
  │ │ │ │ ├─┬ cache-base@1.0.1
  │ │ │ │ │ ├─┬ collection-visit@1.0.0
  │ │ │ │ │ │ ├─┬ map-visit@1.0.0
  │ │ │ │ │ │ │ └── object-visit@1.0.1 deduped
  │ │ │ │ │ │ └─┬ object-visit@1.0.1
  │ │ │ │ │ │   └── isobject@3.0.1 deduped
  │ │ │ │ │ ├── component-emitter@1.3.0 deduped
  │ │ │ │ │ ├── get-value@2.0.6
  │ │ │ │ │ ├─┬ has-value@1.0.0
  │ │ │ │ │ │ ├── get-value@2.0.6 deduped
  │ │ │ │ │ │ ├─┬ has-values@1.0.0
  │ │ │ │ │ │ │ ├── is-number@3.0.0 deduped
  │ │ │ │ │ │ │ └── kind-of@4.0.0 extraneous
  │ │ │ │ │ │ └── isobject@3.0.1 deduped
  │ │ │ │ │ ├── isobject@3.0.1 deduped
  │ │ │ │ │ ├─┬ set-value@2.0.1
  │ │ │ │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ │ │ │ ├── is-extendable@0.1.1
  │ │ │ │ │ │ ├─┬ is-plain-object@2.0.4
  │ │ │ │ │ │ │ └── isobject@3.0.1 deduped
  │ │ │ │ │ │ └── split-string@3.1.0 deduped
  │ │ │ │ │ ├─┬ to-object-path@0.3.0
  │ │ │ │ │ │ └── kind-of@3.2.2 extraneous
  │ │ │ │ │ ├─┬ union-value@1.0.1
  │ │ │ │ │ │ ├── arr-union@3.1.0 deduped
  │ │ │ │ │ │ ├── get-value@2.0.6 deduped
  │ │ │ │ │ │ ├── is-extendable@0.1.1 deduped
  │ │ │ │ │ │ └── set-value@2.0.1 deduped
  │ │ │ │ │ └─┬ unset-value@1.0.0
  │ │ │ │ │   ├── has-value@0.3.1 extraneous
  │ │ │ │ │   └── isobject@3.0.1 deduped
  │ │ │ │ ├─┬ class-utils@0.3.6
  │ │ │ │ │ ├── arr-union@3.1.0
  │ │ │ │ │ ├── define-property@0.2.5 extraneous
  │ │ │ │ │ ├── isobject@3.0.1 deduped
  │ │ │ │ │ └─┬ static-extend@0.1.2
  │ │ │ │ │   ├── define-property@0.2.5 extraneous
  │ │ │ │ │   └─┬ object-copy@0.1.0
  │ │ │ │ │     ├── copy-descriptor@0.1.1
  │ │ │ │ │     ├── define-property@0.2.5 extraneous
  │ │ │ │ │     └── kind-of@3.2.2 extraneous
  │ │ │ │ ├── component-emitter@1.3.0
  │ │ │ │ ├── define-property@1.0.0 extraneous
  │ │ │ │ ├── isobject@3.0.1 deduped
  │ │ │ │ ├─┬ mixin-deep@1.3.2
  │ │ │ │ │ ├── for-in@1.0.2
  │ │ │ │ │ └── is-extendable@1.0.1 extraneous
  │ │ │ │ └── pascalcase@0.1.1
  │ │ │ ├─┬ debug@2.6.9
  │ │ │ │ └── ms@2.0.0
  │ │ │ ├── define-property@0.2.5 extraneous
  │ │ │ ├── extend-shallow@2.0.1 extraneous
  │ │ │ ├── map-cache@0.2.2 deduped
  │ │ │ ├── source-map@0.5.7
  │ │ │ ├─┬ source-map-resolve@0.5.3
  │ │ │ │ ├── atob@2.1.2
  │ │ │ │ ├── decode-uri-component@0.2.0
  │ │ │ │ ├── resolve-url@0.2.1
  │ │ │ │ ├── source-map-url@0.4.0
  │ │ │ │ └── urix@0.1.0
  │ │ │ └── use@3.1.1
  │ │ └─┬ to-regex@3.0.2
  │ │   ├── define-property@2.0.2 deduped
  │ │   ├── extend-shallow@3.0.2 deduped
  │ │   ├── regex-not@1.0.2 deduped
  │ │   └── safe-regex@1.1.0 deduped
  │ └─┬ resolve-dir@1.0.1
  │   ├─┬ expand-tilde@2.0.2
  │   │ └─┬ homedir-polyfill@1.0.3
  │   │   └── parse-passwd@1.0.0
  │   └─┬ global-modules@1.0.0
  │     ├─┬ global-prefix@1.0.2
  │     │ ├── expand-tilde@2.0.2 deduped
  │     │ ├── homedir-polyfill@1.0.3 deduped
  │     │ ├── ini@1.3.5
  │     │ ├── is-windows@1.0.2 deduped
  │     │ └─┬ which@1.3.1
  │     │   └── isexe@2.0.0
  │     ├── is-windows@1.0.2 deduped
  │     └── resolve-dir@1.0.1 deduped
  ├── lodash.camelcase@4.3.0
  ├── minimist@1.2.5
  └── semver@5.7.1

788个js文件和48000行代码。

每个依赖项中的每个都是另一个机会,让您被告知某些东西已损坏,不建议使用,存在新漏洞等。基本上,通过使用具有如此多依赖项的东西,当您本来可以花钱的时候,这会增加工作量时间运送,跳舞,和孩子一起玩,等等。您以为使用依赖项可以节省时间,但是如果它具有太多的依赖项,那么与较低或简单的无依赖项选项相比,您就不会节省时间,因为您将永远处理这些依赖项的问题。

这是deps-ok的依赖树,这更加合理。

└─┬ deps-ok@1.4.1
  ├── check-more-types@2.24.0
  ├─┬ debug@3.1.0
  │ └── ms@2.0.0
  ├── lazy-ass@1.6.0
  ├── lodash@4.17.10
  ├── minimist@1.2.0
  ├─┬ q@2.0.3
  │ ├── asap@2.0.6
  │ ├── pop-iterate@1.0.1
  │ └── weak-map@1.0.5
  ├── quote@0.4.0
  └── semver@5.5.0

但是它仍然设法证明依赖关系的问题

❯ npm audit
                                                                                
                       === npm audit security report ===                        
                                                                                
┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.11                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ deps-ok                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ deps-ok > lodash                                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/782                             │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.12                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ deps-ok                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ deps-ok > lodash                                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1065                            │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.19                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ deps-ok                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ deps-ok > lodash                                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1523                            │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimist                                                     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=0.2.1 <1.0.0 || >=1.2.3                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ deps-ok                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ deps-ok > minimist                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1179                            │
└───────────────┴──────────────────────────────────────────────────────────────┘
found 4 vulnerabilities (2 low, 2 high) in 13 scanned packages
  4 vulnerabilities require manual review. See the full report for details.

现在当然,您可能并不在意这些漏洞,因为此脚本仅在构建过程中使用,但是现在您遇到了一个新问题,即任何真正的漏洞都将被埋没在您不关心的漏洞中。

我不知道上面的解决方案有多么健壮或全面。好处是,它依赖于npm,所以无论npm install要做什么,它都在做准确的事情。