Javascript est incontournable tout simplement car c'est le seul langage utilisable pour exécuter des applications directement dans un navigateur. Et le navigateur tend à devenir de plus en plus omniprésent et ubiquitaire.
On m'aurait dit ça il y a 15 ans je ne l'aurais pas cru : "quoi ce machin immonde pour bidouilleurs du dimanche ?" me serais je écrié. Comme quoi, parfois on peut bien se planter (et en outre sur le jugement de valeur du langage faussé par une incompréhension initiale, mais bon faut savoir reconnaître ses erreurs).
Il faut dire que l'histoire a quand même failli me donner raison ; il y a quelques années on pariait beaucoup sur le succès de diverses solutions techniques basées sur des plugins de navigateurs exécutant des machines virtuelles et supportant des langages plus évolués : Flex d'Adobe, SilverLight de Microsoft ont connu le succès avant de disparaître brutalement. Google a même proposé un nouveau langage pour supplanter javascript (DART), mais sans succès.
Désormais les dés en sont jetés, c'est ainsi : les grands acteurs de l'informatique ont tous fait le choix de javascript et investi des sommes colossales en R&D pour en améliorer l'usage, avec succès.
Mais le javascript d'aujourd'hui est bien différent de celui d'hier. Le langage, si il conserve toujours un grand nombre de ses défauts de jeunesse, a évolué dans le bon sens. La normalisation du cœur du langage et de ses principales APIS, bien qu'incomplète, a permis d'améliorer la compatibilité cross-navigateur. Et diverses techniques se sont développées pour permettre de vivre du mieux possible avec et contourner ses défauts et limitations. De nombreuses initiatives visant à continuer les améliorations sont toujours en cours et avancent rapidement.
Je dresse un petit tour d'horizon rapide du sujet. Les premiers paragraphes sont là plus pour rappel car ils abordent des sujets déjà un peu ancien et assez largement connus, les deux derniers s'intéressent à des aspects bien plus novateurs.
Pour le lecteur qui ne serait pas familiarisé avec les bases techniques indispensables, la série d'article suivante donne les pré-requis, en particulier le dernier épisode qui explique le rôle du javascript et son fonctionnement au sein du navigateur :
Pour le lecteur qui ne serait pas familiarisé avec les bases techniques indispensables, la série d'article suivante donne les pré-requis, en particulier le dernier épisode qui explique le rôle du javascript et son fonctionnement au sein du navigateur :
- Les bases pour comprendre le Web - Episode 1
- Les bases pour comprendre le Web - Episode 2
- Les bases pour comprendre le Web - Episode 3
Petit rappel rapide sur les architecture web
Pour bien comprendre pourquoi le js est aussi important aujourd'hui, il faut bien avoir en tête les architectures actuelles. Je résume grossièrement et rapidement le sujet.
Initialement, les applications web étaient construites en mode page à page : un navigateur émettait une requête http, le serveur web la passait au serveur d'application (ou moteur de script dans le cas de php par exemple) qui fabriquait une page html et la renvoyait. Toute la logique était gérée côté serveur (back-end), toute action de l'utilisateur côté client impliquait ce cycle complet. Avec a la clé, une ergonomie insatisfaisante et une charge serveur importante.
Avec la standardisation du XHR (XmlHttpRequest), une fonctionnalité du langage javascript permettant de faire des requêtes http asynchrones, la programmation AJAX s'est popularisée et a permis l'apparition du web 2.0. Il devenait possible de rafraîchir partiellement une page sans devoir la recharger : le programme js fait une requête au serveur http, qui renvoie des données et non une page html, données qui sont utilisées par le programme js pour manipuler le DOM de la page et modifier les données à l'écran (technique autrefois appelée DHTML, D pour Dynamic).
Voici l'étape suivante qui est l'état de l'art actuel, et une tendance lourde pour les nouveaux développements : on télécharge une application client javascript dans le navigateur (elle peut être développée dans un autre langage, cf les explications plus loin, mais le code qui s'exécute est du js), cette application gère toute la logique de navigation (ce qui n'est donc plus fait côté serveur) et d'affichage (plus du tout, ou beaucoup moins, selon le type d'application et les choix d'architecture, de génération de code html côté serveur), et elle fait appel aux services implémentant les règles métier (par exemple un calcul de devis) et l'accès aux bases de données, qui eux s'exécutent toujours côté serveur.
Tout ceci nous ramène donc à l'architecture client serveur d'il y a 20 ans, hormis le fait qu'on s'appuie sur des standards ouverts alors que les architectures client/serveur s'appuyaient quasiment toutes sur des standards propriétaires et fermés : on a donc une application client (en js), une application serveur (java, ruby, groovy, C#, php, js, perl, python etc.), des appels client/serveur de procédures distantes (RPC Remote Procedure Call) comme il y a 20 ans, mais avec un protocole de transport standard (HTTP), un format de donnée JSON standard (un standard javascript, en lieu et place de divers formats binaires spécifiques à chaque éditeur). Ajoutons que les serveurs ont désormais la possibilité d'envoyer directement des données aux clients sans que ceux ci aient à le solliciter (websockets ou version 2 de la norme HTTP), et on est de retour à l'époque pré-internet.
Des conventions établies sur la syntaxe d'appel aux services donnent son nom à cette architecture : REST. REST est un style architectural qui définit notamment la sémantique des différents verbes du protocole HTTP (tel verbe pour une création, tel autre pour une lecture, tel autre pour une suppression, tel autre pour une mise à jour) et la forme que doivent prendre les url (chaque appel RPC étant une requête http, il est bien entendu défini par une url).
L'émergence de ce modèle a pour origine et pour conséquence les améliorations des technologie js.
Librairies
Le premier pas a été l'apparition de librairies permettant d'améliorer le niveau d'abstraction du langage, la productivité des développeurs, et la compatibilité cross-navigateurs. Je pense bien sur à JQuery en premier lieu.
Un petit mot sur le sujet de la compatibilité cross-navigateur.
Le langage javascript a été inventé par un chercheur de la société qui éditait le navigateur Netscape Navigator, un des tout premiers navigateurs ayant existé. C'était donc à l'origine une initiative privée, hors de tout contexte normatif. L'idée de base étant bonne, elle a été reprise par les autres éditeurs de navigateurs qui ont fait leur propre version du langage, compatible pour une grande part mais avec chacun diverses extensions (des capacités supplémentaires du langage) qui leur étaient propres, et des syntaxes parfois un peu différentes.
Il faut bien comprendre qu'à l'époque il y avait une guerre féroce entre les acteurs du marché pour essayer d'imposer leur navigateur qui devenait, du fait de l'importance prise en entreprise et chez les particuliers par ce logiciel, un enjeu majeur. En sortant le premier une extension adoptée par les développeurs, on captait le marché.
Du coup, un site web développé en faisant usage d'une extension propre à un navigateur ne pouvait fonctionner que sur un navigateur, celui de l'éditeur ayant inventé ladite extension, et pas sur les autres navigateurs (du moins le temps qu'il s'alignent). Autant dire que ça allait à l'encontre des principes même ayant conduit à l'adoption du web. La conséquence est que les développeurs devaient faire plusieurs versions d'un même site, en détectant le navigateur sur lequel le code s'exécutait, ce qui posait de nombreux problèmes, à commencer par une majoration significative des coûts de développement. Notons que ce problème se posait également pour le langage CSS (et HTML dans une moindre mesure).
Un petit mot sur le sujet de la compatibilité cross-navigateur.
Le langage javascript a été inventé par un chercheur de la société qui éditait le navigateur Netscape Navigator, un des tout premiers navigateurs ayant existé. C'était donc à l'origine une initiative privée, hors de tout contexte normatif. L'idée de base étant bonne, elle a été reprise par les autres éditeurs de navigateurs qui ont fait leur propre version du langage, compatible pour une grande part mais avec chacun diverses extensions (des capacités supplémentaires du langage) qui leur étaient propres, et des syntaxes parfois un peu différentes.
Il faut bien comprendre qu'à l'époque il y avait une guerre féroce entre les acteurs du marché pour essayer d'imposer leur navigateur qui devenait, du fait de l'importance prise en entreprise et chez les particuliers par ce logiciel, un enjeu majeur. En sortant le premier une extension adoptée par les développeurs, on captait le marché.
Du coup, un site web développé en faisant usage d'une extension propre à un navigateur ne pouvait fonctionner que sur un navigateur, celui de l'éditeur ayant inventé ladite extension, et pas sur les autres navigateurs (du moins le temps qu'il s'alignent). Autant dire que ça allait à l'encontre des principes même ayant conduit à l'adoption du web. La conséquence est que les développeurs devaient faire plusieurs versions d'un même site, en détectant le navigateur sur lequel le code s'exécutait, ce qui posait de nombreux problèmes, à commencer par une majoration significative des coûts de développement. Notons que ce problème se posait également pour le langage CSS (et HTML dans une moindre mesure).
Un mot rapide encore sur la technique utilisée pour détecter le navigateur. Elle peut se faire côté serveur car une requête HTTP émise par un navigateur embarque certaines informations dont une donnée appelée USER-AGENT qui permet de savoir à quel navigateur on a affaire. Il suffit alors de renvoyer un code js spécifique au navigateur utilisé. Mais la technique probablement la plus utilisée est bien plus ennuyeuse ; il s'agit d'une série d'astuces de programmation empiriques qui consistent à exécuter un bout de code et à voir ce que ça donne et deviner le navigateur en fonction du résultat constaté. On appelle ça un hack et c'est une technique assez risquée : comme elle résulte de comportement pas forcément spécifié, sa connaissance est empirique et rien ne garantit sa pérennité dans le temps (quand c'est basé sur des comportements non spécifiés). L'usage fréquent de ces techniques faisait de la programmation web un art plus qu'une science ...
Il y a eu une prise de conscience des éditeurs et le langage js a été normalisé et est devenu ECMAScript (javascript étant une implémentation de la norme, d'autres implémentations existant par ailleurs). Les API telles que DOM permettant de manipuler le contenu des pages ont également été standardisées. Mais le mal était fait et il a fallu beaucoup de temps pour que les navigateurs implémentent correctement les normes officielles ; voilà pourquoi il est préférable, et de plus en plus souvent obligatoire, d'avoir un navigateur récent sur son poste de travail (pour Internet Explorer au minimum une version 10, et de préférence la 11 ou encore Edge son successeur sous Windows 10, une version à jour de Chrome ou Firefox).
Bref, l'utilisation de JQuery a permis de masquer toute cette complexité (les hacks sont implémentés dans la librairie et le développeur n'a pas a en avoir conscience) et d'améliorer la productivité et la qualité des développements (par exemple pour manipuler le DOM d'une page).
Bref, l'utilisation de JQuery a permis de masquer toute cette complexité (les hacks sont implémentés dans la librairie et le développeur n'a pas a en avoir conscience) et d'améliorer la productivité et la qualité des développements (par exemple pour manipuler le DOM d'une page).
Frameworks
En introduction à cette section, le lecteur peu familiarisé avec la notion de framework et de design pattern peut lire cet article : Mythes et légendes de la POO 1/2. La lecture du second volet n'est pas indispensable. L'article traite des concepts qui nous intéressent dans le cadre plus spécifique de la programmation selon le paradigme objet, mais peu importe.
Après JQuery, de véritables frameworks sont apparus ces dernières années, rendant disponible côté client un grand nombre des techniques d'ingénierie logicielle éprouvées côté serveur (injection de dépendance, structuration du code par le pattern MVC, tests unitaires ...)
A la clé, amélioration de la productivité, testabilité, maintenabilité accrue.
Ce domaine est en pleine effervescence et le développeur qui veut gagner plein de pepettes aujourd'hui à tout intérêt à se spécialiser là-dessus. Je pense bien sur à Angular et consorts.
A la clé, amélioration de la productivité, testabilité, maintenabilité accrue.
Ce domaine est en pleine effervescence et le développeur qui veut gagner plein de pepettes aujourd'hui à tout intérêt à se spécialiser là-dessus. Je pense bien sur à Angular et consorts.
De nouvelles normes sont en maturation au sein des éditeurs et du w3c. Quand elles seront enfin disponibles, elle représenteront un progrès considérable. Je pense en particulier à "l'arlésienne" WebComponents qui semble avoir bien du mal à sortir. Cette spécification permettra de modulariser les développements sous formes de composants d'IHM réutilisables ce qui sera un grand pas en avant. Elle est très attendue mais sa mise au point semble poser un grand nombre de difficultés, comme d'habitude liées au poids de l'existant, à savoir en l’occurrence les spécifications initiales de HTML / CSS et bien sur js (modularisation non prévue bien que possible via certaines conventions et design pattern).
Le projet CommonJS devrait également apporter des avancées significatives, d'autant que selon certaines rumeurs le w3c s'intéresse de près à cette initiative. Ce projet apporte par exemple un système de module utilisé par exemple par Node.js (plateforme d'exécution javascript totalement décorrélée du navigateur permettant le développement d'applications serveur ou standalone) qui a inspiré la spécification de la version 6 du langage Ecmascript.
Tout un tas d'autres APIS sont standardisée, ou en voie de l'être, dans de nombreux domaines (persistence des données, accès au matériel, ...). Le plus simple pour les personnes intéressées est de jeter un oeil ici.
Interpréteurs, JIT, Environnement d'exécution
Google a lancé la course avec V8 voici 6 ou 7 ans. Cet interpréteur javascript de nouvelle génération a explosé tous les records de performance, notamment grâce à l'usage de la compilation à la volée (JIT). Rappelons que les techniques JIT permettent de compiler en code binaire natif des portions de code javascript (sous réserve qu'il soit écrit de manière qui le permette).
Les autres acteurs ont suivi, Microsoft longtemps à la traîne a enfin réagi avec Edge (le navigateur par défaut de Windows 10) et une nouvelle version de Chakra (son moteur js). Tellement performant qu'il y a désormais une version de Node.js animée par ce moteur (V8 de façon classique). SpiderMonkey de Mozilla n'est pas en reste non plus.
On doit également citer Node.js un environnement d'exécution Javascript implémentant le pattern Reactor grâce à une libraire C++ d'I/O asynchrone ultra-performante.
Ce produit a permis à Javascript de quitter le seul univers du navigateur pour devenir une solution plus que crédible pour le développement back-end (développement serveur par opposition au développement client dît front-end) ou d'applications standalone.
Ce produit a permis à Javascript de quitter le seul univers du navigateur pour devenir une solution plus que crédible pour le développement back-end (développement serveur par opposition au développement client dît front-end) ou d'applications standalone.
Transpileurs
Malgré les améliorations apportées au langage, le javascript reste un langage qui n'est pas très adapté pour des programmes de taille importante. Il n'apporte pas les mécanismes requis de façon simple et native. La version 6 de la norme EcmaScript (sortie mi 2015) apporte des améliorations significatives mais elle ne sera pas supportée tout de suite. Il faudra en outre du temps pour que les développeurs se l'approprient. Notons toutefois que cette version apporte enfin un mécanisme de modules standardisé.
La transpilation (ou compilation source à source) est un procédé qui consiste à lire un code source et à le transformer pour produire en sortie un seconde code source exprimé dans un autre langage (ou dans une autre version du langage source). Le transpiler est l'outil qui réalise l'opération. La technique est utilisée pour améliorer, simplifier, enrichir divers langages : CSS est ainsi amélioré par SASS (par exemple), et Javascript par toute une famille de langages.
Il est ainsi possible de développer dans un langage plus évolué et de transpiler le code en javascript qui s'exécutera dans la navigateur. Le langage de départ peut être un langage très proche de javascript pour faciliter la transition aux développeurs déjà formés, ou être totalement différent.
Microsoft qui investit beaucoup sur la technologie javascript fournit TypeScript qui permet de faire du développement selon le paradigme objet (javascript le permet nativement mais c'est extrêmement complexe). Nul doute que ce soit une solution appelée à prendre de l'importance dans le futur. Le support apporté par Microsoft au sujet n'est pas neutre et témoigne de l'importance du sujet.
Il existe d'autres solutions plus anciennes comme CoffeeScript par exemple.
Il existe d'autres solutions plus anciennes comme CoffeeScript par exemple.
Il est également possible d'écrire du code en EcmaScript 6 et de le compiler (transpiler pour être précis, cet abus de langage est fréquent) en EcmaScript 5. L'intérêt est que quand les navigateurs supporteront la dernière version du langage, on pourra simplement supprimer cette phase de transpilation et continuer à utiliser le même code (ainsi on peut développer dès aujourd'hui en profitant des apports au langage de la dernière version et exécuter dans les navigateurs actuels qui ne la supportent pas encore, ou incomplètement).
Outillage des développeurs
On ne peut décemment pas parler du js d'aujourd'hui sans dire deux mots sur l'outillage actuel.Initialement, on avait un éditeur de texte dans lequel on tapait son js, puis on l'exécutait dans un navigateur en le faisant charger par une page html. Ca marchait ou pas, et quand ça marchait pas on avait juste un message d'erreur généralement incompréhensible et inexploitable. La mise au point était un vrai cauchemar d'autant que les mauvaises pratiques autorisées, voire encouragées, par le langage (portée des variables globale par défaut) étaient vecteurs de production de bugs. Sans parler du manque de normalisation de l'API DOM utilisée pour interagir avec le contenu de la page, de la difficulté à modulariser le code, et diverses autres joyeusetés.
Ce temps est révolu. Tous les navigateurs modernes embarquent des débugueurs puissants. Ce sont des outils qui permettent de visualiser le code au moment de son exécution, le contenu des variables, de stopper une programme et de le dérouler pas à pas etc. Bien plus facile de faire la mise au point.
L'introduction du mode strict dans le langage a permis de supprimer certaines mauvaise pratiques, et des analyseurs de code (Lint, JsLint) sont apparus qui permettent d'alerter le développeur sur une suspicion ou erreur avérée de programmation.
Les IDE ont progressé et proposent de la coloration syntaxique et diverses assistances pour vérifier la conformité de son code au fur et à mesure du développement. On limite ainsi les erreurs de programmation. Bien sur la nature dynamique du langage js, et le fait qu'il soit interprété ne permettent pas d'avoir le même niveau de contrôle en amont qu'avec un langage compilé, mais ce qu'on perd en rigueur on le gagne en souplesse et en facilité pour les non professionnels. On a aujourd'hui des IDE spécialisés très performants (Webstorm par exemple), ou des bons plugins pour des outils plus généralistes (par exemple pour NetBeans, Eclipse est à la traîne).
Puis progressivement on a vu apparaître, depuis disons 2 ou 3 ans, les mêmes outils que ceux utilisés depuis très longtemps côté serveur pour booster la productivité et la qualité des développements. Nous allons citer rapidement les principaux et donner leur équivalent côté back-end pour les développeurs java (le langage le plus utilisé). Mais en préalable je dois me plaindre... Pourquoi nom de dieu, les développeurs ont ils encore ressenti le besoin de réinventer la roue et redévelopper de zéro de nouveaux outils au lieu de simplement faire évoluer les outils existant côté serveur ? A tous les coup pour des raisons à la con (ego des développeurs, volonté de tout faire en js, concurrence ...) mais bref c'est comme ça.
Alors, commençons par les gestionnaires de package... kesako ? Tout projet un tant soit peu important fait usage de nombreuses librairies externes. L'approche traditionnelle qui consiste à les télécharger manuellement depuis le site web du projet est source de nombreux problèmes qui sont résolus par les gestionnaires de packages. Ces derniers se chargent de faire le boulot automatiquement en s'appuyant sur un repository centralisé sur Internet où toutes les librairies sont proprement rangées et versionnées.
Il existe deux solutions concurrentes : Bower et Npm (issu du projet Node.js).
L'équivalent principal côté back-end Java est Maven.
Continuons par les outils de build automatisé. Ces outils automatisent le processus de build et évitent une gestion manuelle fastidieuse et hasardeuse (source d'erreurs). Le build est l'ensemble des phases nécessaires pour passer d'un code source à une application prête à être délivrée.
Ici aussi, on a deux solutions qui se tirent la bourre : Grunt et Gulp.
L'équivalent principal côté back-end Java est encore Maven (ou Ant si on veut).
Passons ensuite sur les outils de test automatisés. On est à la frontière entre le framework (composant logiciel) qui facilite le développement des programmes de test (des programmes qui testent des programmes, oui je sais les informaticiens sont des gens bizarres), et l'outillage qui permet d'exécuter automatiquement ces tests et vérifier qu'il n'y a pas d'erreur (dans le processus de build).
Deux solutions ont le vent en poupe à ma connaissance : Karma et Jasmine.
L'équivalent principal côté back-end Java est JUnit ou TestNG.
Ensuite, un outil de scaffolding. Hein scaquoi ? Le scaffolder est un outil qui génère automatiquement le squelette et une partie du code d'une application. C'est un outil qui permet de gagner du temps car il automatise certains travaux qu'on ferait sinon manuellement sur tout nouveau projet. Il apporte un gain de qualité car il fait les choses selon les meilleures pratiques, ce que ne ferait pas nécessairement le développeur pas toujours au fait des choses. Et il standardise la façon de faire ce qui est bon aussi.
Je connais une solution : Yeoman
L'équivalent principal côté back-end Java ? Il en existe pas mal, disons que les archetypes Maven sont le mécanisme le plus répandu.
Voilà un tour d'horizon rapide et sans doute incomplet. Mon idée est surtout de montrer qu'il y a une forte évolution de l'outillage, qui accompagne logiquement l'adoption massive de l'architecture REST, qui renforce l'importance du js (et donc la nécessité de gains de qualité et de productivité).
Asm.js
Accrochez vous à vos slips, ça devient un poil plus compliqué.
Pour ceux qui n'auraient pas les idées très claires sur ce qu'est une architecture processeur, du code binaire, la compilation, et les machines virtuelles, je préconise de lire ces deux articles :
Pour ceux qui n'auraient pas les idées très claires sur ce qu'est une architecture processeur, du code binaire, la compilation, et les machines virtuelles, je préconise de lire ces deux articles :
Mozilla a développé un outillage qui permet de compiler du code C ou C++ en javascript tellement optimisé qu'il s'exécute à peu près aussi vite qu'un code C# ou Java (c'est donc un progrès considérable). Des démos de jeux en 3D portés selon cette technique et s'exécutant sous Mozilla Firefox sont totalement bluffantes.
Cet article en anglais explique parfaitement la technique. J'en résume les idées clés.
Le code source (C ou C++) est dans un premier temps compilé, via un compilateur spécial (clang) dans un format de bytecode (code binaire virtuel) générique (non spécifique à une architecture particulière de VM). Tout cet outillage est fourni par le projet LLVM. Il est prévu le support d'autres langages.
Ce code binaire virtuel est ensuite transformé en un code javascript bien particulier via un outil développé par la fondation Mozilla (emscripten). Ce code est du code javascript mais il est généré d'une façon très particulière, respectant la spécification asm.js ; le résultat est que ce code javascript est directement traductible en binaire par un compilateur JIT spécialement optimisé ; Mozilla a optimisé le sien, et comme cette optimisation n'est pas très complexe et apporte des gains de performances extraordinaires, les autres acteurs ont suivis.
A priori tous les principaux navigateurs sont aujourd'hui optimisés pour asm.js, à l'exception d'Opera.
Un navigateur dont le compilateur javascript n'aurait pas été optimisé spécifiquement pourra également faire fonctionner le code, puisque c'est du javascript, mais il ne bénéficiera pas des gains de performance.
Un navigateur dont le compilateur javascript n'aurait pas été optimisé spécifiquement pourra également faire fonctionner le code, puisque c'est du javascript, mais il ne bénéficiera pas des gains de performance.
WebAssembly (wasm de son petit nom)
Tout nouveau, tout chaud.
WebAssembly est un format binaire censé être supporté par tous les navigateurs et destiné à être standardisé par le w3c (organisme qui normalise entre autre html, css, javascript) afin d'être totalement portable entre navigateurs (plus précisément entre interpréteurs js)
WebAssembly est un format binaire censé être supporté par tous les navigateurs et destiné à être standardisé par le w3c (organisme qui normalise entre autre html, css, javascript) afin d'être totalement portable entre navigateurs (plus précisément entre interpréteurs js)
On est dans la prolongation du principe asm.js mais alors que le code asm.js est exprimé en javascript (donc en texte), on a ici un format binaire.
WebAssembly est un format binaire mais ce n'est pas du tout du bytecode destiné à être exécuté par une machine virtuelle. Les informations exprimées par les 0 et les 1 ne sont pas des instructions destinées à une architecture de processeur (qu'elle soit virtuelle comme dans le cas d'une JVM Java par exemple, ou réelle en cas de code natif pour processeur Intel x386 par exemple) mais des structures de données.
Pour comprendre le principe, il faut connaître le fonctionnement des compilateurs. En simplifiant, une première étape consiste à analyser le code source et à écrire une représentation mémoire abstraite de son comportement. Ce qu'on appelle un AST Abtract Syntax Tree. Dans une seconde étape, cet AST est lu pour produire le code binaire correspondant à la plateforme cible. L'existence de l'AST découple les deux phases ce qui est très pratique car le code source peut ainsi être exprimé dans divers langages sources (il faut écrire un analyseur syntaxique pour chaque langage, et ils construisent tous un AST avec les mêmes conventions), et que ce code source peut être utilisé pour produire du code binaire pour différentes architectures processeurs physiques ou virtuelles (il suffit d'écrire un générateur de code binaire pour chaque plateforme). Ce principe est très souple et explique par exemple comment Microsoft permet d'exécuter divers langages sur une même machine virtuelle (CLR Common Language Runtime), ou comment un même code source peut servir à produire des exécutables pour des architectures processeurs différentes.
Dans le cas qui nous intéresse, la partie finale, qui consomme un AST pour produire du code binaire, est toujours la même : c'est le compilateur JIT (ou AOT, peu importe la nuance ici) embarqué par l'environnement d'exécution javascript, c'est à dire le navigateur (ou Node.js).
Dans le mesure où la structure de l'AST est normalisée, tout AST est portable entre environnements. Et c'est précisément le chantier en cours chez tous les éditeurs de navigateur : se mettre d'accord sur une structure normalisée et implémenter dans leurs moteurs respectifs (chakra, V8, spiderMonkey) la capacité de le lire pour générer directement du code binaire sur cette base (qui bien sur s'exécute bien plus vite, disons 10X plus vite, que le code interprété).
Il nous manque encore la partie avant, c'est à dire la capacité de générer cet AST depuis différents langages sources. De nouveaux langages vont peut être apparaître à cette occasion, le langage javascript va peut être évoluer pour se prêter plus facilement à cet usage, l'avenir nous le dira, le chantier est en cours. Mais d'ores et déjà, une partie du travail effectué pour le support de asm.js est exploitable et adaptable. Les outils qui compilent du code source C ou C++ en bytecode LLVM existent déjà. Modifier emscripten qui sait déjà lire ce format pour générer un binaire wasm au lieu d'un texte asm.js n'est probablement pas très compliqué...
wasm est donc une possibilité en cours de développement, complémentaire et distincte de asm.js.
Premier avantage, elle évite la phase de parsing du code asm.js qui est coûteuse en temps d'exécution (en particulier sur les devices peu performants comme les smartphones), et complique la maintenance des runtime javascript (qui doivent implémenter deux parsers, un pour le code "régulier" et un pour le code "asm.js").
Second avantage, un format binaire est plus compact qu'un format texte et le temps de transport du code par le réseau sera également fortement réduit.
Donc en conclusion, au lieu de faire voyager du bytecode par le réseau ce qui obligerait à implémenter une machine virtuelle sur chaque environnement (ce qui existe depuis 20 ans avec les applets java), on a choisi de faire voyager une représentation binaire d'une phase intermédiaire de la compilation qui est achevée sur l'environnement client. Le choix a été fait pas des très grands esprits de l'informatique, on peut donc supposer qu'ils ont leurs raisons, même si il n'est pas impossible que des motivations d'ordre tactico-économiques aient pesées dans la balance.
Je vous invite à lire cette interview de Brendan Eich (l'ignoble individu qui a créé Javascript, et le pire c'est qu'il en est fier).
Pour finir, on peut quand même penser, bien que Brendan Eich s'en défende, que ce choix signifiera à terme la mort du javascript ou du moins la fin de sa prévalence. En effet, n'importe quel langage accompagné d'un analyseur syntaxique capable de produire un AST au format wasm pourra être utilisé. Et ce sera un très grand progrès pour les développeurs de la prochaine décennie.
Pour finir, on peut quand même penser, bien que Brendan Eich s'en défende, que ce choix signifiera à terme la mort du javascript ou du moins la fin de sa prévalence. En effet, n'importe quel langage accompagné d'un analyseur syntaxique capable de produire un AST au format wasm pourra être utilisé. Et ce sera un très grand progrès pour les développeurs de la prochaine décennie.
Conclusion
Le poids de l'existant... en informatique ça a toujours été quelque chose de très lourd.
Javascript est un langage plein d'inconvénients et de défauts mais on doit faire avec. Ces inconvénients étant en bonne partie liés au fait que l'usage qu'on en fait aujourd'hui est très différent de ce pour quoi il était apparu à l'origine (un langage de scripting accessible aux non professionnels pour dynamiser des pages web et écrire des programmes courts).
Du coup, on (ré)invente des tas de technologies complexes, et envisageables uniquement car les processeurs actuels en ont sous le pied, pour faire de façon compliquée ce qu'on aurait pu faire mille fois plus simplement en reprenant les choses à la base.
Enfin quoi qu'il en soit, les choses vont dans le bon sens et n'ont manifestement pas fini de progresser.
Ha oui, dernier point, on constate que le sujet est complexe, riche, et en perpétuelle évolution. Pour cette raison je ne peux que conseiller à tout société qui investirait sur le développement d'applications en javascript, de se faire accompagner par des vrais spécialistes du sujet. Comme côté back-end, la fonction d'architecte prend tout son sens, ce n'est pas qu'une invention des SSII pour facturer plus chers des prestations... Même si bien entendu il n'est pas inutile de vérifier que le profil qu'on vous place comme architecte a bien la large culture technique et le côté pragmatique indispensables pour ce poste clé dans une équipe de production (fuyez les geeks).
Javascript est un langage plein d'inconvénients et de défauts mais on doit faire avec. Ces inconvénients étant en bonne partie liés au fait que l'usage qu'on en fait aujourd'hui est très différent de ce pour quoi il était apparu à l'origine (un langage de scripting accessible aux non professionnels pour dynamiser des pages web et écrire des programmes courts).
Du coup, on (ré)invente des tas de technologies complexes, et envisageables uniquement car les processeurs actuels en ont sous le pied, pour faire de façon compliquée ce qu'on aurait pu faire mille fois plus simplement en reprenant les choses à la base.
Enfin quoi qu'il en soit, les choses vont dans le bon sens et n'ont manifestement pas fini de progresser.
Ha oui, dernier point, on constate que le sujet est complexe, riche, et en perpétuelle évolution. Pour cette raison je ne peux que conseiller à tout société qui investirait sur le développement d'applications en javascript, de se faire accompagner par des vrais spécialistes du sujet. Comme côté back-end, la fonction d'architecte prend tout son sens, ce n'est pas qu'une invention des SSII pour facturer plus chers des prestations... Même si bien entendu il n'est pas inutile de vérifier que le profil qu'on vous place comme architecte a bien la large culture technique et le côté pragmatique indispensables pour ce poste clé dans une équipe de production (fuyez les geeks).