零弐壱蜂

[Node.js] ChalkやpicocolorsをstyleTextに置き換える方法

はじめに

Node.js v20.12.0でutil.styleTextが追加され、v22.13.0でStable APIとなった。これにより、ターミナルのテキスト装飾に外部パッケージが不要になるケースが増えている。

util.styleTextとは

node:utilモジュールに組み込まれたテキストスタイリング関数である。ANSIエスケープシーケンスを使い、ターミナル出力に色や装飾を適用する。

import { styleText } from 'node:util';

// 単一スタイル
console.log(styleText('red', 'Error! Error!'));

// 複数スタイルの組み合わせ(配列構文)
console.log(styleText(['bold', 'underline'], 'Important message'));

配列で渡した場合、左から右の順にスタイルが適用される。同系統のスタイルを複数指定すると、後のものが前のものを上書きする点に注意が必要である。

// greenが適用される(redをgreenが上書き)
console.log(styleText(['red', 'green'], 'text'));

利用可能なスタイル

util.inspect.colorsに定義されたフォーマットを使用できる。

グループスタイル
修飾子reset, bold, dim, italic, underline, doubleunderline, strikethrough, hidden, overlined, blink, inverse, framed
前景色black, red, green, yellow, blue, magenta, cyan, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright
背景色bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite および各Brightバリアント

Chalkからの移行

対応機能:

Compatible Features:

  • Basic colors (red, green, blue, yellow, etc.)
  • Bright colors (redBright, greenBright, etc.)
  • Background colors (bgRed, bgGreen, etc.)
  • Text modifiers (bold, dim, italic, underline, strikethrough, etc.)
  • Style chaining via array syntax
  • Environment variable support (NO_COLOR, NODE_DISABLE_COLORS, FORCE_COLOR)

互換のない機能:

Incompatible Features:

  • Custom RGB colors (chalk.rgb(), chalk.hex())
  • 256-color palette (chalk.ansi256())
  • Template literal syntax (chalk...``)
  • Advanced modifiers with limited terminal support (overline, blink, etc.)

変換例

Chalkはメソッドチェインで複数スタイルを組み合わせる構文を持つ。

Before(Chalk)After(styleText)
import chalk from 'chalk';

// 単色
console.log(chalk.red('Error message'));

// メソッドチェインで複数スタイルを組み合わせ
console.log(chalk.red.bold('Important error'));

// チェインした結果を変数に代入して再利用
const red = chalk.red;
console.log(red('Error'));

const boldBlue = chalk.blue.bold;
console.log(boldBlue('Info'));
import { styleText } from 'node:util';

// 単色
console.log(styleText('red', 'Error message'));

// 複数スタイル(配列構文)
console.log(styleText(['red', 'bold'], 'Important error'));

// 関数として部分適用する場合
const red = (text) => styleText('red', text);
console.log(red('Error'));

const boldBlue = (text) => styleText(['blue', 'bold'], text);
console.log(boldBlue('Info'));

picocolorsからの移行

picocolorsはChalkの軽量な代替として広く使われているパッケージである。パッケージサイズはChalk(101kB)に対して7kB、ロード時間もChalk(約6ms)に対して約0.5msである。PostCSS、SVGO、Stylelint、Browserslistなどで採用されている。

Chalkと異なりメソッドチェインをサポートしていない。複数スタイルの適用は関数のネストで行う。

picocolorsもstyleTextで置き換え可能な機能はChalkと同様に置き換え可能である。

Before(picocolors)After(styleText)
import pc from 'picocolors';

// 単色
console.log(pc.red('Error'));

// チェインではなく関数のネストで複数スタイルを組み合わせる
console.log(pc.bold(pc.blue('Info')));

// テンプレートリテラル内でのネスト
console.log(pc.green(`Status: ${pc.bold('OK')}`));
import { styleText } from 'node:util';

// 単色
console.log(styleText('red', 'Error'));

// picocolorsのネスト呼び出しを配列構文で1回にまとめられる
console.log(styleText(['blue', 'bold'], 'Info'));

// テンプレートリテラル内でのネスト
console.log(styleText('green', `Status: ${styleText('bold', 'OK')}`));

picocolorsのネスト構文もstyleTextのネスト構文も冗長になりがちだが、styleTextは配列構文で1要素に複数スタイルを適用する場合にまとめられる点で簡潔になる。

codemodによる自動変換

Node.jsプロジェクトがChalk向けの公式codemodを提供しており自動で移行もできる。ちなみにpicocolors向けのcodemodは提供されていない。

npx codemod @nodejs/chalk-to-util-styletext

codemodが処理する内容:

  • chalkのメソッド呼び出しをstyleTextに変換
  • import文の書き換え
  • package.jsonからのchalkパッケージの削除

参考資料