Мы представляем вашему вниманию обзор модулей, которые автор материала, программист, занимающийся, кроме прочего, ещё и веб-разработкой, считает полезными. Среди них — библиотеки для работы с изображениями, средства для проверки того, что пользователи вводят в формы, модули для оптимизации и минификации данных различных типов, инструменты для создания 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/luxonvintage
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, как и ожидалось.