Модуль 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 нет.

Что делает promisify
  1. 1 Функция с колбэкомfn(args, (err, result) => …)
  2. 2 util.promisify(fn)Оборачивает в промис-версию
  3. 3 Новая функция → промисfn(args) возвращает Promise
  4. 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.

Частые вопросы

Что делает util.promisify?
Превращает функцию с колбэком в стиле Node (ошибка первым аргументом) в функцию, возвращающую промис. Это позволяет использовать старые API с колбэками через async/await вместо вложенных колбэков.
Зачем нужен util.inspect?
Форматирует любой объект в читаемую строку для отладки, показывая вложенность, скрытые свойства и типы глубже, чем console.log. Можно настроить глубину, цвета и показ несчётных свойств через опции.
Что такое util.debuglog?
Создаёт функцию логирования, которая печатает только если в переменной окружения NODE_DEBUG указано её имя. Это способ оставить отладочные сообщения в коде, но включать их выборочно без правки кода.
Нужен ли ещё promisify, если многие API уже на промисах?
Современные модули вроде fs/promises уже дают промисы, но promisify остаётся нужен для старых библиотек и своих функций с колбэками. Также многие встроенные функции имеют готовый промис-вариант через util.promisify.custom.
Чем util.inspect лучше console.log для объектов?
console.log обрезает глубоко вложенные объекты как [Object] и не показывает служебные свойства. util.inspect с опцией depth раскрывает всю структуру, показывает символы и геттеры — это полнее для отладки сложных объектов.