Node.js コンソールで強調表示されたコードを印刷する方法

Node.js コンソールで強調表示されたコードを印刷する方法

序文

コードを実行してエラーが発生すると、エラーが出力されます。エラーにはスタック情報が含まれており、これを使用して対応するコードの場所を見つけることができます。しかし、エラー箇所のコードをより直接的かつ正確に印刷したい場合もあります。例えば:

これは @babel/code-frames を使用して実行できます。

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

const res = codeFrameColumns(コード, {
  開始: { 行: 2, 列: 1 },
  終了: { 行: 3、列: 5 },
}, {
  ハイライトコード: true、
  メッセージ: 「ここで問題が発生しました」
});

コンソールログ(res);

魔法のように感じますか? 上記のコード形式 (コード フレーム) をどのように印刷するのでしょうか?

この記事では、その原則について説明します。

以下の 3 つの主な質問に答えます。

  • 対応する位置コードをマークするコードフレームの印刷方法(上図の印刷形式)
  • 構文強調表示を実装する方法
  • コンソールで色を印刷する方法

コードフレームを印刷する方法

ハイライトを無視して、次の形式で印刷してみましょう。

何かアイデアはありますか?

実際、考えるのは比較的簡単です。ソース コードと、マークの開始と終了の行番号と列番号を渡した後、どの行と列にマーカーが表示されるかを計算し、各コード行を順番に処理します。この行にマーカーがない場合は、そのままにします。この行にマーカーがある場合は、先頭にマーカー ">" を印刷し、その下にマーカー "^" の行を印刷します。最後のマーカー行には、エラー メッセージも印刷されます。

@babel/code-frame の実装を見てみましょう。

まず、文字列を行ごとに配列に分割し、渡された位置に基づいてマーカーの位置を計算します。

たとえば、2 行目には列 1 ~ 12、3 行目には列 0 ~ 5 です。

次に各行を処理します。この行にマークがある場合は、マーカー + ガター (行番号) + コードの形式で綴られます。次に別のマーカー行を印刷し、最後のマーカー行にメッセージを印刷します。マークなしは処理されません。

最終的なコードフレームは次のようになります。

コード フレームのスプライシングを実装し、ハイライトを一時的に無視しました。では、構文のハイライトはどのように行うのでしょうか?

構文強調表示を実装する方法

構文の強調表示を実装するにはコードを理解する必要がありますが、強調表示だけであれば、字句解析で十分です。 Babel も同じことを行います。@babel/highlight パッケージは、コードを強調表示するロジックを実装します。

まず効果を見てみましょう:

定数a = 1;
定数b = 2;
コンソールにログ出力します。

上記のソース コードはトークン配列に分割されています。

[
[ '空白', '\n' ], [ 'キーワード', 'const' ],
[ '空白', ' ' ], [ '名前', 'a' ],
[ '空白', ' ' ], [ '句読点', '=' ],
[ '空白', ' ' ], [ '数字', '1' ],
[ '句読点', ';' ], [ '空白', '\n' ],
[ 'キーワード', 'const' ], [ '空白', ' ' ],
[ '名前', 'b' ], [ '空白', ' ' ],
[ '句読点', '=' ], [ '空白', ' ' ],
[ '数字', '2' ], [ '句読点', ';' ],
[ '空白', '\n' ], [ '名前', 'コンソール' ],
[ '句読点', '.' ], [ '名前', 'ログ' ],
[ '括弧', '(' ], [ '名前', 'a' ],
[ '空白', ' ' ], [ '句読点', '+' ],
[ '空白', ' ' ], [ '名前', 'b' ],
[ '括弧', ')' ], [ '句読点', ';' ],
[ '空白', '\n' ]
]

トークンはどのように分割されますか?

一般的に言えば、字句解析は有限状態オートマトン (DFA) ですが、ここでの実装は規則的なマッチングを通じて比較的単純です。

js-tokens パッケージは、正規表現と関数を公開します。正規表現はトークンを識別するために使用されます。正規表現には多くのグループがあり、関数はグループ添字ごとに異なるタイプを返すため、トークンの識別と分類を完了できます。

これは @babel/highlight パッケージでも使用されます:

(正規表現には、再帰を処理できないなど、字句解析に関する多くの制限があるため、この方法は普遍的ではありません。一般的な字句解析では、依然としてステート マシン (DFA) を使用する必要があります。)

分類が完了すると、異なるトークンが異なる色で表示され、マップを作成できます。

@babel/highlight も同じことを行います:

Chalk の API を使用して構文の強調表示や色の印刷を行う方法はわかっていますが、コンソールで色を印刷する原理は何でしょうか?

コンソールで色を印刷する方法

コンソールは ASCII コードを出力しますが、すべてのコードが可視文字に対応しているわけではありません。ASCII コードの一部の文字は制御文字に対応しています。たとえば、27 は ESC です。これはキーボードの ESC キーで、エスケープの略です。これを押すと、いくつかの制御機能を実行できます。ここで、ESC の ASCII コードを出力することで、印刷色を制御する状態に入ることができます。

形式は次のとおりです。

ESC の ASCII コードを出力し、その後に開始を表す [、終了を表す m、その間に ; で区切られた n 個の制御文字を出力します。これにより、前景色、背景色、太字、下線などの多くのスタイルを制御できます。

ESC の ASCII コードは 27 で、書き方はいくつかあります。1 つは文字表現 \e、1 つは 16 進数の \0x1b (27 に対応する 16 進数)、もう 1 つは 8 進数の \033 です。3 つとも ESC を表します。

試してみましょう: 1 は太字、36 は前景色がシアン、4 は下線を意味します。次の 3 つの書き方は同じです。

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

試してみましょう:

写真はすべて正しいスタイルで印刷されています。

もちろん、スタイルを追加した後に削除したい場合は、\e[0m を追加できます (\033[0m、\0x1b[0m は同等です)。

chalk (ターミナルで色を印刷するための nodejs ライブラリ) のさまざまな方法は、これらの ASCII カラー制御文字をカプセル化することです。

上記のコードの各行の後のコードが強調表示されています。

これにより、さまざまな色での印刷が可能になります。

要約する

この時点で、当初の効果を実現できます。コードフレームの印刷をサポートし、構文の強調表示をサポートし、カラーで印刷できます。

この記事では、コード フレームの結合方法から始めて、コードの各行を強調表示する方法、強調表示をカラーで印刷する方法まで、この効果の実装原理について説明します。

コード フレームの印刷、構文の強調表示、コンソールの印刷色など、これらはすべて非常に一般的な機能です。この記事が、これら 3 つの側面の原理を徹底的に習得するのに役立つことを願っています。

これで、Node.js コンソールのハイライト印刷コードに関するこの記事は終了です。Node.js コンソールのハイライト印刷に関する関連コンテンツをさらにご覧になりたい場合は、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Node とブラウザ コンソールで色付きのテキストを印刷する方法

<<:  CentOS 7でsambaを使用してフォルダーを共有するための完全な手順

>>:  CentOS の MySQL に MariaDB をインストールするときに発生する方法と問題

推薦する

ウェブページのテーブルの境界線を設定する方法

<br />前回は、Web テーブルにセルの線を設定する方法を学びました。今日は、Web...

CSSマスクのフルスクリーン中央揃えを実装する方法

具体的なコードは次のとおりです。 <スタイル> #トーストローダーフルスクリーン{ 高さ...

nestjs における例外フィルター Exceptionfilter の具体的な使用法

Nestjs 例外フィルターといえば、非常に強力な .Net のグローバル フィルターについて触れな...

ボリュームを使用してホストと Docker コンテナ間でファイルを転送する方法

以前、Docker コンテナとローカル マシン間のファイル転送に関する記事を書きました。しかし、この...

JS関数のカリー化の詳細な説明

目次1. 補足知識ポイント: 関数の暗黙的な変換2. 補足知識: call/apply を使って配列...

Linux で pyenv をインストールする方法

前提条件gitをインストールする必要があるインストール手順1. リモートリポジトリからpyenvをク...

Vueプロジェクトはログインと登録の効果を実現します

この記事の例では、ログインと登録の効果を実現するためのvueプロジェクトの具体的なコードを共有してい...

Vue の computed と watch の違いを分析する

目次1. 計算入門1.1、getとsetの使い方1.2. 計算された属性キャッシュ2. 時計の紹介3...

MySQL の自動増分主キーが使い果たされた場合の対処方法

面接では、次のようなシナリオを経験する必要があります。インタビュアー: 「MySQL を使用したこと...

優秀なウェブ開発者が開発スキルを向上させるために知っておくべき10のこと

「開発とは、単にコードを書くだけではない」というのは、3EV の Dan Frost 氏の言葉です。...

Vue Element フロントエンドアプリケーション開発 従来の Element インターフェースコンポーネント

目次1. リストインターフェースとその他のモジュールの表示処理2. 従来のインターフェースコンポーネ...

Vue-Jest自動テストの基本構成の詳しい説明

目次インストール構成よくある間違い事前テスト作業依存関係の扱いインスタンスとDOMを生成する要約する...

CSSはマウスが画像に移動したときにマスク効果を実現します

1.マスクレイヤーのHTMLコードと画像をdivに配置する.img_div に入れました。 <...

crontab の実行結果を電子メールでユーザーに通知する方法

症状Centos7 ホストに crontab タスクを設定しましたが、時間が来るとメールを実行して「...