如何在Node.js中输出表情符号(在Windows上)?

时间:2017-05-18 18:05:52

标签: node.js windows unicode console emoji

在Windows上,控制台中有一些基本的表情符号支持,因此如果输入,我可以获得单色字形,例如: 。我可以从PowerShell或C#控制台应用程序或Python输出一个字符串,它们都显示这些字符足够好。

然而,从Node.js,我只能显示几个表情符号(例如),而不是其他表情符号(而不是我看到)。但是,如果我throw包含这些字符的字符串,它们会正确显示。

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

如果我运行上面的脚本,输出是

 � ☕

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

无论如何我能正确输出那些表情符号而不会抛出错误吗?或者,除了通过标准Node.js API可以使用的内容之外,是否发生了异常?

3 个答案:

答案 0 :(得分:10)

如果不更改 libuv ,可能无法获得所需内容。当您(或控制台)在Windows上写入stdoutstderr且流是TTY时, libuv 会自行从UTF-8转换为UTF-16。在这样做时,它明确拒绝输出代理对,而是为BMP之外的任何代码点发出替换字符U+FFFD。。

以下是uv/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;
  }

throw消息正确显示,因为Node在将消息写入控制台之前允许Windows使用MultiByteToWideChar()(发出代理项对)从UTF-8转换为UTF-16。 (见PrintErrorString() in src/node.cc。)

答案 1 :(得分:2)

(免责声明:我没有解决方案,我使用Windows 10上的工具探索使打印表情符号处理异常处理的原因 - 运气好的话可能会对这个问题有所了解,也许有人会认识到某些事情并提出解决方案)

看起来Node的异常报告代码用于Windows调用不同的Windows API,这恰好可以更好地支持Unicode。

让我们看一下Node 7.10的来源:

ReportException  → AppendExceptionLine  → PrintErrorString

PrintErrorString中,特定于Windows的部分detects output type (tty/console or not):   - 对于非tty /控制台上下文,它将打印到stderr(例如,如果您重定向到文件)   - 在cmd控制台中(没有重定向),它将convert发送MultiByteToWideChar()文本,然后发送pass发送到WriteConsoleW()

如果我使用ConEmu运行您的程序(比使用unicode和表情符号更容易获得标准cmd - 是的,我在这里有点懒惰),我看到类似于您所看到的内容:console.log无法打印表情符号,但异常消息中的表情符号打印正常(即使是滚动字形)。

如果我将所有输出重定向到一个文件(node test.js > out.txt 2>&1,也可以在Windows cmd中运行),我会得到" clean"在这两种情况下都是Unicode。

因此,当程序在Windows控制台中打印到stdoutstderr时,控制台会在打印前执行一些(不良)重新编码工作。当程序直接使用Windows控制台API时(使用MultiByteToWideChar进行转换,然后使用WriteConsoleW()写入控制台),控制台会显示光荣的未经改动的表情符号。

当JS程序使用console API记录内容时,Node可能会尝试(在Windows上)检测控制台并执行与报告异常相同的操作。请参阅@BrianNixon's answer,其中解释了libuv中实际发生的情况。

答案 2 :(得分:0)

下一个“ Windows Terminal”(来自Kayla Cinnamon)和Microsoft/Terminal项目应该能够显示表情符号。

这将从2019年6月开始提供。 通过使用Consolas字体,将提供 partial Unicode支持。

Microsoft/Terminal issue 387中的请求正在进行中。
并且Microsoft/Terminal issue 190正式要求“向Windows控制台添加表情符号支持”。

但是仍然存在问题(2019年3月):

  

几天前我将Win10从1803更新为1809,现在不再显示所有字符> = U + 10000(UTF-8具有4个字节或更多)。
  我还尝试了最新的内部人员版本(Windows 10内部人员预览版18358.1(19h1_release)),不幸的是,此错误仍然存​​在。