npm-скрипты: автоматизация команд

Как прятать длинные команды за короткими именами и запускать их через npm run.

Зачем нужны скрипты

Команды запуска бывают длинными: с флагами, переменными окружения, путями. Печатать их каждый раз вручную утомительно и легко ошибиться. Раздел scripts в package.json позволяет дать команде короткое имя.

{
  "scripts": {
    "start": "node index.js",
    "dev": "node --watch index.js",
    "test": "jest",
    "lint": "eslint src"
  }
}

Теперь вместо длинной команды достаточно вызвать скрипт по имени.

Запуск через npm run

Большинство скриптов запускают командой npm run имя:

npm run dev
npm run lint

У нескольких имён есть «привилегия» — их можно вызывать без слова run:

npm start    # то же, что npm run start
npm test     # то же, что npm run test

Это работает только для зарезервированных имён (start, test, stop, restart). Для всех остальных слово run обязательно.

Запуск локальных инструментов

Скрипты удобны ещё и тем, что видят программы из node_modules/.bin. То есть если вы поставили jest или eslint локально, в скрипте достаточно написать просто jest — npm найдёт нужную версию в проекте, а не глобальную.

Pre- и post-хуки

npm умеет автоматически запускать скрипт «до» и «после» по имени. Если есть скрипт build, то prebuild выполнится перед ним, а postbuild — после:

{
  "scripts": {
    "prebuild": "rm -rf dist",
    "build": "webpack",
    "postbuild": "echo Готово"
  }
}

Вызов npm run build прогонит все три по порядку. Это удобно для подготовки и уборки.

Передача аргументов

Дополнительные аргументы скрипту передают после --:

npm run test -- --watch

Всё, что идёт после --, дописывается к команде скрипта.

Скрипты — это просто «алиасы»

По сути scripts — это словарь «короткое имя → реальная команда». Идею легко изобразить на чистом JS:

const scripts = {
  start: "node index.js",
  dev: "node --watch index.js",
  test: "jest"
};

function npmRun(name) {
  const command = scripts[name];
  if (!command) return `Скрипт "${name}" не найден`;
  return `Выполняю: ${command}`;
}

console.log(npmRun("dev"));
console.log(npmRun("deploy"));

Вывод:

Выполняю: node --watch index.js
Скрипт "deploy" не найден

Итог

  • Раздел scripts в package.json даёт командам короткие имена.
  • Запуск: npm run имя; start и test можно без run.
  • Скрипты видят локальные инструменты из node_modules/.bin.
  • pre/post-хуки и аргументы после -- расширяют возможности.
Проверьте себя
1. Как запустить пользовательский скрипт с именем dev?
Anpm dev
Bnpm run dev
Cnode dev
Dnpm exec dev
2. Какой скрипт автоматически выполнится перед build?
Abeforebuild
Bprebuild
Cbuild:pre
Dinit
3. Зачем нужны npm-скрипты?
AЧтобы хранить пароли
BЧтобы прятать длинные команды за короткими именами
CЧтобы заменить package-lock.json
DЧтобы ускорить V8
Поддержать проект