Node.js — это программная платформа, которая популярна для бекэнд-разработки на JavaScript. Но при создании своего приложения на Node, новичок или искушённый разработчик должен следовать определённым практикам программирования.
В этой статье мы осветим 10 лучших приёмов, которые помогут максимально задействовать всю функциональность платформы Node и языка JavaScript.
Сохраняйте точную версию пакета в файл package.json
Разработка приложения на Node.js сопровождается постоянным добавлением новых пакетов, расширяющих его функциональности. Обычно для этого используют следующую команду:
npm install express --save
- «express» – название пакета;
- «—save» – параметр, отвечающий за добавление зависимости в package.json.
Менеджер npm устанавливает назначенный пакет и фиксирует зависимость в файле package.json следующим образом:
"express": "^4.17.1",
- «^4.17.1» – версия пакета.
Использование карета «^» предполагает, что для версии приемлемо значение в диапазоне «>=4.17.1 <5.0.0».
Это станет проблемой, если кто-либо ещё будет использовать файл package.json, который мы при помощи команды «npm install» создали для настройки среды приложения и установки зависимостей. При возникновении такой ситуации менеджер npm проигнорирует указанную в package.json версию и установит более новый пакет, который может некорректно работать в связке с программой.
Есть два метода предотвратить конфликт версий пакетов. В обоих случаях каждая новая зависимость будет прописываться в package.json с указанием точной версии (т. е. без символа карета).
Первый метод
Постоянно использовать «—save-exact» в случаях, когда нужно добавить устанавливаемый пакет в зависимости package.json:
npm install express --save --save-exact
Второй метод
Единственный раз настроить npm через конфигурационный файл .npmrc, чтобы при установке пакетов автоматически указывалась точная версия:
npm config set save-exact=true
Теперь, когда кто-либо другой будет использовать файл package.json для установки зависимостей, менеджер npm поставит пакет именно той версии, которая применялась во время разработки.
Применяйте средства перезапуска приложения
Во время программирования на Node.js вам придётся вручную останавливать и перезапускать приложение, чтобы применять даже небольшие изменения, внесённые в исходный код. Выполняя эти монотонные действия, можно обнаружить, что они мешают сосредоточиться на поставленной задаче.
Для решения этой проблемы можно использовать инструменты, которые следят за исходниками и автоматически применяют изменения при каждом внесении правок в код.
Популярные утилиты мониторинга кода в Node.js
- Nodemon автоматически перезапускает приложение при любом изменении кода. Пакет можно установить из библиотеки npm и в последующем работать с программой, используя в командной строке «nodemon» (например, запустив «nodemon app» вместо «node app»).
- Forever также обеспечивает автоматический перезапуск, что и Nodemon, но имеет большую функциональность. Утилита способна установить рабочий каталог и записать логи, которые в обычном случае были бы отражены в дескрипторе файлов (stdout).
- PM2 — это ещё один инструмент управления процессами. По сравнению с первыми двумя он предоставляет больше контроля и возможностей для управления процессами в условиях эксплуатации приложения.
Использовать эти инструменты можно даже в том случае, когда приложение Node уже обслуживает посетителей. При возникновении ошибки выполнения, утилита сделает откат изменений.
Подобные программы можно настроить так, чтобы при «падении» сервера приложение автоматически перезапускалось. Это иногда помогает в случае возникновения несерьёзных сбоев.
Используйте руководства по стилю оформления
Когда в разработке проекта участвует несколько программистов, неизбежны различия в их стиле оформления кода. Это зачастую мешает коллективной работе. Сложно удержаться от того, чтобы переформатировать код по своему вкусу, если вам не нравится стиль другого разработчика. Закончится это тем, что на эту бессмысленную задачу будет потрачено много ценного времени.
Программисты любят поспорить о том, какой стиль кода JavaScript лучше. Но этот выбор по большей части субъективен. Поэтому рекомендуется перед началом проекта согласовать или выбрать уже готовый стайл-гайд – руководство по стилю оформлению кода.
Есть инструменты, помогающие контролировать следование правилам выбранного стайл-гайда. Для проверки написанного кода можно использовать ESLint, а для автоматизации форматирования — Prettier.
Используйте синтаксис async/await
Когда JavaScript только появился, его асинхронная природа была реализована через использование функций обратного вызова или, как их еще называют, колбэков. Но, как каждый разработчик знает по опыту, колбэки легко выходят из-под контроля, когда вложены друг в друга. Такое явление принято называть «ад колбэков». С этого момента код становится практически нечитабельным.
Тем не менее в JavaScript стандарта ES6 вскоре добавили возможность использования синтаксиса async/await. Поэтому каждому разработчику рекомендуется использовать это нововведение и стараться избегать попадания в «ад колбэков».
Вот пример лёгкого варианта «ада колбэков»:
function callbackHellExample(err, result, cb) { if (err) { cb(err) } functionA(result, (resultA) => { functionB(resultA, (resultB) => { cb(resultB) }) }) }
Такого развития событий легко избежать, используя async/await:
async function asyncAwaitExample(err, result) { if (err) { return err } let resultA = await functionA(result) let resultB = await functionB(resultA) return resultB }
Выбирайте подходящее средство журналирования
Логи не рекомендуется вести с помощью console.log. Забудьте о том, чтобы в принципе использовать эту функцию для ведения журнала приложения. Помимо прочих минусов, метод console.log не предлагает достаточно опций для настройки журналирования или фильтрации поступающей информации.
Для Node есть несколько фреймворков, специализированных для ведения логов. Вот несколько примеров таких инструментов:
Помимо обычного журналирования, они позволяют разделять записи в логах на уровни. Например: «ошибка», «предупреждение», «информация и отладка». В некоторых инструментах также можно включить ведение журналов только на необходимых уровнях.
Объявляйте переменную с помощью спецификатора const
Применяя спецификатор const, вы не сможете переназначить или повторно использовать переменную после первого присвоения. Таким образом, const вынуждает объявлять новые переменные с подходящими именами. Это делает код чище и понятнее.
Но бывают случаи, когда нужна возможность переназначать аргумент переменной. Тогда можно воспользоваться let. Например, с помощью этого спецификатора, вам придётся объявлять инкрементальную переменную внутри цикла for.
До появления let в стандарте ES6, программисты использовали спецификатор var. Некоторые разработчики по-прежнему используют его в коде.
Важно также быть внимательным к области видимости таких ключевых слов, как const и var, прежде чем объявлять переменную.
Используйте инструменты для анализа покрытия кода
Мы не включаем тестирование Node-приложения в число главных правил, поскольку выполнение этого условия уже должно подразумеваться по умолчанию. Тем не менее использование средств покрытия кода — одна из лучших практик, которой нужно следовать при разработке на Node.js.
Инструменты для анализа покрытия кода используют, чтобы определить уровень тестового покрытия программы. Они обнаруживают и подсвечивают не подвергшиеся проверке фрагменты.
Istanbul/NYC — отличный инструмент, выполняющий цветовую разметку кода, которая помогает определить области, не затронутые модульными тестами.
Для использования утилиты установите пакет при помощи npm в качестве зависимости на этапе разработки.
npm install nyc --save-dev
Затем добавьте скрипт для запуска NYC, и создайте отчёт по покрытию кода.
"scripts": { "test": "mocha", "coverage: "nyc npm run test" }
Теперь можно использовать команду «npm coverage» для генерации отчётов.
Применяйте более строгий оператор «===»
В Node, для проверки равенства двух переменных, можно использовать оба оператора: «===» и «==». В то время, как первый более точен, второй признаёт равными и переменные, эквивалентность которых условна.
Для оператора «===» обе переменные должны не только совпадать по значению, но и быть одного типа.
1 === 1 // true (истина) 1 === "1" // false (ложь) false === 0 // false 0 === “” // false “” === false // false null === undefined // false NaN === null // false NaN === undefined // false NaN === NaN // false
Второй оператор «==» считает две переменные одинаковыми, если равны их значения. Это происходит даже когда типы различны.
1 == 1 // true 1 == "1" // true false == 0 // true 0 == “” // true “” == false // true null == undefined // true NaN == null // false NaN == undefined // false NaN == NaN // false
По параметрам видно, что использование оператора «==» не всегда даёт ожидаемые ответы. Это не станет проблемой, если вы привыкнете к этим особенностям и будете учитывать их при написании программ.
Но можно не переживать из-за неочевидного поведения языка и просто использовать для сравнения строгий оператор равенства «===».
Не связывайте фронтенд с Node
Node обслуживает все запросы к серверу в один поток, который, соответственно, нужно стремиться наиболее эффективно использовать. Качество этой оптимизации влияет на производительность приложения.
Поток может перегружаться, если Node используется для отправки статического содержимого (HTML, CSS-файлов, медиафайлов и т. д.). Это неприемлемо при работе с динамическим контентом, для которой требуется максимально задействовать компоненты и логику работающего приложения. В результате несбалансированного распределения ресурсов, производительность приложения заметно снижается.
Чтобы избежать дисбаланса, нужно снять задачу обработки статического контента с сервера Node. Для этого можно установить стороннее промежуточное ПО (middleware), которое будет выполнять обслуживание пользователей по части фронтенда. Например, Nginx, S3 или CDN. Тогда Node будет свободно работать с динамическим контентом без потери производительности.
Не храните информацию в приложении
Размещайте любой вид данных из своего приложения (сессии пользователей, их данные, кэш) только во внешних хранилищах. Нельзя допускать хранения данных в самой программе.
Иначе говоря, приложение не должно зависеть от какого-либо состояния (протокол stateless). Нужно иметь возможность остановить сервер в любой момент и перезапустить его так, чтобы это не повлияло на пользователей. В качестве альтернативы можно использовать бессерверные платформы, такие как AWS Lambda, которые предполагают работу с stateless-протоколом по умолчанию.
Заключение
В этой статье мы обсудили лучшие практики программирования, которым следует придерживаться Node-разработчику. Следуя им, можно сделать код читабельней и быстрее.
Важно отметить, что, помимо рассмотренных, вам нужно следовать и другим правилам, применимым к любому языку программирования. Необязательно пытаться использовать все из них сразу. Выберите те, которые покажутся вам важнейшими, и начните с них. Со временем вы сможете охватить куда больше приёмов.
Нужна надёжная база для разработки веб-приложений? Выбирайте виртуальные сервера от Eternalhost с технической поддержкой 24/7 и бесплатной защитой от DDoS!
Автор оригинала: Juan Cruz Martinez