Как запускать локальные 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 для локальных исполняемых файлов
- Создание npm-скриптов
- Shell-функции для поведения, похожего на bundle exec
- Модификация пути с помощью npm bin
- Лучшие практики и рекомендации
Использование npx для локальных исполняемых файлов
Команда npx, которая поставляется с npm по умолчанию начиная с версии 5.2, — это, откровенно говоря, самый современный и рекомендуемый подход для запуска локально установленных исполняемых файлов пакетов. Когда вы запускаете npx coffee, npx сначала проверит, существует ли coffee в вашем локальном каталоге node_modules/.bin, прежде чем искать глобально.
# Запуск локально установленного исполняемого файла 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 при запуске скриптов, поэтому вы можете ссылаться на исполняемые файлы по их именам напрямую.
{
"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"
}
}
Затем вы можете запустить:
npm run build
npm start
npm test
Как объясняется в Better Stack Community, “npm-скрипты автоматически получают доступ к бинарным файлам из ваших локально установленных пакетов без необходимости указывать полный путь”. Этот подход особенно полезен для сложных рабочих процессов и обеспечивает согласованное использование команд в вашей команде. Лично я использую этот метод почти во всех своих проектах сейчас.
Shell-функции для поведения, похожего на bundle exec
Если вы хотите создать команду, которая точно имитирует Ruby’s bundle exec, вы можете настроить shell-функции. Вот как это сделать в разных shell:
Функция Bash
# Добавьте это в ваш ~/.bashrc или ~/.bash_profile
function npm-exec() {
local cmd="$1"
shift
"$(npm bin)/$cmd" "$@"
}
Функция ZSH
# Добавьте это в ваш ~/.zshrc
function npm-exec() {
local cmd="$1"
shift
"$(npm bin)/$cmd" "$@"
}
Windows CMD
@echo off
for /f %%i in ('npm bin') do set NPM_BIN_PATH=%%i
%NPM_BIN_PATH%\%*
Windows PowerShell
function npm-exec {
param($cmd, $args)
& "$(npm bin)/$cmd" @args
}
Теперь вы можете запустить:
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/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
for /f %%i in ('npm bin') do set NPM_BIN_PATH=%%i
%NPM_BIN_PATH%\coffee script.coffee
Этот подход полезен, когда вам нужно запустить несколько команд и вы хотите, чтобы все они использовали одни и те же локальные бинарные файлы. Я обнаружил, что он особенно удобен для разовых задач, где я не хочу настраивать полный скрипт.
Лучшие практики и рекомендации
-
Используйте npx для разовых команд: Для запуска отдельных команд, которые не являются частью вашего регулярного рабочего процесса,
npxявляется самым простым и надежным вариантом. Честно говоря, это то, к чему я обращаюсь в первую очередь, когда мне просто нужно запустить инструмент один раз. -
Используйте npm-скрипты для рабочих процессов проекта: Создавайте скрипты в
package.jsonдля команд, которые вы запускаете регулярно. Это обеспечивает согласованность и делает ваш процесс сборки воспроизводимым. Это стало моим основным подходом для большинства проектов. -
Создавайте shell-функции для поведения, похожего на bundle exec: Если вам конкретно нужен эквивалент
bundle exec, настройте shell-функции, которые используютnpm binдля поиска локальных исполняемых файлов. Это особенно полезно, если вы пришли из Ruby. -
Блокируйте версии с помощью package-lock.json: Всегда добавляйте
package-lock.jsonв ваш репозиторий, чтобы гарантировать, что все устанавливают точно такие же версии зависимостей. В моем опыте это недопустимо для командных проектов. -
Рассмотрите Yarn, если вам нужен больший контроль: Хотя npx npm теперь довольно мощный, Yarn предлагает некоторые дополнительные функции для управления локальными исполняемыми файлами и исторически был более надежным для сложных сценариев зависимостей. Я использовал оба варианта, и у каждого есть свои сильные стороны.
Официальная документация npm о скриптах подчеркивает, что “если вы зависите от модулей, которые определяют исполняемые скрипты, такие как тестовые наборы, то эти исполняемые файлы будут добавлены в PATH для выполнения скриптов”. Это автоматическое управление PATH — почему npm-скрипты так мощны.
Для вашего примера с coffee-script вот что я бы рекомендовал:
{
"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 является наиболее прямым эквивалентом. Используя эти подходы, вы можете гарантировать, что каждый разработчик в вашей команде использует точно такую же версию установленных исполняемых файлов пакетов без глобальных системных установок. Честно говоря, как только вы привыкнете к этим паттернам, вы будете удивляться, как когда-либо работали без них.
Источники
- How to use executables from a package installed locally in node_modules? - Stack Overflow
- How to Use Executables from NPM Package - Better Stack Community
- Executing A Project-Specific Node/NPM Package A-la “bundle exec” - Los Techies
- Running locally installed npm executables - 2ality
- Use npx to run locally installed node modules - egghead.io
- npm vs npx: Key Differences and When to Use Each - Medium
- 5 Tips for better NPM script organization - DEV Community
- Executing Local NPM Packages: A Simple Guide - CodeForGeek
- npx | npm Docs
- scripts | npm Docs