
Мы представляем вашему вниманию обзор модулей, которые автор материала, программист, занимающийся, кроме прочего, ещё и веб-разработкой, считает полезными. Среди них — библиотеки для работы с изображениями, средства для проверки того, что пользователи вводят в формы, модули для оптимизации и минификации данных различных типов, инструменты для создания PDF-файлов, для логирования и разработки приложений командной строки.
Графика
?1. Работа с изображениями
GraphicsMagick и ImageMagick — это два популярных инструмента для работы с изображениями. Ими можно пользоваться из JavaScript-кода благодаря npm-модулю gm. В целом, всё это позволяет создавать, править, комбинировать изображения. Например — менять их размеры, кадрировать, выполнять преобразование форматов.
Вот как выглядит работа с этим модулем.
const gm = require('gm');
gm('/path/to/image.jpg')
.resize(500, 250)
.autoOrient()
.write(response, error => {});?2. Обработка изображений
Модуль sharp основан на невероятно быстрой библиотеке обработки изображений libvips. В задачах сжатия изображений и изменения их размера он, как говорится на его странице, в 4-5 раз быстрее ImageMagick или GraphicsMagick. Модуль поддерживает форматы JPEG, PNG, WebP, TIFF, GIF и SVG, он умеет выводить изображения в форматах JPEG, PNG, WebP, или в виде несжатых потоков исходных пиксельных данных.
?3. Создание спрайт-листов
Спрайт-листы — это графические файлы, которые содержат множество маленьких изображений (например — иконок). В нашем случае речь идёт о так называемых CSS-спрайтах. Они часто используются для того, чтобы облегчить задачу загрузки изображений, что благотворно влияет на скорость вывода страниц. Создание спрайт-листов вручную — задача неблагодарная. Автоматизировать этот процесс можно с помощью модуля spritesmith. На вход этого модуля передают сведения о папке с графическими файлами, а он преобразует все эти файлы в единый спрайт-лист. Кроме того, он генерирует JSON-файл со сведениями о координатах каждого изображения в готовом спрайт-листе, которым можно пользоваться в CSS.
Даты, строки, цвета
?4. Форматирование дат

Moment.js — отличная альтернатива стандартному объекту Date
В стандартном API JavaScript имеется объект Date, предназначенный для работы со значениями, представляющими собой дату и время. Однако, этот объект не особенно удобен в делах вывода и форматирования дат. Для того, чтобы упростить работу с датой и временем можно воспользоваться библиотекой Moment.js. Она имеет чёткий, продуманный интерфейс, а код, который получается при её использовании, оказывается понятным и читабельным.
moment()
.add(7, 'days')
.subtract(1, 'months')
.year(2009)
.hours(0)
.minutes(0)
.seconds(0);Кроме того, имеется плагин к этой библиотеке, который используется для разбора и форматирования дат для различных временных зон.
?5. Проверка строковых данных
Если вы предлагаете пользователям вашего сайта заполнить форму, не забывайте о проверке введённых ими данных. Делать это стоит не только на стороне клиента, но и на сервере — для того, чтобы отфильтровать опасные данные, отправленные злоумышленником. Модуль, предназначенный для решения задач проверки строк, validate.js, даёт в распоряжение разработчика множество полезных методов, назначение которых понятно из их названий. Например, это методы
isEmail(), isURL(), isMobilePhone(), isCreditCard(). Пользоваться им можно и на сервере, и на клиенте.?6. Работа с цветовыми значениями
Преобразование значений, представляющих цвета из одного формата в другой — это одна из задач, которая периодически встаёт перед фронтенд-разработчиком. Модуль TinyColor2 упрощает решение этой задачи, пользоваться им можно и в браузере, и в среде Node.js. Он даёт в распоряжение программиста набор методов для преобразования цветовых значений, вроде
toHexString(), toRGBString(), а также методы для выполнения различных операций с цветами. Среди них — lighten(), saturate(), complement().Работа с данными различных форматов
?7. Создание PDF-файлов
Если вам нужно динамически генерировать PDF-файлы — обратите внимание на модуль PDFKit. Он поддерживает встраивание в документы шрифтов, изображений и описаний векторных рисунков, либо генерируемых программно (используя API, похожее на Canvas), либо созданных в формате SVG. Более того, с его помощью можно создавать гиперссылки, включать в файлы заметки, выделять текст и делать ещё много всего полезного. Пожалуй, если вам нужно нечто подобное, начать работу с PDFKit стоит с изучения его интерактивной демонстрации, которая работает в браузере.
?8. Обработка HTML-файлов

Cheerio упрощает разбор HTML-файлов на сервере
Если вы попадали в ситуацию, когда надо было разобрать на сервере HTML-файл, и при этом вам не хватало возможностей jQuery, то вам, вполне возможно, стоит взглянуть на Cheerio. Хотя этот модуль представляет собой лишь реализацию подмножества возможностей jQuery, он значительно облегчает разбор HTML-файлов на сервере. Он построен на базе модуля htmlparser2 (это — парсер для HTML, XML и RSS). Кроме того, принимая во внимания результаты бенчмарков, он в восемь раз быстрее чем jsdom, ещё один модуль, позволяющий работать с DOM на сервере.
?9. Обработка CSV-файлов

Модуль node-csv упрощает работу с CSV-данными
Формат CSV (comma-separated value, значения, разделённые запятыми) часто используется для организации обмена данными, представленными в виде таблиц. Например, Microsoft Excel позволяет экспортировать или импортировать данные, используя этот формат. Модуль node-csv упрощает процесс работы с CSV-данными в JavaScript и даёт средства для создания, обработки, трансформации CSV-файлов, позволяет преобразовывать их в строки. Его API поддерживает функции обратного вызова, потоки, есть и его синхронный вариант, что даёт разработчику возможность выбрать именно то, что ему нужно.
?10. Обработка markdown-файлов
Markdown — это популярный формат для создания материалов, предназначенных для веб. Если вам нужно программно обрабатывать markdown-данные (то есть, например, вы хотите создать собственный markdown-редактор) — взгляните на модуль marked. На вход он принимает код в формате markdown, а выводит уже HTML-код. При этом средства этого модуля позволяют производить дальнейшую обработку полученного HTML-кода, используя средства рендеринга, настраиваемые разработчиком.
Оптимизация и минификация данных
?11. Оптимизация и минификация изображений

Imagemin — модуль для минификации и оптимизации изображений
Imagemin — это отличный модуль для минификации и оптимизации изображений. Его можно использовать из командной строки, в виде плагина для gulp или Grunt, работать с ним можно и средствами imagemin-app — приложения с графическим интерфейсом, доступного для всех самых распространённых ОС. Архитектура imagemin основана на плагинах. Это говорит о гибкости данного модуля, и о том, что его возможности по поддержке различных графических форматов можно расширять.
?12. Минификация HTML

Средство html-minifier может считаться лучшим из существующих HTML-минификаторов
После оптимизации изображений стоит задуматься о минификации HTML-кода веб-приложения. Эту задачу позволяет решить модуль html-minifier, который может работать из командной строки, а так же доступен для gulp и Grunt. Кроме того, существуют решения, позволяющие интегрировать его в веб-фреймворки вроде Koa и Express, в результате HTML можно минифицировать прямо в процессе работы сервера, до отправки HTML-страниц клиентам. В соответствии с результатами бенчмарков, которые имеются на домашней странице модуля, это — лучший из существующих инструментов для минификации HTML-кода.
?13. Минификация CSS
Минифицировав и оптимизировав HTML-код и изображения, отправляемые с сервера клиентам, стоит рассмотреть и вопрос минификации CSS. Решить эту задачу позволяет очень быстрый модуль clean-css, который можно использовать и из командной строки, и из JS-кода. Он поддерживает карты кода (source maps), а также — различные режимы совместимости, которые позволяют обеспечивать работу с полученным минифицированным CSS в старых версиях IE.
?14. Минификация JavaScript

Модуль UglifyJS2 умеет не только минифицировать JavaScript-код, но эту задачу он решает очень хорошо
Популярный модуль UglifyJS2 часто используется для минификации JS-кода, но, благодаря его возможностям по разбору кода, его, в принципе, можно использовать для решения широкого круга задач, связанных с обработкой текстов программ на JavaScript. Этот модуль преобразует JavaScript-код в абстрактное синтаксическое дерево (это — объектная модель, представляющая код) и предоставляет средства для обхода этого дерева. Этот модуль подойдёт и тем, кто подумывает о написании собственного JavaScript-оптимизатора.
?15. Минификация SVG
Тема минификации SVG-данных приведена в конце этого раздела, но она так же важна, как и всё то, о чём мы тут говорили. В последние несколько лет можно наблюдать возрождение этого формата. Всё дело в том, что его отлично поддерживают браузеры, и в том, что существуют удобные инструменты для работы с ним. К сожалению, SVG-данные, которые генерируют редакторы, часто содержат в себе избыточную или бесполезную информацию вроде комментариев и метаданных.
Для того, чтобы убрать всё лишнее из SVG-данных, можно воспользоваться модулем SVGO. Этот модуль поддерживает систему плагинов, тут практически каждая оптимизация представлена в виде отдельного плагина. Как и в случае с другими модулями, предназначенными для минификации, SVGO можно использовать как из командной строки, так и из JS-кода.
Утилиты
?16. Логирование
Когда вы работаете со сложными веб-приложениями, то, и в ходе разработки, и в продакшне, хорошая библиотека для логирования может оказаться весьма полезной для того, чтобы находить ошибки, возникающие в процессе работы этих приложений. В этой сфере весьма популярен модуль winston. Он поддерживает различные способы работы с данными, например, может выводить информацию в консоль, писать в файл, сохранять в базе данных (например, в CouchDB, MongoDB или Redis), или даже давать доступ к ним по HTTP для дальнейшей обработки.
?17. Создание фиктивных данных
В ходе разработки или тестирования пользовательских интерфейсов часто возникает необходимость в неких условных данных, таких, как адреса электронной почты, имена пользователей, домашние адреса, телефонные номера. Помочь в решении подобных задач может библиотека faker.js. Пользоваться ей можно и на сервере (в виде модуля для Node.js), и на клиенте. Этот инструмент предоставляет набор методов для создания фиктивных данных. Вам нужно имя пользователя? Вызовите метод
faker.internet.userName() — и случайным образом сгенерированное имя в вашем распоряжении. Требуется название компании? Обратитесь к методу faker.company.companyName(). На самом деле, faker.js способен помочь в создании практически любых данных такого рода.?18. Отправка сообщений электронной почты

Nodemailer поддерживает SSL/STARTTLS и умеет отправлять сообщения, содержащие обычный текст, HTML и изображения
В ходе разработки веб-сайтов нередко возникает необходимость в программной отправке электронных писем. Подобное нужно, например, для отправки пользователям подтверждений регистрации, для рассылки уведомлений о важных событиях, новостей. На самом деле, существует масса ситуаций, в которых нужны возможности по работе с электронными письмами.
В стандартном API Node.js нет средств для отправки электронных писем. Эту задачу можно решить с помощью модуля Nodemailer. Он поддерживает отправку писем, содержащих в себе обычный текст, HTML, изображения, и, что самое важное, поддерживает безопасный протокол обмена информацией SSL/STARTTLS.
?19. Создание REST-API
REST — это стандарт де-факто, применяемый при создании веб-приложений, использующих веб-сервисы. Фреймворки вроде Express помогают в деле создания подобных сервисов, но часто, «в нагрузку», разработчик получает средства для работы с шаблонами и системы рендеринга, которые, в зависимости от конкретной ситуации, могут оказаться невостребованными. В подобной ситуации стоит взглянуть на модуль restify, который ориентирован исключительно на разработку и тестировании REST-API. Его API очень похож на ПО промежуточного слоя Connect (на котором основан фреймворк Express), но обеспечивает разработчику более высокий уровень контроля над HTTP-взаимодействиями и поддерживает DTrace для поиска проблем с приложениями в реальном времени.
?20. Создание приложений командной строки
Существует огромное количество приложений командной строки, созданных средствами Node.js и предназначенных для решения самых разных задач (например, это относится к рассмотренным выше средствам для минификации и оптимизации данных). Если вы подумываете о создании собственного приложения командной строки — обратите внимание на пакет Commander.js. Его удобные инструменты позволяют описывать различные аспекты таких приложений, среди которых — команды, опции, псевдонимы, справочные материалы. Он серьёзно упрощает процесс создания приложений командной строки.
Итоги
На самом деле, в этом материале мы рассмотрели лишь малую часть из тех полезных инструментов, которые созданы для Node.js. Сейчас JavaScript пользуется невероятной популярностью, и новые npm-модули появляются буквально каждую неделю. Если вы хотите самостоятельно найти что-нибудь интересное — посмотрите домашнюю страницу npm, обращая внимание на проекты, получившие самые высокие оценки сообщества, и загляните на GitHub, в раздел популярных репозиториев.
Уважаемые читатели! Если вы заняты разработкой для платформы Node.js, у вас, наверняка, есть список любимых модулей. Просим о них рассказать.

Комментарии (48)

Cyber0x346
02.04.2018 16:35Интересно и полезно. Как только сдохнет не православный require и появится нормальный import я начну использовать node.js :)
mayorovp
02.04.2018 17:07А ключ --experimental-modules на что?

Cyber0x346
02.04.2018 17:48Хм. Я вообще не смотрел еще. Пару раз установил, побаловался — удалил. Я думаю о том, что после production релиза можно будет принимать решение, что именно использовать. Это будет то, что работает на import(это будет значить что код актуален). Как-то так мыслю…

yhaskell
02.04.2018 18:37importи так работает, правда приходится компилировать. но кто не компилирует в наш век ?)
Cyber0x346
02.04.2018 18:53Я не компилирую. Считаю, babel неизбежно ненужным. Сейчас Edge поддерживает даже классы. Предпочитаю современный код в ущерб совместимости в угоду динозаврам.

Leopotam
02.04.2018 19:06Вместо babel можно попробовать typescript — там можно использовать вообще все что-угодно (async/await, import, etc) + указывать таргет — все транспилируется куда надо, включая es5. Ну и получаем бонус в виде статической проверки типов.

Cyber0x346
02.04.2018 19:24Не стандарт.

Leopotam
02.04.2018 19:32Стандарт не стандарт, а под ноду гораздо приятнее писать со статической типизацией, последними фичами языка и без необходимости установки монстроидального бабеля с разными плагинами — все идет одним пакетом. Как вариант — flowtype, но оно очень плохо развивается по сравнению с ts.

Cyber0x346
02.04.2018 23:45Возможно. Но почему до сих пор нет хотя бы драфта? Я согласен с вами: есть сигареты, а есть сигары; что-то модно, а что-то вечно. Да и вечного тоже не бывает по сути. Просто внутреннее отторжение.

Cyber0x346
03.04.2018 09:42Насчет типизации. Я как-то так сделал и мне, в принципе, этого хватает.
// strip string to number stripNum: (v) => +v.replace(/\D+/g,"") - 0, // is HTML Object defined and how htmlObj: (e) => RR.isO(e) ? e : RR.get(e), // is callback defined isC: (c) => c && RR.isF(c) ? true : null, // is object isO: (v) => typeof(v) === 'object' ? true : null, // is string isS: (v) => typeof(v) === 'string' ? true : null, // is array isA: (v) => typeof(v) === 'array' ? true : null, // is function isF: (v) => typeof(v) === 'function' ? true : null, // is undefined isU: (v) => typeof(v) === 'undefined' ? true : null, // is number isN: (v) => typeof(v) === 'number' ? true : null,
Leopotam
03.04.2018 09:57+1Фишка типизации не в этом, а в статической проверке типов в момент написания кода — в конечном JS никаких проверок не будет (что дает бонусы в виде повышения быстродействия и уменьшения размера кода). Валидацию внешних данных, разумеется, никто не отменял — JS остается JS-ом. Но после валидации — все внутренние постоянные проверки просто не нужны.

Cyber0x346
03.04.2018 10:31Господи…
Написать тысячу раз number, чтобы потом не ошибиться… Ожидал большего. У меня и так не возникает проблем, но за предложение спасибо.
Leopotam
03.04.2018 10:35Если модуль написан изначально на ts, то вся эта портянка типов генерируется автоматически (одним флажком в tsconfig), причем может быть частью npm модуля (код на js + тайпинги — современные IDE подхватывают такое на ура), что уже используется свежими версиями пакетов. Если это legacy-проект, то да, руками, что есть боль и страдание.

Cyber0x346
03.04.2018 10:42Пока не работаю на node. Нет серверного компилятора и кэша. Клиент от этого будет быстрее? :)
> Если это legacy-проект, то да, руками, что есть боль и страдание.
Я вас понял. Для меня это удовольствие. Но я и legacy не поддерживаю больше.
Leopotam
03.04.2018 10:49Статическая типизация дает уверенность в том, что все типы передаются внутри приложения правильно — это убирает необходимость их валидировать на типы вообще, отсюда потенциальное ускорение. Все данные, которые приезжают извне и неизвестны на момент транспиляции типизированного кода в чистый JS — их нужно валидировать очень подробно, после этого данные становятся «чистыми» для всего внутреннего кода и их не нужно валидировать на каждый чих. Если единственный смысл приложения в постоянном получении данных, их проверке и минимальной обработке, то плюсов от типизации немного, проще будет ее отключить (но останутся плюсы по сигнатурам методов — этакая замена JSDoc).
mayorovp
03.04.2018 11:41Да, клиент определенно будет работать быстрее. За счет того что из кода пропадут перечисленные вами выше проверки из-за своей бессмысленности.

Cyber0x346
03.04.2018 12:07Меня часто ругают за то, что я экономлю на килобайтах трафика. Можно я вас поругаю за миллисекунды выполнения? Что typeof это настолько ресурсоемкая операция, что стоит об этом париться? (:
Это в любом случае где-то выполняется. Если нет проверки — значит есть какое-то приведение в уже скомпилированном виде. Или я ошибаюсь?
Leopotam
03.04.2018 14:47Нет никакого приведения и проверок — просто чистый «опасный» JS код. Все проверки делаются в момент транспиляции из ts в чистый JS: если типы не совпадут или могут быть проблемы с неоднозначностью проверки на null, например — оно заорет благим матом и откажется генерировать конечный JS код. Т.е или пишем правильно или не получаем JS код.

Cyber0x346
03.04.2018 14:20Внезапно родилось хокку:
Весною набухают почки и на своем стоят типочки…
Спасибо за минусы :) Пропадает всякое желание посещать этот чудный ресурс: слишком «здраво» воспринимаете новичков.
Leopotam
03.04.2018 14:49За карму не стоит беспокоиться (у всех свое мнение), а тем более писать об этом в паблик — обычно после этого она еще сильнее уходит в минусы :)

abyrkov
03.04.2018 14:43Про flowtype не согласен, он просто нацелен на типизацию, а не на компиляцию в JS

Leopotam
03.04.2018 14:51Говорим Flowtype — подразумеваем Babel, потому что без отрезания типов код не станет валидным JS. Т.е что так что так — транспиляция нужна, а зачем держать 2 инструмента, если можно все делать одним? Настраивать меньше, размером оно тоже выигрывает.

wert_lex
04.04.2018 10:58Flow очень правильная штука с очень грустным туллингом и процессом разработки. Настолько грустным, что тайпскрипт, похоже, победил. А жаль.
Zenitchik
02.04.2018 19:12-1Это Вы с корпоративным клиентом не работаете. Можете себе позволить такие понты.

Cyber0x346
02.04.2018 19:26Работаю. С меня этого не требуют. Да и не понты. Это в РФ правительственные задницы жалеют на апгрейд. Даже банкоматы на дырявом устаревшем дерьме работают.

ReklatsMasters
03.04.2018 08:58Вам придётся очень долго ждать, т.к. удаление require, так же как и new Buffer сломает всю экосистему. Более того, импорты не совместимы с require. Хотя вроде как придумали какой-то костыль для некоторых ситуаций.
В общем, нужно свыкнуться с мыслью, что require останутся в ноде навсегда.
iShatokhin
02.04.2018 22:18Moment.js
Я бы не стал на него ориентироваться сейчас, т.к. авторы создали другой проект, только на этот раз в его основе нативный Intl — moment.github.io/luxon
vintage
03.04.2018 00:45-1И всё-равно те же самые родовые травмы. Я бы рекомендовал всё же эту легковесную шуструю изоморфную библиотеку с отличной поддержкой тайпскрипта: habrahabr.ru/post/263041

Leopotam
03.04.2018 10:02+1Тогда уж date-fns.org вместо монстра moment.js. Да, не весь функционал, но для обычных манипуляций с датами хватит за глаза.

Logans
03.04.2018 07:261. Еще один аналог работы с CSV файлами node-csvtojson
2. Монады monet.js
3. Библиотека для проверки строк string-similarity
4. Библиотека для раскраски текста в терминале chalk
5. Библиотека для конвертирования объектов в вложенные объекты используя ключи dot-object
6. Библиотека для подгрузки environment файлов перед стартом скрипта env-cmd
7. Подборка маленьких скриптов для JavaScript (не совсем библиотека но тоже полезная вещь) 30-seconds-of-code
8. HTTP клиент для браузеров и Node.js axios
Возможно мое описание не достаточно точно поэтому советую читать описание в репозиториях.
P.S. А вообще советую искать на GitHub по тегам Node.js, JavaScript и т.д
helgisbox
05.04.2018 15:01Подумать только, до чего дошел прогресс. Все больше и больше различных средств становится. А минификация штука вообще полезная — трафик меньше будет.
AstarothAst
Самые полезные модули эти, встречайте хитпарад:
is-string — пол миллиона с хвостиком скачиваний за последние 7 дней(https://www.npmjs.com/package/is-string)
is-odd — почти 3 миллиона (https://www.npmjs.com/package/is-odd)
И! Наш лидер!
is-number — почти 10 миллионов скачиваний за последнюю неделю (https://www.npmjs.com/package/is-number)
А вы говорите ;)
Zenitchik
О них и так все знают. А статья о тех, о которых стоит узнать.
ReklatsMasters
Вот что отвечает автор большого количества микромодулей.
justboris
Видимо ни одной статьи о node модулях не обойдется без шуточки об этих модулях. Ха-ха.
А что вы предлагаете взамен? Писать вот эту магию приведения к числу каждый раз заново?
iShatokhin
Если я не ошибаюсь, всю его магию можно сократить до:
justboris
На самом деле есть две функции isFinite()
Number.isFinite()– не работает для строк, содержащих числа, напримерNumber.isFinite('123')вернет falseisFinite. Она вернет true для случая из примера выше, но все равно имеет проблемы, напримерisFinite([])тоже вернет true, хотя очевидно, что это не число.Вот так и получается, что иногда нужен именно пакет is-number.
justboris
UPD не сразу заметил, что вы предлагаете еще добавить приведение
Number. Все равно этого не достаточноis-number в обоих случаях вернет false, как и ожидалось.