Node.js Color 模塊實現入門淺析

Node.js 中有不少常用的 Color 模塊,例如 chalk、colors.js、cli-color 等,通過這些模塊我們輸出各種帶顏色、方面區分或者更酷的日誌以及 CLI 工具提示。那麼今天帶大家簡單了解一下 Color 模塊的實現。

ANSI escape code

與前端上對元素內的文字加上了 CSS 修飾一樣。terminal 中輸出的文字包含顏色也是因為文字的數據跟隨了顏色描述的數據。而要了解 terminal 上的顏色,首先需要了解 ANSI escape code。

顏色修飾數據對於 terminal 而言,是跟 "
" 類似的讓顯示出現變化的一種轉義字元。與常見的轉義字元不同,修飾顏色字元(在大部分平台上)按照 CSI codes 的格式以 "ESC" + "[" 字元開頭,形如:ESC[ + code1;code2;...;codeN + m 結束(其中的 code 即修飾顏色的數據)。例如:

echo -e "33[31;42mhello"; # 控制字元[紅色文字;綠色背景結束符號helloecho -e "33[0m"; # 重置顏色修飾echo -e "33[33mworld"; # 控制字元[黃色文字結束符號worldecho -e "33[0m"; # 重置顏色修飾

各位用戶(win除外)可以在 terminal 上嘗試一下執行效果,或者使用 Node.js (包括win)運行以下代碼試試:

console.log("33[31;42mhello"); // 控制字元[紅色文字;綠色背景結束符號helloconsole.log("33[0m"); // 重置顏色修飾console.log("33[33mworld"); // 控制字元[黃色文字結束符號worldconsole.log("33[0m"); // 重置顏色修飾

執行效果:

注意:ESC 轉義字元在 ASCII 碼中十進位是 27,八進位是 033,十六進位是 0x1B。所以在 Node.js 中除了 33 之外還可以寫成 u001b (嚴格模式強制)。

ANSI colors and styles

ANSI 的標準中,特定的 code 表示特定的含義,對於 terminal 的顏色主要有三方面的定義。分別是樣式、顏色、明亮度。

樣式

常見的字體樣式分別是(支持情況視 terminal 而定):

顏色 & 明亮

code 30 - 37 為字體顏色,91 - 97 為字體顏色的明亮版。40 - 47 為背景色,100 - 107 為背景色的明亮版。terminal 的默認字體色 code 是 39,默認背景色是 49。

完整的 code 信息參見 CSI codes 中的 SGR (Select Graphic Rendition) parameters。

Color 模塊實現

了解了 ANSI 編碼中關於顏色部分的知識之後,在 Node.js 中實現一個顏色模塊就很簡單了。

首先我們可以明確一點,跟某段輸出的內容加上顏色,其實要做的事情就是將該內容使用修飾顏色的數據包起來即可。例如輸出一段綠底紅字,相當於輸出 「綠色背景紅色文字修飾數據」 + 「輸出文字」 + 「重置修飾」。其效果可以簡單這樣寫:

function getRedTextGreenBg(text) { return "33[31;42m" + text + "33[0m";}console.log(getRedTextGreenBg("hello world"));

如果了解 CSI codes 的規則就會發現,對於顏色數據 ESC[ + code1;code2;...;codeN + m 的寫法其實和 ESC[ + code1 + m + ESC[ + code2 + m + ... + ESC[ + codeN + m 的效果是一樣的,目前 Node.js 中大部分 Color 模塊都是按照後者的情況來實現的。

完整一點的 styles 數據可以參考 chalk 的 ansi-styles。那麼我這邊換個簡單的思路模仿 chalk 的調用方式來實現一版,供各位大佬圍觀:

"use strict";// 嚴格模式要用 unicode 的十六進位不能用八進位的 33const styles = { // style: [ style code, reset code ] "bold": ["u001b[1m", "u001b[22m"], // ... "black": ["u001b[30m", "u001b[39m"], "red": ["u001b[31m", "u001b[39m"], "green": ["u001b[32m", "u001b[39m"], "yellow": ["u001b[33m", "u001b[39m"], // ... "bgBlack": ["u001b[40m", "u001b[49m"], "bgRed": ["u001b[41m", "u001b[49m"], "bgGreen": ["u001b[42m", "u001b[49m"], "bgYellow": ["u001b[43m", "u001b[49m"], // ...};const color = {};Object.keys(styles).map((key) => color[key] = (text) => styles[key][0] + text + styles[key][1]);console.log( color.bgGreen(color.red("hello,")) + color.yellow(" world!"));

執行效果:


推薦閱讀:

25歲女生多久能學會前端,如何學習?
Firebug 和 Chrome 自帶的開發人員工具相比起來有哪些優缺點?

TAG:Nodejs | 前端开发工具 |