web-dev-qa-db-ja.com

Node.js(Windows)でコンソールに絵文字を出力する方法は?

Windowsでは、コンソールにいくつかの基本的な絵文字サポートがあり、入力するとモノクロのグリフを取得できます。 または????。 PowerShellやC#コンソールアプリケーション、またはPythonから文字列を出力できます。それらはすべて、これらの文字を十分に表示します。

ただし、Node.jsから表示できるのは、いくつかの絵文字(例:)のみで、他のものは取得できません(????の代わりにが表示されます)。ただし、これらの文字を含む文字列をthrowした場合、正しく表示されます。

console.log(' ???? ☕ ');
throw ' ???? ☕ ';

上記のスクリプトを実行すると、出力は

 � ☕

C:\Code\emojitest\emojitest.js:2
throw ' ???? ☕ '; 
^
 ???? ☕

エラーをスローせずにそれらの絵文字を正しく出力できるとにかくありますか?または、その例外は、標準のNode.js APIを通じて私が利用できるものの外で発生していますか?

15
bdukes

libuvを変更しないと、必要なものが実現できない場合があります。あなた(またはコンソール)がWindowsでstdoutまたはstderrに書き込み、ストリームがTTYである場合、libuv UTF-8からUTF-16への独自の変換を行います。そうすることで、サロゲートペアの出力を明示的に拒否し、代わりにBMPを超えるコードポイントの置換文字_U+FFFD_�を発行します。

v/src/win/tty.c の原因は次のとおりです。

_  /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */
  /* windows console doesn't really support UTF-16, so just emit the */
  /* replacement character. */
  if (utf8_codepoint > 0xffff) {
    utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
  }
_

Nodeを使用すると、WindowsがMultiByteToWideChar()(サロゲートペアを発行する)を使用してUTF‑8からUTF‑16に変換できるため、throwメッセージが正しく表示されます。メッセージをコンソールに書き込みます(src/node.ccの PrintErrorString()を参照 を参照してください)。

11
Brian Nixon

(免責事項:私には解決策がありません。Windows10にあるツールを使用して絵文字の印刷に関して例外処理を特別なものにしているものについて調べました-いくつかの幸運でいくつかの光を当てるかもしれません問題、そしておそらく誰かが何かを認識して解決策を考え出すでしょう)

Windowsが別のWindows APIを呼び出すためのNodeの例外レポートコードのように見えます。

Node 7.10ソースで見てみましょう:

ReportExceptionAppendExceptionLinePrintErrorString

PrintErrorStringでは、Windows固有のセクション が出力タイプ(tty/consoleかどうか) を検出します:-tty/console以外のコンテキストの場合、stderrに出力されます(たとえば、ファイル)-cmdコンソール(リダイレクトなし)では、 convert text with MultiByteToWideChar() and then pass それをWriteConsoleW()に渡します。

ConEmu を使用してプログラムを実行する場合(標準のcmdを取得してunicodeと絵文字を操作するよりも簡単です-はい、ここでは少し面倒です)、あなたが見たものと同様のものが表示されます。 _console.log_は絵文字の印刷に失敗しますが、例外メッセージの絵文字は(スクロールグリフでも)OKで印刷されます。

すべての出力をファイルにリダイレクトすると(_node test.js > out.txt 2>&1_、はい、Windows cmdでも機能します)、どちらの場合も「クリーン」なUnicodeが得られます。

したがって、Windowsコンソールでプログラムがstdoutまたはstderrに出力すると、出力前にコンソールが何らかの(悪い)再エンコード処理を行います。プログラムがWindowsコンソールAPIを直接使用する場合(MultiByteToWideCharを使用して変換自体を実行し、次にWriteConsoleW()を使用してコンソールに書き込む)、コンソールは見栄えの良い絵文字を表示します。

JSプログラムがconsole APIを使用してログに記録する場合、Nodeが(Windowsの場合)コンソールを検出して、例外の報告と同じことを行う可能性があります。 を参照してください。 @BrianNixonの回答 libuvで実際に起こっていることを説明しています。

2
Hugues M.

次の " Windowsターミナル "(from Kayla Cinnamon )および Microsoft/Terminal プロジェクトは絵文字を表示できる必要があります。

これは2019年6月から利用可能になります。Consolasフォントを使用することで、partialUnicodeサポートが提供されます。

リクエストは進行中です Microsoft/Terminal 387号
そして Microsoft/Terminal issue 19 正式に「Windowsコンソールに絵文字サポートを追加する」を要求します。

しかし、まだ問題があります(2019年3月):

数日前にWin10を1803から1809に更新しましたが、現在、すべての文字> = U + 10000(4バイト以上のUTF-8)が表示されなくなりました。
私は最新のインサイダーバージョン(Windows 10 Insider Preview 18358.1(19h1_release))も試しましたが、残念ながらこのバグはまだ存在しています。

1
VonC