#node.js #npm #npm-install
#node.js #нпм #npm-установка
Вопрос:
Есть ли какой-нибудь способ установить только часть проекта NodeJS при запуске через npm install
, но установить дополнительные функции при npm install -g
использовании?
У меня есть библиотека с интерфейсом командной строки, однако CLI бесполезен для любых последующих проектов, использующих мою библиотеку. Поэтому, когда эти проекты подключаются к моей библиотеке, я не хочу, чтобы они отключали зависимости, подобные chalk
этим, используются только для CLI, к которому они никогда не будут прикасаться.
Однако, если конечный пользователь решит установить мою библиотеку глобально в своей системе npm install -g
, я хочу, чтобы CLI был установлен и через bin
раздел in package.json
помещен в их path, чтобы они могли запускать его как любую другую программу.
Я не могу понять, как это сделать, не разделяя CLI на отдельный пакет. Варианты, которые я исследовал, следующие:
- Поместите зависимости CLI в виде
devDependencies
. Это предотвращаетchalk
установку etc. в последующих проектах, но недостатком здесь является то, что пользователь долженnpm install -g
находиться в режиме разработки, что означает, что он также получает установленную платформу тестирования и инструменты компоновки, даже если они никогда не будут их использовать. - Поместите CLI как отдельный пакет / модуль NodeJS. Недостатком здесь является то, что это затрудняет тестирование (так как часто CLI и библиотека изменяются одновременно и используются для тестирования новых функций), и разработчикам, желающим внести свой вклад в библиотеку, придется разбираться со связыванием двух пакетов, поэтому, хотя это будет работать, это не идеально с точки зренияперспектива рабочего процесса.
- Поместите CLI в папку внутри основного пакета и создайте
package.json
там другой только для CLI, подключив основной проект черезnpm install ..
. Это работает до тех пор, пока вы не дойдете до точки установки, когда вы поймете, что нет способа установить CLI после публикации пакета.npm install @my/library
будет устанавливаться только изpackage.json
корня проекта, невозможно сказать «о, также установите пакет вcli
подкаталог».
В идеале я хотел бы, чтобы это:
npm install @my/library
— запускается разработчиком, желающим использовать библиотеку в своем проекте. Добавляет библиотеку только к зависимостям своего проекта, игнорирует как CLI, так и любые зависимости, необходимые CLI.npm install -g @my/library
— запускается конечным пользователем, устанавливает библиотеку и CLI глобально в своей системе, включая зависимости CLI, и добавляет CLI к пути пользователя черезpackage.json
bin
раздел.npm install --dev
— используется разработчиком, вносящим вклад в библиотеку, для установки тестовой платформы, чтобы они могли запускать модульные тесты перед отправкой своего кода для включения.- Нет необходимости разделять CLI на отдельный проект.
Возможно ли это?
Ответ №1:
Есть ли какой-нибудь способ установить только часть проекта NodeJS при запуске через
npm install
, но установить дополнительные функции приnpm install -g
использовании?
Вы можете написать postinstall
сценарий, который использует is-globally-installed
(или другой аналогичный пакет) для проверки, установлен ли модуль глобально, а затем запустить все, что подходит для установки CLI (возможно npm install -g
, для отдельного пакета, который имеет только CLI).
Комментарии:
1. Это отличная идея, но как мне передать
npm
параметры? Например, если исходный вызывающий написалnpm install -g --prefix /my/install/folder
, есть ли простой способ обеспечить передачу этих дополнительных параметров дочернемуnpm
процессу? Я знаюmake
, что в программе есть специальная$(MAKE)
переменная, которая расширяется до команды со всеми установленными дополнительными параметрами, но я не вижу, имеет лиnpm
она эквивалент. Я предполагаю, что он нужен, потому что, когда я попытался запуститьcd cli amp;amp; npm install -g
post-install
скрипт, он завис.
Ответ №2:
Ну, я придумал обходной путь.
Я вернул CLI только для разработки (с учетом его требований, devDependencies
чтобы его могли использовать локальные разработчики, но они не будут подключаться к проектам, использующим библиотеку). Затем я создал еще один пакет для CLI, но все, что это был package.json
файл и ничего больше.
То, что делает этот пакет, зависит от основной библиотеки, плюс только зависимости, необходимые CLI. Затем он использует bin
раздел, чтобы указать на CLI внутри основной библиотеки, поэтому в этом пакете код не требуется — это буквально один файл. Вот так:
{
"name": "@my/library-cli", // new module to install the CLI
"bin": {
"myprog": "./node_modules/@my/library/bin/myprog.js" // the command is inside the dependency
},
"dependencies": {
"@my/library": "*", // require the library itself where the CLI code sits
"command-line-args": "*" // dependency needed by the CLI
}
}
Единственным недостатком этого является то, что этот новый пакет dependencies
необходимо синхронизировать с основной библиотекой devDependencies
(по крайней мере, с dep, требуемыми CLI), но поскольку в моем случае они не будут часто меняться, я могу с этим смириться.
Я попробовал перехват после установки, как предложил @Trott, но, похоже, это не сработало:
"scripts": {
"postinstall": "[ $npm_config_global == 'true' ] amp;amp; (cd cli amp;amp; npm install -g)"
}
По какой-то причине это было невероятно медленно и, казалось, застревало в цикле, пытаясь и не устанавливая снова и снова. Я также не уверен, что он бы уважал запуск с помощью команды, например npm install -g --prefix /my/install/folder
, поскольку этот нестандартный префикс может не передаваться дочернему npm
процессу.