Wie wird Emoji in Node.js (unter Windows) zur Konsole ausgegeben?

9

Unter Windows gibt es einige grundlegende Emoji-Unterstützung in der Konsole, so dass ich eine monochrome Glyphe erhalten kann, wenn ich z. oder

bdukes 18.05.2017, 18:05
quelle

2 Antworten

7

Was Sie wollen, ist möglicherweise nicht möglich, ohne libuv zu ändern. Wenn Sie (oder die Konsole) schreiben stdout oder stderr auf Windows und der Strom ist ein TTY, libuv hat seine eigene Konvertierung von UTF-8 in UTF-16. Dabei lehnt es ausdrücklich zur Ausgabe Ersatzpaaren, emittiert, anstatt das Ersatzzeichen U+FFFD für jeden Codepunkt über das BMP.

Hier ist der Täter in uv / src / win /tty.c :

%Vor%

Die throw Nachricht richtig angezeigt wird, weil Knoten läßt Windows die Konvertierung von UTF-8 in UTF-16 mit MultiByteToWideChar() tun (die Ersatzpaare emittieren wird), bevor die Nachricht an die Konsole zu schreiben. (Siehe PrintErrorString() in src / node.cc .)

    
Brian Nixon 25.05.2017, 10:45
quelle
2

(Disclaimer: Ich habe keine Lösung, ich habe untersucht, was Exception-Handling in Bezug auf das Drucken von Emoji besonders macht, mit den Tools, die ich auf Windows 10 habe - mit etwas Glück, das vielleicht geplant wurde etwas Licht auf das Thema, und vielleicht jemand wird etwas erkennen und mit einer Lösung kommen)

Sieht aus wie der Ausnahmeberichtscode von Node für Windows-Aufrufe an eine andere Windows-API, die Unicode besser unterstützt.

Sehen wir uns mit Knoten 7.10 Quellen an:

ReportException  → AppendExceptionLine  → PrintErrorString

In PrintErrorString erkennt der Windows-spezifische Abschnitt den Ausgabetyp (tty / Konsole oder nicht) :  - Für nicht-tty / console context wird es auf stderr gedruckt (z. B. wenn Sie in eine Datei umleiten)  - In einer Cmd-Konsole (ohne Umleitung) wird konvertiert Text mit MultiByteToWideChar() und dann übergeben das an WriteConsoleW() .

Wenn ich dein Programm mit ConEmu ausführe (einfacher als standardmäßiges cmd zu bekommen, um mit Unicode & amp; emoji zu arbeiten - ja, ich hier etwas faul), sehe ich etwas Ähnliches wie das, was du gesehen hast: console.log kann Emoji nicht drucken, aber die Emoji in der Ausnahmemeldung werden OK gedruckt (sogar das Scroll-Zeichen).

Wenn ich alle Ausgaben in eine Datei umleite ( node test.js > out.txt 2>&1 , ja das funktioniert auch in Windows cmd), bekomme ich in beiden Fällen "sauberen" Unicode.

So scheint es, wenn ein Programm in einer Windows-Konsole auf stdout oder stderr druckt, die Konsole vor dem Drucken einige (schlechte) Neucodierungsarbeiten durchführt. Wenn das Programm die Windows-Konsolen-API direkt verwendet (indem es die Konvertierung selbst mit MultiByteToWideChar ausführt und dann mit WriteConsoleW() in die Konsole schreibt), zeigt die Konsole das glorreiche, unveränderte Emoji.

Wenn ein JS-Programm console API verwendet, um Daten zu protokollieren, könnte Node versuchen (unter Windows), die Konsole zu erkennen und dasselbe wie beim Melden von Ausnahmen zu tun. Siehe @ BrianNixons Antwort , die erklärt, was tatsächlich in libuv passiert.

    
Hugues M. 25.05.2017 10:51
quelle