Использование скриптов npm в разработке
Development, Java | Комментировать запись
Современные технологии открывают разработчикам доступ ко все большему количеству инструментов, что позволяет увеличить скорость и эффективность их работы. Возможно, одним из наиболее влиятельных и важных факторов растущей популярности Node.js и подобных бэкенд инструментов Javascript является то, что они позволяют использовать знакомый синтаксис на каждом этапе разработки.
Например, сегодня у нас есть таск-раннеры. Это программы, единственная цель которых – автоматизировать рутинные аспекты процесса разработки. Есть множество невероятно полезных Javascript таск-раннеров и инструментов сборки, которые стоит попробовать, например Grunt.js, Gulp и webpack. Эти инструменты очень популярны, однако есть еще один инструмент, который не привлекает столько внимания, но ведет себя аналогичным образом и может быть столь же полезным – и это встроенная функция скриптов npm.
Давайте рассмотрим различные способы использования сценариев npm для управления процессом разработки.
Файл package.json
Каждый проект в Node имеет файл package.json, который содержит метаданные. В этом файле можно найти заголовок, описание, версию и зависимости. Основная цель этого файла – разрешить публикацию проекта. Когда кто-то хочет установить разработанную вами программу из npm, его система должна знать, от каких еще программ зависит ее работа; также системе необходимо знать определенные вещи о поведении и конфигурации программы. Она получает всю эту информацию из файла package.json.
Файл package.json может выглядеть примерно так:
{
"name": "Crispy",
"version": "1.0.0",
"description": "Cooked to perfection!",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"author": "AlligatorIO",
"license": "ISC",
"dependencies": {
"ws": "^3.3.2"
},
"devDependencies": {
"webpack": "^3.8.1"
}
}
Как видите, это довольно простой файл, содержащий объект JSON с информацией по проекту.
Раздел scripts – это записи о сценариях или командах, которые будут запускаться в различные моменты жизненного цикла разработки и публикации проекта. Два наиболее распространенных сценария npm – это start и test. В предыдущем примере вы можете увидеть, что сценарий start не определен. Это связано с тем, что npm имеет для этого скрипта значение по умолчанию, node server.js. То есть, если вы не выберете собственный стартовый сценарий, вы можете ввести в командную строку npm start, и это автоматически выполнит поиск файла по имени server.js и запустит его в Node, если он будет найден.
Также обратите внимание, что скрипт test имеет значение mocha. Mocha – это распространенный набор инструментов для тестирования JavaScript, и после установки его можно запустить с помощью команды mocha. В этом случае наш тестовый сценарий не делает ничего, кроме этого.
Существует множество различных сценариев npm для разных ситуаций, но сейчас нас больше интересуют способы использования этих сценариев – это позволит облегчить жизнь разработчика во время создания нового проекта.
Жизненный цикл npm
Первый шаг к пониманию сценариев npm и их возможностей – это разобраться, что делает npm, когда вы запускаете сценарий. Первым делом он проверяет файл package.json, чтобы убедиться, что вы определили значение для этого скрипта. Если он обнаруживает, что вы определили это значение, он ищет две другие версии сценария: это версии pre и post. Если он обнаружит любую из них, он запустит их для указанного сценария. Например:
{
"scripts": {
"prestart": "node loadJaw.js",
"start": "node Gator.js",
"poststart": "node bite.js"
}
}
Если бы npm нашел такой фрагмент в нашем файле package.json, он запустил бы скрипты в следующем порядке: prestart, start, poststart. Все, что мы должны сделать для запуска – это ввести npm start в командной строке. Это невероятно полезно в тех ситуациях, когда вам нужно, чтобы что-то произошло непосредственно перед или сразу после основного действия. В процессе разработки нам может потребоваться подключение, чтобы запустить локальную копию базы данных или связать файлы (и убедиться, что это произойдет до запуска нашего сервера, чтобы избежать ошибок).
Если мы настроим наши скрипты правильно, то простая команда npm start сможет удовлетворить все наши потребности и сделает это в правильном порядке.
Режим разработки и режим производства
Один из наиболее полезных способов использования сценариев npm – изменение переменной Node_ENV, которая доступна в любой программе Node через глобальную переменную Process. Просто обратитесь к process.env.Node_ENV, чтобы найти это значение.
function getEnvironment(){
return process.env.Node_ENV;
}
getEnvironment(); // returns 'production';
Многие фреймворки используют значение переменной Node_ENV, чтобы определить среду, в которой следует запускать приложение. Разница в том, что часто производственная среда оптимизирована для производительности, а режим разработки – для отладки. Мы можем использовать этот общий механизм в собственных проектах, написав программы, которые настраиваются по-разному в зависимости от значения переменной Node_ENV.
Например, допустим, что мы хотим регистрировать посетителей нашего сайта. В режиме производства мы можем просто записывать IP-адрес каждого нового посетителя в логе для дальнейшего использования. В режиме разработки мы можем анализировать трафик в реальном времени, чтобы отсеивать ошибки, поэтому нам нужно регистрировать информацию о новых посетителях в другом файле, а также регистрировать трафик на консоли, чтобы мы могли наблюдать за тем, как это происходит. Это можно сделать с помощью простого фрагмента:
const inDevelopmentMode = process.env.Node_ENV === development;
function newVisitor(ip){
let logMessage = "New Visitor IP: " + ip;
if(inDevelopmentMode){
fs.writeFile("development_log.txt", logMessage, (err) => {
if(err) throw err;
});
console.log(logMessage);
}
else{
fs.writeFile("production_log.txt", logMessage, (err) => {
if(err) throw err;
});
}
}
Здесь для взаимодействия с нашей файловой системой мы используем модуль fs. Мы обращаемся к переменной Node_ENV, чтобы определить, находимся ли мы в режиме разработки, и если да, то ведем лог как в файле development_log.txt, так и в консоли. Если мы находимся в режиме производства, информация будет записываться в наш production_log.txt без входа в консоль.
Но как изменить переменную Node_ENV? Один из способов – использовать скрипты npm. Поместите в файл package.json:
{
"scripts": {
"start": "SET Node_ENV=development& node server.js",
}
}
Синтаксис может показаться немного забавным и на первый взгляд вызвать несколько вопросов. Мы объясним, почему делается именно так. Есть несколько важных и непредсказуемых вещей, на которые следует обратить внимание при попытке выполнить такой код.
- Установка переменной Node_ENV на этапе, который не будет с ней взаимодействовать, может привести к ошибкам. Это происходит потому, что запуск каждого нового сценария npm считается другим процессом. Если бы мы изменили значение Node_ENV в скрипте prestart, оно не было бы перенесено в процесс скрипта start. Поэтому мы должны изменить его именно в скрипте start, если собираемся взаимодействовать с ним в файле server.js.
- Есть небольшая разница между тем, как Linux и Windows обрабатывают изменение этой переменной. В Linux вы можете опустить команду SET и просто использовать Node_ENV=development& node server.js. В Windows вы должны обязательно использовать SET, чтобы изменить переменную.
- Важно убедиться, что в этой строке кода нет пробела между development и &, иначе этот пробел будет частью значения переменной и приведет к ошибке при проверке process.env.Node_ENV === “development”.
Конечно, разница между тем, как Linux и Windows устанавливают переменную среды, может привести к несовместимости, если команда работает над проектом в обеих операционных системах. Есть несколько способов исправить это. Вы можете использовать сценарий или модуль типа cross-env, который перед запуском команды пытается определить, в какой операционной системе работает программа. Также вы можете написать разные сценарии npm для каждой операционной системы и оставить их использование на усмотрение разработчиков. Оба способа допустимы. Но как создать альтернативные сценарии npm, которые делают аналогичные вещи для разных контекстов?
Пользовательские скрипты npm
К счастью, npm уже позволяет разработчикам определять собственные сценарии. Им можно присваивать любые имена, и npm будет запускать их точно так, как мы ожидаем. Он по-прежнему будет пытаться запустить все этапы жизненного цикла сценария («pre» и «post»). Это позволяет создать любое количество пользовательских скриптов, которые мы сможем использовать при разработке. Есть только одно ключевое отличие: в том, как такой скрипт запускается из командной строки.
Если для запуска встроенного сценария npm мы вводим npm <script-name>, чтобы запустить пользовательский сценарий, нам нужно использовать npm run <script-name>. Это единственная разница. Если бы нам был нужен измененный стартовый скрипт для работы с Linux, мы могли бы создать скрипт, в котором команда SET из стартового скрипта опускается. Назвать такой скрипт можно как угодно.
Предположим, нам нужен собственный скрипт для запуска локального экземпляра MongoDB. Для этого подойдет вот такой код:
{
"scripts": {
"start": "SET Node_ENV=development& node server.js",
"mongo": "mongod --dbpath=./pathToDatabase/db"
}
}
Теперь мы можем использовать команду npm run mongo для запуска базы данных.
Пользовательские сценарии отлично подходят для запуска различных последовательностей команд. К примеру:
{
"scripts": {
"test": "mocha",
"start": "SET Node_ENV=development& node server.js",
"mongo": "mongod --dbpath=./pathToDatabase/db",
"launch": "npm test && npm run mongo && npm start",
}
}
Этот сценарий запускает сценарии test, mongo и start в указанном порядке. Мы также можем использовать в сценариях пакеты типа concurrently для одновременного выполнения действий.
Примечание: Если в стартовом сценарии запустить производственную среду и создать пользовательский сценарий dev для запуска среды разработки, вам не нужно будет ничего изменять в package.json, чтобы вернуться в режим производства, – достаточно запустить npm start.
Заключение
Надеемся, что этот мануал дал вам общее представление о том, как можно использовать сценарии npm для облегчения процесса разработки.
Tags: Node.js, npm