Основные отличия npx от npm
Npm (Node Package Manager) — это менеджер пакетов, который загружает и хранит библиотеки в локальной или глобальной директории проекта. Каждый установленный пакет оседает в папке node_modules и занимает место на диске, даже если используется редко.
Npx (Node Package Executor), напротив, фокусируется на динамической загрузке и выполнении пакетов. Вместо постоянного хранения он загружает их временно, выполняет необходимые действия и немедленно удаляет. Сама утилита устанавливается вместе с npm начиная с версии 5.2.0.
# Установка и запуск create-react-app
npm install -g create-react-app
create-react-app my-project
# Создание проекта без глобальной установки
npx create-react-app my-project
В первом случае npm требует глобальной установки всего пакета create-react-app, который будет занимать место на диске независимо от частоты использования. Во втором npx загружает только необходимую версию create-react-app, выполняет команду и удаляет временные файлы. Механизм работы npx:
- Локальный поиск: инструмент проверяет наличие пакета в локальных node_modules текущего проекта.
- Кеширование: при отсутствии локальной версии npx обращается к глобальному кешу npm.
- Загрузка: если пакет не найден, происходит скачивание последней версии.
- Выполнение: пакет запускается с переданными параметрами.
- Очистка: временные файлы удаляются после завершения работы.
Технически npx работает поверх npm, используя его инфраструктуру и добавляя слой абстракции для более гибкого управления пакетами.
Почему появился npx и каковы его преимущества
История появления npx тесно связана с эволюцией экосистемы JavaScript и потребностью разработчиков в более гибких инструментах. До его появления программисты были вынуждены либо устанавливать глобально все нужные инструменты либо прописывать длинные пути к локальным бинарным файлам в node_modules. Он решает несколько критических проблем современной веб-разработки:
- минимизация дискового пространства. Вместо хранения множества редко используемых файлов загружает только необходимую для конкретной задачи версию инструмента;
- изоляция окружения. Он не засоряет глобальное пространство установленными пакетами, что уменьшает риск конфликтов версий;
- гарантированное использование актуальной версии. При каждом запуске он скачивает последнюю версию пакета, что автоматически защищает от устаревших версий;
- быстрый одноразовый запуск скриптов;
- упрощение настройки рабочего окружения;
- отсутствие необходимости управлять глобальными зависимостями.
# Мгновенный запуск линтера без установки
npx eslint myfile.js
# Генерация документации
npx documentation build src/** -f html -o docs
# Использование случайных утилит
npx cowsay "Hello, JavaScript!"
# Выполнение пакета напрямую из GitHub
npx github:username/some-utility
Каждый из этих сценариев раньше требовал предварительной установки пакета, теперь же обеспечено мгновенное выполнение. Загруженные файлы попадают в кеш, что позволяет не скачивать их каждый раз заново, если они уже были загружены ранее. Также npx поддерживает выполнение пакетов напрямую с GitHub или других платформ. В совокупности все это позволяет быстро тестировать нужные библиотеки, экспериментировать и сосредоточиться только на выполнении задачи.
Отличия npx от npm exec
Инструмент npm exec был введен в npm с версии 7.0.0 и представляет собой более универсальный способ выполнения команд, связанных с уже установленными пакетами, прямо из командной строки, аналогично npx.
Перед выполнением команды npm exec может предварительно разрешить или установить зависимости, если это необходимо. Также он может, в отличие от npx, использовать двойной дефис для разделения опций npm и параметров, передаваемых самой исполняемой команде, что позволяет удобнее работать с аргументами. Таким образом, для работы с уже установленными в проекте пакетами подходит именно npm exec, хотя npx все еще может быть для этого применен.
То есть npm exec выполняет те же функции, что и npx, по части использования уже установленных пакетов, но при этом глубже интегрируется с npm-экосистемой. Основная цель npm exec — это запуск исполнимых файлов или скриптов, определенных в локальных или глобальных пакетах, в том числе через их конкретные версии. Npm exec работает больше в контексте уже настроенной экосистемы npm, где команды могут быть определены в package.json через npm-скрипты. В свою очередь, npx позволяет запускать команды, даже если они не прописаны в package.json, но доступны через глобальные установки или в node_modules.
Когда использовать npx:
- для одноразового запуска команд, которые требуют пакетов, не установленных в проекте (например, запуск create-react-app или других инструментов без их установки);
- для работы с разными версиями пакетов без изменения глобальных или локальных зависимостей.
Когда использовать npm exec:
- для выполнения команд в рамках локальных или глобальных зависимостей, если работа происходит в проекте с установленными пакетами и нужно управлять их запуском через npm;
- если нужно более тесно интегрироваться с экосистемой npm и использовать возможности, связанные с управлением зависимостями и версионированием.
Более подробную информацию можно найти в документации npm exec.
Полезные команды в работе с npx
Название | Описание |
--package, -p <package> | Запуск установленного или удаленно доступного пакета |
--<package>@<version> | Запуск конкретной версии пакета. Пример:npx create-react-app@3.4.1 my-project |
--cache <path> | Указывает путь к кешу для использования с npx |
--always-spawn | Всегда запускать под-процесс для выполнения команды |
--yes, -y | Выполнить команду без запроса на подтверждение |
--no-install | Пропустить установку, если пакет отсутствует |
--userconfig <path> | Путь к пользовательскому файлу npmrc |
--call, -c <script> | Выполнить строку как команду, если внутри ‘npm run-script’ |
--shell, -s <shell> | Указать оболочку для выполнения команды, если требуется |
--shell-auto-fallback <shell-fallback> | Генерировать shell-код для использования npx в качестве резервной команды при ошибке "команда не найдена". То есть когда оболочка не находит команду в $PATH, она автоматически переключится на npx для выполнения этой команды |
--ignore-existing | Игнорировать существующие бинарники в $PATH или в локальном проекте. Это заставляет npx временно установить и использовать последнюю версию |
--quiet, -q | Сокращает вывод логов от npx в консоль, оставляя только вывод от выполняемой команды |
--npm <path to binary> | Путь к бинарнику npm для использования во внутренних операциях |
--node-arg, -n <arg> | Дополнительный аргумент для node при вызове бинарного файла node |
--version, -v | Показать номер версии пакета |
--help, -h | Показать справку по пакету, если она в нем предусмотрена |