Как я могу узнать, когда предлагать пользователю запустить npm install, если есть какие-либо неудовлетворенные зависимости package.json?

Я хотел бы сделать это, потому что, если какой-либо require() выйдет из строя, пользователь получит плохое сообщение об ошибке:

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

Ранее я пытался просто проверить наличие каталога node_modules, но это эффективно работает только для новых клонов git. Я также пробовал просто требовать npm и бегать npm install как часть нагрузки, но это очень большой вес.

Я надеюсь, что существует более легкая библиотека, которая просто анализирует package.json и проверяет, удовлетворяет ли содержимое node_modules требованиям.

Одна из идей заключалась в том, чтобы использовать process.on('uncaughtException') только для обнаружения ошибок импорта модуля, но сначала посмотреть, есть ли "стандартное" решение.

14
mmocny 7 Апр 2014 в 18:44
Перебрать node_modules, проанализировать version в их package.json и сравнить со своим собственным package.json?
 – 
jgillich
7 Апр 2014 в 18:59
Нет эффективного способа сделать это, npm install заботится обо всех зависимостях модулей, я не понимаю, как он должен выдавать ошибку при загрузке модулей в ваш пакет npm. Есть необязательные зависимости, если это то, что вы ищете.
 – 
Gntem
7 Апр 2014 в 20:34
Мой пример использования: я получаю отчеты об ошибках от пользователей, которые запускают мой скрипт, забыв обновить node_modules. Я доставляю пакет через npm, который обрабатывает это автоматически, но эти отчеты поступают от пользователей, использующих git clone для тестирования невыпущенных версий. Таким образом, любое решение, требующее инструментов за пределами самого скрипта узла, не будет работать (то есть без ворчания). Однако, возможно, я мог бы создать пакет узла, как предлагает @jbillich, возможно, используя скрипт grunt в качестве отправной точки. Хотя надеялся, что это уже существует.
 – 
mmocny
8 Апр 2014 в 20:16
Я тоже хотел бы это увидеть.
 – 
Seth
18 Дек 2014 в 17:50

6 ответов

Лучший ответ

Нашел это сегодня. Не уверен, что вам это еще нужно.

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
}
8
Arun Sivasankaran 15 Янв 2015 в 05:13

Если вы используете github или, по крайней мере, размещаете свой project.json на github, вы можете использовать: https: // david-dm. org /

Замените свое имя пользователя и репо.

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

Затем вы можете увидеть что-то вроде https://david-dm.org/bower/bower, чтобы идентифицировать устаревшие пакеты.

1
crh225 3 Авг 2016 в 21:37

Вы можете использовать yarn и делать yarn check --verify-tree (вы можете продолжать использовать npm для всего остального)

10
kuceb 20 Май 2019 в 17:36

npm ls сообщит об отсутствии пакетов при запуске из папки проекта.

документация npm-ls

Однако это может вызвать проблемы, если вы используете зависимости git. (Спасибо @gman).

3
Dylan 14 Июл 2020 в 17:58
На самом деле это не удается. type git clone somerepo; cd somerepo; npm install; rm -rf node_modules/somedep; npm ls не замечает, что dep отсутствует. Даже просто git clone somerepo; cd somerepo; npm ls ничего не сообщает об отсутствии
 – 
gman
13 Июл 2020 в 07:57
Ни один из них не подходит для меня. Можете ли вы предоставить репо, которое вы использовали, там, где оно не удалось? я использую npm 6.14.4
 – 
Dylan
14 Июл 2020 в 14:47
1
Похоже, что это не работает с зависимостями на основе git. npm install --save git+https://github.com/someperson/somerepo.git#v1.2.3 теперь удалите node_modules/somerepo, и npm ls не заметит, что он исчез, но npm install будет
 – 
gman
14 Июл 2020 в 16:40

Другое решение

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 здесь < / а>. Он добавляет команду 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 ни собирался делать, он делает именно это.

1
gman 15 Июл 2020 в 04:59
1
Хорошее решение. Обратной стороной является то, что npm install требует времени для запуска. deps-ok работает очень быстро, и вы можете перехватить его перед любым скриптом без заметных задержек.
 – 
pmoleri
18 Фев 2021 в 00:14

Не уверен, что есть способ сделать это npm, но нашел, что это кажется полезным:

Сообщение в блоге: http://bahmutov.calepin.co/check- dependencies-in-grunt-by-default.html

Проект: https://github.com/bahmutov/deps-ok

0
dolzenko 14 Янв 2015 в 19:53
3
Пожалуйста, постарайтесь не публиковать ответы только по ссылке, так как связанный контент может быть удален в любое время.
 – 
David Pärsson
16 Апр 2015 в 18:20
Не уверен, что мне делать? скопировать описание проекта? В оригинальном плакате именно такая библиотека запрашивается.
 – 
dolzenko
17 Апр 2015 в 12:35
2
Читая ваш ответ, мне непонятно, решает ли проект проблему. Я предполагаю, что это говорится в содержании первой ссылки, но эта ссылка кажется мертвой.
 – 
David Pärsson
17 Апр 2015 в 17:18
Стоит упомянуть archive.org, которые пытаются сделать резервную копию в Интернете, и вы можете искать исторические версии мертвых ссылки на их Wayback Machine.
 – 
James McGuigan
15 Июл 2020 в 12:55
Черт возьми, эта ссылка на самом деле не работает: bahmutov.calepin.co /check-dependencies-in-grunt-by-default.html хотя я не согласен с копированием большого количества контента из ссылок, дайте автору блога трафик
 – 
Devin Rhode
26 Фев 2021 в 00:28