Как я могу узнать, когда предлагать пользователю запустить 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')
только для обнаружения ошибок импорта модуля, но сначала посмотреть, есть ли "стандартное" решение.
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
}
Если вы используете github или, по крайней мере, размещаете свой project.json на github, вы можете использовать: https: // david-dm. org /
Замените свое имя пользователя и репо.
https://david-dm.org/username/repo.svg
Затем вы можете увидеть что-то вроде https://david-dm.org/bower/bower, чтобы идентифицировать устаревшие пакеты.
Вы можете использовать yarn
и делать yarn check --verify-tree
(вы можете продолжать использовать npm
для всего остального)
npm ls
сообщит об отсутствии пакетов при запуске из папки проекта.
Однако это может вызвать проблемы, если вы используете зависимости git. (Спасибо @gman).
git clone somerepo; cd somerepo; npm install; rm -rf node_modules/somedep; npm ls
не замечает, что dep отсутствует. Даже просто git clone somerepo; cd somerepo; npm ls
ничего не сообщает об отсутствии
npm install --save git+https://github.com/someperson/somerepo.git#v1.2.3
теперь удалите node_modules/somerepo
, и npm ls
не заметит, что он исчез, но npm install
будет
Другое решение
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
ни собирался делать, он делает именно это.
npm install
требует времени для запуска. deps-ok
работает очень быстро, и вы можете перехватить его перед любым скриптом без заметных задержек.
Не уверен, что есть способ сделать это npm, но нашел, что это кажется полезным:
Сообщение в блоге: http://bahmutov.calepin.co/check- dependencies-in-grunt-by-default.html
Проект: https://github.com/bahmutov/deps-ok
Похожие вопросы
Связанные вопросы
Новые вопросы
node.js
Node.js — это основанная на событиях, неблокирующая, асинхронная среда выполнения ввода-вывода, использующая движок Google V8 JavaScript и библиотеку libuv. Он используется для разработки приложений, которые интенсивно используют возможность запуска JavaScript как на стороне клиента, так и на стороне сервера и, следовательно, выигрывают от возможности повторного использования кода и отсутствия переключения контекста.
node_modules
, проанализироватьversion
в ихpackage.json
и сравнить со своим собственнымpackage.json
?npm install
заботится обо всех зависимостях модулей, я не понимаю, как он должен выдавать ошибку при загрузке модулей в ваш пакет npm. Есть необязательные зависимости, если это то, что вы ищете.npm
, который обрабатывает это автоматически, но эти отчеты поступают от пользователей, использующихgit clone
для тестирования невыпущенных версий. Таким образом, любое решение, требующее инструментов за пределами самого скрипта узла, не будет работать (то есть без ворчания). Однако, возможно, я мог бы создать пакет узла, как предлагает @jbillich, возможно, используя скрипт grunt в качестве отправной точки. Хотя надеялся, что это уже существует.