最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

nodejs控制臺打印高亮代碼的實(shí)現(xiàn)方法

 更新時間:2021年05月11日 12:08:07   作者:神說要有光zxg  
這篇文章主要給大家介紹了關(guān)于nodejs控制臺打印高亮代碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

當(dāng)代碼運(yùn)行報錯時,我們會打印錯誤,錯誤中有堆棧信息,可以定位到對應(yīng)的代碼位置。但有的時候我們希望能夠更直接準(zhǔn)確的打印報錯位置的代碼。比如這樣:

這個可以使用 @babel/code-frames 來做到:

const { codeFrameColumns } = require('@babel/code-frame');

const res = codeFrameColumns(code, {
  start: { line: 2, column: 1 },
  end: { line: 3, column: 5 },
}, {
  highlightCode: true,
  message: '這里出錯了'
});

console.log(res);

有沒有感覺比較神奇,它是怎么做到的打印出上面的代碼格式的(code frame)?

本文我們就來探究下原理。

主要會解答三個問題:

  • 如何打印出標(biāo)記相應(yīng)位置代碼的 code frame(就是上圖的打印格式)
  • 如何實(shí)現(xiàn)語法高亮
  • 如何在控制臺打印顏色

如何打印 code frame

我們先不管高亮,實(shí)現(xiàn)這樣的格式的打?。?/p>

有啥思路沒?

其實(shí)也比較容易想到,傳入了源代碼、標(biāo)記開始和結(jié)束的行列號,那么我們就能夠計算出顯示標(biāo)記(marker)的行是哪些,以及這些行的哪些列,然后依次對每一行代碼做處理,如果本行沒有標(biāo)記則保持原樣,如果本行有標(biāo)記的話,那么就在開始打印一個 marker “>”,并且在下面打印一行 marker "^",最后一個標(biāo)記行還要打印錯誤信息。

我們來看一下 @babel/code-frame 的實(shí)現(xiàn):

首先,分割字符串成每一行的數(shù)組,然后根據(jù)傳入的位置計算出 marker 所在的位置。

比如圖中第二行的第 1 到 12 列,第三行的 0 到 5 列。

然后對每一行做處理,如果本行有標(biāo)記,則拼成 marker + gutter(行號) + 代碼的格式,下面再打印一行 marker,最后的 marker 行打印 message。沒有標(biāo)記不處理。

這樣最終拼出的就是這樣的 code frame:

我們實(shí)現(xiàn)了 code frame 的拼接,暫時忽略了高亮,那么怎么做語法高亮呢?

如何實(shí)現(xiàn)語法高亮

實(shí)現(xiàn)語法高亮需要理解代碼,但是如果只是高亮,詞法分析就足夠了。babel 也是這么做的,@babel/highlight 包里面完成了高亮代碼的邏輯。

先看效果:

const a = 1;
const b = 2;
console.log(a + b);

上面的源碼被分成了 token 數(shù)組:

[
  [ 'whitespace', '\n' ], [ 'keyword', 'const' ],
  [ 'whitespace', ' ' ],  [ 'name', 'a' ],
  [ 'whitespace', ' ' ],  [ 'punctuator', '=' ],
  [ 'whitespace', ' ' ],  [ 'number', '1' ],
  [ 'punctuator', ';' ],  [ 'whitespace', '\n' ],
  [ 'keyword', 'const' ], [ 'whitespace', ' ' ],
  [ 'name', 'b' ],        [ 'whitespace', ' ' ],
  [ 'punctuator', '=' ],  [ 'whitespace', ' ' ],
  [ 'number', '2' ],      [ 'punctuator', ';' ],
  [ 'whitespace', '\n' ], [ 'name', 'console' ],
  [ 'punctuator', '.' ],  [ 'name', 'log' ],
  [ 'bracket', '(' ],     [ 'name', 'a' ],
  [ 'whitespace', ' ' ],  [ 'punctuator', '+' ],
  [ 'whitespace', ' ' ],  [ 'name', 'b' ],
  [ 'bracket', ')' ],     [ 'punctuator', ';' ],
  [ 'whitespace', '\n' ]
]

token 怎么分的呢?

一般來說詞法分析就是有限狀態(tài)自動機(jī)(DFA),但是這里實(shí)現(xiàn)比較簡單,是通過正則匹配的:

js-tokens 這個包暴露出來一個正則,一個函數(shù),正則是用來識別 token 的,其中有很多個分組,而函數(shù)里面是對不同的分組下標(biāo)返回了不同的類型,這樣就能完成 token 的識別和分類。

在 @babel/highlight 包里也是這樣用的:

(正則來做詞法分析有很多限制條件,比如不能處理遞歸的情況,所以這種方式不是通用的,通用詞法分析還是得用狀態(tài)機(jī) DFA。)

有了分類之后,不同 token 顯示不同顏色,建立個 map 就行了。

@babel/highlight 也是這么做的:

我們知道了怎么做語法高亮,使用 chalk 的 api 就可以打印顏色,那控制臺打印顏色的原理是什么呢?

如何在控制臺打印顏色

控制臺打印的是 ASCII 碼,并不是所有的編碼都對應(yīng)可見字符,ASCII 碼有一部分字符是對應(yīng)控制字符的,比如 27 是 ESC,就是我們鍵盤上的 ESC 鍵,是 escape 的縮寫,按下它可以完成一些控制功能,這里我們可以通過打印 ESC 的 ASCII 碼來進(jìn)入控制打印顏色的狀態(tài)。

格式是這樣的:

打印一個 ESC 的 ASCII 碼,之后是 [ 代表開始,m 代表結(jié)束,中間是用 ; 分隔的 n 個控制字符,可以控制很多樣式,比如前景色、背景色、加粗、下劃線等等。

ESC 的 ASCII 碼是 27,有好幾種寫法:一種是字符表示的 \e ,一種是 16 進(jìn)制的 \0x1b(27 對應(yīng)的 16進(jìn)制),一種是 8 進(jìn)制的 \033,這三種都表示 ESC。

我們來試驗(yàn)一下:1 表示加粗、36 表示前景色為青色、4 表示下劃線,下面三種寫法等價:

\e[36;1;4m
\033[36;1;4m
\0x1b[36;1;4m

我們來試一下:

圖片都打印了正確的樣式!

當(dāng)然,加了樣式還要去掉,可以加一個 \e[0m 就可以了(\033[0m,\0x1b[0m 等價)。

chalk(nodejs 的在終端打印顏色的庫)的不同方法就是封裝了這些 ASCII 碼的顏色控制字符。

上面每行代碼被高亮過以后的代碼是:

這樣也就實(shí)現(xiàn)了不同顏色的打印。

總結(jié)

至此,我們能實(shí)現(xiàn)開頭的效果了:支持 code frame 的打印,支持語法高亮,能夠打印顏色

本文我們探究了這種效果的實(shí)現(xiàn)原理,先從 code frame 是怎么拼接的,然后每一行的代碼是怎么做高亮的,之后是高亮具體是怎么打印顏色的。

不管是 code frame 的打印,還是語法高亮或者控制臺打印顏色,都是特別常見的功能,希望這篇文章能夠幫你徹底掌握這 3 方面的原理。

到此這篇關(guān)于nodejs控制臺打印高亮代碼的文章就介紹到這了,更多相關(guān)nodejs控制臺打印高亮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Node.js中參數(shù)傳遞的兩種方式詳解

    Node.js中參數(shù)傳遞的兩種方式詳解

    這篇文章主要為大家介紹了Node.js中參數(shù)傳遞的兩種方式:GET方式和POST方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-04-04
  • 手把手帶你搭建一個node cli的方法示例

    手把手帶你搭建一個node cli的方法示例

    這篇文章主要介紹了手把手帶你搭建一個node cli的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 教你如何在Node.js中使用jQuery

    教你如何在Node.js中使用jQuery

    本文給大家分享的是如何在Node.js中使用jQuery的方法,包含步驟以及出錯的處理,非常的詳細(xì),有需要的小伙伴可以參考下
    2016-08-08
  • 利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟

    利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟

    最近工作中遇到一個需求,大致需求就是將Excel文件在導(dǎo)入時解析為json格式轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu)再傳輸給后臺,下面這篇文章主要給大家介紹了關(guān)于如何利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟,需要的朋友可以參考下
    2022-11-11
  • KOA+egg.js集成kafka消息隊列的示例

    KOA+egg.js集成kafka消息隊列的示例

    這篇文章主要介紹了KOA+egg.js集成kafka消息隊列的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Node.js開發(fā) path路徑模塊詳解

    Node.js開發(fā) path路徑模塊詳解

    path 模塊是 Node.js 官方提供的、用來處理路徑的模塊,它提供了一系列的方法和屬性,用來滿足用戶對路徑的處理需求,這篇文章主要介紹了Node.js開發(fā) path路徑模塊,需要的朋友可以參考下
    2024-02-02
  • Node.js 使用 Express-Jwt和JsonWebToken 進(jìn)行Token身份驗(yàn)證的操作方法

    Node.js 使用 Express-Jwt和JsonWebToken 進(jìn)行Token身份

    這篇文章主要介紹了Node.js 使用 Express-Jwt和JsonWebToken 進(jìn)行Token身份驗(yàn)證的操作方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • node.js中PC端微信小程序包解密的處理思路

    node.js中PC端微信小程序包解密的處理思路

    我們使用node.js去寫一個解碼的程序。根據(jù)上邊加密的流程,我們首先讀取加密文件,把前6個字節(jié)的固定字符串去除,這篇文章主要介紹了node.js中PC端微信小程序包解密,需要的朋友可以參考下
    2021-12-12
  • Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑

    Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑

    這篇文章主要介紹了Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑
    2016-04-04
  • Node.js操作MongoDB數(shù)據(jù)庫實(shí)例分析

    Node.js操作MongoDB數(shù)據(jù)庫實(shí)例分析

    這篇文章主要介紹了Node.js操作MongoDB數(shù)據(jù)庫,結(jié)合實(shí)例形式分析了node.js連接MongoDB數(shù)據(jù)庫以及增刪改查等相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01

最新評論

嘉义县| 奉新县| 青铜峡市| 东乡族自治县| 赫章县| 清丰县| 泰宁县| 阳谷县| 临夏县| 成都市| 延边| 池州市| 齐齐哈尔市| 慈利县| 始兴县| 含山县| 新乐市| 黄平县| 深圳市| 固镇县| 墨竹工卡县| 轮台县| 普兰县| 高安市| 庄浪县| 项城市| 花莲市| 惠水县| 商都县| 东明县| 扶余县| 唐河县| 赤峰市| 蕉岭县| 湾仔区| 聂拉木县| 瑞金市| 江津市| 刚察县| 广平县| 卢氏县|