이 글에서는 nodejs가 강조 표시된 코드를 콘솔에 인쇄하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
코드가 실행되고 오류가 보고되면 오류를 인쇄합니다. 오류에는 스택 정보가 있으며 해당 코드 위치를 찾을 수 있습니다. 하지만 때로는 오류 위치의 코드를 더 직접적이고 정확하게 인쇄하고 싶을 때가 있습니다. [추천 학습: "nodejs tutorial"]
예:
이 작업은 @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);
더 마법적인 느낌이 드시나요? 인쇄는 무엇인가요? 위 코드의 코드 프레임은 무엇입니까?
이 글에서는 원리를 살펴보겠습니다.
주로 세 가지 질문에 답변해 드립니다.
먼저 강조 표시를 무시하고 다음 형식으로 인쇄를 구현해 보겠습니다.
어떤 아이디어가 있나요?
사실 소스 코드와 마크의 시작과 끝의 행과 열 번호를 전달하면 어느 행에 마커(마커)가 표시되는지, 어느 열에 표시되는지 계산할 수 있습니다. 그런 다음 각 행을 차례로 수행합니다. 이 줄에 표시가 없으면 그대로 유지됩니다. 이 줄에 표시가 있으면 시작 부분에 표시가 인쇄됩니다. “>”
,并且在下面打印一行 marker "^"
, 마지막으로 표시된 줄에 오류 메시지가 인쇄됩니다.
@babel/code-frame의 구현을 살펴보겠습니다.
먼저 문자열을 각 줄의 배열로 분할한 다음 전달된 위치를 기준으로 마커의 위치를 계산합니다.
예를 들어 사진에서 두 번째 행의 1~12열, 세 번째 행의 0~5열입니다.
그런 다음 각 줄을 처리하면 이 줄에 표시가 있으면 마커 + 여백(줄 번호) + 코드 형식이 됩니다. 다음으로 마커 줄, 마지막 마커 줄을 인쇄합니다. 메시지를 인쇄합니다. 태그가 처리되지 않습니다.
최종 코드 프레임은 다음과 같습니다.
코드 프레임의 스플라이싱을 구현하고 당분간 강조 표시를 무시했습니다. 그러면 구문 강조를 어떻게 해야 할까요?
구문 강조를 구현하려면 코드에 대한 이해가 필요하지만, 단순히 강조만 한다면 어휘 분석이면 충분합니다. Babel은 동일한 작업을 수행하며 코드 강조 논리는 @babel/highlight 패키지에서 완성됩니다.
먼저 효과를 살펴보겠습니다.
const a = 1; const b = 2; console.log(a + b);
위 소스코드는 토큰 배열로 나누어져 있습니다.
[ [ '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' ] ]
토큰은 어떻게 나누어지나요?
일반적으로 어휘 분석은 유한 상태 자동 장치(DFA)이지만 여기서의 구현은 정규 일치를 통해 비교적 간단합니다.
js-tokens 이 패키지는 정규 표현식과 함수를 노출하며 정규 표현식은 다음 작업에 사용됩니다. 토큰 식별 , 많은 그룹이 있으며 함수는 다양한 그룹 첨자에 대해 다양한 유형을 반환하므로 토큰 식별 및 분류가 완료될 수 있습니다.
는 @babel/highlight 패키지에도 사용됩니다:
(일반 어휘 분석에는 재귀를 처리할 수 없는 등 많은 제한이 있으므로 이 방법은 보편적이지 않습니다. 보편적인 어휘 분석 분석 여전히 상태 머신 DFA를 사용해야 합니다.)
분류 후에는 서로 다른 토큰이 서로 다른 색상을 표시하고 지도를 생성합니다.
@babel/highlight도 다음을 수행합니다.
우리는 구문 강조를 수행하는 방법과 분필 API를 사용하여 색상을 인쇄하는 방법을 알고 있습니다. 그렇다면 콘솔에 색상을 인쇄하는 원리는 무엇입니까?
控制台打印的是 ASCII 码,并不是所有的编码都对应可见字符,ASCII 码有一部分字符是对应控制字符的,比如 27 是 ESC,就是我们键盘上的 ESC 键,是 escape 的缩写,按下它可以完成一些控制功能,这里我们可以通过打印 ESC 的 ASCII 码来进入控制打印颜色的状态。
格式是这样的:
打印一个 ESC
的 ASCII 码,之后是 [
代表开始,m
代表结束,中间是用 ;
分隔的 n 个控制字符,可以控制很多样式,比如前景色、背景色、加粗、下划线等等。
ESC 的 ASCII 码是 27,有好几种写法:一种是字符表示的 \e
,一种是 16 进制的 \0x1b
(27 对应的 16进制),一种是 8 进制的 \033
,这三种都表示 ESC。
我们来试验一下: 1 表示加粗、36 表示前景色为青色、4 表示下划线,下面三种写法等价:
\e[36;1;4m \033[36;1;4m \0x1b[36;1;4m
我们来试一下:
都打印了正确的样式!
当然,加了样式还要去掉,可以加一个 \e[0m
就可以了(\033[0m
,\0x1b[0m
等价)。
chalk(nodejs 的在终端打印颜色的库)的不同方法就是封装了这些 ASCII 码的颜色控制字符。
上面每行代码被高亮过以后的代码是:
这样也就实现了不同颜色的打印。
至此,我们能实现开头的效果了:支持 code frame 的打印,支持语法高亮,能够打印颜色
本文我们探究了这种效果的实现原理,先从 code frame 是怎么拼接的,然后每一行的代码是怎么做高亮的,之后是高亮具体是怎么打印颜色的。
不管是 code frame 的打印,还是语法高亮或者控制台打印颜色,都是特别常见的功能,希望这篇文章能够帮你彻底掌握这 3 方面的原理。
更多编程相关知识,请访问:编程视频!!
위 내용은 nodejs가 콘솔에 강조 표시된 코드를 인쇄하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!