Программирование

Как запускать локальные npm пакеты: Полное руководство

Узнайте несколько способов запуска npm-пакетов из node_modules без глобальной установки. Используйте npx, npm-скрипты или shell-функции для согласованности в командной работе.

Как использовать исполняемые файлы из пакета, установленного локально в node_modules?

Я пытаюсь разобраться, как использовать локальную версию модуля в Node.js. Например, после установки coffee-script с помощью:

npm install coffee-script

Пакет устанавливается в ./node_modules, а команда coffee находится по пути ./node_modules/.bin/coffee. Как мне запустить эту команду из основной директории проекта? Я ищу что-то похожее на то, как работает bundle exec в Ruby bundler. Главное, чего я хочу добиться — это чтобы все члены команды использовали одну и ту же версию coffee-script для этого проекта.

Я знаю, что я мог бы использовать флаг -g для установки coffee глобально и сделать его доступным во всей системе, но это не то, что я хочу здесь. Мне нужно решение, которое позволит разным проектам использовать разные версии coffee. Как настроить это с помощью пакетов Node.js?

Чтобы использовать исполняемые файлы из локально установленных npm-пакетов в вашем проекте, есть несколько современных подходов, которые гарантируют, что все члены вашей команды будут использовать одну и ту же версию. Честно говоря, самые эффективные методы включают использование npx, создание npm-скриптов и настройку shell-функций, имитирующих поведение Ruby’s bundle exec. Эти подходы действительно изменили то, как я работаю над проектами Node.js за эти годы.

Содержание


Использование npx для локальных исполняемых файлов

Команда npx, которая поставляется с npm по умолчанию начиная с версии 5.2, — это, откровенно говоря, самый современный и рекомендуемый подход для запуска локально установленных исполняемых файлов пакетов. Когда вы запускаете npx coffee, npx сначала проверит, существует ли coffee в вашем локальном каталоге node_modules/.bin, прежде чем искать глобально.

bash
# Запуск локально установленного исполняемого файла coffee
npx coffee

# Или указание конкретной версии, если необходимо
npx coffee@latest

Согласно Mozilla Developer Network, npx автоматически добавляет ./node_modules/.bin в PATH при выполнении команд, гарантируя, что локально установленные бинарные файлы имеют приоритет над глобально установленными. Это именно то, что вам нужно для обеспечения согласованности версий в вашей команде.

В официальной документации npm объясняется, что npx “локально установленные бинарные файлы всегда присутствуют в выполняемом процессе PATH”, что делает его идеальным инструментом для вашего случая использования. Я обнаружил, что это настоящая революция для командной работы.


Создание npm-скриптов

Еще один отличный подход — создание скриптов в вашем файле package.json. npm автоматически добавляет node_modules/.bin в PATH при запуске скриптов, поэтому вы можете ссылаться на исполняемые файлы по их именам напрямую.

json
{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "build": "coffee -c source/*.coffee",
    "start": "coffee server.coffee",
    "test": "mocha tests/**/*.js"
  },
  "dependencies": {
    "coffee-script": "^2.0.0"
  },
  "devDependencies": {
    "mocha": "^8.0.0"
  }
}

Затем вы можете запустить:

bash
npm run build
npm start
npm test

Как объясняется в Better Stack Community, “npm-скрипты автоматически получают доступ к бинарным файлам из ваших локально установленных пакетов без необходимости указывать полный путь”. Этот подход особенно полезен для сложных рабочих процессов и обеспечивает согласованное использование команд в вашей команде. Лично я использую этот метод почти во всех своих проектах сейчас.


Shell-функции для поведения, похожего на bundle exec

Если вы хотите создать команду, которая точно имитирует Ruby’s bundle exec, вы можете настроить shell-функции. Вот как это сделать в разных shell:

Функция Bash

bash
# Добавьте это в ваш ~/.bashrc или ~/.bash_profile
function npm-exec() {
  local cmd="$1"
  shift
  "$(npm bin)/$cmd" "$@"
}

Функция ZSH

zsh
# Добавьте это в ваш ~/.zshrc
function npm-exec() {
  local cmd="$1"
  shift
  "$(npm bin)/$cmd" "$@"
}

Windows CMD

cmd
@echo off
for /f %%i in ('npm bin') do set NPM_BIN_PATH=%%i
%NPM_BIN_PATH%\%*

Windows PowerShell

powershell
function npm-exec {
    param($cmd, $args)
    & "$(npm bin)/$cmd" @args
}

Теперь вы можете запустить:

bash
npm-exec coffee script.coffee
npm-exec mocha tests/

Как объясняется в Los Techies, этот подход “позволяет мне запускать любой произвольный бинарный файл пакета, который я хочу”, и его даже можно поместить в /usr/local/bin для доступности во всех проектах Node. На самом деле, именно так я настраиваю свою среду разработки, когда работаю над несколькими проектами.


Модификация пути с помощью npm bin

Вы также можете временно изменить ваш PATH, чтобы включить локальный каталог bin. Команда npm bin возвращает путь к ближайшему каталогу node_modules/.bin.

Однократное выполнение команды

bash
# Для bash/zsh
PATH=$(npm bin):$PATH coffee script.coffee

# Для bash/zsh с функцией (как предлагается в [2ality](https://2ality.com/2016/01/locally-installed-npm-executables.html))
function npm-do {
  (PATH=$(npm bin):$PATH; eval "$@";)
}

# Использование
npm-do "coffee script.coffee && eslint ."

Для Windows Command Prompt

cmd
for /f %%i in ('npm bin') do set NPM_BIN_PATH=%%i
%NPM_BIN_PATH%\coffee script.coffee

Этот подход полезен, когда вам нужно запустить несколько команд и вы хотите, чтобы все они использовали одни и те же локальные бинарные файлы. Я обнаружил, что он особенно удобен для разовых задач, где я не хочу настраивать полный скрипт.


Лучшие практики и рекомендации

  1. Используйте npx для разовых команд: Для запуска отдельных команд, которые не являются частью вашего регулярного рабочего процесса, npx является самым простым и надежным вариантом. Честно говоря, это то, к чему я обращаюсь в первую очередь, когда мне просто нужно запустить инструмент один раз.

  2. Используйте npm-скрипты для рабочих процессов проекта: Создавайте скрипты в package.json для команд, которые вы запускаете регулярно. Это обеспечивает согласованность и делает ваш процесс сборки воспроизводимым. Это стало моим основным подходом для большинства проектов.

  3. Создавайте shell-функции для поведения, похожего на bundle exec: Если вам конкретно нужен эквивалент bundle exec, настройте shell-функции, которые используют npm bin для поиска локальных исполняемых файлов. Это особенно полезно, если вы пришли из Ruby.

  4. Блокируйте версии с помощью package-lock.json: Всегда добавляйте package-lock.json в ваш репозиторий, чтобы гарантировать, что все устанавливают точно такие же версии зависимостей. В моем опыте это недопустимо для командных проектов.

  5. Рассмотрите Yarn, если вам нужен больший контроль: Хотя npx npm теперь довольно мощный, Yarn предлагает некоторые дополнительные функции для управления локальными исполняемыми файлами и исторически был более надежным для сложных сценариев зависимостей. Я использовал оба варианта, и у каждого есть свои сильные стороны.

Официальная документация npm о скриптах подчеркивает, что “если вы зависите от модулей, которые определяют исполняемые скрипты, такие как тестовые наборы, то эти исполняемые файлы будут добавлены в PATH для выполнения скриптов”. Это автоматическое управление PATH — почему npm-скрипты так мощны.

Для вашего примера с coffee-script вот что я бы рекомендовал:

json
{
  "scripts": {
    "coffee": "coffee"
  }
}

Затем ваша команда может просто запустить npm run coffee script.coffee, чтобы использовать локально установленную версию. Это обеспечивает ту же согласованность версий, которую вы ищете с bundle exec. Это небольшое изменение, которое имеет большое значение для командной работы.


Заключение

  • npx — это современное решение для запуска локально установленных исполняемых файлов пакетов и должно быть вашим первым выбором для разовых команд
  • npm-скрипты обеспечивают наиболее надежную интеграцию рабочего процесса, автоматически добавляя node_modules/.bin в PATH
  • Shell-функции могут точно имитировать поведение bundle exec, если вам нужен командный эквивалент
  • Всегда используйте package-lock.json для обеспечения согласованности версий в вашей команде
  • Для регулярных рабочих процессов рекомендуется использовать npm-скрипты, так как они являются наиболее переносимым и поддерживаемым решением

Ключевое понимание заключается в том, что npm предоставляет несколько способов достижения того, что делает bundle exec в Ruby, при этом npx является наиболее прямым эквивалентом. Используя эти подходы, вы можете гарантировать, что каждый разработчик в вашей команде использует точно такую же версию установленных исполняемых файлов пакетов без глобальных системных установок. Честно говоря, как только вы привыкнете к этим паттернам, вы будете удивляться, как когда-либо работали без них.

Источники

  1. How to use executables from a package installed locally in node_modules? - Stack Overflow
  2. How to Use Executables from NPM Package - Better Stack Community
  3. Executing A Project-Specific Node/NPM Package A-la “bundle exec” - Los Techies
  4. Running locally installed npm executables - 2ality
  5. Use npx to run locally installed node modules - egghead.io
  6. npm vs npx: Key Differences and When to Use Each - Medium
  7. 5 Tips for better NPM script organization - DEV Community
  8. Executing Local NPM Packages: A Simple Guide - CodeForGeek
  9. npx | npm Docs
  10. scripts | npm Docs
Авторы
Проверено модерацией
Модерация