Des ressources pour apprendre le Javascript en 2018

a marqué ce sujet comme résolu.

Hello les agrumes,

Comme suggéré par victor dans mon topic à ce sujet, je vous fait un topic pour regrouper les ressources intéressantes que je trouve au cours de mon apprentissage de Javascript.

N’hésitez pas à en suggérer dans la suite.

Hypothèses

  • Je lis couramment l’anglais.
  • J’ai des bases en Javascript, et sait déjà programmer dans d’autres langages.
  • Mes besoins ne sont plus les mêmes du tout que dans le précédent topic, là j’essaie de monter un projet avec vue.js (en ES6, peut-être en TypeScript plus tard).
  • Je développe avec IntelliJ (ça pourrait être WebStorm, mais j’ai déjà une licence IntelliJ et y’a les mêmes outils dedans).

Méthodologie

La manière générale de procéder

En trois mots : curiosité, documentation et tests.

Je m’intéresse à un concept, je lis la doc à son sujet, je la recroise avec ce que je trouve ailleurs sur le net si ça me parait louche, et surtout j’essaie.

À noter que c’est assez lent comme processus : il faut prendre le temps de découvrir et tester.

Le linter

Un truc vachement pratique aussi, c’est de coller un linter (analyseur de code) en mode « paranoïaque » et d’aller se renseigner sur chaque insulte qu’il sort en analysant le code. Le but est surtout de comprendre pourquoi il définit telle ou telle règle.

C’est très intéressant parce que ça donne les bonnes pratiques du langage (selon le réglage du linter), et permet de découvrir des tas de trucs et astuces que j’aurais jamais eu l’idée de chercher sans ça.

Personnellement j’utilise ESLint avec les profiles airbnb-base et vue/recommended.

Liens

Javascript et dérivés

Outils


En prime, hallucination du jour : en plus du package.json (description des dépendances), npm nous génère un joli package-lock.json, qui si j’ai bien compris sert à avoir exactement la même version des dépendances si on clone le projet. Pour moi ça devrait être le boulot du package.json, mais soit. Non, ce qui me fait vraiment halluciner, c’est qu’un projet vue.js de base, sans les frameworks de test, et donc sur un outil qui n’est pas connu pour être le plus lourd de l’écosystème, me génère à l’initialisation un descriptif de dépendances de plus de 12 000 lignes et 420 ko…

En fait package.json donne des indications sur quelle version installer (une version minimal par exemple, en autorisant ou non le passage à une version mineure supérieure, etc.) alors que package-lock.json décrit la version exacte installé, pour pouvoir débuguer et tester avex différentes versions. Pratique pour tester les nouvelles versions de certaines dépendances en local sans forcément mettre à jour la liste ou pour débuguer quand certains environnements ont des versions différentes (mais autorisées par le package.json).


Sinon les linters c’est la vie pour travailler à plusieurs et/ou pour maintenir un code un minimum cohérent et lisible.


Enfin je vois que tu gueules pas sur le nombre de dépendances nécessaires pour créer un projet basique de nos jours. Je sais pas si c’est bon signe… 😅

Enfin je vois que tu gueules pas sur le nombre de dépendances nécessaires pour créer un projet basique de nos jours. Je sais pas si c’est bon signe… 😅

En fait c’est de la blasitude totale, plutôt.

Sinon, dans les effets idiots, je note que les templates par défaut du plugin Jetbrains Vue.js n’est pas tout à fait compatible avec ESLint/airbnb, donc j’ai systématiquement des corrections à faire. Je me demande si je ne vais pas changer de linter pour ça.

En prime, hallucination du jour : en plus du package.json (description des dépendances), npm nous génère un joli package-lock.json, qui si j’ai bien compris sert à avoir exactement la même version des dépendances si on clone le projet. Pour moi ça devrait être le boulot du package.json, mais soit.

SpaceFox

Ça ne devrait pas être le boulot du package.json, non. Le package.json doit être compréhensible et modifiable par un humain, tu y indiques notamment les dépendances de ton projet. Comme le requirements.txt habituel de python, par exemple. Imagine si tu devais préciser, dans le fichier où tu donnes les dépendances que tu as choisies, toutes les dépendances transitives et leurs versions exactes. Pour ton simple projet d’exemple, tu aurais dû y indiquer plusieurs milliers de dépendances (dont un tas de doublons, parce que tes dépendances dépendent souvent des mêmes trucs).

Sans lockfile, le problème classique c’est que tu dépends de x@~2.2.1, qui lui dépend de y@^1.0.0, tu l’installes et ça installe disons x@2.2.2 et y@1.3.0. Ton truc tourne bien. Quelqu’un (voire toi) veut l’installer 6 mois plus tard, alors que x@2.2.11 a été publié et y@1.9.7 aussi. Ton projet n’est donc plus le même, et la possibilité qu’il ne fonctionne plus existe. Avec un lockfile (environ tous les package managers modernes ont un mécanisme de locking), npm aurait installé les versions exactes sauvées dans ton lockfile, l’installation de ton projet serait donc déterministe, ce qui est souhaitable.

Deux autres remarques à propos du lockfile de npm :

  • Il est méga-verbeux parce qu’il encode l’arborescence du node_modules/ local. Ça permet à npm de réduire drastiquement le temps nécessaire à installer un paquet pour deux raisons : 1/ il n’a pas à calculer comment dé-dupliquer* les dépendances 2/ il n’a pas à calculer comment organiser les choses de façons optimales en sous-dossiers. Ces 2 choses sont faites une fois pour toute lors de la génération du lockfile.
  • Tu n’as pas besoin de le modifier à la main, même en cas de merge conflict si tu utilises git. Un package-lock.json qui contient des marqueurs de conflits git reste lisible par npm, tu lances npm install et paf il calcule comment résoudre et enlève les marqueurs de conflit, t’as plus qu’à stager le fichier et continuer ton merge ou ton rebase.

* Tiens à propos de doublons je viens de faire npm ls | grep dedup | wc -l pour voir combien de dépendances du projet dans lequel je suis ont été dédupliquées parce que plusieurs dépendances (transitives) dépendaient des mêmes trucs. 749.

+0 -0

En fait ça me choque parce que je viens du monde Java, dans lequel quand tu as besoin d’une dépendance, la pratique habituelle c’est de donner la version exacte dont tu dépends, et ce sur toute l’arborescence. Donc, ton fichier de définition avec ta poignée de dépendances directe te donne directement un arbre de dépendances exact et stable dans le temps. On a parfois un problème de conflit de sous-dépendance (A dépend de Z version 1.0.2, B dépend de Z aussi mais version 2.1.7), mais honnêtement c’est rare.

J’ai l’impression que c’est autant le bordel dans l’écosystème JS parce que :

  1. il y a beaucoup plus de dépendances ;
  2. ces dépendances sont très souvent mises à jour ;
  3. pour éviter de passer son temps à mettre à jour des numéros de version, les gens n’indiquent pas en dépendance des versions exactes mais « compatibles » ;
  4. donc il faut un mécanisme supplémentaire pour garantir une stabilité de l’arbre de dépendance.

Sinon, dans les effets idiots, je note que les templates par défaut du plugin Jetbrains Vue.js n’est pas tout à fait compatible avec ESLint/airbnb, donc j’ai systématiquement des corrections à faire. Je me demande si je ne vais pas changer de linter pour ça.

SpaceFox

Pour les petites erreurs pas bien méchantes, ESlint possède une option --fix qui lui dit de les corriger automatiquement. Ça peut faire gagner un temps fou :)

Y’a une logique qui m’échappe avec le packages.json et le package-lock.json.

Situation :

  1. Je tire une branche depuis master, j’ajoute une dépendance (npm i bidule --save (ou --save-dev). package-lock.json est mis à jour, genre sur à peu près toutes les lignes.
  2. Je tire une autre branche depuis le même master j’ajoute une autre dépendance (npm i machin --save (ou --save-dev). package-lock.json est mis à jour, genre sur à peu près toutes les lignes.

Le problème c’est qu’entre 1 et 2 y’a des tas de différences qui ne sont pas exactement les mêmes (des tas de versions mineures fixées bougent, surtout dès qu’il y a plusieurs jours de délais entre 1 et 2). Conséquence : à chaque fois qu’une situation de ce genre se produit, j’ai des conflits sur ce fichier.

Une recherche rapide ne me donne rien de probant (certains disent que ce fichier doit absolument être versionné, d’autres que non, certains ont des techniques ninja…).

Si quelqu’un a une bonne pratique éprouvée par la réalité, ça m’intéresse :)

Perso j’ai pris pour habitude de fixer les versions complètes des dépendances de prod pour éviter les surprises. Du coup le package-lock ne doit pas changer des masses d’une branche à l’autre (sauf pour les ajouts/suppressions qui ne devraient pas créer trop de conflits).

Pour les dépendances de dev, soit tu peux faire pareil (ce qui assure que tout le monde a la même chose, notamment pour les linters et outils de test), soit il faudra effectivement trouver une autre méthode (comme celles que tu cites que je ne trouve pas idéales).

Au alors tu attends deno 😀

C’est pas vraiment une ressource, mais je note ici que contrairement à ce que j’ai pensé la première fois que je suis tombé dessus, l’opérateur destructuring assignment ... peut s’avérer extrêmement pratique. Surtout quand la tâche en cours consiste principalement à créer un objet énorme.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte