Hallo Habr! Ich präsentiere Ihnen die Übersetzung von
The Joy of Haxe. FontStrukts Liebesbeziehung mit einer vernachlässigten Programmiersprache .
Ein ziemlich grober Versuch, das Haxe-Logo im FontStruct-Schrifteditor zu reproduzierenWir haben kürzlich den Quellcode für den wichtigsten Teil unseres Moduls zur Erstellung von Schriftarten geöffnet. Dies ist die
fonthx- Bibliothek zum Erstellen von TrueType-Schriftarten, die in
Haxe geschrieben ist .
In diesem Artikel ist praktisch kein Code enthalten. Wenn Sie sich nur für den Code interessieren, können Sie sich auf
github mit ihm vertraut machen. Die Arbeit wird
am Beispiel des einfachsten Pixel-Font-Editors gezeigt, der mit der fonthx-Bibliothek erstellt wurde.
Unabhängig davon, ob Sie mit Haxe vertraut sind oder nicht, kann das fonthx-Projekt für Sie von Interesse sein, da es einige erstaunliche Merkmale der Sprache zeigt, die außerhalb der Haxe-Community wenig bekannt sind - insbesondere die Fähigkeit, Code in einer schönen Sprache mit weiterer Kompilierung / Übersetzung zu schreiben, ist nicht nur In Javascript, aber auch in vielen anderen Plattformen, im Fall von fonthx, sind solche Plattformen JVM (Projektcode wird in Java übersetzt), nativer Code (C ++ oder C #), NodeJS oder WASM.
Ich kann als überzeugter Polyglot bezeichnet werden. Wie viele andere Entwickler schreibe ich Code in verschiedenen Sprachen und respektiere die ernsthaften Absichten derer, die sich lieber nur auf eine Sprache spezialisieren, und fürchte auch all jene Fans und evangelischen Betrüger, die über eine wirklich wahre Sprache sprechen. Aber was hat mich dazu veranlasst, eine Nischensprache wie Haxe zu verwenden, um die Schlüsselkomponenten von FontStruct zu erstellen und diesen Artikel zu schreiben? Und was ist Haxe?
Haxe
Haxe ist eine moderne, stark typisierte Programmiersprache mit einigen interessanten Funktionen und einer kleinen Standardbibliothek.
Das wichtigste Merkmal einer Sprache ist ihre Fähigkeit, denselben Code für verschiedene Zielplattformen zu kompilieren.
Die meisten Entwickler sind mit dem Konzept der „isomorphen“ Entwicklung vertraut, wenn ein Programmierer sowohl Server- als auch Client-Code in einer Sprache schreibt. Am häufigsten wird Javascript oder TypeScript als solche Sprache verwendet, es kann jedoch auch jede andere Sprache verwendet werden, die in Javascript kompiliert werden kann. Haxe geht viel weiter in diese Richtung und eröffnet eine Reihe interessanter zusätzlicher Möglichkeiten. Es ist möglich, eine ausführbare Datei, eine Java-Anwendung, ein WASM-Modul, eine NodeJS-Anwendung, eine browserbasierte Anwendung, eine mobile Anwendung und sogar Bibliotheken für Sprachen wie PHP, Lua oder Python aus einer Codebasis auf Haxe zu kompilieren.
Bei FontStruct nutzen wir diese Gelegenheit, indem wir Schlüsselkomponenten unserer Haxe-Anwendung entwickeln. Servermodule werden als Java-Servlets kompiliert, und Clientmodule werden als JS-Anwendungen kompiliert. Obwohl wir uns derzeit hauptsächlich auf diese beiden Zielplattformen konzentrieren (sowie auf NodeJS, um Geschwindigkeitstests durchzuführen), erwägen wir auch, die vom Haxe-Ökosystem bereitgestellten Tools zum Erstellen mobiler Anwendungen in C ++ zu verwenden. Darüber hinaus kann die zukünftige Verwendung von Haxe die Erstellung einer nativen (nicht auf Electron basierenden) Desktop-Anwendung ermöglichen.
Aufgrund der Tatsache, dass Haxe so viele Zielplattformen unterstützt, implementiert es besser als jeder andere (zumindest für unsere Aufgaben) die Idee, "Code einmal schreiben - überall ausführen", besser als jedes Tool, mit dem ich in den letzten zwanzig Jahren zusammengetroffen bin. Dies gibt das Gefühl, dass der gleiche Code für jede Plattform oder Laufzeit kompiliert werden kann.
Haxe Adoptionsprozess
FontStructor - Kostenloser Schrifteditor bei FontStruct.comVor mehr als 10 Jahren, als FontStruct gestartet wurde, wurde Adobe Flash für den FontStructor-Schrifteditor sowie Widgets zum Anzeigen von Schriftarten verwendet. Zum Erstellen von TrueType-Schriftarten auf dem Server wurde vollständig unabhängiger Code verwendet, der in Java geschrieben wurde.
Alte Flash-Version des FontStructor-Editors. Alle darin enthaltenen Steuerelemente wurden in Flash gezeichnet. Beachten Sie die seltsamen Bildlaufleisten in den Bedienfeldern links. Im Laufe der Zeit weicht das Hauptmenü oben auf der Seite visuell und funktional allmählich von dem im Rest der Site verwendeten HTML-Menü ab. Hier gibt es kein DOM oder CSSObwohl FontStruct ein großer Erfolg war und bleibt, haben unsere ersten technischen Lösungen den Test der Zeit nicht bestanden. Die Entwicklung von Webstandards und die mangelnde Unterstützung von Plug-Ins auf mobilen Plattformen haben Flash für die Verwendung in Webanwendungen ungeeignet gemacht. Wir mussten uns auch mit der Codeduplizierung zwischen einem Java-Server und einem Flash-Client sowie zwischen Flash und anderen in HTML / JS / CSS geschriebenen Teilen des Clients befassen. Es war notwendig, die drei Codebasen in Bezug auf Funktionalität und Design ständig untereinander zu synchronisieren.
Im Jahr 2013 haben wir begonnen, die Möglichkeit in Betracht zu ziehen, Haxe insbesondere als Mittel zur Übersetzung des FontStructor-Editors von Flash nach HTML5 zu verwenden. Bei unseren ersten Untersuchungen haben wir festgestellt, dass bereits Tools zum automatischen Konvertieren von ActionScript-Code in Haxe (
as3hx ) und sogar in den
Haxe-Port des Robotlegs MVC-Frameworks
verfügbar sind , das wir in der Flash-Version verwendet haben. Und so haben wir das Experiment zum Portieren des Clients gestartet.
Langsamer und problematischer Start
Unser erstes Jahr der Beziehung mit Haxe war von Unentschlossenheit und Zweifel begleitet.
Aus mehreren Gründen und nicht zuletzt aufgrund der begrenzten Ressourcen, die wir dafür verwenden konnten, erwies sich der Portierungsprozess als ziemlich langsam. Wie
andere Autoren bereits
bemerkt haben , erwies sich das Tool zum automatischen Konvertieren von ActionScript-Code in Haxe (as3hx) als sehr nützlich, jedoch nicht ohne Nachteile - der damit erhaltene Code musste zusätzlich überprüft und bearbeitet werden. Während dieses Prozesses wurde deutlich, dass unsere Codebasis aufgebläht und fehlerhaft im Design war. Daher haben wir uns parallel zur Portierung für Verbesserungen entschieden, um den weiteren Fortschritt weiter zu verlangsamen. Darüber hinaus war Haxe eine neue Sprache für uns, sodass wir beim Lernen dieser Sprache und ihrer Werkzeuge unweigerlich Fehler gemacht haben.
Unser mit Abstand größter Fehler war die Entscheidung, zusätzlich ein UI-Framework eines Drittanbieters für Haxe zu verwenden.
Für Haxe gibt es viele solcher Frameworks (vielleicht sogar zu viele), die eine einheitliche API zum Rendern von Grafiken auf verschiedenen Plattformen bereitstellen.
OpenFL und
NME sind Beispiele für solche Frameworks und bieten Tools zum
Erstellen von Haxe-Anwendungen für mobile Plattformen und sogar Konsolen. Dabei bieten sie eine Flash-API-Implementierung zum Rendern von Grafiken. All dies schien sehr verlockend - wir konnten unsere Anwendung mithilfe der bekannten API auf HTML5 übertragen und möglicherweise sogar gleichzeitig Anwendungen für Android und iOS erstellen!
Aus diesem Grund haben wir uns entschieden, OpenFL zu verwenden, um unsere Anwendung auf Haxe zu portieren.
Ich möchte OpenFL nicht missachten (ich möchte sogar sagen: „Das Problem liegt nicht bei OpenFL, sondern bei uns“). OpenFL ist ein fantastisches Projekt, das sich in vielen Projekten gut bewährt hat, und wir können in Zukunft darauf zurückkommen. Nachdem wir jedoch etwa 90% unserer Anwendung auf Haxe portiert haben, haben wir beschlossen, es aufzugeben.
OpenFL stellte sich als viel ernstere Abhängigkeit heraus, als wir erwartet hatten. Es war ursprünglich geplant, es nur als externe Bibliothek für unsere Benutzeroberfläche zu verwenden, aber am Ende stellte sich heraus, dass OpenFL seine eigenen Tools zum Erstellen von Projekten, spezielle Dateiformate zum Beschreiben von Projekten sowie zusätzliche externe Abhängigkeiten schleppte. Vielleicht liegt dies an der Tatsache, dass OpenFL wie der größte Teil des Haxe-Ökosystems versucht, die Bedürfnisse von Indie-Spieleentwicklern zu erfüllen, während es sich recht schnell entwickelt und das Hauptaugenmerk bei seiner Entwicklung auf das Hinzufügen neuer Funktionen und nicht auf Stabilität gelegt wird.
Das Wichtigste für uns war, dass der mit OpenFL generierte HTML5-Code ideal für Spiele ist, aber nicht für eine Anwendung wie FontStruct geeignet ist. Am Ende wollten wir im Browser nur einen regulären DOM-Baum anzeigen, den wir mit CSS formatieren konnten, und keine von OpenFL erstellten Canvas-Elemente oder Sprites.
Wir brauchten reguläres HTML5, keinen Versuch, Flash in einem Browser zu replizieren, ohne zusätzliche Plugins zu verwenden.
Spaß
Sobald wir die Verwendung von OpenFL aufgaben und feststellten, dass wir mit Haxe alles tun konnten, was wir wollten, ging alles schneller, einfacher und machte letztendlich viel mehr Spaß.
Und mit Haxe zu arbeiten macht Spaß. Man kann sagen, dass es von lustigen Experten erstellt wurde - unabhängigen Spieleentwicklern. Spieleentwickler benötigen eine schnelle Kompilierung sowie eine einzige Codebasis zum Erstellen von Anwendungen für Desktop-Computer, Browser, iOS, Android und Konsolen. Spieleentwickler benötigen einen produktiven und stabilen Code. Und Haxe bietet all diese großartigen Funktionen, nicht nur für Spieleentwickler.
Ich habe keine Angst davor, die Idee auszudrücken, dass eines der größten Probleme von Haxe - die relativ geringe Größe seiner Community und die damit verbundene Kargheit seines Ökosystems - auch sein Erfahrungsvorteil für den Entwickler ist. Wenn Sie mit Haxe arbeiten, werden Sie wahrscheinlich nicht stundenlang googeln und nach Informationen zum Stapelüberlauf suchen oder verschiedene Lektionen zu einem interessanten Thema analysieren und vergleichen sowie die API eines neuen Frameworks oder einer neuen Bibliothek studieren - diese Antworten, Lektionen und Bibliotheken existieren möglicherweise einfach nicht. Und wenn ja, dann sind sie höchstwahrscheinlich die einzigen Materialien zu diesen Themen. Mit Haxe lösen Sie Programmierprobleme selbst (!), Schreiben Bibliotheken selbst oder erfinden das Rad selbst neu oder portieren es, ohne das geringste Schuldgefühl zu spüren. Das macht Spaß und gibt Freiheit, und das ist es, was viele Entwickler nach endlosen Frameworks und moderner Entwicklung im Zusammenhang mit dem Kopieren von Code aus verschiedenen Quellen anstreben. Nach dem Prinzip „weniger ist besser“ ist Haxe nicht einzigartig, aber es ist das definitive Plus.
Haxe bietet dem Programmierer einzigartige Möglichkeiten. Es gibt ein besonderes Gefühl von erstaunlicher Entdeckung und Freude. Bei Verwendung von Haxe mit seiner Fähigkeit, Code für viele Zielplattformen zu kompilieren, besteht das Gefühl, dass der Programmierer von einer der grundlegendsten Abhängigkeiten von allen vorhandenen befreit ist - der Laufzeit selbst.
Renderer FontStruct
Der Start unserer ersten Haxe-Komponente für die FontStruct-Site im April 2015 war ein seltsames und unerwartetes Ereignis.
Die Galerie ist ein zentraler Bestandteil von FontStruct: durchsuchbare, sortierbare Listen mit Tausenden von Schriftarten, die auf unserer Plattform erstellt wurden. Von Anfang an hatten wir 2008 ständige Probleme mit der Download-Geschwindigkeit und der Leistung der Schriftvorschau sowohl in der Galerie selbst als auch auf anderen Seiten der Website.
Der Teil der FontStruct-Galerieseite, auf dem die Vorschau der auf der Plattform erstellten Schriftarten angezeigt wird. Zunächst wurde jedem einzelnen Vorschauelement ein langsam ladender Flash-Film präsentiert!Da FontStruct-Schriftarten ("FontStructions") in einem proprietären Format gespeichert und häufig bearbeitet werden, können sie nicht wie normale TrueType-Schriftarten gerendert werden. Dies bedeutete die Unfähigkeit, Bitmap-Bilder auf dem Server für die Vorschau von Schriftarten zu erstellen (unter Verwendung der FreeType-Bibliothek).
Um dieses Problem zu „lösen“, haben wir in den frühen Tagen von FontStruct separate Flash-Filme für Galerieelemente verwendet. Jeder Flash-Film hat Daten in unserem proprietären Format heruntergeladen und analysiert und anschließend das Bild zur Vorschau auf dem Client angezeigt. Bei der Anzeige solcher Clips auf Seite 20 oder mehr, von denen jeder Daten heruntergeladen und versucht hat, eine Schriftart zu zeichnen, nahmen die Ladezeit und der Ressourcenverbrauch des Benutzers erheblich zu, und die Situation wurde mit der Zeit weiter verschärft, da die in unserem Editor entwickelten Schriftarten immer mehr wurden und komplexer.
Am Ende haben wir eine ausgefallene Hybridlösung verwendet: Beim ersten Betrachten der Schriftart haben wir einen Flash-Film verwendet, der ein Bild für die Vorschau generiert hat. Dieses Bild wurde dann aufgenommen und als PNG-Dateien auf dem Server gespeichert. Für die Vorschau für die folgenden Benutzer wurden bereits die auf dem PNG-Server gespeicherten verwendet. - Dieser seltsame Hack hat die Ladezeit der Seite erheblich verbessert, war aber schmutzig und letztendlich falsch oder so. Die richtige Entscheidung wäre, ein komplett neues Servermodul zu schreiben - zum Beispiel in Java oder PHP -, um Schriftdaten zu laden und zu analysieren und dann eine darauf basierende Bitmap zu erstellen, aber wir hatten einfach nicht die Ressourcen, um dies zu tun.
In der Zwischenzeit ging der Fontstructor-Portierungsprozess nach Haxe sehr langsam voran, und wir waren weit von der Veröffentlichung entfernt. Wir sind jedoch weit genug gekommen, um zu verstehen, dass der neue Haxe-Code unsere Probleme bei der Vorschau von Schriftarten in der Galerie lösen kann.
Wir hatten bereits Haxe-Code zum Laden und Parsen unseres Schriftformats. Wir hatten Code zum Rendern von Glyphen (auf Canvas in HTML5 oder auf Sprites in Flash). Wir hatten auch alle Komponenten, die zur Lösung des Problems auf der Client-Seite erforderlich waren. Können wir diesen Code für die Verwendung auf dem Server anpassen?
Ja! Nachdem wir dies erkannt hatten, ging der Prozess sehr schnell. Zuerst dachten wir daran, C ++ und die Cairo-Bibliothek zum Rendern von Schriftarten zu verwenden (in der Hoffnung, dass wir eine Erweiterung für PHP oder eine Art CGI-Modul schreiben könnten), aber stattdessen entschieden wir uns für Java. "Wie wunderbar ist es, mit ein paar Zeilen Code und bedingter Kompilierung eine so grundlegende Entscheidung treffen zu können!" Wir könnten hierfür auch NodeJS und Node-Canvas verwenden, waren jedoch bereits mit dem Erstellen und Bereitstellen von Java-Servlets vertraut, und Java verfügt über alle Funktionen, die zum Zeichnen und Bearbeiten von Bitmaps erforderlich sind. Wir haben wahrscheinlich keinen Code in Java geschrieben, aber mit Haxe ist dies nicht mehr erforderlich.
Solch ein Rendering-Code auf hoher Ebene kann kompiliert und sowohl auf dem Client (JavaScript) als auch auf dem Server (in der JVM) ausgeführt werden.Infolgedessen haben wir nur wenige Tage gebraucht, um Änderungen an unserer Codebasis vorzunehmen, und ein neuer Renderer wurde gestartet. Über Nacht haben wir die Leistung der FontStruct-Galerie erheblich verbessert, die Verwendung schmutziger Hacks beseitigt und vor allem unsere allererste Komponente auf Haxe für den Kampf gestartet. Wir haben festgestellt, dass Haxe überraschen kann und viel mehr Fähigkeiten hat, als wir erwartet hatten.
Abschied von Flash (und c Vanilla Java)
Im November 2015, dh nach 7 Monaten, haben wir das erste Haxe-Client-Modul erfolgreich gestartet - die HTML5-Version des Widgets für die Vorschau von Schriftarten. Ich denke, dass unsere Benutzer die Änderungen fast nicht bemerkt haben, was einerseits irgendwie enttäuscht, aber letztendlich ein Indikator für den Erfolg dieser Initiative ist.
Jetzt hatten wir nur noch ein Flash-Modul auf der Website - den FontStructor-Editor, und wir brauchten ein weiteres Jahr, um die HTML5-Version im November 2016 endlich zu starten. Es ist also an der Zeit, unseren AS3-Code endgültig aufzugeben und FontStruct für Flash-frei zu erklären.
Neue HTML5-Version von FontStructor wurde 2016 veröffentlichtIm August 2018 haben wir das FontMortar-Modul zur Schriftgenerierung nach Haxe portiert. Dieser letzte Port ermöglichte es uns, in Java geschriebenen Code vollständig aufzugeben.
Ich bin nicht bereit, Haxe für alles zu verwenden. Ja, ich weiß, dass es Projekte gibt, in denen es als Hauptwerkzeug für alle Aspekte der Webentwicklung verwendet wird, aber ich bin sehr zufrieden mit dem hervorragenden
Symfony- Framework als Grundlage unserer Webanwendung. FontStruct verwendet weiterhin viele verschiedene Programmiersprachen, aber durch die Einführung von Haxe konnten wir die Größe und Komplexität der wichtigsten Teile unseres Codes reduzieren. Für unsere kleine Organisation hat sich diese Vereinfachung als entscheidend für die Wartung und Weiterentwicklung der Plattform erwiesen.
Tiefer in Hux eintauchen
Wenn Sie zum ersten Mal von Haxe gehört haben und meine Geschichte Sie interessiert hat, muss ich nur noch ein paar Fakten über ihn auflisten.
- Die Sprachunterstützung seitens der IDE ist recht anständig und wird ständig verbessert. Module für IntelliJ Idea und Visual Studio Code werden aktiv weiterentwickelt.
- Haxe bietet Tools für die Arbeit mit nativem Code und Bibliotheken , sodass Ihre Funktionen nicht eingeschränkt werden und nur eine kleine Teilmenge der verfügbaren Funktionen erforderlich ist. Wenn Sie für JavaScript entwickeln, haben Sie die Möglichkeit, eine beliebige JavaScript-Bibliothek zu verwenden. Für die Arbeit mit React stehen beispielsweise verschiedene Ordner zur Verfügung. Für FontStructor verwenden wir mehrere npm-Module wie interaktive.js und opentip. Das Schreiben von Ordnern für sie dauerte nur ein paar Minuten.
- Haxe verfügt über ein robustes erweitertes Typsystem mit Funktionen wie Typparametrisierung , generischen Klassen und Methoden , abstrakten Typen und Typinferenz .
- Haxe verfügt über äußerst leistungsstarke Makros , die zur Kompilierungszeit Zugriff auf den AST bieten. Dadurch können Entwickler ihre eigenen Sprachkonstrukte hinzufügen und Code dynamisch generieren.
- Trotz der Tatsache, dass es im Internet nicht viele Ressourcen zu Haxe gibt, gibt es ein Repository mit Bibliotheken , das die allgemeinen Bedürfnisse von Entwicklern außerhalb der Standardbibliothek abdeckt (außerdem finden Sie auf Github noch mehr Repositorys, die nicht in haxelib vertreten sind - ca. Übersetzer). .
- Last but not least hat Haxe eine sehr talentierte und reaktionsschnelle Community .
Fazit
Die meisten erfahrenen Entwickler sind bereit für Änderungen, aber sie wählen die verwendeten Technologien sorgfältig aus. Es ist wahrscheinlich, dass die meisten von Ihnen irgendwann auch Lust hatten, die Programmiersprache im Rahmen des Projekts zu ändern, insbesondere wenn neue, trendige Sprachen mit vielen interessanten Funktionen auftauchen. Wir haben uns sorgfältig für Haxe entschieden und darüber nachgedacht, wie lange unsere Beziehung dauern würde. Unsere Gedanken über ihn waren ungefähr so :Es klingt großartig, aber es hat eine so kleine Gemeinschaft. Was wird mit ihm in 5 Jahren passieren? Die Seite scheint normal zu sein, sieht aber aus irgendeinem Grund nicht modern aus. Und das schafft kein Vertrauen.
Es scheint nicht so gut dokumentiert zu sein.
Ist das nicht für Indie-Spieleentwickler?Nach fünf Jahren mit Haxe bin ich aufrichtig überrascht, dass ich unsere Wahl dieser Technologie nicht bereue. Trotz aller Mängel und Schwierigkeiten, die durch sie verursacht wurden, trotz der relativ kleinen Community und des Fehlens großer Unternehmenssponsoren, ist Haxe seinen Aufgaben voll und ganz gewachsen. Mit Haxe fühle ich mich frei und unabhängig von jeder Plattform. Jetzt haben wir eine einzige Codebasis für die Hauptkomponenten von FontStruct, während es zuvor zwei davon gab. In den letzten Monaten sind neuere Versionen der Servlets, die für die Generierung von Schriftarten und Bildern für die Vorschau verantwortlich sind, nie ausgefallen. Der neue HTML5-Editor und das Vorschau-Widget funktionieren jetzt in allen Browsern, einschließlich Mobilgeräten, während wir zuvor mit veralteter und aussterbender Technologie arbeiten mussten.Und abgesehen von den praktischen Vorteilen bringt die Arbeit mit Haxe Freude und ein Gefühl von Magie, die Freude von Haxe !