Catégories
javascript

Recom­mençons à zéro — Javas­cript 101

PHP a été mon langage favori pendant presque 10 ans. Ruby l’a suivi pour à peu près la même durée. Javas­cript a été l’ou­til secon­daire pas très atti­rant pour quand il n’y a pas d’autre choix, c’est à dire sur navi­ga­teur.

Avant-hier j’ai eu un petit pince­ment de frus­tra­tion en cher­chant à déstruc­tu­rer un diction­naire lors d’une affec­ta­tion. Ruby n’a toujours qu’une demie solu­tion pas très élégante. PHP et Javas­cript ont tous deux énor­mé­ment évolué entre temps, au point qu’on ne les recon­nait qu’à peine.

Si Ruby garde des capa­ci­tés inéga­lées pour faire de la méta-program­ma­tion, 10 ans c’est peut être le bon moment pour reprendre un autre langage de zéro.

Je fais du web, j’aime beau­coup l’idée de l’iso­mor­phisme, il me faudra donc quelque chose qui sache compi­ler en Javas­cript. Elm pour­rait me faire du pied vu sa gestion des types mais c’est un pari osé consi­dé­rant qu’il est encore absent côté serveur.

Ça sera donc Javas­cript. D’abord pour quelques scripts en ligne de commande, puis peut-être des appli­ca­tions plus sérieuses.

Reprendre de zéro c’est l’oc­ca­sion de lais­ser le passé derrière soi et recom­men­cer 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 arri­vera demain.

Il s’agit aussi de reprendre de zéro, pour apprendre. Exit donc les boiler plate et autres kits de démar­rage rapide.


Première étape : instal­la­tion de npm (3.10.3) et nodejs (6.3.1).

# Sur Mac avec Homebrew (http://brew.sh/)
brew install nodejs

et initia­li­sa­tion 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’uti­li­ser le nouveau Javas­cript moderne et ne cher­cher aucune compa­ti­bi­lité passée. Instal­la­tion de Babel pour gérer ES2015 et + :

npm install --save-dev babel-cli

La plupart des sites recom­mandent des preset pour ES2015 ou React mais visi­ble­ment Nodejs 6.x gère déjà l’es­sen­tiel des fonc­tions nati­ve­ment. Il existe au moins trois preset spéci­fiques pour Nodejs 6 mais la seule confi­gu­ra­tion commune aux trois est le plugin qui trans­forme les modules ES2015 en modules Commonjs. Je suis donc reparti de là :

npm install --save-dev babel-plugin-transform-es2015-modules-commonjs

Puis l’édi­tion du .babelrc :

{
  "presets": [ ],
  "plugins": [ "transform-es2015-modules-commonjs" ]
}

Si quelque chose manque à Nodejs 6, il faudra que j’ajoute le plugin corres­pon­dant. Voici les plugins sur lesquels mes trois presets étaient en désac­cord :

  • trans­form-es2015-func­tion-name,
  • syntax-trai­ling-func­tion-commas,
  • trans­form-es2015-destruc­tu­ring,
  • trans­form-es2015-para­me­ters,
  • trans­form-object-rest-spread,
  • trans­form-es2015-sticky-regex,
  • trans­form-es2015-unicode-regex,
  • trans­form-es2015-modules-commonjs,
  • et trans­form-class-proper­ties.

Je n’ai pas pris le temps de les tester un par un pour voir lesquels étaient réel­le­ment néces­saires pour pas. Si quelqu’un a le courage de faire le travail…

Reste à enfin permettre d’exé­cu­ter un premier script. J’ai tenté de suivre les usages en mettant les sources dans src/ et les fichiers compi­lés dans lib/ avec un index.js comme fichier prin­ci­pal.

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 confi­gu­ra­tion 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 compi­ler tous les fichiers, un npm run watch permet de surveiller en temps réel les modi­fi­ca­tions des fichiers sources pour mettre à jour les fichiers desti­na­tion corres­pon­dants.


J’ai ajouté un README, le .giti­gnore proposé par Github pour un projet Nodejs, une licence, et ‘op, vous trou­ve­rez le tout sur Github.

Ça fait déjà pas mal pour toujours aucune ligne de Javas­cript utile.

Quelques feed­back après ce tout petit premier pas :

1– C’est long et complexe

Oui, j’ai cher­ché 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 compi­la­tion avec Babel n’aide pas mais Java pour­rait en dire tout autant. Pourquoi n’existe-t-il pas un babel init qui lit la version courante de Nodejs, m’ins­talle un .babelrc adapté à cette version et me modi­fie mon package.json pour m’ajou­ter les raccour­cis build et watch ?

Oui, je pour­rais faire une pull-request, mais fallait-il m’at­tendre ?

2– La doc aide peu

Fran­che­ment 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 incom­plètes, et il est bien diffi­cile de savoir si telle ou telle a pris en compte les dernières évolu­tions.

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’ou­blie il n’y a pas de message rouge très expli­cite pour indiquer que les npm install –save-dev n’au­ront pas l’ef­fet demandé. Il a fallu comprendre qu’il fallait créer un package.json, puis décou­vrir qu’il n’était pas néces­saire de le faire à la main.

Ce n’est que le début. Quand il va s’agir de choi­sir une biblio­thèque ou des outils, je sens que ça va être toute une histoire pour d’y retrou­ver. La doc de setup de Babel en donne un premier aperçu.

J’ai l’im­pres­sion qu’à chaque étape la roue est en pleine recons­truc­tion, et qu’on en a fait plusieurs versions diffé­rentes en paral­lèle, pour tout.

3– Qui a eu l’idée d’uti­li­ser des fichiers de config JSON ?

Je suis aussi assez peu fana aussi des config dans des fichiers Json. J’ai l’im­pres­sion de retrou­ver les fichiers de confi­gu­ra­tion XML de Java. Je n’ai pas l’im­pres­sion que ce soit beau­coup plus lisible.

La grosse diffé­rence c’est que Java a créé ces confi­gu­ra­tions avec tout un outillage autour. Le déve­lop­peur n’avait que rare­ment besoin d’y plon­ger manuel­le­ment. C’était géré auto­ma­tique­ment 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 acco­lades fermantes.… et déjà un diction­naire dans un tableau dans un tableau dans un diction­naire. Rien que ça.

Même mon petit package.json me parait déli­cat à mani­pu­ler malgré l’in­den­ta­tion. Heureu­se­ment que les dépen­dances sont ajou­tées auto­ma­tique­ment par npm lors de leur instal­la­tion.

Là, dès qu’on dépasse le simple clef valeur, j’ai l’im­pres­sion de me retrou­ver avec une double peine : Un fichier de confi­gu­ra­tion peu aisé à mani­pu­ler, mais pas pour autant d’ou­til pour le faire à ma place.

5 réponses sur « Recom­mençons à zéro — Javas­cript 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.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *