Запустить сценарий (например, 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.

  1. Конкретный проект .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
    }
    

    Примечание. Чтобы лучше понять, что делает этот файл, обратитесь к разделу "Пояснение" ниже.

  2. В ~/.bashrc файл:

    Чтобы сделать собственную логику, т.е. npm функции в вышеупомянутом .bashrcфайла, необходимо настроить Bash для чтения вышеупомянутого "специфичного для проекта" .bashrcфайл. Чтобы настроить это, добавьте следующую строку кода в~/.bashrc:

    PROMPT_COMMAND='if [[ "$bashrc" != "$PWD" && "$PWD" != "$HOME" && -e .bashrc ]]; then bashrc="$PWD"; . .bashrc; fi'
    

    Примечание. Чтобы лучше понять, что делает эта строка кода, обратитесь к разделу "Объяснение" ниже.

  3. В ~/.bash_profile файл:

    Обычно ваш ~/.bash_profile содержит следующую строку кода для загрузки ~/.bashrc файл (или его вариант):

    if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
    

    Если этого нет, его необходимо добавить в ~/.bash_profile.


Дополнительная информация.

Помощники по установке / настройке:

Подумайте, что ваши разработчики используют следующие две команды для помощи в настройке своих файлов запуска Bash в соответствии с вышеупомянутыми шагами два и три.

  1. Для шага два выполните следующую команду:

    echo $'\n'"PROMPT_COMMAND='if [[ \"\$bashrc\" != \"\$PWD\" && \"\$PWD\" != \"\$HOME\" && -e .bashrc ]]; then bashrc=\"\$PWD\"; . .bashrc; fi'" >> ~/.bashrc
    

    Это добавит PROMPT_COMMAND=... строка кода к существующей ~/.bashrc файл или создайте новый, если он еще не существует:

  2. На третьем шаге выполните следующую команду, чтобы добавить строку кода, необходимую в ~/.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

Примечание. Чтобы это изменение вступило в силу, вам потребуется создать новый сеанс.


Объяснение

  1. Конкретный проект .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, в его теле мы выполняем следующие задачи:

      1. Запустите данный npm install --save ... команду как есть через строку, которая гласит:

        command npm "$@"
        
      2. Проверить, есть ли 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 команда всегда существует, поэтому сделайте вывод, что в этой проверке нет необходимости.

      3. Если npx команда существует глобально, затем мы запускаем псевдо-команду "postinstall", т.е.

        command npx snowpack
        
    • Когда условия, указанные в if утверждения НЕ выполняются, т.е. они false, пользователь, по сути, выполняет любую другую команду npm, которая не npm install --save <pkg_name>. Поэтому вelse ветке запускаем команду как есть:

      command npm "$@"
      
  2. Файл ~/.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"
  }
}
Другие вопросы по тегам