Запустить сценарий (например, postinstall) после установки одного пакета npm?
Начинаю играть со Snowpack. Он отличается от Webpack подходом, объединяя отдельные пакеты сразу после их установки.
"Проблема" в том, что когда я устанавливаю пакет, мне нужно сначала запустить npm install --save my-package
а затем мне нужно вручную упаковать его npx snowpack
. В документации Snowpack упоминается, что я могу включитьprepare
сценарий, который бы snowpack
все после бега npm install
но это не относится к отдельным пакетам, только к общему npm install
всех зависимостей в моем package.json
. Насколько я могу судить, это относится ко всем хукам npm, упомянутым в документации npm.
Есть ли способ автоматически запускать скрипт при установке отдельного пакета? Единственный способ, который я могу придумать, - это перезаписать установочный скрипт и что-нибудь добавить к нему. Есть ли примеры этого на GitHub или где-то еще?
Обновление: для пояснения я бы хотел запуститьnpx snowpack
каждый раз, когда я устанавливаю новый пакет с --save
но желательно не с --save-dev
или без --save
. Это никогда не будет отличаться для любого пакета. Это будет специфично для определенного репо / проекта, а не глобально в моей системе.
Недостаточно бежать snowpack
после простого запуска npm install
как если бы вы подключились к postinstall
или release
. Кроме того, я хочу убедиться, что разработчики, работающие над моим проектом, могут использоватьnpm install --save newdep
как обычно, а затем snowpack
будет работать. Я не хочу требовать от разработчиков использования специального именованного скрипта.
3 ответа
В более новых версиях Snowpack (>=2) вы можете запускать snowpack dev
и он будет следить за твоим npm_modules
папка для сборки новых модулей.
Краткий ответ: к сожалению, npm не предоставляет никаких встроенных функций, отвечающих вашим требованиям.
Хуки / сценарии жизненного цикла, такие как postinstall
вызываются только при запуске универсального npm install
команда, а не когда кто-то бежит npm install --save <pkg_name>
на этапе разработки проектов.
Обходной путь: рассмотрите возможность настройки логики npm install --save
составная команда, по существу переопределив npm
команда на уровне оболочки.
Следующее решение, хотя и предназначенное для Bash, описывает, как эту настраиваемую логику можно реализовать для конкретного проекта (ов). Однако это решение зависит от следующих условий:
- Разработчики, работающие над вашим проектом, должны иметь оболочку, установленную на Bash при запуске
npm install --save
составная команда. - Разработчикам, работающим над вашим проектом, необходимо будет настроить свои файлы запуска Bash, а именно:
~/.bashrc
и возможно~/.bash_profile
. - Каталог проекта, то есть каталог проекта, для которого вы хотите, чтобы настраиваемая логика действовала, должен содержать настраиваемую
.bashrc
файл.
Решение Bash:
Следующие три шага необходимы для настройки вашего проекта и операционных систем, чтобы при запуске разработчика npm install --save <pkg_name>
(или его вариации) npx snowpack
затем вызывается команда.
Примечание. Второй и третий пункты (ниже) - это задачи, которые разработчики должны выполнить (один раз) для настройки своих файлов запуска Bash.
Конкретный проект
.bashrc
файл:Сначала создайте следующий "специфичный для проекта"
.bashrc
файл в корне каталога вашего проекта, т.е. сохраните его на том же уровне, что и ваши проекты.package.json
файл находится:/some/path/to/my-project/.bashrc
npm() { local name_badge="\x1b[37;40mpostinstall\x1b[0m" array_includes() { local word=$1 shift for el in "$@"; do [[ "$el" == "$word" ]] && return 0; done } log_warn_message() { local cmd_name=$1 warn_badge warn_mssg warn_badge="\x1b[30;43mWARN!\x1b[0m" warn_mssg="${cmd_name} command not found. Cannot run npx snowpack." echo -e "\n${name_badge} ${warn_badge} ${warn_mssg}" >&2 } log_run_message() { echo -e "\n${name_badge} Running pseudo postinstall hook." } if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then # 1. Run the given `npm install --save ...` command. command npm "$@" # 2. Check whether the `npx` command exists globally. command -v npx >/dev/null 2>&1 || { log_warn_message npx return 1 } log_run_message # 3. Run the pseudo "postinstall" command. command npx snowpack else # Run all other `npm` commands as per normal. command npm "$@" fi }
Примечание. Чтобы лучше понять, что делает этот файл, обратитесь к разделу "Пояснение" ниже.
В
~/.bashrc
файл:Чтобы сделать собственную логику, т.е.
npm
функции в вышеупомянутом.bashrc
файла, необходимо настроить Bash для чтения вышеупомянутого "специфичного для проекта".bashrc
файл. Чтобы настроить это, добавьте следующую строку кода в~/.bashrc
:PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'
Примечание. Чтобы лучше понять, что делает эта строка кода, обратитесь к разделу "Объяснение" ниже.
В
~/.bash_profile
файл:Обычно ваш
~/.bash_profile
содержит следующую строку кода для загрузки~/.bashrc
файл (или его вариант):if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
Если этого нет, его необходимо добавить в
~/.bash_profile
.
Дополнительная информация.
Помощники по установке / настройке:
Подумайте, что ваши разработчики используют следующие две команды для помощи в настройке своих файлов запуска Bash в соответствии с вышеупомянутыми шагами два и три.
Для шага два выполните следующую команду:
echo $'\n'"PROMPT_COMMAND='if [[ \"\$bashrc\" != \"\$PWD\" && \"\$PWD\" != \"\$HOME\" && -e .bashrc ]]; then bashrc=\"\$PWD\"; . .bashrc; fi'" >> ~/.bashrc
Это добавит
PROMPT_COMMAND=...
строка кода к существующей~/.bashrc
файл или создайте новый, если он еще не существует:На третьем шаге выполните следующую команду, чтобы добавить строку кода, необходимую в
~/.bash_profile
для загрузки~/.bashrc
файл:echo $'\n'"if [ -f ~/.bashrc ]; then . ~/.bashrc; fi" >> ~/.bash_profile
Моя оболочка настроена на Bash?
Чтобы проверить, настроена ли оболочка для Bash, вы можете создать новый сеанс, т.е. создать новое окно терминала и запустить:
echo $0
Если он печатает -bash
тогда он использует Bash.
Как мне настроить свою оболочку на Bash?
Если echo $0
не печатает -bash
тогда вам нужно будет сменить оболочку. Чтобы изменить его на Bash, запустите:
chsh -s /bin/bash
Примечание. Чтобы это изменение вступило в силу, вам потребуется создать новый сеанс.
Объяснение
Конкретный проект
.bashrc
файл:Этот
.bashrc
файл содержит функцию оболочки с именемnpm
. Тело этой функции содержит логику, необходимую для отмены значения по умолчанию.npm install|i --save
команда.Условия, указанные в
if
заявление, т. е. часть, которая читает;if [[ $* == "install "* || $* == "i "* ]] && array_includes --save "$@"; then ... fi
по существу читает
$*
специальный параметр, чтобы проверить, переданы ли аргументы вnpm
функция начинается с любого;install
, или его сокращенный эквивалентi
, и будет ли--save
параметр / аргумент также был передан.Чтобы проверить наличие
--save
аргумент мы передаем$@
специальный параметр дляarray_includes
функция. Мы обрабатываем этот аргумент по-другому, потому что положение--save
опция может отличаться в составной команде. Например, пользователь может установить пакет, запустив его;# Example showing `--save` option at the end npm install <pkg_name> --save
или это (или какой-то другой вариант):
# Example showing `--save` option in the middle npm i --save <pkg_name>
Когда условия, указанные в
if
утверждения выполнены, т.е. ониtrue
, в его теле мы выполняем следующие задачи:Запустите данный
npm install --save ...
команду как есть через строку, которая гласит:command npm "$@"
Проверить, есть ли
npx
команда существует глобально через часть, которая гласит:command -v npx >/dev/null 2>&1 || { log_warn_message npx return 1 }
Если
npx
недоступна (глобально), мы предупреждаем пользователя, чтоnpx snowpack
команда не может быть запущена, иreturn
из функции раньше со статусом выхода1
.Примечание. Моя логика в этой проверке предполагает, что вы будете устанавливать
npx
глобально. Однако, если вы устанавливаетеnpm
локально в вашем проекте вам нужно будет изменить эту логику. Возможно, проверив, действительно ли./node_modules/.bin/npx
вместо этого существует. Или вы можете быть уверены, чтоnpx
команда всегда существует, поэтому сделайте вывод, что в этой проверке нет необходимости.Если
npx
команда существует глобально, затем мы запускаем псевдо-команду "postinstall", т.е.command npx snowpack
Когда условия, указанные в
if
утверждения НЕ выполняются, т.е. ониfalse
, пользователь, по сути, выполняет любую другую команду npm, которая неnpm install --save <pkg_name>
. Поэтому вelse
ветке запускаем команду как есть:command npm "$@"
Файл ~/.bashrc:
В разделе 5.2 Переменные Bash о "Bash Reference Manual"
PROMPT_COMMAND
переменная описывается следующим образом:PROMPT_COMMAND
Если установлено, значение интерпретируется как команда, выполняемая перед печатью каждого основного приглашения (
$PS1
).Итак, эта строка кода (вот она снова):
PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'
загружает "специфичный для проекта"
.bashrc
(если он существует), который, в свою очередь, отменяетnpm
команда сnpm
функция. По сути, это то, что обеспечивает механизм отменыnpm install --save
составная команда для конкретного проекта (ов).Смотрите этот ответ на
@Cyrus
для дальнейшего объяснения.
Я думаю, что лучше всего будет создать новый скрипт, выполняющий желаемое действие. Что-то вроде следующих строк в вашем package.json:
{
"scripts": {
"snowpack-install" : "npm install --save && npx snowpack"
}
}
Исправление
Фактически вы можете использовать опцию postinstall в package.json. Постинсталляция будет запущена "ПОСЛЕ установки пакета". Это будет выглядеть примерно так:
{
"scripts": {
"postinstall" : "npx snowpack"
}
}