PHP a été mon langage favori pendant presque 10 ans. Ruby l’a suivi pour à peu près la même durée. Javascript a été l’outil secondaire pas très attirant pour quand il n’y a pas d’autre choix, c’est à dire sur navigateur.
Avant-hier j’ai eu un petit pincement de frustration en cherchant à déstructurer un dictionnaire lors d’une affectation. Ruby n’a toujours qu’une demie solution pas très élégante. PHP et Javascript ont tous deux énormément évolué entre temps, au point qu’on ne les reconnait qu’à peine.
Si Ruby garde des capacités inégalées pour faire de la méta-programmation, 10 ans c’est peut être le bon moment pour reprendre un autre langage de zéro.
Je fais du web, j’aime beaucoup l’idée de l’isomorphisme, il me faudra donc quelque chose qui sache compiler en Javascript. Elm pourrait me faire du pied vu sa gestion des types mais c’est un pari osé considérant qu’il est encore absent côté serveur.
Ça sera donc Javascript. D’abord pour quelques scripts en ligne de commande, puis peut-être des applications plus sérieuses.
Reprendre de zéro c’est l’occasion de laisser le passé derrière soi et recommencer comme si c’était un nouveau langage. Je ne prends que les dernières versions et outils récents dans la chaîne, voire ce qui n’est pas encore sec mais qui arrivera demain.
Il s’agit aussi de reprendre de zéro, pour apprendre. Exit donc les boiler plate et autres kits de démarrage rapide.
Première étape : installation de npm (3.10.3) et nodejs (6.3.1).
# Sur Mac avec Homebrew (http://brew.sh/) brew install nodejs
et initialisation du projet (un peu de doc si besoin pour aider à remplir)
mkdir my-js-project cd my-js-project npm init
Ensuite l’idée c’est d’utiliser le nouveau Javascript moderne et ne chercher aucune compatibilité passée. Installation de Babel pour gérer ES2015 et + :
npm install --save-dev babel-cli
La plupart des sites recommandent des preset pour ES2015 ou React mais visiblement Nodejs 6.x gère déjà l’essentiel des fonctions nativement. Il existe au moins trois preset spécifiques pour Nodejs 6 mais la seule configuration commune aux trois est le plugin qui transforme les modules ES2015 en modules Commonjs. Je suis donc reparti de là :
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
Puis l’édition du .babelrc :
{ "presets": [ ], "plugins": [ "transform-es2015-modules-commonjs" ] }
Si quelque chose manque à Nodejs 6, il faudra que j’ajoute le plugin correspondant. Voici les plugins sur lesquels mes trois presets étaient en désaccord :
- transform-es2015-function-name,
- syntax-trailing-function-commas,
- transform-es2015-destructuring,
- transform-es2015-parameters,
- transform-object-rest-spread,
- transform-es2015-sticky-regex,
- transform-es2015-unicode-regex,
- transform-es2015-modules-commonjs,
- et transform-class-properties.
Je n’ai pas pris le temps de les tester un par un pour voir lesquels étaient réellement nécessaires pour pas. Si quelqu’un a le courage de faire le travail…
Reste à enfin permettre d’exécuter un premier script. J’ai tenté de suivre les usages en mettant les sources dans src/ et les fichiers compilés dans lib/ avec un index.js comme fichier principal.
mkdir lib echo "Compiled files will go here." > lib/README.md echo "Leave these files untouched" >> lib/README.md echo "and modify ../src/* instead." >> lib/README.md mkdir src echo "Source files will go here." > src/README.md echo "They should be compiled before any use." >> src/README.md touch src/index.js
Et la configuration du package.json pour lancer tout ça (notez le main qui prend en compte notre nouveau chemin et le scripts qui liste nos deux nouvelles actions) :
{ "name": "my-project", "main": "./lib/index.js", "scripts": { "build": "babel src -d lib --source-maps", "watch": "babel src -d lib --watch --source-maps" }, "devDependencies": { "babel-cli": "^6.11.4", "babel-plugin-transform-es2015-modules-commonjs": "^6.11.5" } }
Un npm run build permet de compiler tous les fichiers, un npm run watch permet de surveiller en temps réel les modifications des fichiers sources pour mettre à jour les fichiers destination correspondants.
J’ai ajouté un README, le .gitignore proposé par Github pour un projet Nodejs, une licence, et ‘op, vous trouverez le tout sur Github.
Ça fait déjà pas mal pour toujours aucune ligne de Javascript utile.
Quelques feedback après ce tout petit premier pas :
1– C’est long et complexe
Oui, j’ai cherché les ennuis, il existe des boiler plate tout faits, mais je ne crois pas avoir le même problème avec Python, Ruby, PHP ou d’autres.
Le fait d’avoir une étape de compilation avec Babel n’aide pas mais Java pourrait en dire tout autant. Pourquoi n’existe-t-il pas un babel init qui lit la version courante de Nodejs, m’installe un .babelrc adapté à cette version et me modifie mon package.json pour m’ajouter les raccourcis build et watch ?
Oui, je pourrais faire une pull-request, mais fallait-il m’attendre ?
2– La doc aide peu
Franchement c’est la plaie. Je ne dirais pas qu’il n’y a aucune doc, mais il y en a dans tous les sens. La plupart ne sont pas à jour, toutes semblent incomplètes, et il est bien difficile de savoir si telle ou telle a pris en compte les dernières évolutions.
Peut-être n’ai-je pas trouvé la bonne référence ? Dites-moi.
Rien que le npm init n’était indiqué sur aucune doc que j’ai croisé. Pire : si on l’oublie il n’y a pas de message rouge très explicite pour indiquer que les npm install –save-dev n’auront pas l’effet demandé. Il a fallu comprendre qu’il fallait créer un package.json, puis découvrir qu’il n’était pas nécessaire de le faire à la main.
Ce n’est que le début. Quand il va s’agir de choisir une bibliothèque ou des outils, je sens que ça va être toute une histoire pour d’y retrouver. La doc de setup de Babel en donne un premier aperçu.
J’ai l’impression qu’à chaque étape la roue est en pleine reconstruction, et qu’on en a fait plusieurs versions différentes en parallèle, pour tout.
3– Qui a eu l’idée d’utiliser des fichiers de config JSON ?
Je suis aussi assez peu fana aussi des config dans des fichiers Json. J’ai l’impression de retrouver les fichiers de configuration XML de Java. Je n’ai pas l’impression que ce soit beaucoup plus lisible.
La grosse différence c’est que Java a créé ces configurations avec tout un outillage autour. Le développeur n’avait que rarement besoin d’y plonger manuellement. C’était géré automatiquement par les IDE et les scripts.
J’ai ajouté un plugin au .babelrc décrit plus haut. Ce plugin a une option. Je me retrouve avec un Json de 7 lignes dont 4 qui contiennent autre chose que des crochets et accolades fermantes.… et déjà un dictionnaire dans un tableau dans un tableau dans un dictionnaire. Rien que ça.
Même mon petit package.json me parait délicat à manipuler malgré l’indentation. Heureusement que les dépendances sont ajoutées automatiquement par npm lors de leur installation.
Là, dès qu’on dépasse le simple clef valeur, j’ai l’impression de me retrouver avec une double peine : Un fichier de configuration peu aisé à manipuler, mais pas pour autant d’outil pour le faire à ma place.
5 réponses à “Recommençons à zéro — Javascript 101”
J’ai l’impression (peut-être vraie ?) de passer pour un rigolo du JavaScript quand je te lis.
Pour commencer à développer en JavaScript, je prends mon notepad, je tape mes lignes de code et hop, je vois le résultat.
Je n’arrive pas à comprendre l’intérêt de toute cette installation. Et c’est peut-être ça qui me fait dire que je suis loin, très loin…
L’écosystème JavaScript est complexe, surchargé, et tout ce que l’on veut, mais seulement parce qu’on veut qu’il le soit.
Tu dis vouloir démarrer à neuf avec les dernières versions du langage. Ça veut dire que tu n’as pas besoin de Babel. Node.js v6 supporte la quasi-intégralité des spécifications ES2015 et ES2016 ; Node.js v7 supporte tout (cf http://node.green/). Tu peux `node` un fichier `index.js` écrit en “new JS”, pas de souci. Babel est sur-utilisé, surtout quand il s’agit de scripting.
En ce qui concerne la gestion des dépendances, ma version préférée au démarrage d’un projet reste `echo « {} » > package.json` pour créer un fichier JSON valide, puis `npm i –save …`. Ça fait le travail, et sans s’encombrer d’un nom, d’une version, d’un main file, de méta-données et du reste. Les dépendances, rien de plus.
Le plus gros souci du JavaScript aujourd’hui, c’est la confusion qui a lieu autour de son outillage et de son écosystème. Tout le monde se sent obligé de démarrer avec beaucoup plus que nécessaire (Babel pour du script, Redux pour de l’application ridiculement simple, des boilerplates en veux-tu en voila, etc.). Ça n’a rien à voir avec le langage, qui est excellent et devient de mieux en mieux à chaque jour qui passe.
Merci pour node.green. C’est ce que je cherchais sans réussir à le trouver. Effectivement, peu besoin de Babel, mais il reste encore la gestion des modules ES2015, qui me parait presque plus importante que pas mal de syntaxes. Visiblement ce n’est pas gagné même pour Node v7. Dans mon exemple je n’utilise Babel que pour ça, donc ça n’aurait pas changé grand chose.
Pour le package.json, oui, « il suffit de… ». Encore faut-il le savoir. Savoir qu’il faut créer un fichier avant de jouer avec npm, puis savoir ce qu’il faut créer. Qu’il suffise d’un { } est intéressant mais finalement quand tu débutes rien ne te l’indique (et j’avoue que si c’est pour permettre un objet JSON sans contenu, npm aurait pu le créer pour moi…). Du coup j’ai tenté de copier un fichier trouvé, puis essayé de voir si quelque chose pouvait le générer pour moi. Quand je pense de problème de doc c’est bien de ça que je parle.
Huhu, ça me rappelle mon premier contact avec NPM, on m’avait demandé de publier mes plugins dessus https://github.com/nico3333fr/jquery-accessible-tabs-aria/issues/10#issuecomment-170561309
Sérieux, c’est rugueux au possible, pas du tout user-friendly (genre t’as des contraintes différentes sur le mot de passe entre la version en ligne et à la ligne de commande), et effectivement la doc est un peu branlante/fragmentée. Heureusement que j’avais quelques bonnes âmes pour me dépatouiller.
Pire, je sais toujours pas si j’ai bien fait comme il faut ou si je me suis brouté qq part.
[…] la mise en place, il est peut-être temps de faire un premier script. J’ai tenté un petit script […]