Journal Réflexions à propos de NodeJS et de Javascript plus globalement

30
18
avr.
2012

Bonjour,

cela fait quelques jours que je me pose la question suivante : « Est-ce que Node.js ne va pas devenir une technologie incontournable / majeur dans les 2 ans qui viennent ? »

Le contexte

Je suis un développeur Python depuis de nombreuses années. J'aime ses librairies, j'aime ses outils, j'aime sa communauté.
J'aime tellement sa syntaxe que quand je vois la syntaxe d'autres langages, j'ai une réaction quelque peu épidermique à la lecture du code.
Avec le temps, l'habitude de la syntaxe Python minimaliste proche d'un pseudo code rend difficile la possibilité d'apprécier un autre langage. Je ne sais pas si c'est positif ou négatif, je me pose simplement la question. Enfin ceci est un autre sujet.

Cependant, mon regard se tourne de plus en plus vers Node.js… je n'ai pas franchi le pas, je n'ai rien développé en Node.js… mais je me demande si je ne passe pas à coté de quelque chose d'important.

Les forces de Node.js

  • Bien que Node.js date seulement de 2009 :

  • tous les développeurs web (front-end) connaissent le langage, il est très populaire. Par conséquent, pour passer à Node.js il n'y a pas le frein d'apprendre un nouveau langage comme ça serait le cas avec l'utilisation d'un framework web basé sur Ruby ou Python. Je pense que dans les mois qui viennent, de nombreux développeurs PHP vont passer à Node.js… surtout ceux qui regardaient ailleurs mais qui ne souhaitent pas apprendre un nouveau langage.

  • la possibilité de partager du code (librairies communes…) entre la partie client et serveur peut être intéressant. La question se pose de plus en plus étant donnée qu'on est de plus en plus amené à effectuer beaucoup de traitement coté client (exemple avec Backbone.js).
    Dernièrement, dans tous mes projets de développement web, j'ai utilisé un moteur de template coté client en plus du moteur de template coté serveur.
    Je dois gérer de plus en plus souvent une couche modèle coté client. Des vues coté client… Cela fait donc plein d'éléments en doubles, utilisés une fois sur le serveur, une fois sur le client. Donc deux technologies à maîtriser.
    Ces derniers jours, la visualisation du screencast du framework javascript Meteor m'a mis la puce à l'oreille.
    Autre exemple, il est possible d'utiliser la même API Canvas coté client et coté serveur (avec node-canvas).

  • Node.js semble être très rapide, ça tient très bien la monté en charge.

  • La vitesse de l'interpréteur Javascript est en constante progression V8 (JavaScript engine)

Faiblesses de Node.js

Je ne sais pas si mes remarques sont exactes, je n'ai aucune expérience en Node.js.

  • Exemple dans la partie Bad Use Cases du guide Felix's Node.js Convincing the boss guide il est indiqué que les framework Node.js sont moins matures que ce que l'on peut trouver en Ruby, Python et Php (bon pour ce dernier j'ai des doutes, je pense que la communauté Node.js est déjà plus mature, plus structurée que la communauté Php… enfin bon…).
  • Je ne pense pas que Sequelize soit aussi mature que SQLAlchemy
  • Je n'ai pas trouvé d'outil comme Whoosh en Javascript (c'est un moteur de recherche léger). J'ai tout de même trouvé Node-xapian

Je ne sais pas si il est encore tôt pour passer à Node.js mais si la communauté continue à être aussi dynamique que ces 2 dernières années… alors les pièces manquantes seront bientôt créées.

Est-ce que l'on va retrouver Javascript partout ?

Voici une petite liste :

Quand je vois cette liste, je me pose sérieusement la question : est-ce que Javascript est le langage incontournable de ces 10 prochaines années ? Certes il est déjà incontournable dans le navigateur, mais pour le reste ?

  • # Que le hype soit avec toi.

    Posté par . Évalué à 3. Dernière modification le 18/04/12 à 14:54.

    Ah oui, je vous présente un hurluberlu qui nous présente node.js : http://www.youtube.com/watch?v=jo_B4LTHi3I

    Moi j'y comprends plus rien mais je sais que c'est très hype donc foncez…

    Voilou :)

    Sinon JS est aussi utilisé dans kate (kde advanced text editor) pour développer des plugins.

    Remarquez que je ne comprends plus rien à ce qu'est, sera et a été javascript. En tout cas s'il me semble prendre un certain essor, il me semble aussi nettement moins généraliste que python ou ruby. En tous cas j'ai l'impression en effet que javascript part dans tous les sens, et je me demande un peu pourquoi. Il doit y avoir une bonne raison, je suis certainement un peu défaitiste :D.

    Systemd, the bright side of linux, toward a better user experience and on the road to massive adoption of linux for the desktop.

  • # Il manque une faiblesse !

    Posté par (page perso) . Évalué à 2.

    Il me semble que la GROSSE faiblesse de javascript est l'existence de multiples versions pas 100% compatibles entre elles, typiquement d'un navigateur à l'autre. Ce qui complique beaucoup son utilisation dans des sites ouebs !

    Par ailleurs son système d'objet (à base de prototype et non de classe) est atypique. Ça peut être un avantage comme un inconvénient, mais les systèmes d'objet à base de classe sont généralement mieux connus des développeurs.

    • [^] # Re: Il manque une faiblesse !

      Posté par . Évalué à 10.

      Au hasard, j'aurais plutôt choisi plein de conneries de conception : variables dont le scope est toute la fonction, utilisation plus ou moins laxiste du point-virgule, j'en passe et des meilleures (lire les derniers chapitres de « Javascript the good parts » pour vous fendre la gueule).
      Honnêtement, je code un peu en JS pour mon boulot, et j'ai toujours l'impression que je vais me faire avoir à cause d'un truc pas clair du langage (p….n de triple "="), et pourtant je code habituellement en C++ qui n'est pas franchement réputé pour sa facilité d'accès.

      Je crois que le jour où j'aurai 5 min, j'irai regarder si l'herbe n'est pas plus verte du côté de Lua (et du coup apprendre enfin à coder en luatex), mais sincèrement, entre python et Javascript, au niveau syntaxe et plaisir de développement, y a pas photo.

      P'tet qu'à cause de la course à la perf de mozilla et chrome, JS est devenue une bête de vitesse incontournable, mais j'ai l'impression qu'on va finir avec une pile de code impossible à maintenir et déboguer dans pas très longtemps.

      • [^] # Re: Il manque une faiblesse !

        Posté par (page perso) . Évalué à 4.

        utilisation plus ou moins laxiste du point-virgule

        En quoi l'utilisation est laxiste ? Les derniers trolls sur le point-virgule sont surtout des personnes qui n'ont jamais appris correctement le javascript et qui écrivent un code dépendant de la mise en forme (et donc qui foire dès qu'on le minifie)

        p….n de triple "="

        Je crois que le jour où j'aurai 5 min, j'irai regarder si l'herbe n'est pas plus verte

        Ben tu devrais plutôt passer 5 minutes à apprendre javascript en premier.
        Oui il y a des choses étranges, mais l'histoire de == === est loin d'être complexe, il faut juste comprendre que plusieurs choses sont fausses et que tester l'égalité entre deux "valeurs fausses" est vrai mais ne veut pas dire que les valeurs sont identiques.

        "" == 0 // true
        "0" == 0 // true
        undefined == null // true
        undefined !== null // true
        
        

        on va finir avec une pile de code impossible à maintenir

        Comme dans tous les langages. Pour le js il "suffit" d'écrire proprement les choses, d'arrêter les syntaxes type jQuery (qui en plus d'être peu lisibles sont peu optimisable). Voir par exemple les "règles" de http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml

        • [^] # Re: Il manque une faiblesse !

          Posté par (page perso) . Évalué à 4.

          Pour jouer un peu :

          var assert = function(test) {
              /return ([^;]+);/.test(test);
              if (!test()) {
                  console.error("Oups, '" + RegExp.$1 + "' is false.");
              } else {
                  console.info("Yeah, '" + RegExp.$1 + "' is true.");
              }
          };
          assert(function() { return undefined; });
          assert(function() { return null; });
          assert(function() { return false; });
          assert(function() { return ""; });
          assert(function() { return 0; });
          assert(function() { return undefined == null; });
          assert(function() { return undefined === null; });
          assert(function() { return "0" == 0; });
          assert(function() { return "" == false; });
          assert(function() { return undefined == false; });
          assert(function() { return undefined === false; });
          
          
          Oups, 'undefined' is false.
          Oups, 'null' is false.
          Oups, 'false' is false.
          Oups, '""' is false.
          Oups, '0' is false.
          Yeah, 'undefined == null' is true.
          Oups, 'undefined === null' is false.
          Yeah, '"0" == 0' is true.
          Yeah, '"" == false' is true.
          Oups, 'undefined == false' is false.
          Oups, 'undefined === false' is false.
          
          
          • [^] # Re: Il manque une faiblesse !

            Posté par . Évalué à 2.

            var assert = function(test) {
            /return ([;]+);/.test(test);

            On est obligé de créer une fonction anonyme pour créer une fonction en js ? Et c'est quoi cette 2e ligne complètement illisible ? Et "RegExp.$1", ça sort d'où ?

            • [^] # Re: Il manque une faiblesse !

              Posté par (page perso) . Évalué à 5.

              On est obligé de rien.
              J'aurais aussi pu écrire

              var assert = function assert(test) {
              };
              
              

              ou

              function assert(test) {
              }
              
              

              Mais les trois écritures ne sont pas tout à fait similaires. Pour ma part je commence toujours pas var ça permet de bien mieux mettre en évidence la portée de ma fonction.

              Heu, quel est le problème de la deuxième ligne ?

              En gros, ce que je voulais, c'est afficher la valeur "source" du return (d'ailleurs le fait de passer par une fonction anonyme dans le assert est là uniquement pour accéder à la source.
              Donc :

              test -> String source de la fonction passée en paramètre.

              /return ([^;]+);/
              
              

              est une bête expression régulière, je cherche tout ce qui est entre return et ; (et en fait je match sur [^;] donc tout caractère différent de ;.

              Comme l'expression régulière est un objet, je peux exécuter une méthode dessus. Ici .test qui me permet de savoir si la chaîne passée en paramètre (ici test.toString() bien que le toString soit implicite) correspond à la regexp.

              En réalité je n'utilise absolument pas le retour (true ou false, ici systématiquement true). Mais lorsqu'on utilise une regexp, l'objet RegExp est peuplé avec le dernier résultat.
              Donc RegExp.$1 me permet de récupérer la première référence, donc le premier groupe entre parenthèse dans ma regexp.

              Au final :

              var func = function() { return "0" == 0; });
              var funcStr = func.toString(); // "function() { return "0" == 0; });" en gros
              var returnValRegExp = /return ([^;]+);/;
              
              if (returnValRegExp.test(funcStr)) {
                console.log(RegExp.$1); // "0" == 0
              }
              
              

              sauf que je n'ai pas mis le if

              • [^] # Re: Il manque une faiblesse !

                Posté par . Évalué à 4.

                Pourquoi tu passe des fonctions en paramètres de ta fonction assert si tu ne t'en sert pas ?

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                • [^] # Re: Il manque une faiblesse !

                  Posté par (page perso) . Évalué à 3.

                  Comme indiqué, uniquement pour pouvoir récupérer la source et faire un log propre.

                  Si j'ai cet usage d'une méthode assert :

                  assert(null == undefined);
                  
                  

                  ma méthode assert est appelée avec comme paramètre le résultat de l'opération null == undefined, ici true. Je ne peux donc pas écrire un log correct ici, je peux juste dire si c'est true ou false.

                  Si j'ai

                  assert(function() { return null == undefined; });
                  
                  

                  ma méthode assert est appelée avec une fonction en paramètre. Je peux exécuter cette fonction (qui me renverra true ou false) mais aussi accéder à la définition de cette méthode, sous forme de string. Je peux donc logger la source qui a été exécutée.

                  J'espère que c'est un peu plus clair, si non pointe ce qui ne l'est pas et je continuerai à détailler.

                  • [^] # Re: Il manque une faiblesse !

                    Posté par . Évalué à 3.

                    Je peux exécuter cette fonction

                    Oui ok, je n'avais pas vu que tu l'exécutais, j'avais l'impression que tu en évaluais le corps. C'est le trop pleins du mon test qui m'a perturbé :

                    /return ([^;]+);/.test(test);
                    if (!test()) {
                    
                    

                    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

              • [^] # Re: Il manque une faiblesse !

                Posté par . Évalué à 2.

                Mais lorsqu'on utilise une regexp, l'objet RegExp est peuplé avec le dernier résultat.

                ? Attends…

                • un objet RegExp de type RegExp instancié automatiquement au démarrage
                • test() qui fait autre chose que retourner true/false

                C'est standard tout ça ? Ni sur Toutjavascript.com, ni sur W3schools.com je n'ai trouvé de trace à ce sujet. Je viens de tenter un alert(RegExp.toString())`` et il me répond :

                function RegExp() {
                  [native code]
                }
                
                

                Je ne dis pas que tu as tort (pas testé ton code), mais sur quelle référence tu te bases ? Et est-ce que c'est bien euh, "standard" ?

                • [^] # Re: Il manque une faiblesse !

                  Posté par (page perso) . Évalué à 3.

                  http://www.toutjavascript.com/reference/reference.php?iref=57 par exemple. Ok c'est pas très explicite mais on parle bien de la propriété $1 de RegExp.
                  http://fr.selfhtml.org/javascript/objets/regexp.htm

                  un objet RegExp de type RegExp instancié automatiquement au démarrage

                  En quelque sorte oui, je sais pas exactement comment c'est fait. J'aurais plutôt tendance à dire qu'on utilise certaines variables statiques de l'objet RegExp (et il ne faut pas oublier comment fonctionne les objets en javascript, il n'y a pas de classe, RegExp n'est pas une classe mais un objet)

                  test() qui fait autre chose que retourner true/false

                  Oui

                  Je viens de tenter un alert(RegExp.toString())

                  Tente alors un alert(RegExp.$1)

                  Tiens, un petit code à tester (je ne sais pas si les dernières lignes sont valides partout par contre) :

                  var fields = ['$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_'];
                  var i, field, l = fields.length;
                  var input = "http://www.linuxfr.org/nodes#new_comment";
                  var reg = /((https?):\/\/)([^/]+)\/(([^#]+)(#.*)?)/;
                  if (reg.test(input)) {
                    for(i = 0; i < l; i++) {
                      field = fields[i];
                      console.log('RegExp.' + field + ' = ' + RegExp[field]);
                    }
                  }
                  
                  

                  Sortie :

                  RegExp.$1 = http://
                  RegExp.$2 = http
                  RegExp.$3 = www.linuxfr.org
                  RegExp.$4 = nodes#new_comment
                  RegExp.$5 = nodes
                  RegExp.$6 = #new_comment
                  RegExp.$7 =
                  RegExp.$8 =
                  RegExp.$9 =
                  RegExp.$_ = http://www.linuxfr.org/nodes#new_comment
                  
                  

                  mais sur quelle référence tu te bases ?

                  Heu, je sais plus, ça fait un bon moment que je le sais que ça fonctionne comme ça, je peux pas dire d'où exactement.

                  Et est-ce que c'est bien euh, "standard" ?

                  Je pense, oui. En tout cas je ne suis pas encore tombé sur un navigateur où ça ne fonctionne pas comme ça.

                  • [^] # Re: Il manque une faiblesse !

                    Posté par . Évalué à 2. Dernière modification le 19/04/12 à 11:19.

                    Ok c'est pas très explicite mais on parle bien de la propriété $1 de RegExp.

                    Mmh

                    var versioncomp = /(\d)/;
                    versioncomp.exec(navigator.userAgent);
                    document.write("Le numéro de version complet de votre navigateur est: " + RegExp.$1);
                    
                    

                    Ah oui tiens, sur SelfHTML RegExp est utilisé en tant qu'objet… Sur les autres sites c'est plutôt versioncomp.$1 qu'on verrait.

                    J'ai testé ton code, effectivement la console affiche bien ça avec Firefox.

                    Bon bon… J'aime bien la référence de Toutjavascript.com, mais reste qu'une référence complète, je cherche toujours. Ça existe ?

                    • [^] # Re: Il manque une faiblesse !

                      Posté par (page perso) . Évalué à 3. Dernière modification le 19/04/12 à 11:47.

                      Pour le moment je n'ai pas encore trouvé de référence à ce RegExp.$n
                      La référence à JS est ici : http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
                      Mais j'ai trouvé dedans (bon j'ai pas tout lu non plus)

                      Et de la doc qu'elle est bien (même si c'est pas dedans non plus) : http://dochub.io

                      Sur les autres sites c'est plutôt versioncomp.$1 qu'on verrait.

                      Sauf que ça ne fonctionne pas j'ai l'impression…

                      var versioncomp = /(\d)/;
                      versioncomp.exec(navigator.userAgent);
                      console.log("Le numéro de version complet de votre navigateur est: " + RegExp.$1);
                      console.log("Le numéro de version complet de votre navigateur est: " + versioncomp.$1);
                      
                      
                      Le numéro de version complet de votre navigateur est: 5
                      Le numéro de version complet de votre navigateur est: undefined
                      
                      
                      • [^] # Re: Il manque une faiblesse !

                        Posté par . Évalué à 2.

                        Sauf que ça ne fonctionne pas j'ai l'impression…
                        Ah non pardon, je me suis embrouillé. Les autres sites parlaient que de la valeur de retour d'exec().

                • [^] # Re: Il manque une faiblesse !

                  Posté par (page perso) . Évalué à 4.

                  C'est standard tout ça ? Ni sur Toutjavascript.com, ni sur W3schools.com je n'ai trouvé de trace à ce sujet.

                  Ces deux sites ne sont pas forcément de très bonnes références. Je recommande plutôt d'utiliser Mozilla Developer Network. Pour naviguer facilement, DocHub est bien pratique (il reprend le contenu de MDN).

              • [^] # Re: Il manque une faiblesse !

                Posté par (page perso) . Évalué à 5.

                Mais lorsqu'on utilise une regexp, l'objet RegExp est peuplé avec le dernier résultat.

                Si tu veux récupérer les résultats, ce n'est pas la méthode test(), mais la méthode exec() qu'il faut utiliser. D'un point de vue sémantique, c'est plus propre et ça te renvoi direct un tableau avec les éléments capturés. Et c'est parfaitement documenté et standardisé.

                https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec

                Autre avantage de exec() : tu ne perds pas les résultats. Si il y a deux test() appelés à la suite, on perd les matchs des autres trucs.

                /(.*)/.test(maString);
                UneFonctionQuiFaitAppelAussiARegexpTest(); // mais tu ne le sais pas forcément
                // pouf, les resultats du premier test() sont perdus.
                
                

                Bref, mauvaise utilisation de test().

                • [^] # Re: Il manque une faiblesse !

                  Posté par (page perso) . Évalué à 3.

                  C'est pas faux.

                  J'aurais du écrire

                  var assert = function(test) {
                      var res = /return ([^;]+);/.exec(test);
                      if (!test()) {
                          console.error("Oups, '" + res[1] + "' is false.");
                      } else {
                          console.info("Yeah, '" + res[1] + "' is true.");
                      }
                  };
                  
                  

                  Après, j'utilise en général .test parce que je trouve ça parfois plus simple/lisible

                  var matches = /return ([^;]+);/.exec(test);
                  if (matches != null && matches.length > 1) {
                    console.log(matches[1]);
                  }
                  
                  // vs
                  
                  if (/return ([^;]+);/.test(test)) {
                    console.log(RegExp.$1);
                  }
                  
                  

                  Après, ça dépend pas mal du contexte, lorsque j'ai une regexp complexe, du traitement important à faire derrière, j'utilise exec. Lorsque j'ai une regexp toute bidon comme ici, dont je connais exactement à l'avance le résultat et dont je recherche juste un élément je fais au plus simple.

        • [^] # Re: Il manque une faiblesse !

          Posté par . Évalué à 3.

          Merci pour les coding rules Javascript, ça me plaît bien.

          Pour l'insertion implicite des points-virgules, je maintiens qu'un langage qui propose un truc aussi bancal et foireux est plus un moyen de se tirer une balle dans le pied qu'autre chose.
          Pour les deux opérateurs d'égalité, j'admets que quand je récupère un objet d'une API, je dois m'arrêter un moment pour savoir lequel choisir ; tu peux mettre ça sur le compte de mon manque d'expérience avec ce langage.

          P.S. je note que tu n'as rien dit sur le scope des variables déclarées avec "var" :-p

          • [^] # Re: Il manque une faiblesse !

            Posté par (page perso) . Évalué à 2. Dernière modification le 18/04/12 à 17:01.

            Pour l'insertion implicite des points-virgules, je maintiens qu'un langage qui propose un truc aussi bancal et foireux est plus un moyen de se tirer une balle dans le pied qu'autre chose.

            Faut voir, si on prend l'un des derniers trolls sur le sujet (https://github.com/twitter/bootstrap/issues/3057) il apparaît (très rapidement) que le problème n'est pas en fait l'absence du ; mais surtout l'usage de ! comme séparateur

            TC39 is considering the use of ! as an infix operator. This code will break in the future. Fix it now. Learn to use semicolons properly. ! is not intended to be a statement separator. ; is.

            Alors c'est sur, javascript est laxiste… mais c'est pour ça qu'il faut arriver à bien comprendre les forces et faiblesses de celui-ci, et surtout connaître les limites. Après c'est beaucoup plus facile de coder avec.

            P.S. je note que tu n'as rien dit sur le scope des variables déclarées avec "var" :-p

            Quel est vraiment le problème ? En effet le scope est la fonction. D'où l'usage courant de

            (function() {
            [...]
            })();
            
            

            afin d'isoler les traitements

            Après il y a des choses bien plus tordues en javascript, notamment ce qui est après un return est accessible
            par exemple :

            var plop = function() {
              b();
              return;
              function b() { console.log('ok'); };
            };
            plop();
            // ok
            
            

            mais

            var plop = function() {
              b();
              return;
              var b = function() { console.log('ok'); };
            };
            plop();
            
            

            ne fonctionnera pas

            Un lien assez sympa http://vic.github.com/jwm-tt-js-ninja/

        • [^] # Re: Il manque une faiblesse !

          Posté par (page perso) . Évalué à 4.

          En quoi l'utilisation est laxiste ? Les derniers trolls sur le point-virgule sont surtout des personnes qui n'ont jamais appris correctement le javascript et qui écrivent un code dépendant de la mise en forme (et donc qui foire dès qu'on le minifie)

          Le troll est loin de toucher que des personnes qui ne connaissent pas bien le JS. Dans un camp (les ; à chaque fin de ligne), on trouve Brendan Eich, le créateur du langage, et Douglas Crockford (jslint, JSON). De l'autre coté, on a Isaac Z. Schlueter, actuel mainteneur de node.js, et Thomas Fuchs (Prototype, Scriptaculous, Zepto).

          D'ailleurs, le code en question était valide, c'était le minificateur de Douglas Crockford qui était en faute.

          Oui il y a des choses étranges, mais l'histoire de == === est loin d'être complexe

          C'est quand même loin d'être simple. Il y a même un cas où a === a renvoie false.

          • [^] # Re: Il manque une faiblesse !

            Posté par (page perso) . Évalué à 2.

            Oui il y a des choses étranges, mais l'histoire de == === est loin d'être complexe

            C'est quand même loin d'être simple. Il y a même un cas où a === a renvoie false.

            Oui, c'est sur. Mais en général, on ne tombe pas bien souvent dessus.
            Et la compréhension de == et === n'est pas si compliquée dans 99% des cas. C'est surtout que les gens ne sont pas habitués à cela, tout comme ils essaient de faire de la programmation par classe en javascript, alors que c'est un langage à prototype.

            D'ailleurs, le code en question était valide, c'était le minificateur de Douglas Crockford qui était en faute.

            Ok, j'avais initialement lu le contraire, d'où ma réponse.
            Il semble que tu ais raison :
            https://github.com/douglascrockford/JSMin/commit/5ca277ea452beae1c25db3bc0ef5c81309a3daf4#jsmin.c

            Il est vrai que, lorsque j'utilisais jsmin, la règle était :

            • toujours ;
            • toujours {}

            Après, c'est sur qu'avoir le créateur de javascript en faveur du ; a un certain point. Mais c'est à ce demander pourquoi ils ne sont pas obligatoire finalement.

      • [^] # Re: Il manque une faiblesse !

        Posté par (page perso) . Évalué à 3.

        Genre une pile de code qui forke openssl, la zlib et une boucle d'evenement ?

        Ou un interpréteur qui s'appuie sur un moteur js qui fait des releases tout les 6 semaines ?

    • [^] # Re: Il manque une faiblesse !

      Posté par (page perso) . Évalué à 6.

      typiquement d'un navigateur à l'autre.

      Ce n'est pas grave il suffit de recoder un navigateur en JS.

  • # On le sait bien les dev PHP sont incompétents

    Posté par . Évalué à 2.

    Exemple dans la partie Bad Use Cases du guide Felix's Node.js Convincing the boss guide il est indiqué que les framework Node.js sont moins matures que ce que l'on peut trouver en Ruby, Python et Php (bon pour ce dernier j'ai des doutes, je pense que la communauté Node.js est déjà plus mature, plus structurée que la communauté Php… enfin bon…).

    C'est quoi ce troll ? PHP ça a 15 ans au bas mot et il possède 2 frameworks qui font référence : zend et symphony (chacun étant plus vieux que Node.js). Le plus irritant c'est que tu dis explicitement que c'est un préjugé.

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: On le sait bien les dev PHP sont incompétents

      Posté par (page perso) . Évalué à 8.

      Pour avoir fait pendant 2 ans du Zend Framework, je suis d'accord avec lui, c'est de la daube par rapport à Django, je ne veux plus toucher à ZF.
      Pas de communauté ZF qui publie des exemples, que de la doc théorique, des kilomètres de code à taper quand quelques lignes suffisent avec Django, des bugs…

      Sans compter qu'en PHP amuse-toi pour faire des threads, des daemons ou tout truc un peu avancé ;-)

    • [^] # Re: On le sait bien les dev PHP sont incompétents

      Posté par (page perso) . Évalué à 10.

      http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/

      S.

      "There's no such thing as can't. You always have a choice." - Ken Gor

    • [^] # Re: On le sait bien les dev PHP sont incompétents

      Posté par (page perso) . Évalué à 6.

      Si on prend par exemple, le système de package.

      En php, il y a pear, depuis longtemps mais vraiment pas pratique… pas grand monde ne l'utilise.

      Depuis il y a un nouveau, qui semble mieux fait Packagist. Il date de juin 2011 ! PHP a 15 ans, il a fallu attendre 14 ans pour avoir un système de package correct et qui est pour le moment très peu utilisé dans les projets.

      C'est pour cela que Node.js me semble déjà plus mature que PHP. La communauté utilise dans son ensemble un système de package…

      Je ne sais pas si le mot mature est le bon… je peux le remplacer par "plus expérimenté".

    • [^] # Re: On le sait bien les dev PHP sont incompétents

      Posté par (page perso) . Évalué à 6.

      PHP ça a 15 ans au bas mot

      Ça reste du Personal Home Page pour autant.
      Je m'y suis mis un peu il y a qq jours. J'avais rien vu d'aussi pourri depuis mes débuts en 85 et les compilos DBase3+.

      • [^] # Re: On le sait bien les dev PHP sont incompétents

        Posté par . Évalué à 5.

        Du personal home page utilisé entre autre par facebook, wikipedia, wordpress,…

        Moi je déteste ce langage (tout comme javascript d'ailleurs), mais force est de constaté qu'il ne se limite plus et depuis quelques temps déjà à servir des petits programmes.

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: On le sait bien les dev PHP sont incompétents

          Posté par . Évalué à 3.

          Facebook

          Facebook il ont reecrit leur propre compilateur (et interpreteur pour la version de dev). Si ils avaient a recommencer aujourd'hui, tu peux etre 100% sur qu'ils feraient pas du PHP.

          Sinon, les devs PHP qui introduisent des trous de secu dans un patch pour corriger un trou de secu et doivent s'y reprendent a 3 fois avant de vraiment corriger le probleme, je sais pas si on peut appeler ca vraiment competent.

          • [^] # Re: On le sait bien les dev PHP sont incompétents

            Posté par . Évalué à 3.

            Je serait intéressé de connaître l'avis de zukerberg là dessus. Je pense que tu as raison sur le fait qu'il ferait un choix différent, mais tes arguments ne sont pas les bons. Je ne pense pas que les créateur de Jython, pypy et autre iron python, le font parce qu'ils n'aiment pas le langage python (au contraire).

            Sinon, les devs PHP qui introduisent des trous de secu dans un patch pour corriger un trou de secu et doivent s'y reprendent a 3 fois avant de vraiment corriger le probleme, je sais pas si on peut appeler ca vraiment competent.

            Tout les langages n'ont pas la qualité de perl.

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: On le sait bien les dev PHP sont incompétents

      Posté par . Évalué à 6.

      On le sait bien les dev PHP sont incompétents

      Bah, mettons que ce genre d'histoire ne plaide pas en leur faveur:
      http://use.perl.org/use.perl.org/_Aristotle/journal/33448.html

  • # Même avis que toi

    Posté par (page perso) . Évalué à 5.

    J'utilise aussi beaucoup Python, et je vois monter NodeJS ces derniers temps, en même temps que mes propres besoins en JS côté client augmentent.

    La grande force de Python, ce sont les librairies, où dans mon domaine, sont bien plus avancées qu'en NodeJS. De plus le langage JS est moins consistant que Python.

    Perso, j'aimerais bien pouvoir utiliser Python côté client plutôt que passer à JS côté serveur, j'ai prévu d'expérimenter certaines solutions, mais j'ai bien peur que je ne pourrais utiliser ça uniquement pour les clients dont on maitrise l'OS client.

    • [^] # Re: Même avis que toi

      Posté par (page perso) . Évalué à 7.

      au lieu d'inventer un nouveau langage (dart), Google aurait pu glisser le support python dans chrome/chromium. Même une version limité sans toutes les libs

      ç'aurait été … ouah énorme

      • [^] # Re: Même avis que toi

        Posté par (page perso) . Évalué à -2.

        tant qu'à faire il aurait peut-être aussi fallu améliorer un peu le modèle objet de python dans ce cas. C'est quand même pas terrible.

        (oué moi j'aime bien Dart au final…)

        • [^] # Re: Même avis que toi

          Posté par (page perso) . Évalué à 1.

          histoire de donner un peu de grain à moudre à mon précédent message : pensez à self

          • [^] # Re: Même avis que toi

            Posté par . Évalué à 4.

            Python ne fait que rendre explicite ce qui existe dans à peu près tous les langages objets : « this » est en fait un argument implicite.

            C’est un choix qu’on peut ne pas aimer, ça ne rend pas le modèle objet de python tout pourri.

            Et ça permet de faire des trucs sympas comme map(str.strip, [" a ", "b "])

            • [^] # Re: Même avis que toi

              Posté par (page perso) . Évalué à 1.

              map(str.strip, [" a ", "b "])

              Et alors, si on prend javascript il n'y en a simplement pas besoin.

              Si j'ai une méthode function plop(arg1, arg2) { [...] } je peux faire :

              • plop(a, b);
              • plop.call(obj, a, b);
              • plop.apply(obj, [a, b]);

              Et hop, aucun besoin de prendre un truc optionnel pour en faire un cas général. C'est juste un mauvais design.
              La majorité des cas c'est que tu exécute la méthode d'un objet sur lui même. L'implicite est absolument évident dans ce cas.
              Et du moment que tu peux, simplement, le faire si besoin, aucun problème. Au final la majorité du code est plus simple et plus lisible et non pourrie par un cas particulier.

              • [^] # Re: Même avis que toi

                Posté par . Évalué à 4. Dernière modification le 20/04/12 à 16:51.

                Ton exemple en JS n’est pas équivalent à mon exemple en Python. Try again :)

                >>> map(str.strip, [" a ", "b "])
                ['a', 'b']
                
                

                Et hop, aucun besoin de prendre un truc optionnel pour en faire un cas général.

                Le but de self n’a jamais été de rendre possible mon exemple. Ce n’est qu’un effet de bord du choix général « explicit is better than implicit ». On peut aimer ou pas ce choix, mais tu ne peux pas dire que c’est incohérent, ou un truc du genre. Pour faire pas mal de Python et de Ruby, je dois dire que parfois en Ruby je me dis de temps en temps (pas tous les jours il est vrai) « tiens, ce serait plus simple avec un self à la python ». Dans l’autre sens (il me fait chier ce self), jamais.

                Ha, et j’ajouterai, c’est bien le dictateur bienveillant de Python qui a dit « Special cases aren't special enough to break the rules ». Donc non, j’insiste : self n’est pas là pour satisfaire un cas spécial.

                Et parler de design illisible pour Python tout en défendant Javascript, fallait oser. Javascript, c’est quand même le (seul à ma connaissance) langage où x=foo.bar;x() et foo.bar() n’ont strictement rien à voir.

      • [^] # Re: Même avis que toi

        Posté par (page perso) . Évalué à 5.

  • # Javascript partout

    Posté par (page perso) . Évalué à 3.

    On trouve même javascript dans les bases de données, pour du Map/Reduce notamment :
    - CouchDB ;
    - MongoDB ;
    - Riak…

    Mais effectivement, NodeJS fait de l'oeil, et Meteor n'a pas aidé ;)

  • # Mon expérience

    Posté par (page perso) . Évalué à 10.

    Mon travail en ce moment consiste a coder un serveur de jeu multijoueur temps réel (dans le sens "pas tour par tour", pas dans le sens système de "temps réel"). On le code en Node.js . Et on est assez content, ca marche pas mal.

    On a hésité a un moment entre Node.js et Python+Twisted. On a choisi Node.js parce que l'environnement de Node.js est bien plus cohérent en ce qui concerne l'asynchronicité : tous les modules sont asynchrone, ou quand ils ne les ont pas, c'est écrit en gros dessus (et ils sont rares). Ce n'est pas le cas avec Python+Twisted, ou des qu'on utilise un module qui ne vient pas de Twisted, on retombe dans des échanges synchrone qui cassent un peut tout l'intérêt du truc (par exemple je me souviens qu'a l'époque ou on avait testé Twisted, on avait pas trouve de lib pour se connecter a une base Postgres asynchrone…)

    En plus, je trouve que la syntaxe du Javascript est bien plus adaptés a l'écriture de code asynchrone que Python+Twisted (note: j'adore Python aussi, je ne fais pratiquement que du JS et du Python).

    Pour autant, je n'utiliserais pas Node.js pour faire un site web "classique" (en tous cas pas encore), car mis a part les domaines ou il a un net avantage, sur le reste, c'est moins facile de le faire en Node.js qu'en Django par exemple.

    La ou Node.js est fort:
    - Si on veut garder une connexion permanente avec le serveur (Websocket)
    - Si on veut garder des datas sous le coude entre deux requêtes: dans un web-serveur classique, on doit passer par un fichier ou une DB quelconque, avec Node.js on peut le stocker en ram aussi longtemps qu'on veut (bon, aussi avec les complications que ca peut impliquer, mais dans certaines situation c'est très pratique).
    - Si on a des contraintes de scalabilites très fortes, avec des requêtes tres simples (dans le sens pas CPU-intensives).
    - Si on a besoin de faire tourner le même code dans le browser et dans le serveur (exemple: un jeu très asynchrone: une partie se déroule a 100% sur le client, a la fin le client envoie tous les évènements au serveur. Le serveur est capable de vérifier s'il n'y a pas eu triche pendant la parte en re-executant toutes les actions, en utilisant exactement la même implémentation (Javascript donc) que sur le client.

    Bref, ce n'est pas (encore) la vocation de Node.js de remplacer Apache sur nos port 80, mais ca reste un outil très intéressant, et non ce n'est pas que du hype…

    • [^] # Re: Mon expérience

      Posté par (page perso) . Évalué à 4.

      D'accord avec toi, sauf sur deux points:
      1. Tu n'as pas cherché longtemps pour faire du PostGreSQL asynchrone ;-) => http://twistedmatrix.com/documents/current/core/howto/rdbms.html#auto4
      2. Perso, je ne trouve pas beaucoup plus la syntaxe de JS adapté pour de l'asynchrone que Twisted, par contre, il faut penser asynchrone avec twisted, ce que ne font pas la plupart des dev python, ils essaient de faire du python "classique" avec twisted.

      • [^] # Re: Mon expérience

        Posté par (page perso) . Évalué à 2.

        1. C'était y a deux ans, mes souvenirs sont pas tout frais, sans doute qu'on est tombé la dessus et que j'ai décide que c'était pas assez KISS pour moi…

        2. j'ai l'impression que c'est un peut subjectif, je me souviens d'avoir vu deux exemples triviaux (genre un echo server) en twisted et en node.js, et d'avoir très largement préféré la version node.js "a l'œil" (a noter qu'a l'époque, je ne faisais pratiquement que du Python depuis des mois et pratiquement pas de JS, ce n'est donc pas par habitude avec la syntaxe JS). Cf les main pages des deux projets respectifs pour se faire une idée par soi-même : http://twistedmatrix.com/trac/ , http://nodejs.org/

        • [^] # Re: Mon expérience

          Posté par (page perso) . Évalué à 2.

          1. Soit tu me dit que tu cherchais un ORM, auquel cas il fallait se tourner vers Twistar, soit tu me dit que tu as horreur du système de callback, alors que fais-tu avec NodeJS, dont le JS est basé sur le même principe ? ;-) Pour moi, cette API de requêtes SQL est KISS en Twisted.
          2. Twisted utilise la notion de Factory pour créer chaque instance de protocole, alors qu'en NodeJS, de ce que j'en vois, c'est directement le protocole qui est attaqué. Peut-être que c'est over-engineered dans Twisted, néanmoins, je me sers souvent de cette notion de factory pour gérer de manière globale un groupe de pool de protocol (reconnexion…). Mais j'imagine que c'est aussi possible de coder ce genre de notions en NodeJS, ce n'est qu'une séparation logique.
          • [^] # Re: Mon expérience

            Posté par (page perso) . Évalué à 3. Dernière modification le 20/04/12 à 13:21.

            Après avoir recontacté mon collègue de l'époque, c'était pas la lib pgsql qui posait problème, par contre effectivement, on voulait l'ORM de Django, parce que nos frontaux étaient en Django, et on a pas réussi a le faire marcher de manière asynchrone. Je ne sais plus si on a considéré utiliser Twistar, je pense que j'aurais catégoriquement refusé l'idée d'utiliser 2 ORM différents pour accéder a la même base, même si il y a une chance que ca marche (au début…)

            J'adore les callbacks, c'est pas le soucis, mais justement je considère (et c'est très personnel) que dans la programmation asynchrone, les fonctions anonymes (et nested) c'est la vie. Et de ce point de vue python est faible face a Javascript: en python tu ne peux faire des fonctions anonymes qu'avec "lambda", et c'est forcement des one-liner.

            Tu peux considérer que cette faiblesse de Python est en faite une force parce que ca force a bien structurer ton code et d'éviter de te retrouver avec un code spaghetti immonde, mais c'est vraiment question de gout et d'usage. Moi je trouve qu'avoir la possibilité de coller le corps du callback directement la ou il va être appeler améliore grandement la lisibilité du code, et c'est ce qui fait que je trouve un code node.js bien plus agréable a lire qu'un code twisted (mais encore une fois, c'est vraiment question de gouts).

            • [^] # Re: Mon expérience

              Posté par (page perso) . Évalué à 2.

              Ok pour l'ORM, de fait, ça a du sens.

              Pour les callbacks en Twisted, c'est un argument que j'ai entendu plusieurs fois.
              Ça a du sens, c'est vrai que c'est plus simple à lire.

              Après, avec de la rigueur, si tu mets la méthode de callback juste en dessous, ça reste simple à lire, mais c'est vrai que sur ce point, le Javascript fait mieux.

    • [^] # Re: Mon expérience

      Posté par (page perso) . Évalué à 5.

      Si on veut garder des datas sous le coude entre deux requêtes: dans un web-serveur classique, on doit passer par un fichier ou une DB quelconque, avec Node.js on peut le stocker en ram aussi longtemps qu'on veut (bon, aussi avec les complications que ca peut impliquer, mais dans certaines situation c'est très pratique).

      Ça veut quand même dire que les données ne seront pas partagées entre les différentes instances du serveur. Du coup, je me suis rarement servi de cette technique. Est-ce que tu pourrais expliquer quelle genre de données tu stockes en RAM ?

      Si on a des contraintes de scalabilites très fortes, avec des requêtes tres simples

      Mon expérience me dirait justement le contraire. Sous de fortes charges, j'avais plutôt constaté que nodejs avait tendance à leaker de la mémoire et à avoir des connexions en erreur. Est-ce que tu pourrais partager ton expérience à ce sujet ?

      • [^] # Re: Mon expérience

        Posté par (page perso) . Évalué à 4.

        Ça veut quand même dire que les données ne seront pas partagées entre les différentes instances du serveur. Du coup, je me suis rarement servi de cette technique. Est-ce que tu pourrais expliquer quelle genre de données tu stockes en RAM ?

        Je m'en suis justement servis dans des cas ou je n'avais a coup sur qu'une seule instance du serveur (dans mon cas, serveur de jeu ou 1 partie = 1 instance de node.js).

        Le jeu était pour téléphone portable, une partie durait environ 10 / 15 minutes, était multijoueurs (jusqu'à une vingtaine de joueurs par partie). Un joueur met a jour sa position environ toutes les 1 a 2 secondes. La communication entre le client et le serveur se faisait par une API HTTP plus ou moins REST, en JSON.

        Au début on utilisait Django avec PostgreSQL. Ça faisait qu'a chaque fois qu'on arrivait dans une méthode qui traitait une requête d'un client, il fallait charger l'état du jeu depuis la SGDB, appliquer les changements suivant la logique de jeu sur les objets en RAM, re-sauvegarder l'état du jeu en SGDB (ce qui peut être une ou plusieurs entrée dans une ou plusieurs tables, suivant ce qui s'est passée dans le jeu).

        C'était particulièrement moche et gourmand en CPU et en RAM. On aurait éventuellement pu intercaler en plus un memcache entre Django et la SGDB, mais ca n'aurait fait qu'ajouter du bordel dans l'usine a gaz.

        Quand on a rationalisé le truc, on s'est rendu compte que finalement, la persistance d'une partie qui dure 15 minutes, on s'en balance. On est passe a Node.js, on fait tourner le jeu "en ram" au lieu de le faire tourner "en DB", avec une instance Node.js = une partie, et depuis on est très content. Tellement qu'on a laisse tombe l'API de polling HTTP et qu'on est passe en Websockets.

        Mais donc, comme je le dis dans mon premier message, c'est pas du tout un cas de site web classique. Si je dois faire un site web, je prends Django et je suis très content, je vais plus vite qu'avec Node.js.

        Mon expérience me dirait justement le contraire. Sous de fortes charges, j'avais plutôt constaté que nodejs avait tendance à leaker de la mémoire et à avoir des connexions en erreur. Est-ce que tu pourrais partager ton expérience à ce sujet ?

        J'avoue je recrachais un peu la plaquette commerciale de Node.js, j'ai pas d'expérience a taille réelle sur le terrain de ce cas d'usage, mais ca me semble quand même étrange que ca leak…

        • [^] # Re: Mon expérience

          Posté par . Évalué à 2.

          Quand on a rationalisé le truc, on s'est rendu compte que finalement, la persistance d'une partie qui dure 15 minutes, on s'en balance. On est passe a Node.js, on fait tourner le jeu "en ram" au lieu de le faire tourner "en DB", avec une instance Node.js = une partie, et depuis on est très content.

          Je présume que ce n'est pas que pour ça que vous êtes passé à node.js parce que sinon c'est vraiment jeter le bébé avec l'eau du bain. Une technique simple pour stocker des données en RAM qui peuvent même être mutualisées entre plusieurs instance, c'est d'utiliser redis.

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: Mon expérience

            Posté par (page perso) . Évalué à 2.

            Ce n'est pas que pour ca mais cette raison seule est largement suffisante.
            Note que j'ai évoqué qu'on avait envisagé d'utiliser un memcached , qui il me semble jouerais le même rôle que ton redis (je connais pas super bien redis…).

            Le besoin qu'on avait et qui n'est pas dans la partie de mon texte que tu as quoté, c'est qu'on voulait un jeu qui tourne "en permanence", pas seulement quand un client fait une requête, et on ne pouvait pas faire ca dans Django, il nous fallait des worker en background pour faire tourner ca, et c'est la que c'est devenu une usine a gaz: apache, django, rabbitmq (amqp), celery (background workers), pgsql…(et le memcache/redis qu'on avait même pas introduit mais qui aurait fini par arriver tôt ou tard…)

            Et on a remplacé tout ca par… node.js . Qui, dans la liste ci-dessus, remplace tout sauf pgsql. Faut reconnaitre que c'était plusieurs ordres de magnitude plus simple et plus maitrisable, avec moins d'interactions complexes et donc moins de risque de bugs difficile a remonter avec un seul processus.

            • [^] # Re: Mon expérience

              Posté par . Évalué à 2.

              il nous fallait des worker en background pour faire tourner ca

              Ok ce n'était pas un problème de données mais de traitement. Je comprends tout à fait la problématique. Elle s'adresse « relativement » bien en Java EE avec les files JMS, mais tu parle d'usine à gaz… :)

              Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Mon expérience

      Posté par (page perso) . Évalué à 2.

      • Si on a des contraintes de scalabilites très fortes, avec des requêtes tres simples (dans le sens pas CPU-intensives).

      La définition de très forte est, disons…, assez variable ;-)

      http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1

    • [^] # Re: Mon expérience

      Posté par . Évalué à 2.

      Si on a besoin de faire tourner le même code dans le browser et dans le serveur (exemple: un jeu très asynchrone: une partie se déroule a 100% sur le client […]

      Excusez-moi pour la question bête, mais : c'est uniquement pour limiter le nombre de transactions ou il y a une autre astuce derrière ?

      • [^] # Re: Mon expérience

        Posté par (page perso) . Évalué à 2.

        Ça peut être pour réduire le nombre de transaction, ca peut être aussi parce que la connectivité n'est pas fiable (pour une application mobile par exemple). En faisant ca on peut laisser le joueur jouer localement et synchroniser avec le serveur quand la connexion revient.

        • [^] # Re: Mon expérience

          Posté par . Évalué à 2.

          D'accord. Ça doit être chaud d'utiliser cette méthode (faire jouer "localement") avec plusieurs joueurs.

          • [^] # Re: Mon expérience

            Posté par (page perso) . Évalué à 3.

            C'etait peut-etre pas tres clair, je n'ai jamais utilise cette methode, c'est juste un cas d'usage que j'imagine bien, et effectivement ca ne se marie pas bien avec un jeu multi tres interactif.

            Par contre ce que j'ai fait souvent, c'est prototyper une fonctionnalité en Javascript dans le browser, avec toutes les facilites d'affichage que cela comporte, pour ensuite utilise le code a l'identique en module dans NodeJS.

  • # Templates

    Posté par (page perso) . Évalué à 3.

    Dernièrement, dans tous mes projets de développement web, j'ai utilisé un moteur de template coté client en plus du moteur de template coté serveur.

    Pourtant, il existe de nombreuses solutions permettant d'utiliser des templates (les mêmes) aussi bien côté client que côté serveur. C'est d'ailleurs, je pense, la meilleure solution pour gérer des sites ou applications web, d'autant plus lorsqu'on souhaite avoir aussi bien une version sans code côté client (accessibilité, indexation, référencement, js désactivé) qu'une version type ajax, rafraichissement côté client, interface agréable, etc.

    Pour ma part j'utilise beaucoup Closure Templates (y compris en prod sur du grand public) : https://developers.google.com/closure/templates/ mais c'est intéressant surtout si on fait du java
    Voir aussi ces très intéressant articles de Linkedin qui est passé de jsp, erb à du templating du même type, avec en bonus une comparaison de plusieurs frameworks de template (le lien parle initialement de templating côté client, mais la solution fait les deux) : http://engineering.linkedin.com/frontend/leaving-jsps-dust-moving-linkedin-dustjs-client-side-templates et http://engineering.linkedin.com/frontend/client-side-templating-throwdown-mustache-handlebars-dustjs-and-more

  • # Faiblesses de Node.JS

    Posté par . Évalué à 8.

    Étant plutôt fan de Node.JS je vais prendre sur moi pour commenter les faiblesses ;)

    Ce que tu cites est plutôt juste: les frameworks "full-stack" sont moins nombreux et moins "bien finis". En fait, je dirais que tout ce qui est lourd ne fait pas partie de l'écosystème Node et que c'est plutôt volontaire.

    C'est en train de changer, et des ORM et des frameworks full-stack tentent des approches, mais généralement (à part Mongoose) le taux d'adoption est très faible. Les gens sont allés vers Node pour sa rapidité, sa légèreté, pour retrouver le plaisir de bosser sur une plateforme qui n'est pas encore sclérosé par des années d'over-engineering… Du coup ma vision du truc c'est que les frameworks full-stack et les ORM hyper abstraits ne font à juste titre pas partie de l'écosystème.

    Quant aux outils "out of the box" comme le moteur de recherche que tu cites, ils sont effectivement aussi assez rares car pour l'instant on a surtout une communauté de développeurs qui font ça "pour le fun", et donc peu de produit qui répondent à un fort besoin fonctionnel. On trouvera facilement des outils à destination des développeurs ou des administrateurs système et réseau, mais sorti de ça l'offre est assez pauvre.

    Voilà c'était juste pour confirmer et préciser la partie "faiblesses" ;)

    • [^] # Re: Faiblesses de Node.JS

      Posté par . Évalué à 3.

      Etant un grand fan, tu sais comment faire pour faire plusieurs requêtes qui chacune est dépendante de l'autre sans faire des cascades de callback ou bien sans utiliser un module (dont je me souviens plus le nom) qui te permet de faire des appels l'une à la suite de l'autre ?

      Parce que perso, même si j'ai adoré nodeJS, son concept, ses idées, etc… je me suis vite pris un retour de bâton quand j'ai voulu faire un CRUD complexe (et cela sans avoir 10.000 appels Jquery/Ajax sur l'interface)

      Si t'as des solutions, je suis preneur. (même si je n'utilise plus -pour l'instant- nodeJS)

  • # IO OK / CPU KO

    Posté par . Évalué à 5.

    Je rajouterais que Node.js n'est pas adapté pour des programmes de calculs. Il est super pour des programmes avec IO et évènements (il est fait pour ça), mais pour du calcul scientifique ou autre programme nécessitant du CPU Node.js n'arrivera jamais aux perfs d'un code compilé en natif.

    Je le trouve moins couteau suisse que Python aussi. Pour le Web il va tuer PHP, Ruby et Python sans problème. Pour le reste non.

    • [^] # Re: IO OK / CPU KO

      Posté par . Évalué à 5.

      Je rajouterais que Node.js n'est pas adapté pour des programmes de calculs. Il est super pour des programmes avec IO et évènements (il est fait pour ça), mais pour du calcul scientifique ou autre programme nécessitant du CPU Node.js n'arrivera jamais aux perfs d'un code compilé en natif.

      C'est simplement que tu veux utiliser un rateau pour percer un trou. Node.js c'est fait pour un but précis, et c'est clairement pas fait pour du calcul.

      Après le côté perf code natif toussa, je rentrerais pas dans le troll.

    • [^] # Re: IO OK / CPU KO

      Posté par (page perso) . Évalué à 7.

      Il est super pour des programmes avec IO et évènements (il est fait pour ça)

      Dans une certaine mesure, oui, mais il est aussi très survendu.

      J'avais fait des benchmarks pour faire un serveur HTTP en mode long-polling capable d'avoir une centaine de milliers de connexions ouvertes en attente. Sur ce scénario totalement tourné IO et événements (aucun calcul), node.js était très loin de la libev en C ou des serveurs Erlang (Mochiweb, cowboy). Et ce, que ce soit pour la charge, la consommation mémoire et, plus important, le nombre de clients en erreur.

      • [^] # Re: IO OK / CPU KO

        Posté par . Évalué à 2.

        Ça pourrait être utile de filer les sources de tes benchs pour reproduire tout ça.

  • # Node.js du javascript partout

    Posté par (page perso) . Évalué à 3.

    Bonjour,

    Je suis grand fan de node.js ( cf. les articles sur mon blog: http://www.it-wars.com/categorie8/dev et mon site anglais http://nodejs-news.com ).

    Au delà des performances, de la laideur que certains peuvent trouver au javascript. Moi ce qui m'a séduit est le fait que du serveur au client en passant par la base de données (couchdb, mangodb,…) : ON UTILISE PLUS QU'UN SEUL LANGAGE !

    C'est vrai que node.js c'est hype, mais j'y vois un gain en terme de temps de dev, de rapidité pour maquetter, la communauté est active et les réponses arrivent vite en cas de problème.

    :)

  • # Juste pour dire

    Posté par (page perso) . Évalué à 10.

    Ça fait vraiment plaisir de lire un journal aussi bien documenté et malgré tout objectif avec des discussions qui ne partent pas en sucettes à Troll et où l'information prime encore dans le débat.
    Bref, j'ai vraiment eu l'impression de gagner du temps en te lisant.
    Rien que pour ça je te remercie.

  • # NodeJS

    Posté par . Évalué à 4.

    Ça faisait quelques temps que j'en avais entendu parler. Ça avait l'air de devenir vraiment à la mode. Moi ce que j'en pensais, c'était juste que comme la plupart des développeurs web sont des gros boulets, ils se retrouvaient à considérer que c'était trop dur d'apprendre, en plus du javascript coté client, du PHP (langage plutôt immonde donc parfait pour les devs web :p) coté serveur. Du coup, ils ont pondu du javascript coté serveur pour pas s'emmerder à apprendre un autre langage.

    Et puis, il y a quelques mois, on a eu un projet web à faire, avec technologies web. Comme on voulait découvrir des nouveaux trucs, on s'est penché sur nodejs, pour voir.

    J'étais vraiment septique mais assez curieux de voir ce que ça allait donner.
    Du coup, j'ai fait des recherches, j'ai bidouillé un peu, et, bordel, c'est vraiment génial comme truc ! Ça permet de développer assez rapidement et le coté événementiel est parfaitement adapté au web.

    Au delà de ça, j'adore Gnome 3 et j'ai regardé un peu comment faire pour créer des extensions (en javascript), et j'ai eu dans le cadre de mon travail à développer une petite extension pour firefox (toujours du javascript).

    Et du coup, je suis un pythonien convaincu, mais il faut le reconnaître chaque langage a son lot de qualités tant qu'il est utilisé correctement (même le PHP ;-)) (comme dit plus haut, ça sert à rien de faire du calcul scientifique en javascript). J'ai trouvé l'utilisation parfaite du javascript : c'est un super langage de scripting / d'extension.

    • [^] # Re: NodeJS

      Posté par . Évalué à 2.

      septique --> sceptique (à moins que tu parles d'une fosse).

      • [^] # Re: NodeJS

        Posté par . Évalué à 2.

        Ou de son moral à l'idée de faire du js…

        --> []

  • # Syntaxe de JavaScript ?

    Posté par (page perso) . Évalué à 2.

    Je réponds à plusieurs commentaires que j'ai vus sur cette page et même indirectement au journal lui-même. La syntaxe de JavaScript est certes difficile à appréhender par moments, mais il existe une "surcouche" de Javascript qui permet de s'en passer, et elle s'appelle CoffeeScript. Je dis "surcouche" car en fait il s'agit d'un langage de script qui se "compile" (réécrit serait le terme plus exact) en JavaScript "propre" (i.e qui passe des validateurs de code JS comme JSLint, censés garantir la qualité du code écrit).

    Ce que CoffeeScript apporte :
    - Syntaxe plus proche du Python : l'indentation définit les blocs, besoin de moins de parenthèses en général, c'est plus léger :

    function makeClickCallback(a) {
      return function() {
        alert("Vous avez cliqué sur le bouton d'id " + a);
      } 
    }
    
    $(document).ready(function() {
      $('#nimportequoi').click(makeClickCallback(a));
    }
    
    

    En CoffeeScript, ça donne

    makeClickCallback = (a) ->
      () ->
        alert "Vous avez cliqué sur le bouton d'id" + a
    
    $(document).ready () ->
      $('#nimportequoi').click makeClickCallback a
    
    

    (bon du coup effectivement, ça peut être un peu difficile de s'y retrouver avec les parenthèses nécessaires)

    • CoffeeScript diminue la difficulté du JavaScript par endroits : en rajoutant les listes de compréhension, l'usage des classes (ça se base effectivement sur les prototypes mais on peut les utiliser comme des classes), le '==' de CoffeeScript devient le '===' de Javascript, et autres billevesées fort intéressantes.

    Pour donner mon avis sur l'usage de NodeJS, effectivement ce n'est pas très intéressant pour un site "classique" (quoique le framework Express rende la mise en place d'un site statique avec appels REST très simple), mais très utile pour les sites plus orientés "échanges avec le serveur" (rien que le fait que les communications puissent toutes se faire en JSON est un argument acceptable pour rendre le tout cohérent).

    • [^] # Re: Syntaxe de JavaScript ?

      Posté par (page perso) . Évalué à 4.

      CoffeeScript c'est sympa, y'a des choses intéressantes, mais : comment on debug ce truc ? Un langage dans lequel on ne peut pas mettre un point d'arrêt ça n'a que peut d'intérêt malheureusement.
      Si je ne me trompe les sourcesmap sont arrivée que récemment (pas encore testé) mais on est simplement au même niveau du debug d'un code compilé javascript - javascript (comme avec closure compiler par exemple).
      J'ai beaucoup de mal à comprendre comment on peut espérer attirer des développeurs, pour faire des applis conséquentes (et non juste deux bricoles) sans debugguer. Et les "console" ou log ne sont pas une solution au problème.
      Dommage car c'est ma plus grande critique au langage.

    • [^] # Re: Syntaxe de JavaScript ?

      Posté par (page perso) . Évalué à 5.

      Petite remarque en passant : la version CoffeeScript n'est pas tout à fait équivalente à la version JavaScript. Si alert venait à renvoyer false, le lien serait suivi pour la version JS mais pas pour la version Coffee. En effet, dans la version coffee, la valeur de la dernière instruction est automatiquement retournée et, quand on renvoie false à un listener jquery, ça stoppe la propagation de l'événement.

      C'est pourquoi, je recommanderais plutôt cette version Coffee :

      makeClickCallback = (a) ->
        () ->
          alert "Vous avez cliqué sur le bouton d'id #{a}"
          null
      
      $(document).ready () ->
        $('#nimportequoi').click makeClickCallback a
      
      

      Et de manière plus générale, quand on structure son code avec des classes, c'est souvent une bonne pratique de renvoyer @ pour pouvoir facilement chaîner les appels.

      • [^] # Re: Syntaxe de JavaScript ?

        Posté par . Évalué à 2.

        Je ne connais rien en Javascript/Coffescript mais dans "makeClickCallback = (a) -> ()", le '()', ça ne veut pas dire que la fonction ne va rien retourner?
        Ce qui, pour moi, est l'équivalent d'ajouter un "return null" à la fin de la fonction..

  • # Mon avis

    Posté par (page perso) . Évalué à 10.

    Sommaire

    Mon avis sur node.js

    Je connais relativement bien Node.js, j'ai sûrement été parmi les premiers à m'y intéresser en France, j'ai commencé à jouer avec en 2009 alors qu'il n'était encore qu'en version 0.1, j'ai développé plusieurs applications node.js qui sont en production, etc.

    Et j'ai un avis relativement mitigé dessus. D'un coté, il y a clairement une très bonne dynamique, plein de nouveaux projets, une communauté active. Et ça utilise JavaScript, le langage avec la plus forte concurrence entre les implémentations. V8 et compagnie bénéficient d'une force de frappe bien plus conséquente que tous les interpréteurs Ruby et Python réunis peuvent avoir et ça se ressent en termes d'optimisations.

    Mais je n'ai pourtant pas souvent envie d'utiliser node.js. Pour faire des applications web complexes, on est vraiment loin de ce que peut proposer Rails, Django ou même les frameworks PHP. Node.js vise beaucoup plus les API REST et les communications serveur à serveur en HTTP ou avec d'autres protocoles.

    Sauf que pour ce genre d'applications, je préfère utiliser d'autres langages de programmation comme Go. Le code node.js a trop vite tendance à être mal organisé, on se retrouve avec des callbacks dans tous les sens. Mais surtout, ça peut très vite devenir un enfer à débugger : on devrait avoir tel callback qui se déclenche mais, dans certaines conditions, ça n'arrive pas et là, bon courage pour trouver le bug. On ne peut pas poser de point d'arrêt ou de console.log sur du code qui n'est pas exécuté. On peut faire ça sur les fonctions qui enregistrent le callback mais on se retrouve avec beaucoup de bruits : plein de logs auxquels ils faut pouvoir rattacher un contexte.

    Le partage de code entre client et serveur

    Pour moi, avoir une même base de code qui tourne coté client et coté serveur est juste un mythe. Partager des templates, c'est facile, on peut même le faire avec d'autres langages. Par exemple, ça m'a déjà arrivé de partager des templates mustache entre du Ruby coté serveur et du JS dans un navigateur. On peut aussi concevoir de partager des règles de validation de formulaire entre les deux cotés (surtout si celle-ci peuvent être décrites en html5).

    Par contre, aller plus loin n'est pas franchement une bonne idée. La manière de structurer du code complexe n'est pas le même entre le coté client (backbone par exemple) et coté serveur. Ce ne sont pas non plus les mêmes API. On peut faire tourner jQuery coté serveur mais je n'ai pas encore vu un cas où ça avait été concluant. L'accès aux données ne se fait pas de la même façon, ni la gestion de l'authentification ou des permissions.

    Bref, partager du code entre client et serveur peut se faire à petite échelle. Mais vouloir avoir une seule application qui tourne aussi bien coté client que coté serveur est juste une fausse bonne idée qui peut vite se transformer en très mauvaise idée.

    CoffeeScript

    Je trouve que CoffeeScript est une grande avancée par rapport à JavaScript. Ça aide bien à structurer son code, à construire des classes plutôt que des fonctions en vrac. Ça apporte aussi des trucs totalement indispensables comme => (ça crée une fonction et ça bind le this à l'objet auquel la fonction est attachée, ça devrait être le défaut en JS).

    Mais ce n'est pas parfait : ça rajoute une étape de compilation, ça complique un peu le débug (on arrive facilement à faire la correspondance entre du code Coffee et le code JS généré mais les numéros de ligne ne sont plus les mêmes ; heureusement SourceMap devrait résoudre ça) et surtout, la syntaxe basée sur l'indentation avec peu de parenthèses et d'accolades donne un style assez bizarre et difficile à relire. Quelques exemples assez courts pris sur un projet récent :

        setTimeout =>
          @trigger 'ended'
        , (options.seconds + 2) * 1000
    
    
    unless App?.Models?
      window.App =
        Models: {}
    
    
      lastAvailableElection: ->
        if 2 in App.availableRounds[2012]
          return {
            year: "2012"
            round: "2"
          }
        if 1 in App.availableRounds[2012]
          return {
            year: "2012"
            round: "1"
          }
        year: "2007"
        round: "2" 
    
    

    Dans l'ensemble, ça reste une grande avancée par rapport au JS de base.

    Est-ce que l'on va retrouver Javascript partout ?

    Je ne sais pas si on va retrouver javascript partout, mais c'est devenu un langage incontournable pour les trolls. Le dernier date, mettre ou ne pas mettre un point-virgule en fin de ligne, a violemment déchiré la communauté JS en deux camps. Ça a démarré avec https://github.com/twitter/bootstrap/issues/3057 puis c'est parti dans tous les sens. Je ne posterais qu'un seul lien pour chaque camp, mais vous pourrez sans mal en trouver plein d'autres : http://brendaneich.com/2012/04/the-infernal-semicolon/ vs http://mir.aculo.us/2012/04/16/writing-semicolon-less-javascript-the-for-people-who-want-to-get-stuff-done-edition/. Pour ma part, je suis dans le 3ème camp : faites du CoffeeScript !

    • [^] # Re: Mon avis

      Posté par (page perso) . Évalué à 2.

      Pour ma part, je suis dans le 3ème camp : faites du CoffeeScript !

      Sur le principe je serais plutôt ok.
      Mais

      la syntaxe basée sur l'indentation avec peu de parenthèses et d'accolades donne un style assez bizarre et difficile à relire

      n'est-ce pas un sérieux problème si on veut avoir un code maintenable et pérenne ?

      Et quelques questions bonus :

      • utilises-tu des choses comme http://jashkenas.github.com/docco/ pour commenter ? Si oui, c'est pas un problème pour commenter les classes (j'ai toujours trouvé que le literate programming avait des problèmes avec la programmation objet)
      • utilises-tu des frameworks avec coffee (voir des frameworks non écrit en coffee) ? Si oui, comment gérer les multiples solutions d'héritages et de création d'objets ? Je pense par exemple à http://bolinfest.com/coffee/)

      Par contre, c'est vrai que unless ? et ?. c'est quand même vraiment sympa.

      • [^] # Re: Mon avis

        Posté par (page perso) . Évalué à 3.

        n'est-ce pas un sérieux problème si on veut avoir un code maintenable et pérenne ?

        C'est effectivement un problème. J'ai déjà converti du code Coffee en JS pour bien comprendre ce qu'il faisait, mais ça reste suffisamment rare pour ne pas être bloquant.

        Là où je bosse (af83), on a pas mal de projets avec du code JS et on commence aussi à en avoir quelques uns avec du coffee. Clairement, on préfère tous reprendre le code en coffee à celui en JS. Dans un cas, on a même utilisé js2coffee pour convertir le JS en Coffee avant de retravailler dessus. Et même s'il a fallu repasser à la main pour nettoyer un peu le code, on a trouvé ça efficace et on réutilisera très certainement cette technique sur d'autres projets.

        utilises-tu des choses comme http://jashkenas.github.com/docco/ pour commenter ? Si oui, c'est pas un problème pour commenter les classes (j'ai toujours trouvé que le literate programming avait des problèmes avec la programmation objet)

        Non, je n'utilise pas. Mais ça doit se faire sans trop de problème : le même auteur a bien fait http://documentcloud.github.com/backbone/docs/backbone.html .

        utilises-tu des frameworks avec coffee (voir des frameworks non écrit en coffee) ? Si oui, comment gérer les multiples solutions d'héritages et de création d'objets ? Je pense par exemple à http://bolinfest.com/coffee/)

        J'ai déjà utilisé Coffee dans des contextes très différents : en node.js, pour faire des plugins jquery, avec Backbone, etc. Et dans l'ensemble, ça se passe bien. Il faut dire que la plupart des frameworks ne reposent pas sur l'héritage et la création d'objets mais plus sur des fonctions.

        Pour Google Closure, je n'ai pas testé.

        • [^] # Re: Mon avis

          Posté par (page perso) . Évalué à 3.

          ça reste suffisamment rare pour ne pas être bloquant.

          OK

          on préfère tous reprendre le code en coffee à celui en JS

          Ha ok. Et (question troll) par rapport à Dart ?

          Il faut dire que la plupart des frameworks ne reposent pas sur l'héritage et la création d'objets mais plus sur des fonctions.

          Oui c'est bien là la question, closure n'étant qu'un exemple.

          Question bonus (encore) : existe-t-il des éditeurs qui savent faire de la complétion sur du coffeescript ?

          • [^] # Re: Mon avis

            Posté par (page perso) . Évalué à 2.

            Ha ok. Et (question troll) par rapport à Dart ?

            Je n'ai pas accroché à Dart. Il y a des trucs sympas mais, dans l'ensemble, c'est très lourd et pas très pratique. Ça fait vraiment penser à un JavaScript codé par des dévs Java qui sont passés à coté de tous les langages modernes (Ruby, Python, Scala, Clojure, Go, etc.).

            Question bonus (encore) : existe-t-il des éditeurs qui savent faire de la complétion sur du coffeescript ?

            Perso, j'utilise Vim et il fait de la complétion bête et méchante (pas d'analyse du code).

            • [^] # Re: Mon avis

              Posté par (page perso) . Évalué à 3.

              Bon, je viens de regarder vite fait. Déjà pour l'éditeur, il y a un bundle pour textmate, donc pour sublime text 2 (oui je sais, c'est pas libre, par contre c'est quand même sympa)

              Côté Dart, je comprend le point de vue. Disons que Dart est une amélioration de JS, mais pas un vrai nouveau langage en quelque sorte.

              Par contre, si j'apprécie certains des points que tu as mentionné, par exemple => j'ai beaucoup beaucoup plus de mal avec l'indentation à la place des {}

              Par exemple, écrire un timeout :

              Doit-on écrire

              window.setTimeout () ->
                alert 'plop'
                , 300
              
              

              ou

              window.setTimeout () ->
                alert 'plop'
              , 300
              
              

              Bon ok, c'est la deuxième. Mais pour ma part j'aurais écrit initialement la première. Peut-être que ceux qui font du python ont moins de problème, sur le coup ça reste quand même perturbant je trouve.

    • [^] # Re: Mon avis

      Posté par . Évalué à 2.

      vouloir avoir une seule application qui tourne aussi bien coté client que coté serveur est juste une fausse bonne idée qui peut vite se transformer en très mauvaise idée.

      Je partage ce point de vue. Chaque chose à sa place et une place pour chaque chose: il existe un langage approprié au côté où l'on se trouve. Je me souviens avoir lu qu'il faut simplifier autant que possible, ce qui ne signifie pas rendre tout simple. Je me demande d'ailleurs ce que vaut, par exemple, lighttpd + perl + websockets comparé à Node.js…

      Ce que je crains par contre, c'est que, comme XML, on veuille mettre Node.js (ou, par voie de conséquence, Javascript) à toutes les sauces tellement c'est moderne/cool/génial/universel/quoi-d'autre. On a fait n'importe quoi avec XML sous prétexte que ça allait arranger tous les soucis; résultat: XML est pris en grippe et est quasiment bon à mettre au panier!

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.