Как установить дополнительные файлы bin, когда `npm install` имеет флаг `-g`?

#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 процессу.