La joie d'Haxe. Un roman avec un langage de programmation négligé

Bonjour, Habr! Je vous présente la traduction de The Joy of Haxe. L'histoire d'amour de FontStruct avec un langage de programmation négligé .

Logo Haxe dans l'éditeur de politiques FontStruct

Une tentative assez grossière de reproduire le logo Haxe dans l'éditeur de polices FontStruct

Nous avons récemment ouvert le code source de la partie la plus importante de notre module de création de polices. Il s'agit de la bibliothèque fonthx pour créer des polices TrueType, et elle est écrite en Haxe .
Il n'y a pratiquement aucun code dans cet article. Si vous n'êtes intéressé que par le code, vous pouvez vous familiariser avec lui sur github , et son travail est illustré sur l'exemple de l' éditeur de polices de pixels le plus simple construit à l'aide de la bibliothèque fonthx.

Que vous soyez familier ou non avec Haxe, le projet fonthx peut vous intéresser, car il démontre des fonctionnalités étonnantes du langage qui sont peu connues en dehors de la communauté Haxe - en particulier, la possibilité d'écrire du code dans une langue agréable avec une compilation / traduction supplémentaire n'est pas seulement en Javascript, mais aussi dans de nombreuses autres plates-formes, dans le cas de fonthx, ces plates-formes sont JVM (le code du projet est traduit en Java), le code natif (C ++ ou C #), NodeJS ou WASM.

Je peux être appelé un polyglotte convaincu. Comme beaucoup d'autres développeurs, j'écris du code dans différents langages et, respectant les intentions sérieuses de ceux qui préfèrent se spécialiser dans un seul langage, je crains également tous ces fans et escrocs évangéliques qui parlent d'un vrai langage. Mais qu'est-ce qui m'a poussé à utiliser un langage de niche comme Haxe pour créer les composants clés de FontStruct, ainsi qu'à écrire cet article? Et qu'est-ce que Haxe?

Haxe


Haxe est un langage de programmation moderne et fortement typé avec quelques fonctionnalités intéressantes et une petite bibliothèque standard.

La caractéristique la plus importante d'un langage est sa capacité à compiler le même code pour différentes plates-formes cibles.

La plupart des développeurs connaissent le concept de développement «isomorphe» lorsqu'un programmeur écrit à la fois du code serveur et client dans une seule langue. Le plus souvent, Javascript ou TypeScript est utilisé comme un tel langage, mais tout autre langage capable de se compiler en Javascript peut également être utilisé. Haxe va beaucoup plus loin dans cette direction, ouvrant un certain nombre d'opportunités supplémentaires intéressantes. Il est possible de compiler un fichier exécutable, une application Java, un module WASM, une application NodeJS, une application basée sur un navigateur, une application mobile et même des bibliothèques pour des langages tels que PHP, Lua ou Python à partir d'une base de code sur Haxe.

Chez FontStruct, nous profitons de cette opportunité en développant des composants clés de notre application Haxe. Les modules serveur sont compilés en tant que servlets Java et les modules clients sont compilés en tant qu'applications JS. Bien que nous nous concentrions actuellement principalement sur ces deux plates-formes cibles (ainsi que NodeJS pour exécuter des tests de vitesse), nous envisageons également d'utiliser les outils fournis par l'écosystème Haxe pour créer des applications mobiles en C ++. De plus, l'utilisation de Haxe à l'avenir pourrait permettre la création d'une application de bureau native (non basée sur Electron).

Étant donné que Haxe prend en charge autant de plates-formes cibles, mieux que quiconque (au moins pour nos tâches) met en œuvre l'idée de «écrire du code une fois - l'exécuter partout», mieux que tout outil que j'ai rencontré au cours des vingt dernières années. Cela donne l'impression que le même code peut être compilé pour n'importe quelle plate-forme ou exécution.

Processus d'adoption de Haxe


FontStructor - Éditeur de politiques gratuites sur FontStruct.com
FontStructor - Éditeur de polices gratuit sur FontStruct.com

Il y a plus de 10 ans, lors du lancement de FontStruct, Adobe Flash était utilisé pour l'éditeur de polices FontStructor, ainsi que des widgets pour l'affichage des polices. Et pour créer des polices TrueType sur le serveur, un code complètement indépendant écrit en Java a été utilisé.

Version Ancienne Flash de FontStructor
Ancienne version Flash de l'éditeur FontStructor. Tous les contrôles qu'il contient ont été dessinés en Flash. Remarquez les barres de défilement étranges dans les panneaux de gauche. Au fil du temps, le menu principal en haut de la page a progressivement divergé visuellement et fonctionnellement du menu html utilisé dans le reste du site. Il n'y a pas de DOM ou CSS ici

Bien que FontStruct ait été et reste un énorme succès, nos solutions techniques initiales n'ont pas passé l'épreuve du temps. Le développement de normes Web et le manque de prise en charge des plug-ins sur les plates-formes mobiles ont rendu Flash impropre à une utilisation dans les applications Web. Nous avons également dû gérer la duplication de code entre un serveur Java et un client Flash, ainsi qu'entre Flash et d'autres parties du client écrites en HTML / JS / CSS. Il était nécessaire de synchroniser constamment entre eux les trois bases de code, à la fois en termes de fonctionnalité et de design.

En 2013, nous avons commencé à envisager la possibilité d'utiliser Haxe, en particulier, comme moyen de traduire l'éditeur FontStructor de Flash en HTML5. Lors de nos premières recherches, nous avons constaté qu'il existait déjà des outils disponibles pour convertir automatiquement le code ActionScript en Haxe ( as3hx ) et même le port Haxe du framework Robotlegs MVC que nous utilisions dans la version Flash. Et nous avons donc commencé l'expérience sur le portage du client.

Démarrage lent et problématique


Notre première année de relation avec Haxe s'est accompagnée d'indécision et de doute.

Pour plusieurs raisons, et notamment en raison des ressources limitées que nous pourrions y consacrer, le processus de portage s'est avéré plutôt lent. Comme d' autres auteurs l' ont déjà noté , l'outil de conversion automatique du code ActionScript en Haxe (as3hx) s'est avéré très utile, mais non sans inconvénients - le code obtenu avec lui a dû en outre être revu et édité. Au cours de ce processus, il est devenu clair que notre base de code était gonflée et erronée dans sa conception, donc en parallèle avec le portage, nous avons décidé d'apporter des améliorations, ralentissant ainsi davantage les progrès. De plus, Haxe était une nouvelle langue pour nous, donc nous avons inévitablement fait des erreurs en étudiant cette langue et ses outils.

De loin, notre plus grande erreur a été la décision d'utiliser en plus un cadre d'interface utilisateur tiers sur Haxe.

Pour Haxe, il existe de nombreux frameworks (peut-être même trop) qui fournissent une API unifiée pour le rendu des graphiques sur différentes plates-formes. OpenFL et NME sont des exemples de tels cadres et fournissent des outils pour créer des applications Haxe pour les plates-formes mobiles et même les consoles. Ce faisant, ils fournissent une implémentation de l'API Flash pour le rendu des graphiques. Tout cela semblait très tentant - nous pourrions transférer notre application vers HTML5 en utilisant l'API familière et, peut-être, même créer des applications pour Android et iOS en même temps!

Par conséquent, nous avons décidé d'utiliser OpenFL pour porter notre application sur Haxe.

Je ne veux pas manquer de respect à OpenFL (je veux même dire que: "Le problème n'est pas dans OpenFL, mais en nous"). OpenFL est un projet fantastique qui s'est bien montré dans de nombreux projets, et nous pourrons y revenir à l'avenir, mais après avoir porté environ 90% de notre application sur Haxe, nous avons décidé de l'abandonner.

OpenFL s'est avéré être une dépendance beaucoup plus grave que prévu. Il était initialement prévu qu'il ne soit utilisé que comme bibliothèque externe pour notre interface utilisateur, mais finalement il s'est avéré qu'OpenFL faisait glisser ses propres outils pour construire des projets, des formats de fichiers spéciaux pour décrire les projets, ainsi que des dépendances externes supplémentaires. Cela est peut-être dû au fait que, comme la plupart de l'écosystème Haxe, OpenFL essaie de répondre aux besoins des développeurs de jeux indépendants, alors qu'il se développe assez rapidement et que la principale attention dans son développement est accordée à l'ajout de nouvelles fonctions, pas à la stabilité.

La chose la plus importante pour nous était que le code HTML5 généré à l'aide d'OpenFL est idéal pour les jeux, mais il ne convient pas pour une application comme FontStruct. Tout ce que nous voulions à la fin était d'afficher dans le navigateur une arborescence DOM régulière que nous pouvions styliser avec CSS, et non un ensemble d'éléments de canevas ou de sprites créés par OpenFL.

Nous avions besoin de HTML5 régulier, pas d'une tentative de réplication de Flash dans un navigateur sans utiliser de plugins supplémentaires.

Amusant


Dès que nous avons abandonné l'utilisation d'OpenFL et réalisé que nous pouvions faire tout ce que nous voulions en utilisant uniquement Haxe, tout est allé plus vite, plus facilement et, finalement, beaucoup plus amusant.

Et travailler avec Haxe est amusant. On peut dire qu'il a été créé par des experts amusants - des développeurs de jeux indépendants. Les développeurs de jeux ont besoin d'une compilation rapide, ainsi que d'une base de code unique pour créer des applications pour les ordinateurs de bureau, les navigateurs, iOS, Android et les consoles. Les développeurs de jeux ont besoin d'un code productif et stable. Et Haxe fournit toutes ces fonctionnalités géniales, et pas seulement pour les développeurs de jeux.

Je n'ai pas peur d'exprimer l'idée que l'un des plus gros problèmes de Haxe - la taille relativement petite de sa communauté et la rareté de son écosystème - est également son avantage en termes d'expérience pour le développeur. Lorsque vous travaillez avec Haxe, il est peu probable que vous passiez des heures à chercher sur Google et à rechercher des informations sur le débordement de pile, à analyser et à comparer différentes leçons sur un sujet d'intérêt, ainsi qu'à étudier l'API d'un nouveau cadre ou d'une nouvelle bibliothèque - ces réponses, leçons et les bibliothèques peuvent tout simplement ne pas exister. Et s'il y en a, ce sera probablement le seul matériel sur ces sujets. Avec Haxe, vous résolvez vous-même les problèmes de programmation (!), Écrivez vous-même les bibliothèques ou, sans ressentir le moindre sentiment de culpabilité, réinventez ou portez la roue vous-même. C'est amusant et donne de la liberté, et c'est ce que de nombreux développeurs recherchent après des cadres sans fin et des développements modernes liés à la copie de code à partir de différentes sources. Utilisant le principe «moins c'est mieux», Haxe n'est pas unique, mais c'est son plus indéniable.

Haxe offre au programmeur des opportunités uniques. Cela donne un sentiment spécial de découverte et de joie incroyables. En utilisant Haxe, avec sa capacité à compiler du code pour de nombreuses plates-formes cibles, on a le sentiment que le programmeur est libéré de l'une des dépendances les plus fondamentales de toutes celles existantes - le runtime lui-même.

Renderer FontStruct


Le lancement de notre premier composant Haxe pour le site FontStruct en avril 2015 a été un événement étrange et inattendu.

La galerie est un élément central de FontStruct: listes consultables et triables de milliers de polices créées sur notre plateforme. Depuis le tout début en 2008, nous avons eu des problèmes constants avec la vitesse de téléchargement et avec la performance des aperçus de polices à la fois dans la galerie elle-même et sur d'autres pages du site.

Aperçu des politiques dans la galerie FontStruct
Partie de la page de la galerie FontStruct où l'aperçu des polices créées sur la plate-forme est affiché. Initialement, chaque élément de prévisualisation individuel a été présenté avec un film Flash à chargement lent!

Étant donné que les polices FontStruct ("FontStructions") sont stockées dans un format propriétaire et sont souvent modifiées, il est impossible de les utiliser pour le rendu comme les polices TrueType standard. Cela signifiait l'impossibilité de créer des images bitmap sur le serveur pour prévisualiser les polices (à l'aide de la bibliothèque FreeType).

Pour «résoudre» ce problème, aux tout premiers jours de FontStruct, nous avons utilisé des animations Flash distinctes pour les éléments de la galerie. Chaque film Flash a téléchargé et analysé des données dans notre format propriétaire, puis a montré l'image sur le client pour un aperçu. Lors de l'affichage à la page 20 ou plus de ces clips, dont chacun a téléchargé des données et tenté de dessiner une police, le temps de chargement et la consommation de ressources de la machine utilisateur ont augmenté de manière significative, et la situation s'est encore aggravée avec le temps, car les polices développées dans notre éditeur sont devenues de plus en plus et plus complexe.

Au final, nous avons utilisé une solution hybride sophistiquée: lors de la première visualisation de la police, nous avons utilisé un film Flash qui a généré une image pour l'aperçu, puis cette image a été capturée et enregistrée sur le serveur en tant que fichiers PNG. Et pour l'aperçu pour les utilisateurs suivants, ceux enregistrés sur le serveur PNG étaient déjà utilisés. - Cet étrange hack a considérablement amélioré le temps de chargement de la page, mais il était sale et, finalement, faux ou quelque chose. La bonne décision serait d'écrire un tout nouveau module serveur - par exemple, en Java ou PHP - pour charger et analyser les données de police, puis créer une image bitmap basée sur celle-ci, mais nous n'avions tout simplement pas les ressources pour le faire.

En attendant, le processus de portage de Fontstructor vers Haxe progressait très lentement, et nous étions loin de la sortie. Mais nous sommes allés assez loin pour comprendre que le nouveau code Haxe peut résoudre nos problèmes avec l'aperçu des polices dans la galerie.

Nous avions déjà du code Haxe pour charger et analyser notre format de police. Nous avions du code pour le rendu des glyphes (sur Canvas en HTML5 ou sur les sprites en Flash). Nous avions également tous les composants nécessaires pour résoudre le problème côté client. Pouvons-nous adapter ce code pour l'utiliser sur le serveur?

Oui! Après avoir réalisé cela, le processus est allé très vite. Au début, nous avons pensé à utiliser C ++ et la bibliothèque du Caire pour rendre les polices (en espérant que nous pourrions écrire une extension pour PHP ou un module CGI), mais à la place, nous avons décidé d'utiliser Java. "Comme c'est merveilleux de pouvoir faire un choix aussi fondamental avec seulement quelques lignes de code et une compilation conditionnelle!" Nous pourrions également utiliser NodeJS et node-canvas pour cela, mais nous connaissions déjà le processus de création et de déploiement de servlets Java, et Java a toutes les fonctions dont nous avons besoin pour dessiner et manipuler des bitmaps. Nous n'aimions probablement pas écrire du code en Java, mais avec Haxe, ce n'est plus nécessaire.

Code de rendu
Ce code de rendu de haut niveau peut être compilé et exécuté à la fois sur le client (JavaScript) et sur le serveur (dans la JVM)

En conséquence, il nous a fallu seulement quelques jours pour apporter des modifications à notre base de code, et un nouveau moteur de rendu a été lancé. Du jour au lendemain, nous avons considérablement amélioré les performances de la galerie FontStruct, nous sommes débarrassés de l'utilisation de hacks sales et, surtout, nous avons lancé notre tout premier composant sur Haxe pour le combat. Nous avons réalisé que Haxe est capable de surprendre et a des capacités beaucoup plus grandes que ce que nous attendions de lui.

Adieu à Flash (et c Vanilla Java)


En novembre 2015, c'est-à-dire après 7 mois, nous avons lancé avec succès le premier module client Haxe - la version HTML5 du widget pour prévisualiser les polices. Je pense que nos utilisateurs n'ont presque pas remarqué les changements, qui d'une part déçoivent en quelque sorte, mais, en fin de compte, sont un indicateur du succès de cette initiative.

Maintenant, nous n'avions qu'un seul module Flash sur le site - l'éditeur FontStructor, et il nous a fallu un an de plus pour enfin lancer sa version HTML5 en novembre 2016. Le moment est donc venu d'abandonner enfin notre code AS3 et de déclarer FontStruct exempt de Flash.

Nouvelle version HTML5 de FontStructor
Nouvelle version HTML5 de FontStructor lancée en 2016

En août 2018, nous avons porté le module de génération de polices FontMortar sur Haxe. Ce dernier port nous a permis d'abandonner complètement le code écrit en Java.

Je ne suis pas prêt à utiliser Haxe pour tout. Oui, je sais qu'il existe des projets où il est utilisé comme outil principal pour tous les aspects du développement web, mais je suis très satisfait de l'excellent framework Symfony comme base de notre application web. FontStruct continue d'utiliser de nombreux langages de programmation différents, mais l'introduction de Haxe nous a permis de réduire la taille et la complexité des parties les plus importantes de notre code. Pour notre petite organisation, cette simplification s'est avérée vitale pour la maintenance et le développement de la plateforme.

Plonger plus profondément dans Hux


Si c'est la première fois que vous entendez parler d'Haxe et que mon histoire vous intéresse, alors je n'ai qu'à énumérer quelques faits supplémentaires à son sujet.

  • Le support du langage de la part de l'IDE est assez décent et s'améliore constamment, les modules pour IntelliJ Idea et Visual Studio Code se développent activement.
  • Haxe fournit des outils pour travailler avec du code natif et des bibliothèques , il ne limite donc pas vos capacités, n'imposant qu'un petit sous-ensemble des fonctions disponibles. Si vous développez pour JavaScript, vous avez la possibilité d'utiliser n'importe quelle bibliothèque JavaScript, par exemple, divers classeurs sont disponibles pour travailler avec React. Pour FontStructor, nous utilisons plusieurs modules npm, tels que interactive.js et opentip. Leur écrire n'a pris que quelques minutes.
  • Haxe possède un système de type avancé robuste avec des fonctionnalités telles que le paramétrage de type , les classes et méthodes génériques , les types abstraits et l' inférence de type .
  • Haxe possède des macros extrêmement puissantes qui permettent d'accéder à l'AST au moment de la compilation, ce qui permet aux développeurs d'ajouter leurs propres constructions de langage et de générer du code de manière dynamique.
  • Malgré le fait qu'il n'y ait pas beaucoup de ressources sur Haxe sur Internet, il existe un référentiel de bibliothèques pour cela couvrant les besoins généraux des développeurs en dehors de la bibliothèque standard (en outre, sur Github, vous pouvez trouver encore plus de référentiels qui ne sont pas représentés sur haxelib - environ Translator) .
  • Enfin et surtout, Haxe a une communauté très talentueuse et réactive .

Conclusion


La plupart des développeurs expérimentés sont prêts à changer, mais ils choisissent avec soin les technologies utilisées. Il est probable qu'à un moment donné, la plupart d'entre vous aient également eu envie de changer le langage de programmation dans le cadre du projet, en particulier lorsque de nouveaux langages à la mode avec beaucoup de fonctionnalités intéressantes apparaissent. Nous avons pris soin de choisir Haxe, en pensant à la durée de notre relation. Nos pensées à son sujet étaient quelque chose comme ceci :

Cela semble génial, mais il y a une si petite communauté. Que va-t-il lui arriver dans 5 ans? Le site semble être normal, mais pour une raison quelconque, il n'a pas l'air moderne. Et cela n'inspire pas confiance.
Cela ne semble pas si bien documenté.

N'est-ce pas pour les développeurs de jeux indépendants?


Après cinq ans d'utilisation de Haxe, je suis sincèrement surpris de ne pas regretter notre choix de cette technologie. Malgré toutes les lacunes et toutes les difficultés qui en découlent, malgré la communauté relativement petite et l'absence de grands mécènes, Haxe fait pleinement face à ses tâches. Avec Haxe, je ressens la liberté et l'indépendance de toute plateforme. Nous avons maintenant une base de code unique pour les principaux composants de FontStruct, alors qu'auparavant il y en avait deux. Au cours des derniers mois, les nouvelles versions des servlets responsables de la génération des polices et des images pour l'aperçu n'ont jamais échoué. Le nouvel éditeur HTML5 et le widget de prévisualisation fonctionnent désormais dans tous les navigateurs, y compris les mobiles, alors qu'auparavant nous devions travailler avec une technologie obsolète et mourante.

Et, en plus des avantages pratiques, travailler avec Haxe apporte de la joie et un sentiment de magie, la joie de Haxe !

Source: https://habr.com/ru/post/fr432750/


All Articles