Модуль util в Node.js: промисификация и отладка
Содержание
О проверке кода. Примеры не запускались в этой сессии (по договорённости — фокус на контенте, а не прогонах). Говорим прямо, а не ставим бейдж «проверено».
Модуль util в Node.js — коллекция мелких, но полезных инструментов. Два из них — promisify и inspect — вы будете применять регулярно. Разберём их и несколько других.
promisify: колбэки в промисы
Много старых API Node построены на колбэках в стиле «ошибка первым аргументом». util.promisify переводит их на промисы:
const util = require('node:util');
const fs = require('node:fs');
// старый колбэк-стиль
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) return console.error(err);
console.log(data);
});
// превращаем в промис
const readFile = util.promisify(fs.readFile);
// теперь можно async/await
const data = await readFile('file.txt', 'utf8');
util.promisify берёт функцию с колбэком (err, result) и возвращает функцию, отдающую промис. Это спасает при работе со старыми библиотеками, где нет промис-варианта, — вместо «ада колбэков» получаете чистый async/await. Для файловой системы, впрочем, уже есть готовый fs/promises — promisify нужен для того, у чего своего промис-API нет.
- 1 Функция с колбэкомfn(args, (err, result) => …)
- 2 util.promisify(fn)Оборачивает в промис-версию
- 3 Новая функция → промисfn(args) возвращает Promise
- 4 await во всей красеconst r = await fn(args) + try/catch
inspect: отладочный вывод объектов
const util = require('node:util');
const deep = { a: { b: { c: { d: { e: 1 } } } } };
console.log(deep); // { a: { b: { c: [Object] } } } — обрезано!
console.log(util.inspect(deep, { depth: null })); // раскрыто полностью
util.inspect форматирует объект в читаемую строку и, в отличие от console.log, показывает структуру глубже. console.log обрезает вложенность как [Object] после нескольких уровней. util.inspect с { depth: null } раскрывает всё, а другие опции показывают скрытые (несчётные) свойства, символы, цвета:
util.inspect(obj, {
depth: null, // без ограничения глубины
colors: true, // подсветка типов
showHidden: true, // несчётные свойства
});
Это первый инструмент, когда console.log «съедает» нужную часть сложного объекта.
debuglog: выборочная отладка
const util = require('node:util');
const debug = util.debuglog('myapp');
debug('запрос обработан за %d мс', 42);
// напечатается ТОЛЬКО если запущено с NODE_DEBUG=myapp
util.debuglog создаёт логгер, который молчит, пока его не включат переменной окружения NODE_DEBUG. Оставляете отладочные сообщения прямо в коде, а включаете их выборочно — NODE_DEBUG=myapp node app.js — без правки кода и без засорения продакшн-вывода. Так устроено отладочное логирование самого Node.
Другие полезные утилиты
const util = require('node:util');
// форматирование строк (как console.log, но возвращает строку)
util.format('Привет, %s! Тебе %d лет.', 'Аня', 30);
// 'Привет, Аня! Тебе 30 лет.'
// цветной текст в терминале (свежие версии Node)
util.styleText('red', 'ошибка!');
// пометить функцию устаревшей
const oldFn = util.deprecate(() => {}, 'oldFn устарела, используйте newFn');
// разбор аргументов командной строки
const { values } = util.parseArgs({
options: { verbose: { type: 'boolean' } },
});
util.format— какconsole.log, но возвращает строку (%s,%d,%j);util.styleText— цвета в терминале без внешних библиотек (в свежих версиях Node);util.deprecate— обернуть функцию предупреждением об устаревании;util.parseArgs— разбор аргументов командной строки без зависимостей.
Когда это нужно
util — не то, что открываешь каждый день, но знать стоит:
promisify— при интеграции старых колбэк-библиотек в современный async-код;inspect— когдаconsole.logне показывает нужную глубину объекта;debuglog— для отладочных сообщений, включаемых по флагу;- остальное — точечно, под конкретную задачу.
Правило то же, что и везде: инструмент под задачу. Не тяните внешнюю зависимость, если util уже решает вопрос.
Смежные темы: промисы и async/await — куда ведёт promisify; файловая система — fs/promises; отладка Node.js. Полный список — в уроках Node.js.