JavaScript : retour sur le serveur
Par Clochix le mercredi 14 octobre 2009, 01:38 - Technoweb - Lien permanent
Utiliser JavaScript sur le serveur, l'idée est ancienne, mais connaît depuis quelques mois un vif regain d'intérêt. Petit tour d'horizon de cette actualité.
Retour aux sources
On l'oublie souvent, mais au moment de sa conception en 1995 par Brendan Eich pour le compte de Netscape, JavaScript a d'abord été un langage pour le serveur, avant de rapidement intégrer le navigateur. Netscape a longtemps essayé de défendre cette utilisation, avant qu'elle ne disparaisse peu à peu.
Langage maudit du Web 1 (à cause des implémentations incompatibles de Navigator et d'IE qui obligeaient à développer le code en double), JavaScript a peu à peu gagné ses lettres de noblesse avec le Web 2, DHTML et AJAX, et les nombreuses bibliothèques qui ont permis de faire abstraction des spécificités des navigateurs. Depuis environ deux ans, les principaux fondeurs de navigateur se livrent à une compétition forcenée autour de JS, et les performances des moteurs ont explosé (en 10 ans, elles auraient été multipliées par presque 100[1]). Aujourd'hui, il devient par exemple de plus en plus envisageable d'avoir dans le navigateur, propulsées par JavaScript, des applications demandant de la puissance de calcul, comme par exemple de la 3D. Et l'utilisation de JavaScript sur le serveur revient au goût du jour, les performances du langage commençant à rivaliser avec celles des autres. Signes de ce retour, le grand nombre de bibliothèques "serveur" qui fleurissent depuis quelques mois, et surtout le projet CommonJS.
Mais pour quoi faire ?
L'intérêt de permettre à JavaScript d'enfin s'ébattre sur le serveur me semble évident. Utiliser le même langage sur le client et le serveur présente plusieurs avantages:
- actuellement, développer une application Web demande de connaître au moins deux langages, l'un sur le serveur, l'autre dans le navigateur[2] et des langages assez différents, car JavaScript, ne serait-ce que par son implémentation particulière du modèle objet, a une logique bien spécifique. J'ai toujours trouvé fatigant, dans un projet Web, de devoir passer sans arrêt de JavaScript à PHP/Python/Java/Ruby/..., parce que les philosophies sont différentes, et accessoirement certaines petites différence de syntaxe sont propices aux erreurs. Les fréquents sauts d'un langage à l'autre empêchent de se mettre en mode automatique et fatiguent;
- de nombreuses opérations (des validations de données saisies par exemple) doivent être codées deux fois, dans deux langages, avec des implémentations le plus proches possibles. En se limitant à un seul langage, on peut réutiliser davantage de code, avoir la garantie qu'il n'y a pas de différence d'implémentation d'un algorithme entre le client et le serveur (ce qui est toujours la cause de soucis difficilement détectables). On diminue ainsi la charge de travail, et accélère le développement.
- la communication entre le client et le serveur s'en trouve facilitée, puisqu'on est sûr que les données sont encodées et décodées de la même façon;
Plusieurs projets relativement pionniers expérimentent déjà ce type
d'architecture. Par exemple Jaxer, un projet
libre développé depuis plusieurs années par Aptana. Jaxer utilise Gecko sur le
serveur, c'est à dire à la fois le moteur JavaScript, SpiderMonkey, et toutes
les bibliothèques incluses dans Firefox pour manipuler du XML, le DOM, les
accès au système de fichier, etc. Parallèlement Aptana a également créé
ActiveJS, un ensemble de bibliothèques
utilisables aussi bien dans le navigateur que sur le serveur, et facilitant la
mise en œuvre de MVC en JavaScript pur. Parmi les autres précurseurs
, on
pourra également regarder du côté d'Helma
ou de Haxe.
CommonJs
Une des principales raisons pour moi du succès de PHP est la grande richesse de bibliothèques disponibles dans le cœur du projet ou à proximité (c'est à dire dans PEAR ou PECL). Quoi que l'on veuille faire, on trouvera une bibliothèque facile à installer et relativement bien documentée.
JavaScript à l'opposé est un langage que je trouve plus puissant que PHP (il est par exemple réellement objet et offre depuis longtemps des mécanismes qui arrivent timidement dans les dernière versions de l'éléphant bleu), mais pauvre en bibliothèques. Hormis la manipulation du DOM, plus récemment un peu de dessin avec les travaux sur Canvas, on est assez frustré dès que l'on veut l'utiliser pour faire autre chose que que rendre dynamique une page Web. C'est possible, mais encore faut-il trouver les bibliothèques qui vont bien et espérer qu'elles soient compatibles avec le moteur qu'on utilise. Ayant effectué l'essentiel de sa croissance au sein du navigateur, le langage a beaucoup de mal à couper le cordon et s'en émanciper, alors qu'il en aurait le potentiel. C'est pourtant un langage de script moderne qui, du strict point de vue du langage, n'a pas grand chose à envier à PHP, Python, Ruby, etc. Sa faiblesse majeure est dans la pauvreté actuelle de son écosytème, sur le serveur du moins.
Kevin Dangoor, qui travaille sur les outils pour les développeurs chez Mozilla, a remis sur le tapis l'utilisation de JavaScript sur le serveur dans un excellent billet au début de l'année, qui a depuis été suivi de nombreux autres allant dans le même sens. What Server Side JavaScript needs détaille les faiblesses actuelles de JavaScript et l'intérêt d'y remédier pour qu'il prenne enfin son envol sur le serveur. Lancé sous le nom de ServerJS, un groupe de discussion a rapidement eu un gros succès, et a donné naissance au projet CommonJS.
L'objet du projet est de définir un socle d'APIs permettant de répondre aux problématiques les plus courantes, pour que JavaScript dispose enfin des bibliothèques qui lui font tant défaut. La tâche est ardue, car si le cœur de JavaScript est standardisé par l'ECMA, les nombreuses implémentations de la spécification ont parfois pris des libertés avec elle, et surtout ont pallié ses manques en implémentant chacun sa solution. Les problèmes de compatibilité du code sont donc nombreux, et les bibliothèques implémentant CommonJS devront fonctionner de façon transparente avec tous les moteurs disponibles (cf une liste plus bas). Mais elles offriront ainsi un socle sur lequel on pourra s'appuyer pour enfin créer des applications de plus haut niveau, comme jQuery, Prototype et compagnie ont permis de s'abstraire des soucis de compatibilité pour se concentrer sur le développement.
Une version 0.1 de la spécification a déjà vu le jour qui définit l'API de modules inter-opérables, pour pouvoir facilement charger des bibliotèques externes et les faire communiquer entre elles. La version 0.5 en cours de développement crée quatre autres API : pour la manipulation d'objets binaires, l'accès à un système de fichiers, les tests unitaires, et la communication avec les serveurs Web (JavaScript Gateway Interface - JSGI). De nombreuses autres sont en cours de discussion sur le wiki et la liste de discussion. Plusieurs projets ont d'ors et déjà entrepris d'implémenter la spécification, l'un des plus avancés étant sans doute Narwal.
Effervescence
Le regain d'intérêt pour l'utilisation de JavaScript sur le serveur est aussi manifeste par le nombre de projets qui ont éclos ces derniers mois. La liste est longue, en voici quelques uns parmi ceux que je trouve les plus prometteurs:
- Narwhal est un ensemble de bibliothèques JS conformes à CommonJS. Le projet aspire à être indépendant du moteur. Narwhal sert entre autre de base à Jack, une couche permettant la communication entre des applications JavaScript s'exécutant sur un serveur, et un serveur Web. Jack implémente la spécification JSGI, développée pour l'occasion, qui définie une API pour ces communications. JSGI s'inspire des spécification WSGI en Python et Rack en Ruby;
- Persevere est un serveur permettant entre autre de stocker des objets JavaScript et d'y accéder directement via des services REST. Il est développé par l'équipe de Dojo et en particulier par Kris Zyp dont j'ai déjà parlé dans mes billets sur JSON. Grâce à CommonJS, Narwhal et Persevere peuvent à présent être utilisés de concert, au travers de l'API de modules;
- Helma NG (Next Generation) est un framework JavaScript serveur écrit en Java et basé sur Rhino. Sa nouvelle version (NG) vise à le simplifier et à implémenter CommonJS;
- Node est un serveur écrit en JavaScript et utilisant le moteur V8. Il propose une implémentation de serveur alternative à celle habituelle basée sur des threads. Il s'inspire par exemple de Twisted en Python. S'il n'implémente pas encore CommonJS, c'est un bel exemple de l'intérêt d'utiliser JS sur le serveur;
Mis à jour j'oubliais que JavaScript est aussi le langage invité de nouvelles bases de données comme CouchDB, où il est utilisé pour faire des requêtes complexes. Il commence donc même à se faire sa place dans le domaine des bases de données.
Quoi d'autre ?
Dernier point, j'ai parlé jusqu'à présent d'unification du langage utilisé
dans le client et sur le serveur, mais il y a un troisième acteur à prendre en
compte: la plate-forme, en l'occurrence le navigateur. Personne n'ignore que
JavaScript est utilisé intensivement dans Firefox, et tout particulièrement
dans les extensions. Une position qui va encore gagner en importance avec
l'arrivée de JetPack, la nouvelle architecture pour les extensions, dont le
slogan est si tu sais créer une appli Web, tu sais aussi créer une
extension
. Pour ce que j'en ai vu, les extensions Chrome vont elles aussi
utiliser JS. CommonJS a donc également une indéniable utilité à ce niveau, en
permettant de créer des composants génériques qui seront également utilisables
par la plate-forme, le navigateur, et portables d'un navigateur à l'autre. A
terme, cela facilitera sans doute encore les interactions entre le navigateur
et les contenus.
Ces nouveaux horizons qui s'ouvrent à JavaScript me plaisent beaucoup. Vu la vitesse à laquelle les différents projets avancent, on devrait voir des trucs assez sympas arriver dans les prochains mois.
Annexe : tour d'horizon des moteurs
A ce jour, les moteurs libres les plus répandus et qui peuvent être utilisés sur le serveur, sont
- SpiderMonkey : inventé par Brendan Eich en même temps que JavaScript, il est aujourd'hui maintenu par Mozilla. Il évolue aujourd'hui sous le nom de TraceMonkey en intégrant des bouts de Tamarin, un projet commun à Mozilla et Adobe. SpiderMonkey étant codé en C, il offre des mécanismes pour utiliser des routines écrites en C ou C++. C'est ainsi que dans Firefox, composants en C++ et modules en JavaScript travaillent de concert;
- Rhino est un moteur en Java développé par Mozilla. Il offre aussi des passerelles avec Java. On peut ainsi appeler des bibliothèques Java depuis le code JavaScript, ou utiliser Rhino dans un projet Java ayant besoin de fonctions de scripting;
- v8 de Google, probablement le plus véloce actuellement;
- SquirrelFish utilisé dans Safari. mise à jour on me glisse en commentaire que 4D, éditeur d'une fameuse base de données sur Mac, travaille sur le projet Wakanda qui l'utilisera;
- je ne parle pas des moteurs utilisés dans Opéra ni IE car je ne sais pas s'ils existent en tant que projets indépendants du navigateur. Ils ne sont de toute façon à ma connaissance pas libres;
- pour aller plus loin, Wikipédia propose une liste plus complète de moteurs;
Notes
[1] référence nécessaire, j'ai vu ça dans une graphique sur un site de développeur Google, mais sans source et je ne le retrouve même plus. Si vous avez des infos...
[2] je n'ai pas encore testé les solutions qui génèrent automatiquement le code client depuis le langage serveur, comme Google Web Toolkit par exemple, j'avoue qu'elles m'attirent moins
Commentaires
Il y a aussi l'extension pecl spidermonkey pour php: http://pecl.php.net/package/spiderm...
"SquirrelFish utilisé Safari. Je n'ai pas connaissance de projets y faisant appel;"
le projet Wakanda, plateforme intégrée de développement de Business Internet Applications, de la société 4D utilise SquirrelFish extreme: http://www.wakandasoftware.com/waka...
@desfrenes : tutafé, JavaScript s'invite également dans d'autres langage serveurs. On peut citer Pydermonkey qui intègre SpiderMonkey à Python sur le même principe que l'extension PECL;
@ckeromen : merci, billet mis à jour, c'est plutôt bon signe de voir qu'une société comme 4D s'intéresse à la chose.
Au passage, j'ai rajouté deux mots au billet pour évoquer CouchDB, qui utilise JS comme langage de script interne pour les requêtes.
Franchement je préfèrerais avoir le Java côté client...
Vu que tu parles de CouchDB, il y a aussi MongoDB qui utilise Spidermonkey pour son shell.
D'ailleurs MongoDB pourrait faire un bon choix pour du Javascript server side si il n'est pas nécessaire d'utiliser une base de données relationnelle.
De plus il est bon noter que les performances atteintes par les différents projets ne sont pas du tout les mêmes.
Par exemple tous les projets basés sur Rhino sont globalement plus lent étant donné que la vitesse n'est la priorité de Rhino contrairement à Tracemonkey et V8.
Dommage qu'il n'y a pas encore de projet SSJS significatif basé sur Spidermonkey, car il dispose d'un atout par rapport à V8, Spidermonkey supporte E4X qui permet de jouer facilement avec du XML en Javascript. On pourrait par exemple faire un système de template très simple pour un framework web ou encore bidouiller avec du XMPP...
Bref affaire à suivre
et n'oublions pas GWT... je ne suis pas très fan de google et de leur manière de phagocyter de la donnée utilisateur, mais l'idée de rendre le javascript debuggable en l'écrivant en java n'est pas franchement mauvaise, bien au contraire. Et d'ailleurs des clones tels que pyjamas sont apparus dans d'autres langages, ce n'est pas pour rien
@Quentin : et moi Python, j'y reviens très bientôt.

Java est disponible depuis très longtemps sous forme d'applets. Mais j'ai l'impression que ça disparaît de plus en plus. Je ne crois pas trop aux langages compilés côté client, même si cette compilation peut être relativement transparente.
@Frédéric : j'ai entendu parler de MongoDB, mais pas encore regardé de près.
Pour ce qui est des perfs, je me doute que V8, SquirrelFish et SpiderMonkey sont plus rapides que Rhino, mais je n'ai pas trouvé de bench, et à vrai dire je n'en ai pas cherché, ne voulant pas lancer de troll.
Par contre du fait de la portabilité de Java, il est plus simple d'ajouter des bibliothèques externes sous forme de jar que des bibliothèques compilées, donc c'est un avantage qui joue en faveur de Rhino.
Pour ce qui est du support d'E4X, merci de me l'apprendre. Effectivement, ce n'est pas prévu dans V8, et ça m'étonne. Merci de m'avoir donné un argument pour répondre aux fans de vitesse qui ne jurent plus que par Chrome
@Romain : j'ai cité GWT, mais ça ne m'intéresse pas. Pour moi le but est de rendre le développement Web plus accessible aux amateurs. Utiliser le même langage partout est une piste. Passer par du Java qui génère du JavaScript est peut-être une bonne solution technique, mais à réserver aux pros.
Oui mais les applets c'est un peu différent. C'est un module inséré dans la page. Moi je verrai le java qui s'interface directement avec le html/css, à la place du javascript. Pour moi ce qui manque au javascript, ce n'est pas forcément le côté compilé, mais un côté plus carré (typage fort, héritage, ...) qui permettrait d'avoir entre autre de véritables IDE.
Après Python effectivement... pourquoi pas.