How to easily verify correct npm dependencies installed?

无人久伴 提交于 2020-08-15 05:49:00

问题


How can I know when to prompt user to run npm install if there are any unmet package.json dependencies?

I would like to do this, because if any require() fails, the user gets a poor error message:

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

I've previously tried to just check for the existence of a node_modules directory, but this only works effectively for fresh git clones. I've also tried just requiring npm and running npm install as part of load, but that is very heavy weight.

I'm hoping there is a lighter weight library out there that just parses package.json and makes sure node_modules contents satisfy the requirements.

One idea was to use process.on('uncaughtException') to catch only module import errors, but looking to see if there is a "standard" solution first.


回答1:


Found this today. Not sure if your still need this.

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

npm install check-dependencies --save-dev

Install this package and save to your package.json.

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

config is the following object, which is then passed to the callback.

{
    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
}



回答2:


You can use yarn and do yarn check --verify-tree (you can continue using npm for everything else)




回答3:


If you use github, or at least host your project.json on github, you can use: https://david-dm.org/

replace your username and repo.

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

Then you can see something like https://david-dm.org/bower/bower to identify the out of date packages.




回答4:


Not sure there is npm way to do it, but just found this seems helpful:

blog post: http://bahmutov.calepin.co/check-dependencies-in-grunt-by-default.html

project: https://github.com/bahmutov/deps-ok




回答5:


npm ls will report missing packages when run from the project folder.

npm-ls documentation

This might have issues if you're using git dependencies, though. (Thanks @gman).




回答6:


Another solution

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;
}

Call it like this

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

If you want to install this as a dependency 🤣 its 5 lines are in an npm package here. It adds a ld-check-dependencies command (the 4 usage lines above) so you can use it directly in your npm scripts. Example:

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

Rationale:

I'm learning that dependencies are a huge liability and should be avoided any time there is a simpler solution.

For example here's is the ridiculous dependency tree for 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 files and 48000 lines of code.

Everyone one of those dependencies is another chance for you to be told something is broke, deprecated, there's a new vulnerability, etc. Basically by using something with so many dependencies you're adding to your workload when you could instead be spending time shipping, dancing, playing with your kids, whatever. You thought you were saving time by using a dependency but if it's got so many dependencies than you're not saving time if you compare to a lower or simple no dependency option because you will be forever dealing with the issues of those dependencies.

Here's the dependency tree for deps-ok which is much more reasonable.

└─┬ 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

But it still manages to demonstrate the problem with dependencies

❯ 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.

Now of course maybe you don't care about those vulnerabilities because this script is only used during building but now you have a new problem that any real vulnerabilities will be buried in these ones you don't care about.

I have no idea how robust or comprehensive the solution above is. The good thing is it relies on npm so whatever npm install is going to do it's doing that exact thing.



来源:https://stackoverflow.com/questions/22915698/how-to-easily-verify-correct-npm-dependencies-installed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!