Npm scripts что это
Перейти к содержимому

Npm scripts что это

  • автор:

Немного о npm-scripts

Если кто не знаком с предметной областью, то NPM — node package manager (аналог bundler/composer/easy_install/nuget) – средство для управления зависимостями в вашем Node.js проекте, что по совместительсву может выполнять некоторое количество полезных функций. Написан Айзеком Шлютером, который достаточно радикальным образом продвигал в начале своей истории (рассылая всем существующим Node.js проектам пулл-реквесты с добавлением package.json — манифестом зависимостей).

Все нижеприведенные вещи известны многим, но для некоторых это может стать приятным открытием, что сэкономит некоторое количество набираемых в символов.

pre-/post- myscript

Иногда, в целях автоматизации некоторой рутины, но при малом желании тащить за собой N мегабайт зависимостей в виде разных билд-инструментов, а в некоторых случаях под впечатлением от статьи за авторством @substack’а, разработчики могут начать в своих npm script’ах писать длиннющие строки, состоящие из перечня команд и ‘&&’. По крайней мере, одним из выходов может служить разбитие одной сложной команды на несколько более простых. Самым замечательным является тот факт, что когда вы запускаете свой скрипт npm run-script myscript , npm также попытается выполнить команды, что занесены в premyscript и postmyscript перед и после выполнения вашего скрипта соответственно. Таким образом, 3 сложных команды, что раньше составляли один скрипт, можно просто разнести в три скрипта.

Код, что отвечает за это, довольно таки прост, и пытается добавить к названию команды pre-/post- и запустить их в случае, если это сама по себе не pre/post команда и не команда ‘restart’, что обрабатывается особым способом.

npm run вместо run-script, npm i вместо npm install

Заголовок, в принципе, всё описывает: очень часто вместо «npm run-script» можно увидеть «npm run», или «npm i», что соответствует запуску команды «npm install». Код, что делает это, прост: используя библиотеку abbrev-js все команды из списка превращаются в огромный словарь, в котором ключами служат сокращения слов, вида:

И запускает соответствующую команду.

Нет необходимости писать пути для исполняемых файлов в скриптах

Иногда npm скрипты используются, чтобы запускать локально установленные npm пакеты с бинарниками. Но часто люди не знают об одной приятной особенности: npm во время исполнения добавляет папку node_modules/.bin в аналог переменой PATH. То есть, если у вас локально установленная mocha, вам не нужно писать

"scripts": < "test": "./node_modules/.bin/mocha" >

А достаточно лишь написать «test»: «mocha» . Приятным бонусом этого является то, что разработчики под виндоус перестанут жаловаться на то, что у них ничего не запускается (причина в том, что используются разные разделители в пути).

Бонус: require на файлах модуля

Команда require, оказывается, при работе с названиями модулей (а не относительными путями) может не только загрузить index.js/index.node файл из корня нашего модуля, что установлен в node_modules, но и предоставить возможность загрузить произвольный файл изнутри модуля (нарушая любую инкапсуляцию, но иногда может быть полезно). Поэтому можно делать require(‘module/lib/hidden-stuff’) .

Бонус #2: пасхалки в npm

В нпм есть парочку забавных пасхалок.

  • nodejs
  • npm
  • пасхальные яйца
  • github
  • вы наверное шутите мистер Шлютер

Почему npm-скрипты?

Я начал использовать скрипты npm в своих проектах примерно полгода назад. До этого я использовал Gulp, а еще раньше Grunt. Они отлично работали и помогали мне быстрее справляться со своей работой, эффективно автоматизируя многие вещи, которые до этого приходилось делать вручную. Однако я начал замечать, что трачу на настройку этих инструментов больше времени, чем на сам код.

Grunt, Gulp, Broccoli, Brunch и подобные инструменты заставляют вас подстраивать ваши задачи под их парадигмы и конфигурации. У каждого инструмента свой собственный синтаксис, свои глюки и заморочки, которые вам приходиться изучать. Это добавляет сложности коду и процессу сборки, заставляет вас фокусироваться на отладке, а не написании кода.

Эти инструменты сборки зависят от плагинов, которые являются обертками для инструментов командной строки. Это добавляет еще один уровень абстракции, что увеличивает вероятность проблем.

Три проблемы, с которыми я многократно сталкивался

  • Если в вашей системе сборки нет плагина для нужного вам инструмента командной строки — можете считать, что вам не повезло. Или написать такой плагин самостоятельно.
  • Плагин, который вы пытаетесь использовать, является оберткой для старой версии нужного вам инструмента. Функционал и документация у инструмента и соответствующего ему плагина из системы сборки не всегда совпадают.
  • Ошибки не всегда обрабатываются так, как надо. Плагин при ошибке может не передать ничего системе сборке, приводя вас в фрустрацию без понимания путей решения проблемы.
Небольшое уточнение

Позвольте мне сказать это: если вас устраивает привычная вам система сборки и она решает все ваши задачи, продолжайте использовать ее! То, что скрипты npm становятся все популярнее, не означает, что вам срочно нужно переходить на них. Фокусируйтесь на написании кода, а не на освоении инструментов. Если у вас появляется чувство, что вы боретесь со своими инструментами, тогда вам стоит подумать об использовании скриптов npm.

Если вы решили, что хотите начать использовать или хотя бы разобраться со скриптами npm, продолжайте читать. Вы найдете множество примеров задач в этой статье. Также я создал npm-build-boilerplate со всеми задачами, который вы можете использовать в качестве образца.

Написание скриптов npm

Большую часть времени мы будем тратить на файл package.json . Именно в нем живут все зависимости и скрипты. Вот несколько урезанная версия из моего шаблонного проекта:

< "name": "npm-build-boilerplate", "version": "1.0.0", "scripts": < . >, "devDependencies": < . >> 

Мы будем расширять наш package.json по мере надобности. Наши скрипты будут добавляться в объект scripts , а все необходимые инструменты будут инсталлироваться и помещаться в объект devDependencies .

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

Структура каталогов нашего проекта

Компиляция SCSS в CSS

Я активно использую SCSS, так что без него мне не обойтись. Чтобы скомпилировать SCSS в CSS я использую node-sass. Для начала надо установить node-sass , это делается в командной строке:

npm install --save-dev node-sass 

Команда установит node-sass в ваш текущий каталог, а также добавит в объект devDependencies в package.json . Это особенно полезно, когда кто-либо другой запускает ваш проект — у него уже есть все для работы проекта. После инсталляции мы можем компилировать SCSS с помощью команды:

node-sass --output-style compressed -o dist/css src/scss 

Разберем, что делает эта команда. Флаг —output-style отвечает за вид скомпилированных стилей, у нас он в значении в значении compressed — стили сжимаются; скомпилированные файлы выводятся в каталог dist/css , это флаг -o ; в каталоге src/scss идет поиск на предмет наличия файлов SCSS, которые мы будем компилировать.

Теперь, когда мы разобрались, как это работает в командной строке, вернемся к нашему скрипту npm. Добавьте эту команду в объект scripts вашего файла package.json , примерно так:

"scripts": < "scss": "node-sass --output-style compressed -o dist/css src/scss" >

Вернитесь в командную строку и выполните:

npm run scss 

Вы увидите точно такой же результат, как и при непосредственном выполнении node-sass .

Любой скрипт npm из этого поста можно выполнить с помощью подобной команды.

Просто замените scss на название задачи, которую вы хотите выполнить.

Как видите, у многих инструментов командной строки, которые мы будем использовать, есть многочисленные опции, которые мы можем настраивать под себя. Вот, например, список опций для node-sass. Вот образец конфигурации с передачей множества опций:

"scripts": < "scss": "node-sass --output-style nested --indent-type tab --indent-width 4 -o dist/css src/scss" >

Автопрефиксер

После компиляции Scss в CSS мы можем автоматически добавить вендорные префиксы, используя Autoprefixer & PostCSS. Мы сразу установим несколько модулей, разделив их пробелами:

npm install --save-dev postcss-cli autoprefixer 

Мы устанавливаем два модуля, потому как сам по себе PostCSS ничего не делает. Он нуждается в других плагинах типа Autoprefixer, чтобы манипулировать переданным CSS.

После установки и сохранения в devDependencies всех необходимых инструментов, добавьте задачу в объект scripts .

"scripts": < . "autoprefixer": "postcss -u autoprefixer -r dist/css/*" >

Эта задача говорит: “Эй, postcss, используй (use, флаг -u ) autoprefixer с заменой всех старых файлов в каталоге dist/css на новые, с вендорными префиксами”. Все! Нужно поменять набор поддерживаемых браузеров для автопрефиксера? Измените его конфигурацию:

"autoprefixer": "postcss -u autoprefixer --autoprefixer.browsers '>5%, ie 9' -r dist/css/*" 

Опять-таки, это далеко не все доступные опции, которые вы можете использовать в своей сборке, вот списки опций для postcss-cli и для autoprefixer.

Линтинг JavaScript

Выдерживание стандартного формата и стиля написания кода важно, так как позволяет свести количество ошибок к минимуму и увеличить эффективность разработчика. Линтинг позволяет сделать это автоматически, поэтому добавим линтинг JavaScript из пакета eslint.

Опять, начнем с установки пакета, в этот раз краткой:

npm i -D eslint 

По действию эта команда идентична традиционной:

npm install --save-dev eslint 

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

eslint --init 

Я предлагаю выбрать вариант “Answer questions about your style” и ответить на все вопросы. В результате в корне вашего проекта будет сгенерирован файл с настройками eslint для линтинга вашего кода.

Теперь добавим задачу в объект scripts нашего файла package.json :

"scripts": < . "lint": "eslint src/js" >

Наша задача по линтингу занимает всего 13 символов! Она просматривает все файлы JavaScript в каталоге src/js и проверяет их на соответствие сгенерированным ранее правилам. У линтера очень много доступных опций.

Минификация JavaScript

Теперь объединим и минифицируем наши файлы JavaScript, это мы сделаем с помощью uglify-js. Начнем, как всегда, с установки:

npm i -D uglify-js 

Затем настроим задачу по минификации в package.json :

"scripts": < . "uglify": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js" >

Одной из сильных сторон скриптов npm является то, что они по своей сути являются псевдонимами для задач в командной строке, которые вы хотите запускать неоднократно. Это значит, что вы можете использовать стандартный код командной строки напрямую в своем скрипте! Наша задача использует две возможности стандартной командной строки, это mkdir и && .

Первая часть задачи ( mkdir -p dist/js ) говорит: “создай каталог ( mkdir ), но только если он еще не существует (флаг -p )”. После успешного выполнения этой команды, запускается вторая часть задачи, непосредственно минификация ( uglifyjs ). Оператор && соединяет эти две команды в последовательность, позволяя запуск второй только после успешного выполнения первой.

Минификатор ( uglifyjs ) проходит через все файлы JavaScript ( *.js ) в каталоге src/js/ и применяет к ним команду “mangle” (флаг м ), выводя результат в файл dist/js/app.js . Изучив документацию минификатора, вы найдете множество конфигурационных опций.

Давайте обновим задачу uglify для создания сжатой версии dist/js/app.js . Добавим еще одну команду uglifyjs , передав ей флаг “compress” (-c):

"scripts": < . "uglify": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js && uglifyjs src/js/*.js -m -c -o dist/js/app.min.js" >

Сжатие изображений

После минификации JavaScript самое время перейти к сжатию изображений. Согласно данным httparchive.org, средний вес страницы из топ-1000 составляет 1.9мб, при этом изображения занимают 1.1мб. Поэтому уменьшение размера изображений на странице это один из лучших способов ускорить ее загрузку.

npm i -D imagemin-cli 

Imagemin хорош тем, что сжимает большинство типов изображений, включая GIF, JPG, PNG и SVG. Вы можете передать ему каталог с изображениями, остальное он сделает сам:

"scripts": < . "imagemin": "imagemin src/images dist/images -p", >

Эта задача заставляет imagemin найти и сжать все изображения в каталоге src/images , поместив сжатые изображения в каталог dist/images . Флаг -p (progressive) означает прогрессивное сжатие изображений, когда это возможно. В документации описаны все доступные опции.

SVG спрайты

Шумиха вокруг SVG усилилась за последние несколько лет и для этого есть хорошая причина. Изображения SVG четкие на всех устройствах, редактируются с помощью CSS и хорошо работают со скринридерами. Однако программное обеспечение для создания SVG обычно оставляет много постороннего и ненужного кода. К счастью, svgo помогает избавиться от мусора (мы установим svgo чуть позже, вместе с другим пакетом).

Вы можете автоматизировать процесс комбинирования и создания спрайтов из SVG для получения одного файла SVG (подробнее эта техника описана в статье на css-tricks.com). Для автоматизации процесса мы установим svg-sprite-generator.

npm i -D svgo svg-sprite-generator 

Последовательность действий уже должна быть знакома вам: после установки мы добавим задачу в объект scripts в файле package.json :

"scripts": < . "icons": "svgo -f src/images/icons && mkdir -p dist/images && svg-sprite-generate -d src/images/icons -o dist/images/icons.svg" >

Обратите внимание, что задача icons делает три вещи, благодаря наличию двух операторов && . Во-первых, мы используем svgo передается каталог (флаг -f , folder) с SVG, которые svgo сжимает. Во-вторых, с помощью команды mkdir -p мы создаем каталог dist/images , если он до сих пор не создан. И в-третьих, мы используем svg-sprite-generator , передавая ему каталог с исходниками (флаг -f , folder) и указав каталог-назначение (флаг -o , output) для готового спрайта.

Локальный сервер и автоматическое применение изменений с BrowserSync

Один из последних фрагментов нашего пазла это BrowserSync. Он может делать несколько вещей: запускать локальный сервер, автоматически обновлять файлы в любом подключенном браузере и синхронизировать клики и прокрутку между браузерами. Установите его и добавьте задачу:

npm i -D browser-sync 
"scripts": < . "serve": "browser-sync start --server --files 'dist/css/*.css, dist/js/*.js'" >

Наша задача BrowserSync запускает сервер (флаг —server ), используя в качестве корневого для сервера текущий каталог. Флаг —files задает путь к отслеживаемым файлам CSS или JS в каталоге dist , когда что-то в этом каталоге меняется, изменения автоматически вставляются на страницу.

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

Группирование задач

Добавив все перечисленные задачи, мы можем делать следующее:

  • Компилировать SCSS в CSS и автоматически добавлять вендорные префиксы
  • Проверять и минифицировать JavaScript
  • Сжимать изображения
  • Конвертировать каталог с изображениями SVG в один спрайт SVG
  • Запускать локальный сервер и автоматически вставлять изменения в любой браузер, подсоединенный к серверу.

Но мы не будем останавливаться на этом.

Объединение задач CSS

Добавим задачу, сочетающую две задачи, связанные с CSS (обработка Sass и запуск автопрефиксера), чтобы нам не приходилось запускать их по отдельности:

"scripts":

Когда вы выполняете npm run build:css , в командной строке выполняется npm run scss , после успешного выполнения этой команды оператор && запускает выполнение второй команды: npm run autoprefixer .

Объединение задач JavaScript

Аналогично задаче build:css мы можем объединить вместе и задачи JavaScript для облегчения их запуска.

"scripts":

Теперь мы можем использовать команду npm run build:js для проверки, объединения и минификации JavaScript в один шаг!

Объединение остальных задач

Мы можем объединить все задачи, связанные с изображениями, а также сделать одну универсальную задачу, объединяющую все предыдущие:

"scripts":

Отслеживание изменений

До этой точки все наши задачи требовали внесения изменений в файл, переключения обратно в командную строку и запуска соответствующей задачи. Одна из самых полезных вещей, которые мы можем сделать, это отслеживание изменений в файлах с соответствующим автоматическим запуском задач. Для того, чтобы сделать это я рекомендую использовать onchange. Устанавливаем как обычно:

npm i -D onchange 

Настроим отслеживание с выполнением задач для CSS и JavaScript:

"scripts": < . "watch:css": "onchange 'src/scss/*.scss' -- npm run build:css", "watch:js": "onchange 'src/js/*.js' -- npm run build:js", >

Вот разбор основных моментов: onchange принимает каталог, который нужно отслеживать. В нашем случае это файлы SCSS и JS. После двух дефисов ( — ) указывается команда, которая будет выполняться при любом добавлении, изменении или удалении файлов в соответствующем отслеживаемом каталоге.

Окончательный вид процесса сборки с помощью скриптов npm

Установим еще один пакет parallelshell:

npm i -D parallelshell 

Как обычно, добавим новую задачу в объект scripts :

"scripts":

parallelshell принимает в качестве аргументов несколько строк с командами, которые выполняет при запуске npm run .

Почему мы используем parallelshell для объединения множественных задач, а не оператор && , как в предыдущих случаях. Я пытался. Проблема в том, что && связывает команды вместе и ждет успешного окончания каждой из них перед тем, как запускать следующую. Однако, так как у нас в цепочке есть команда watch , завершения не будет — мы застрянем в бесконечном цикле.

Поэтому использование parallelshell позволяет нам одновременно выполнять несколько задач watch . Подобным функционалом обладает также npm-run-all.

Итоговая задача сначала запускает сервер с BrowserSync , используя задачу npm run serve . Затем отслеживание файлов CSS и JavaScript, при наличии изменений запускается сборка, а так как BrowserSync настроен на отслеживание измений в каталоге dist , все результаты изменений автоматически передаются в подсоединенный браузер.

Прочие полезные команды

npm может решать множество задач. Добавим еще одну задачу к нашим сборочным скриптам.

"scripts":

postinstall запускается сразу после выполнения npm install в командной строке. Это особенно хорошо для работы в команде: когда кто-либо клонирует ваш проект и выполняет npm install , задачи в watch:all стартуют немедленно, то есть запускается сервер и открывается окно браузера, в котором отслеживаются все изменения файлов.

Заключение

Да, мы сделали это! Надеюсь, что вы изучили некоторые основы использования npm-скриптов для процесса сборки и работы командной строки в целом.

На случай, если вы что-то упустили, я создал npm-build-boilerplate, в котором есть все упомянутые задачи и который можно использовать в качестве стартовой точки.

scripts

The «scripts» property of your package.json file supports a number of built-in scripts and their preset life cycle events as well as arbitrary scripts. These all can be executed by running npm run-script or npm run for short. Pre and post commands with matching names will be run for those as well (e.g. premyscript , myscript , postmyscript ). Scripts from dependencies can be run with npm explore — npm run .

Pre & Post Scripts

To create «pre» or «post» scripts for any scripts defined in the «scripts» section of the package.json , simply create another script with a matching name and add «pre» or «post» to the beginning of them.

"scripts":
"precompress": ">",
"compress": ">",
"postcompress": ">"
>
>

In this example npm run compress would execute these scripts as described.

Life Cycle Scripts

There are some special life cycle scripts that happen only in certain situations. These scripts happen in addition to the pre , post , and scripts.

  • prepare , prepublish , prepublishOnly , prepack , postpack , dependencies

prepare (since npm@4.0.0 )

  • Runs BEFORE the package is packed, i.e. during npm publish and npm pack
  • Runs on local npm install without any arguments
  • Runs AFTER prepublish , but BEFORE prepublishOnly
  • NOTE: If a package being installed through git contains a prepare script, its dependencies and devDependencies will be installed, and the prepare script will be run, before the package is packaged and installed.
  • As of npm@7 these scripts run in the background. To see the output, run with: —foreground-scripts .

prepublish (DEPRECATED)

  • Does not run during npm publish , but does run during npm ci and npm install . See below for more info.

prepublishOnly

  • Runs BEFORE the package is prepared and packed, ONLY on npm publish .

prepack

  • Runs BEFORE a tarball is packed (on » npm pack «, » npm publish «, and when installing a git dependency).
  • NOTE: » npm run pack » is NOT the same as » npm pack «. » npm run pack » is an arbitrary user defined script name, where as, » npm pack » is a CLI defined command.

postpack

  • Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally)

dependencies

  • Runs AFTER any operations that modify the node_modules directory IF changes occurred.
  • Does NOT run in global mode
Prepare and Prepublish

Deprecation Note: prepublish

Since npm@1.1.71 , the npm CLI has run the prepublish script for both npm publish and npm install , because it’s a convenient way to prepare a package for use (some common use cases are described in the section below). It has also turned out to be, in practice, very confusing. As of npm@4.0.0 , a new event has been introduced, prepare , that preserves this existing behavior. A new event, prepublishOnly has been added as a transitional strategy to allow users to avoid the confusing behavior of existing npm versions and only run on npm publish (for instance, running the tests one last time to ensure they’re in good shape).

See https://github.com/npm/npm/issues/10074 for a much lengthier justification, with further reading, for this change.

Use Cases

If you need to perform operations on your package before it is used, in a way that is not dependent on the operating system or architecture of the target system, use a prepublish script. This includes tasks such as:

  • Compiling CoffeeScript source code into JavaScript.
  • Creating minified versions of JavaScript source code.
  • Fetching remote resources that your package will use.

The advantage of doing these things at prepublish time is that they can be done once, in a single place, thus reducing complexity and variability. Additionally, this means that:

  • You can depend on coffee-script as a devDependency , and thus your users don’t need to have it installed.
  • You don’t need to include minifiers in your package, reducing the size for your users.
  • You don’t need to rely on your users having curl or wget or other system tools on the target machines.
Dependencies

The dependencies script is run any time an npm command causes changes to the node_modules directory. It is run AFTER the changes have been applied and the package.json and package-lock.json files have been updated.

Life Cycle Operation Order

npm cache add
npm ci
  • preinstall
  • install
  • postinstall
  • prepublish
  • preprepare
  • prepare
  • postprepare

These all run after the actual installation of modules into node_modules , in order, with no internal actions happening in between

npm diff
npm install

These also run when you run npm install -g

  • preinstall
  • install
  • postinstall
  • prepublish
  • preprepare
  • prepare
  • postprepare

If there is a binding.gyp file in the root of your package and you haven’t defined your own install or preinstall scripts, npm will default the install command to compile using node-gyp via node-gyp rebuild

These are run from the scripts of

npm pack
  • prepack
  • prepare
  • postpack
npm publish
  • prepublishOnly
  • prepack
  • prepare
  • postpack
  • publish
  • postpublish

prepare will not run during —dry-run

npm rebuild
  • preinstall
  • install
  • postinstall
  • prepare

prepare is only run if the current directory is a symlink (e.g. with linked packages)

npm restart

If there is a restart script defined, these events are run, otherwise stop and start are both run if present, including their pre and post iterations)

  • prerestart
  • restart
  • postrestart
npm run
npm start
  • prestart
  • start
  • poststart

If there is a server.js file in the root of your package, then npm will default the start command to node server.js . prestart and poststart will still run in this case.

npm stop
  • prestop
  • stop
  • poststop
npm test
  • pretest
  • test
  • posttest
npm version
  • preversion
  • version
  • postversion
A Note on a lack of npm uninstall scripts

While npm v6 had uninstall lifecycle scripts, npm v7 does not. Removal of a package can happen for a wide variety of reasons, and there’s no clear way to currently give the script enough context to be useful.

Reasons for a package removal include:

  • a user directly uninstalled this package
  • a user uninstalled a dependant package and so this dependency is being uninstalled
  • a user uninstalled a dependant package but another package also depends on this version
  • this version has been merged as a duplicate with another version
  • etc.

Due to the lack of necessary context, uninstall lifecycle scripts are not implemented and will not function.

User

When npm is run as root, scripts are always run with the effective uid and gid of the working directory owner.

Environment

Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process.

path

If you depend on modules that define executable scripts, like test suites, then those executables will be added to the PATH for executing the scripts. So, if your package.json has this:

"name": "foo",
"dependencies":
"bar": "0.1.x"
>,
"scripts":
"start": "bar ./test"
>
>

then you could run npm start to execute the bar script, which is exported into the node_modules/.bin directory on npm install .

package.json vars

The package.json fields are tacked onto the npm_package_ prefix. So, for instance, if you had in your package.json file, then your package scripts would have the npm_package_name environment variable set to «foo», and the npm_package_version set to «1.2.5». You can access these variables in your code with process.env.npm_package_name and process.env.npm_package_version , and so on for other fields.

See package.json for more on package configs.

current lifecycle event

Lastly, the npm_lifecycle_event environment variable is set to whichever stage of the cycle is being executed. So, you could have a single script used for different parts of the process which switches based on what’s currently happening.

Objects are flattened following this format, so if you had > in your package.json, then you’d see this in the script:

process.env.npm_package_scripts_install === "foo.js"

Examples

For example, if your package.json contains this:

"scripts":
"install": "scripts/install.js",
"postinstall": "scripts/install.js",
"uninstall": "scripts/uninstall.js"
>
>

then scripts/install.js will be called for the install and post-install stages of the lifecycle, and scripts/uninstall.js will be called when the package is uninstalled. Since scripts/install.js is running for two different phases, it would be wise in this case to look at the npm_lifecycle_event environment variable.

If you want to run a make command, you can do so. This works just fine:

"scripts":
"preinstall": "./configure",
"install": "make && make install",
"test": "make test"
>
>

Exiting

Scripts are run by passing the line as a script argument to sh .

If the script exits with a code other than 0, then this will abort the process.

Note that these script files don’t have to be Node.js or even JavaScript programs. They just have to be some kind of executable file.

Best Practices

  • Don’t exit with a non-zero error code unless you really mean it. Except for uninstall scripts, this will cause the npm action to fail, and potentially be rolled back. If the failure is minor or only will prevent some optional features, then it’s better to just print a warning and exit successfully.
  • Try not to use scripts to do what npm can do for you. Read through package.json to see all the things that you can specify and enable by simply describing your package appropriately. In general, this will lead to a more robust and consistent state.
  • Inspect the env to determine where to put things. For instance, if the npm_config_binroot environment variable is set to /home/user/bin , then don’t try to install executables into /usr/local/bin . The user probably set it up that way for a reason.
  • Don’t prefix your script commands with «sudo». If root permissions are required for some reason, then it’ll fail with that error, and the user will sudo the npm command in question.
  • Don’t use install . Use a .gyp file for compilation, and prepare for anything else. You should almost never have to explicitly set a preinstall or install script. If you are doing this, please consider if there is another option. The only valid use of install or preinstall scripts is for compilation which must be done on the target architecture.
  • Scripts are run from the root of the package folder, regardless of what the current working directory is when npm is invoked. If you want your script to use different behavior based on what subdirectory you’re in, you can use the INIT_CWD environment variable, which holds the full path you were in when you ran npm run .

See Also

  • npm run-script
  • package.json
  • npm developers
  • npm install

Что такое npm и зачем он нужен

Что такое npm и зачем он нужен

Node.js — платформа, с помощью которой создают серверные приложения на JavaScript. В ее основе — модульная система, которая позволяет подтягивать отдельные пакеты в приложение.

Для управления зависимостями в Node.js используют Node Package Manager (npm). Он загружает и устанавливает необходимые для проекта модули из сторонних источников.

Рассказываем, как работать с npm.

Инициализация и установка пакетов

Разработка ведется на разных устройствах, а команда может установить необходимые модули в терминале. Пакеты в таком случае подтягиваются из открытых или частных репозиториев. Найти и прочитать информацию о пакете (описание, версионность, частота внесения изменений) можно в реестре npm.

Частота скачиваний за неделю (Weekly Downloads) и количество зависимостей (Dependents) свидетельствуют о надежности пакета — чем их больше, тем чаще его используют разработчики.

Также информацию о пакете можно посмотреть с помощью команды в терминале:

Для инициализации проекта введите npm init

Эта команда запрашивает у разработчика основную информацию о проекте и генерирует package.json на основе ответов. В этом файле хранится информация о проекте и его зависимостях.

курс по теме: Алгоритмы и структуры данных
Артем Верещака Tech Lead в Bolt

Этап с вопросами можно пропустить с помощью npm init -y. Пакеты загружаются командой npm install или, сокращенно, npm i. Если в вашем проекте уже есть package.json, подтянутся модули, которые в нем указаны. Если пакет не был прописан в package.json, нужно написать его название после команды:

Пакеты можно подтягивать не только по имени, но и по ссылке:

В конце команд можно добавлять флаги, которые модифицируют их выполнение. Например, добавить зависимость в package.json:

По умолчанию пакеты устанавливаются в директорию node_modules в папке проекта. Также доступна установка в глобальное хранилище на ПК. Например, на Windows — в папку AppData на диске с операционной системой. Для этого нужно добавить флаг:

Пакеты можно обновить до последней версии с помощью команды npm update

статьи по теме:

Рассказывает FullStack Developer (React/Node.js) в SoftServe.

Что нужно, чтобы стать фулстеком.

Версионность npm

Иногда новый пакет некорректно работает с другими зависимостями или может содержать ошибки. Чтобы это исправить, можно установить более раннюю версию. Выделяют три группы версий:

  • MAJOR — пакет, в котором код и логика существенно отличается от предыдущих, например, был заменен ключевой класс. Версия 3.0.0 будет существенно отличаться от 2.0.0.
  • MINOR — пакет, в который просто был добавлен новый функционал, например, 3.1.0 расширяет 3.0.0.
  • PATCH — тут только вносились патчи и фиксы. Если нам нужно будет внести фикс в 3.1.0, то мы назовем версию 3.1.1.

Чтобы посмотреть все версии пакета, нужно ввести команду:

Для установки конкретной версии используется команда с указанием версии после @:

Добавление флага —save-exact установит и добавит последнюю версию в package.json. Таким же способом можно откатиться до необходимой.

Скрипты и тесты

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

"scripts": < "build": "npm run build:node && npm run build:browser", "build:browser": "rollup -c config/rollup.browser-config.js", "build:node": "rollup -c config/rollup.node-config.js", "clean": "git clean -fdxe node_modules", "lint": "eslint src/", "start": "node -i -e 'YAML=require(\"./dist/index.js\")'", >

Например, скрипт lint запускает линтер для директории src. Для запуска скриптов используется команда:

Если ваш проект содержит тесты, их можно запустить с помощью:

Если вы забыли нужную команду или доступные для нее флаги, вы можете ввести:

Также доступна документация с описанием всех команд и флагов для различных версий npm.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *