[
	{
		"content": "Lors de l’atelier de samedi je vous ai promis un prompt Bash qui déboîte quand on fait du Git.\nCelui-ci repose sur une série de fonctions Bash dont la plus “high-level” est appelée à chaque prompt. Elle permet de voir immédiatement :\n\nDans quelle branche on est\nSi on a des modifs en working tree\nSi on a des modifs en stage\nSi on a des fichiers untracked\nSi on a du stash\n\nToutes choses fort utiles au moment de faire son commit, histoire de ne rien oublier…\n\n\n  Cet article est obsolète ; vous trouverez une version plus à jour et plus utile dans l’article plus récent\n  « Un prompt Git qui déchire ».\n\nVoici le code source avec quelques commentaires. Vous pouvez aussi aller piocher le Gist directement.\n\nNotez les variables qui configurent ce qui est affiché :\n\nGIT_PS1_SHOWDIRTYSTATE fait remonter les modifs en working tree (symbole *) et en stage (symbole +)\nGIT_PS1_SHOWUNTRACKED_FILES fait remonter les fichiers non présents dans l’index (non pris en compte jusqu’à ajout explicite) (symbole %)\nGIT_PS1_SHOWSTASHSTATE indique qu’on a des trucs dans le stash (symbole $)\n\nÇa ralentit un tout petit peu le premier prompt de votre session dans un dépôt non trivial, le temps pour les commandes Git internes de construire les caches d’accès à l’index et à l’historique… Ensuite c’est instantané.\nJe ne pourrais pas vivre sans !\nEnjoy!\n",
		"description": "On se cale à la main un prompt Bash qui déboîte pour faire du Git…",
		"date": 1279065600,
		"image": "/assets/images/art-vid/art-git-prompt.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Le prompt Bash qui change la vie avec Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/le-prompt-bash-qui-change-la-vie-avec-git/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Il y a plusieurs raisons pour vouloir disposer d’un hébergement Git. Les trois principales sont :\n\ndisposer d’un backup distant de son travail,\nmettre son travail à la disposition d’autrui,\ncollaborer avec d’autres sur un projet.\n\n\nHébergement public ou privé ?\nLorsque le projet est libre, ou qu’en tout cas son contenu est public, le plus simple consiste à exploiter un bon service d’hébergement Git qui serait gratuit pour les dépôts publics. Dans ce domaine, l’acteur désormais incontournable (et particulièrement bien foutu) est le célèbre GitHub.\nEn revanche, pour les dépôts privés, soit on reste sur GitHub, mais dès lors, c’est payant (pas cher ceci dit : à partir de $9/mois, ce qui permet de bénéficier de l’infrastructure massive du service, notamment en termes de fiabilité de stockage). Soit on crée son propre hébergement Git, ce qui a notamment l’intérêt éventuel de le rendre interne à sa société (et donc, potentiellement, très rapide d’accès sur un réseau local performant).\nCe billet vise à explorer en détail l’option technique favorite pour héberger son propre serveur Git : Gitosis.\nQuand on connaît la procédure, récupérer, installer et configurer Git, qu’on soit sur OSX ou Linux, est l’affaire de 10 à 15 minutes. En lisant ce billet et les explications, ce sera naturellement un peu plus long. Mais ça reste rapide et facile !\nPrincipes de fonctionnement de Gitosis\nComme GitHub, Gitosis base sa gestion d’accès sur le protocole SSH et des clés asymétriques.\nChaque utilisateur reconnu par le système est identifié au moyen d’une paire de clés asymétriques dont le serveur connaît la partie publique : côté client, il faut donc disposer de la clé privée correspondante dans son « portefeuille de clés » SSH. Un même utilisateur logique dans Gitosis peut être associé à un nombre quelconque de clés (par exemple une depuis sa machine au boulot, une depuis son laptop, une par compte sur un serveur où du code est déployé…).\nC’est à mon sens une excellente façon de procéder. En effet, révoquer l’accès peut se faire de façon très granulaire si on utilise une clé par couple Utilisateur + Machine : il devient alors possible de révoquer les accès depuis une machine quelconque, ou pour un utilisateur à travers toutes les machines, ou pour un cas Utilisateur + Machine précis.\nUn autre aspect de Gitosis que j’aime particulièrement est que toute sa configuration est dans un… dépôt Git, ce qui fait qu’on la met à jour avec un git push. C’est délicieusement récursif, j’adore !\nInstaller le serveur\nAllez, c’est parti, on va se coller un p’tit Gitosis perso.\nRécupérer les dépendances éventuelles\nDéjà, il vous faut Git. Mais si vous lisez ce blog, je suppose que vous l’avez déjà…\nIl faut aussi Python et son module setup-tools. Sur OSX on a déjà l’équivalent, mais sur un Linux il faudra installer le paquet correspondant. Par exemple, sur Debian/Ubuntu :\n\nÀ partir de là, on récupère Gitosis depuis son dépôt et procéder à l’installation :\n\nCette installation nous fournit une série de binaires (programmes) pour Gitosis, au premier rang desquels gitosis-serve, qui va servir de « shell » à l’utilisateur système git que nous allons créer. Ce binaire fournit toutes les fonctions du serveur Git, ainsi que le mécanisme d’authentification, de gestion des droits, etc.\nCréer et configurer l’utilisateur « git »\nVous avez sans doute déjà remarqué que les URLs « lecture-écriture » d’un dépôt distant Git sont généralement de la forme git@le-serveur.tld:le-depot.git (ou plus rarement ssh://git@le-serveur.tld:le-depot.git, ce qui revient au même). La convention veut en effet qu’on configure un utilisateur système git sur le serveur, seul moyen d’accéder au serveur Git.\nCet utilisateur n’a pas de mot de passe, mais au lieu de fournir un shell classique (ce qui, vu le manque de mot de passe frontal, serait assez dangereux…), il exécute uniquement votre serveur Git, lequel se charge alors de l’authentification.\nEn revanche, le home directory (répertoire personnel) de ce compte constituera le dossier racine de vos dépôts Git sur le serveur. Du coup, plutôt que d’utiliser la convention usuelle (/home/login sur Linux, /Users/login sur OSX), on aura tendance à préciser un dossier plus conforme à ce type d’usage, typiquement /var/lib/git. Vous pouvez en fait mettre ce que vous voulez, mais je précise le raisonnement ici histoire que vous ne soyez pas surpris dans les lignes de commande qui vont suivre.\nIl nous faut donc configurer cet utilisateur. C’est là que la procédure diverge entre les Linux (qui ont tous les binaires système adduser et/ou useradd) et OSX (dont la gestion des utilisateurs repose directement sur son mécanisme d’annuaire, c’est-à-dire sa couche LDAP).\nCommençons par la version Linux. Selon la commande que vous voulez employer, les options ne sont pas exactement les mêmes. Voici les deux variantes :\n\nou\n\nPassons rapidement en revue la signification de ces arguments :\n\n--system précise qu’il s’agit d’un utilisateur système : entre autres",
		"description": "Une exploration pas à pas, en profondeur, de la mise en œuvre de notre propre serveur Git à l’aide de Gitosis.",
		"date": 1279411200,
		"image": "/assets/images/art-vid/art-git-gitosis.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Héberger un serveur Git avec Gitosis (Linux / OSX)",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/heberger-un-serveur-git-avec-gitosis-linux-osx/",
		"locale": "fr",
		"readingTime": "14 min"
	},	{
		"content": "Vous aimez déjà Git, ou vous souhaitez le découvrir ? Vous allez participer à un Atelier Git Attitude ? Il vous faut alors installer une version récente sur votre poste de travail, et sans doute aussi sur vos machines de déploiement, de staging, etc. Cet article essaie de vous donner toutes les clés pour faire cela aussi rapidement et facilement que possible.\n\nRécent… c’est-à-dire ?\nÀ l’heure où j’écris ceci, la dernière version stable de Git est la 1.7.2.1. La plupart des systèmes pré-packagés sont encore sur la précédente, la 1.7.1.1 (qui est très récente aussi), mais ça va vite se mettre à jour…\nConcrètement, les différences avec des versions plus anciennes (jusqu’à 1.5.0, qui a introduit les derniers changements en date de structure du dépôt) sont quelque peu mineures et focalisées sur des détails d’options et de raffinement dans les décorations des logs, l’exécution d’outils externes (on pense notamment aux outils de diff), quelques fonctionnalités de confort, etc.\nEn termes de compatibilité sur le dépôt et d’opérations courantes, tout Git au moins 1.5.0 saura manipuler un dépôt plus récent, par exemple (ce qui peut avoir son importance si, par exemple, vous déployez sur un hébergement mutualisé dont les versions seraient un peu rances).\nJe vous recommande d’avoir au moins une 1.6.6, mais compiler le code source sur votre plate-forme reste la meilleure façon d’avoir une version à jour, optimisée pour votre situation et dotée de tout le dernier confort proposé, notamment pour les usages avancés.\nUn mot sur la doc\nGit est un outil extrêmement puissant et riche, avec ses quelque 75 commandes de haut niveau (dites « porcelain ») et près de 60 commandes de bas niveau, à usage surtout interne (dites « plumbing »). Même les commandes principales, utiles pratiquement au quotidien, qui sont à peu près 20, recèlent une puissance insoupçonnée ; à ce titre, leur documentation est un atout précieux.\nEn effet, je trouve que les auteurs et mainteneurs de Git ont fait un boulot exceptionnel sur la documentation des commandes, à laquelle on peut accéder soit en tapant git help COMMANDE soit, lorsqu’on a la commande man, avec un man git-COMMANDE (les deux sont équivalents mais je préfère personnellement la première syntaxe).\nCependant, les méthodes d’installation par source ou par paquets ne l’installeront pas toujours par défaut : il vous appartient d’installer les bons paquets auxiliaires (typiquement git-doc) ou d’appeler les bonnes commandes de compilation et d’installation. Nous y reviendrons.\nInstaller Git sur OSX\nSur OSX, je ne saurais trop vous recommander de passer par l’installeur binaire hébergé sur Google Code, le projet git-osx-installer. Il est calé (là tout de suite) sur la 1.7.2 et installe les docs au passage, donc aucune raison de se priver ! Tout est installé dans /usr/local/git par défaut.\nC’est de loin l’option la plus simple : compiler à partir des sources sur OSX exige une kyrielle de pré-requis qui peuvent être pénibles à obtenir, qu’on passe par Macports, Fink, Homebrew ou d’autres voies…\nInstaller Git sur Linux\nApproche 1 : utiliser des paquets\nIl existe généralement plusieurs paquets se répartissant les fonctionnalités et documentations de Git, paquets aux noms raisonnablement explicites, typiquement git comme « paquet chapeau » (paquet virtuel entraînant l’installation des autres), git-core (la quasi-totalité des commandes), git-doc, git-gui, gitk et gitweb (interfaces graphiques et frontal web de navigation de dépôt), git-svn et git-cvs (passerelles avec d’autres SCM)…\nSur Ubuntu et ses dérivés, les paquets sont assez récents (1.7.0 sur Lucid Lynx à l’heure où j’écris ceci) ; il est toutefois possible d’avoir des versions très à jour en passant par un PPA (Personal Package Archive, dépôt Ubuntu officieux maintenu par une entité quelconque, un particulier par exemple), le plus connu dans le cas qui nous occupe étant celui d’Andrey Voronov, qui propose des paquets tout frais (donc 1.7.2) pour Ubuntu 8.04 (Hardy Heron) et 10.04 (Lucid Lynx). Si vous avez une 9.x, vous pouvez tester ces dépôts quand même, utiliser le paquet fourni (Git 1.6.0 en 9.04, Git 1.6.3 en 9.10) ou compiler la source.\nDebian dispose de paquets raisonnablement récents, avec la 1.7.1 (si vous êtes en stable/lenny, vous aurez cependant besoin des dépôts « backports »).\nPour les distributions basées RPM, telles que Red Hat, SuSE et Mandriva, le site officiel de Git maintient des paquets RPM très à jour. Gentoo a un paquet dev-vcs/git en unstable, et comme c’est Gentoo, on est basés sur sources donc assez récent (1.7.2 semble-t-il). ArchLinux est, comme souvent, très à jour avec un paquet git en 1.7.2.1 qui n’a que peu de dépendances.\nEnfin, sachez qu’on peut avoir un Git récent sur Solaris en passant par Sun Freeware.\nApproche 2 : compiler le code source\nCommencez par récupérer l’archive du code source complet (préfixe git-) au format de votre choix. Par exemple pour la 1.7.2.1, l’une des deux suivantes :\n\nhttp://www.kernel.o",
		"description": "Tout ce qu’il faut savoir pour installer une version bien récente de Git, quel que soit votre OS.",
		"date": 1280966400,
		"image": "/assets/images/art-vid/art-git-install.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Installer un Git récent",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/installer-un-git-recent/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Je viens de sortir un petit outil open-source qui facilite énormément le suivi de temps sur Basecamp relatif à vos travaux sur Git.\nQuoi ?! Vous n’utilisez pas Basecamp ! Mais c’est pas bien, ça ! Allez donc voir comme c’est top.\nL’idée est d’analyser vos messages de commit à la recherche d’un petit tag spécifique sur la fin, qui va permettre à un script post-commit de déterminer le temps de travail, l’éventuelle tâche spécifique associée, et de loguer le temps qui va bien. C’est super pratique et je m’en sers déjà sur plusieurs projets, toute la journée.\nÇa se passe ici, et y’a une doc détaillée. Enjoy !\n",
		"description": "Un petit outil à base de hooks pour automatiquement manipuler vos tâches Basecamp à l’aide de vos messages de commits.",
		"date": 1283904000,
		"image": "/assets/images/art-vid/art-git-basecamp.jpg",
    "_tags": ["outil","git"],
		"title": "Git, Basecamp, et un peu de magie",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-basecamp-et-un-peu-de-magie/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Git base toute sa gestion d’authentification sur le mécanisme des clés SSH. Ce système est d’ailleurs immensément utile de façon générale sous Linux, Unix et OSX, dès qu’il s’agit de s’authentifier sur une machine tierce. Afin d’avoir un maximum de confort lorsqu’on accède à un dépôt nécessitant une identification (lecture de dépôts privés ou écriture dans le cas général), il est donc important de bien maîtriser les clés SSH.\nCe billet tente de vous donner toutes les clés (ahem) pour comprendre et manipuler aisément vos identités SSH.\n\nAprès un topo rapide sur le principe des clés asymétriques, nous verrons rapidement quels algorithmes sont à favoriser, quelles tailles de clé sont acceptables, et les meilleures pratiques de protection de vos clés (tant en termes de passphrase que de gestion des droits d’accès à vos fichiers de clés).\nCes fondamentaux étant assimilés, nous pourrons vérifier si vous avez déjà des clés, comment en créer de nouvelles, et comment vous en servir efficacement et confortablement pour vos accès à des dépôts Git.\nPrincipe des clés asymétriques\nQuand vous travaillez avec des clés asymétriques, par principe, vous avez deux clés (on parle de paire de clés) : une clé publique, que vous pouvez diffuser librement, voire mettre à disposition sur un serveur de clés ; et une clé privée, qui constitue véritablement votre « identité », et ne doit jamais être diffusée : elle reste simplement présente dans votre dépôt de clés personnel.\nComme toujours en cryptographie, on peut faire deux choses avec une clé : chiffrer un contenu (l’encrypter) ou le signer (calculer une valeur unique, reposant sur le contenu concerné et sur votre clé privée, pour obtenir une valeur de signature, comme un cachet spécifique). Seule la clé « d’en face » (la publique si vous avez utilisé la privée, et inversement) permet de déchiffrer ou de vérifier la signature. Notez au passage que signer un contenu permet non seulement d’attester que vous êtes bien l’envoyeur (ou l’auteur, etc.), mais aussi que le contenu n’a pas été modifié après signature.\nUne paire de clé permet donc de vous représenter vis-à-vis d’un système tiers, en lui fournissant à l’avance votre clé publique, pour ensuite communiquer avec lui à l’aide de votre clé privée ; puisque seules les clés d’une même paire peuvent se comprendre, le système distant est à même non seulement de vérifier que vous êtes bien celui (ou celle) que vous prétendez être, mais aussi que ce qu’il reçoit est bien ce que vous envoyé. Pas mal !\nSi le sujet vous intéresse, vous trouverez une tonne d’infos sur Wikipedia. Mais si j’étais vous, je finirais cet article d’abord histoire de ne pas partir sur une tangente…\nRSA vs. DSA\nIl existe de nombreux algorithmes de chiffrement basés sur des clés asymétriques, mais les deux dominants, et de loin, son RSA et DSA, d’après les initiales de leurs auteurs respectifs. RSA est historiquement le premier, et DSA a été développé plus récemment, comme une alternative alors qu’RSA était encore breveté.\nDe nombreux didacticiels, articles et documentations exploitent RSA, mais vous pouvez choisir librement RSA ou DSA pour vos clés, du moment que vous utilisez une taille suffisante (voir ci-après).\nTaille de clé\nUne clé a une taille, exprimée en nombre de bits. Par exemple, les clés exploitées par les certificats de chiffrement des sites web utilisant la protection SSL (vous savez, ces URLs qui démarrent en https://, par exemple votre gestion de compte bancaire en ligne) sont généralement limitées, pour des raisons légales d’origine honteuse, à 256 bits. En revanche, vos propres clés ne font pas (ou plus, suivant le pays où vous vivez) l’objet d’une telle limitation.\nÀ ce jour, une taille de 2Ko, c’est-à-dire 2048 bits (oui, 8 fois plus qu’un certificat bancaire !) est considérée raisonnablement sécurisée pour RSA, en tout cas pour un particulier. En gros, même si la toute-puissante NSA avait envie de casser votre chiffrage pour jeter un œil à ces données, il leur faudrait quelques heures pour y parvenir. Et pour qu’ils daignent vous allouer quelques heures de leur système, vous devez en gros être un très, très gros poisson.\nDonc on est tranquilles.\nNotez qu’en revanche une clé DSA fait obligatoirement 1024 bits (1Ko). C’est comme ça.\nPassphrase\nVous avez certainement l’habitude voir le terme password, c’est-à-dire mot de passe. Et vous avez sûrement déjà rencontré des tas de systèmes, services et outils qui vous demandent de saisir un mot de passe, en lui imposant une taille minimum (ce qui est bien) et maximum (ce qui est parfaitement stupide et contre-productif). À cause de ce maximum, justement, ces systèmes insistent pour que vous mélangiez à loisir majuscules, minuscules, chiffres et symboles, et n’utilisiez pas de termes trop évidents (dates de naissances, prénoms, noms de vos animaux, mots basiques, segments de touches du clavier, etc.).\nDu coup, tout le monde se retrouve forcé d’utiliser des mots de passe genre &amp;dF@8^Xy+, qui sont telle",
		"description": "Le didacticiel français de référence sur les clés SSH et leur manipulation efficace, avec ou sans Git, quel que soit votre OS.",
		"date": 1284336000,
		"image": "/assets/images/art-vid/art-ssh-keys.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Comprendre et maîtriser les clés SSH",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/comprendre-et-maitriser-les-cles-ssh/",
		"locale": "fr",
		"readingTime": "11 min"
	},	{
		"content": "Parfois on se retrouve à faire du Git, en local, sur un dépôt distant Subversion. Ça arrive en fait dans deux situations :\n\nOn est en train de passer un dépôt de Subversion vers Git, en vue d’abandonner le premier au profit du second (yay !).\nOn est obligé de bosser sur un dépôt Subversion, mais on refuse de laisser tomber le confort quotidien de Git en local.\n\nGit propose une passerelle au moyen de la commande git svn et de ses sous-commandes. Moyennant quelques précautions d’usage, on peut ainsi travailler avec Git en local et synchroniser vers (et depuis) le dépôt Subversion distant. C’est un sujet assez vaste et j’y reviendrai plus en détail dans un prochain billet.\nToutefois, ceux qui rencontrent déjà ces situations ont sans doute remarqué un phénomène irritant : Git ne prend pas en compte la propriété svn:ignore. En fait, il ne prend en compte que svn:executable (ce qui est déjà pas mal, vu comme elle est grave utile…).\n\nLa propriété svn:ignore est similaire au fichier .gitignore : elle permet de lister des motifs de fichiers qui ne doivent pas être versionnés. Il est donc dommage qu’on n’en bénéficie pas automatiquement sur Git, risquant ainsi de versionner par erreur des fichiers qui devraient être ignorés.\nVoilà pourquoi j’ai développé un petit outil qui va automatiquement synchroniser vos svn:ignore vers vos .gitignore, à tout moment, pour votre master (c’est-à-dire votre trunk distant), sans écraser d’éventuelles infos déjà présentes dans vos .gitignore… C’est le premier d’une série probable de petits scripts du même genre, destinés à faciliter l’utilisation de Git au quotidien.\nComme mon récent outil git-basecamp, il est disponible en open-source, et documenté, sur GitHub. Je vous invite donc à jeter un œil à mon dépôt git-helpers. Notez qu’il existe aussi une quantité de dépôts nommés « git-tools » sur Github, mais aucun de ceux que j’ai regardés n’avait cette fonctionnalité (et la plupart des aides qu’ils fournissent m’ont semblé un peu basiques…).\nEnjoy !\n",
		"description": "Un petit outil qui migre vos définitions svn:ignore vers des fichiers .gitignore tout propres…",
		"date": 1284595200,
		"image": "/assets/images/art-vid/art-git-svn-ignore.jpg",
    "_tags": ["outil","tutoriel","git"],
		"title": "Git + Subversion : arrêtez d’ignorer ce que vous devriez ignorer (?!)",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-subversion-arretez-d-ignorer-ce-que-vous-devriez-ignorer/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Une couverture exhaustive des expressions rationnelles a jusqu’ici fait partie de l’atelier JS Puissant. Elle occupait bien 1h, voire 1h30, en matinée.\nC’est un sujet qui me tient véritablement à cœur, pour les raisons que je vais développer dans les deux premiers titres. Mais on m’a quelquefois fait remonter, très justement, qu’une telle couverture, au sein d’un atelier de 8h, est tout-à-fait hors de proportion, et que le temps libéré pourrait être utilement mis à profit en entrant plus dans le détail d’autres aspects (programmation fonctionnelle, structuration de code…).\nAfin de ne pas simplement cesser de transmettre ces connaissances et de « convertir » les gens au bon usage des expressions rationnelles, j’ai donc opté pour l’approche inverse : sortir ce contenu des formations pour en faire un contenu librement accessible sur le site de JS Attitude !\nQui sait ? Peut-être cet article, s’il est suffisamment bien fichu, deviendra-t-il, à son petit niveau, une sorte de référence francophone sur ce sujet, comme le sont désormais les articles sur les clés SSH ou l’installation de Gitosis…\n\nLe croque-mitaine\nTraditionnellement, les expressions rationnelles ne sont pas enseignées. Il est déjà assez difficile de trouver un prof de BTS ou DUT capable de faire véritablement du Java, sans même parler de Python, Ruby ou JavaScript, pour espérer avoir carrément des cours décents d’expressions rationnelles.\nPopularisées par Perl, les expressions rationnelles débarquent en général au travers d’un morceau de code parfaitement abscons, comme le dégorgement inattendu d’un fragment de fichier binaire au beau milieu du code source. Et de fait, quel développeur, pas forcément junior mais globalement sain d’esprit, n’aurait pas le cœur au bord des lèvres en tombant tout à coup sur ce genre de chose :\n\nC’est vrai, quoi, comprenez-les. Les pauvres, personne ne les a prévenus, sinon ils n’auraient pas choisi le pâté de tripes à midi, vous pensez bien, c’était trop risqué.\nFaute d’enseignement, faute de rationalité justement, faute de démystification utile, les expressions rationnelles restent à la périphérie de nos regards et de notre conscience, les banshees du développement, on les garde soigneusement à distance de peur qu’en y touchant elles ne nous attrapent tout entiers et nous volent ce qui nous reste de raison, tels de petits Cthulhus tout de symboles vêtus.\nLe bon outil pour manipuler du texte\nNaturellement, il n’en est rien, ne prêtez pas attention à cette porte qui claque quelque part dans l’asile d’Arkham. Les regex restent un outil extrêmement efficace pour extraire rapidement des éléments spécifiques d’un contenu textuel. Par exemple, repérer certaines balises dans du HTML ; trouver les lettres en double dans un texte ; capitaliser un texte (mettre ses initiales en majuscules et le reste en minuscules) ; détecter qu’un texte est bien une adresse e-mail (ou IP, ou URL…) valide ; etc.\nIl est bien sûr possible d’écrire des algorithmes manuels pour tous ces usages, mais ceux-ci présentent deux inconvénients majeurs vis-à-vis des expressions rationnelles équivalentes :\n\nIls sont souvent largement plus verbeux (jusqu’à plusieurs centaines de lignes de code), et donc sujets à potentiellement bien davantage de bugs, notamment des erreurs de bornes (les erreurs +1/-1, ou fencepost errors) et de conditions de boucle.\nIls sont en général significativement plus lents que leur équivalent à base d’expressions rationnelles.\n\nVous me rétorquerez peut-être qu’ils sont bien plus lisibles. C’est un argument aussi classique que fallacieux.\nÀ part les cas triviaux d’analyse de texte (par exemple, en compter les consonnes), ce n’est pas vrai : tout traitement un tant soit peu avancé requiert automatiquement un volume non négligeable de code, avec ses variables, conditions, etc. La lisibilité se dégrade rapidement, ou à défaut, on obtient du code lisible, mais volumineux, dont il faut en outre comprendre l’algorithme pour en saisir l’objectif. Même si on se cantonne aux cas où le code alternatif est court, l’expression rationnelle équivalente est, elle, triviale, et ne devrait donc pas poser de souci de lisibilité.\nQui plus est, la lisibilité d’une expression rationnelle est perçue traditionnellement comme mauvaise pour deux raisons : d’une part, nombre de gens écrivent des expressions balourdes, pataudes, ne tirant pas le meilleur parti de la syntaxe qu’elles alourdissent inutilement. D‘autre part, cette syntaxe, bien que grammaticalement assez simple, est effectivement assez peu intuitive : la majorité des développeurs ont donc connu le syndrome du « WTF?! » lors de leurs premières rencontre avec de telles expressions, ce qui entraîne un préjugé.\nEnfin, nombre de personnes n’utilisent pas (où n’ont pas à disposition, comme c’est hélas le cas en JavaScript natif) le drapeau de syntaxe x, qui permet de découper et commenter une expression rationnelle lors de sa déclaration, ce qui accomplit des miracles en termes de lisibilité. Nous y rev",
		"description": "Les regex, c’est le bien.  C’est la puissance.  Et ce n’est (vraiment) pas si difficile.  Voici un vrai tuto de référence.",
		"date": 1344816000,
		"image": "/assets/images/art-vid/art-js-regex.jpg",
    "_tags": ["js"],
		"title": "Enfin maîtriser les expressions rationnelles",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/enfin-maitriser-les-expressions-rationnelles/",
		"locale": "fr",
		"readingTime": "27 min"
	},	{
		"content": "Lorsqu’on vient à JavaScript, il est tentant de recourir à de bons vieux motifs de code hérités des autres langages que l’on pratique. Un cas classique est l’abréviation de conditions en se reposant sur les « équivalents booléens » des valeurs. Le danger, c’est que JavaScript a beaucoup plus de valeurs falsy que les autres langages, et utilise des protocoles de conversion implicite parfois surprenants.\nDans cet article, nous allons explorer ensemble quelles valeurs sont falsy, et donc lesquelles sont truthy, mais aussi l’impact que ça a sur de nombreux motifs de code courants, avec les pièges que ça peut poser.\n\nTruthy et falsy\nDans un langage de programmation, on dit qu’une valeur est truthy si, considérée dans un contexte booléen (le plus souvent comme seul composant d’une condition, ou comme opérande d’un opérateur booléen tel que &amp;&amp; ou ||), elle équivaut à true.\nOn dit que le protocole de conversion implicite de son type vers Boolean donne true. En JavaScript, ce protocole spécifique est régi, pour JavaScript « classique » (ECMAScript 3e édition) par la section 9.3 de la spécification (ECMA-262). Par complément, toute valeur dont la conversion ne donne pas true donne nécessairement false.\nLa spécification indique clairement que les types Undefined et Null équivalent toujours à false. Toute chaîne vide (longueur zéro) également. Côté nombres, les zéros (positif ou négatif) et NaN équivalent eux aussi à false. En revanche, n’importe quel autre objet (dont les tableaux et objets litéraux, même vides) équivaudra à true.\nCes règles semblent assez simples, même s’il peut être surprenant de voir que '' est équivalent à false (mais que new Boolean(false), étant un objet, est équivalent à true, un magnifique WTF). Toutefois, n’arrêtez pas là votre lecture, car dans divers cas « piégeux » les conversions implicites s’enchaînent sur une même valeur et donnent un résultat surprenant ! Nous avons vu les règles de base, mais attendez la suite…\nImpact sur les motifs de code usuels\nExaminons tour à tour les principaux cas où l’emploi booléen d’une valeur autre se présente dans du code JavaScript usuel.\nBoucle numérique « façon C »\nUne tentation courante consiste à reproduire les boucles numériques du C. Par exemple :\n\nOu encore :\n\nPas de problème particulier sur cette boucle, en tout cas vis-à-vis de son équivalent C.\nLe même risque potentiel existe, naturellement : si par mégarde le contenu de la boucle modifie le compteur, et que du coup celui-ci « saute » zéro ou est compensé dans son mouvement normal, cette boucle n’aura pas de fin (en C, elle finirait par un overflow/underflow, mais en JS, qui n’a que des nombres flottants, la fin est si loin qu’en pratique on ne patientera jamais assez longtemps, sans parler des bugs causés par le dépassement de limite).\nLe piège est notamment là en JS, qui n’a pas de variables de blocs (sauf à disposer d’un JS garanti suffisamment récent pour pouvoir utiliser l’instruction let) :\n\nAhem…\nTester la présence d’un texte\nAttention ici à la notion de « présence ». Si seul un texte absolument vide (longueur zéro) vous ennuie, pas de souci, c’est bien la sémantique d’origine :\n\nMais si vous voulez un texte non-blank, c’est-à-dire contenant autre chose que du whitespace, il faudra préférer une regex (hein ?!) pour vérifier le contenu du texte :\n\nTester la présence de nœuds du DOM\nSi getElementById renvoie bien null s’il ne trouve pas l’élément d’id indiqué, l’immense majorité d’entre nous utilisons une bibliothèque JavaScript pour interagir avec le DOM. La plupart du temps, nous utilisons une API basée sur jQuery, qu’il s’agisse de jQuery lui-même, Zepto ou encore Ender. Du coup, ce que nous avons sous la main se comporte en fait comme un tableau, et n’est donc jamais équivalent false !\nVoyez plutôt :\n\nC’est la raison pour laquelle on voit tant de code comme celui-ci :\n\nParamètre doté d’une valeur par défaut\nEn CoffeeScript, c’est trivial à gérer, mais en JS pur c’est un peu plus compliqué. Tout dépend en fait des valeurs considérées comme valides pour l’argument.\nSi aucune valeur falsy n’est valide, on est tranquille et on peut juste utiliser le || (OU logique) :\n\nIci, on considère par exemple que howMuch à zéro, NaN, chaîne vide, et simplement non passé (undefined) ne constituerait pas une valeur acceptable. Il n’est donc pas possible d’appeler earnMoney avec un deuxième argument à zéro :\n\nLorsque des valeurs falsy sont acceptables, il vous appartient de tester plus efficacement. Par exemple, on pourrait refuser toute valeur négative ou nulle, et gérer évidemment le cas “argument manquant” :\n\n(Notez au passage le recours à l’opérateur unaire préfixe +, qui force le protocole de conversion explicite ToNumber (conversion vers un nombre), et refusera notamment toute valeur textuelle ne constituant pas intégralement un nombre décimal valide. Cette technique est en ce sens supérieure à parseFloat.)\nIci on a bien le comportement souhaité :\n\nPièges des priorités de conversion\nLes conv",
		"description": "JS, c’est le langage ou plein de chose sont falsy, plus qu’ailleurs.  Et en plus, la conversion booléenne dépend du contexte.",
		"date": 1347235200,
		"image": "/assets/images/art-vid/art-js-truthy-falsy.jpg",
    "_tags": ["js"],
		"title": "Truthy ou falsy : quand est-on dans le vrai en JavaScript ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/truthy-ou-falsy-en-javascript/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Les nombres sont parfois trompeurs, en JavaScript comme ailleurs. Ouvrez donc une console JavaScript et tentez les expressions suivantes :\n\nVoyons ensemble la baleine qui se cache sous ce gravier…\n\nMais quelle magie obscure fait que 999999999999999 se comporte bien, mais pas 9999999999999999 ?\nComme dans de très nombreux langages, nous voilà pris au piège du standard IEEE-754, datant de 1985 (bientôt 30 ans…), qui gouverne la représentation 64-bit des nombres flottants. Vous retrouverez ce souci dans C, C++, Java, PHP, et pour autant que je sache, .NET (C#, VB, etc.) et ColdFusion… Mais uniquement sur les nombres flottants. Les nombres entiers 64-bit vont bien au-delà.\nSeulement voilà, JavaScript ne différencie pas entiers et flottants. Le type Number est forcément flottant, c’est pourquoi en JavaScript 5 / 2 === 2.5, alors que les opérandes semblent « entiers ».\nIEEE-754 prévoit une double précision (d’où le nom usuel du type associé dans de nombreux langages : double) de 15 chiffres. Au total (avant et après la virgule éventuelle). Dès qu’on dépasse ce nombre de chiffres, la représentation mémoire utilisée commence à faire des arrondis. Et plus on a de chiffres voulus, plus l’arrondi est brutal :\n\nAu passage, et pour le plaisir, notez que l’approximation n’a pas lieu que sur des très hautes valeurs. Si on tombe sur des valeurs qui ne sont pas représentables pile-poil par IEEE-754, on obtient des trucs comiques :\n\nEt oui, comme pour le statut truthy, la valeur seule ne suffit pas à garantir le bon fonctionnement : la façon d’y arriver est tout aussi importante.\nIci, il se trouve que 0.1 est représenté, en interne, par une valeur retranscrite en 0.10000000000000002. Et de même, 0.2 par 0.20000000000000002. Du coup, la somme aboutit à un résultat… étonnant !\n",
		"description": "Rions ensemble avec les blagues inhérentes au format IEEE-754 qui gouverne les nombres flottants à double précision, dont les `Number` en JS.",
		"date": 1347494400,
		"image": "/assets/images/art-vid/art-js-ever-growing-number.jpg",
    "_tags": ["js"],
		"title": "Le nombre qui s'incrémente tout seul",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/le-nombre-qui-s-incremente-tout-seul/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Nous les développeurs JS, on grince souvent des dents lorsqu’on tombe sur quelqu’un qui, en parfaite ignorance, met dans le même sac JavaScript et Java. Nous demande une « formation Java », ou nous classe comme « développeur Java ».\nAyant moi-même pondu quelques millions de lignes (littéralement, mais en Java ça n’est pas si impressionnant que ça) de Java et J2EE (ça ne s’appelait pas encore Java EE ; je me fadais les premières versions des EJB, JSP et servlets…), dans JBuilder, Eclipse, NetBeans et IDEA, je sais pourquoi j’ai fui cet univers et pourquoi JavaScript n’a strictement rien à voir.\nSeulement voilà, le nommage prête à confusion, c’est un fait. Au mieux, on nous demande « c’est quoi la différence entre Java et JavaScript ? » Ce à quoi j’aime à répondre « la même qu’entre l’or et l’ordinateur » : à part le préfixe phonétique, la rapport est plutôt ténu…\nPour ceux qui aimeraient comprendre la petite histoire derrière la génèse de JavaScript et ce nommage foireux, permettez-moi de vous éclairer…\n\nLe besoin d’origine et le cœur de la différence\nDébut 1995, Netscape domine le marché du web en général, fournissant tant des logiciels serveurs que le navigateur alors le plus populaire, Netscape Navigator. Ils viennent de lancer un partenariat avec Sun Microsystems pour exploiter leur nouveau langage et sa VM multi-plateforme, Java, tant au sein du navigateur (pour fournir une UI riche portable) que côté serveur (pour fournir le cœur d’applications accessibles via le web, au moyen d’un simple navigateur).\nC’est une offre impressionnante, en concurrence directe avec Microsoft, qui commence à peine à accepter le fait que le web est là pour durer et qu’il constitue le prochain pivot technologique majeur.\nToutefois, Java est perçu par Sun et Netscape comme un langage de professionnels, peu adapté à une utilisation simple dans le cadre de pages web (on ne parle pas encore d’applis web, il faudra attendre 10 ans et l’avènement d’Ajax). Java est en quelque sorte le concurrent du Visual C++ de Microsoft, de ce point de vue. Il lui faut un langage compagnon plus simple d’approche, plus facile d’emploi pour les néophytes ou développeurs débutants, qui soit, si l’on veut, l’équivalent de Visual Basic. Facile à prendre en main, facile à imbriquer dans une page ou ailleurs.\nC’est à Brendan Eich, gourou technique chez Netscape et futur CTO de Mozilla, qu’est revenue la tâche de créer ce langage « compagnon » de toutes pièces.\nCeci dit, on exige également que les deux soient bien différenciés, au sens où les développeurs potentiels doivent sentir que le nouveau langage est « dans le style Java » mais est moins puissant. Comme l’a expliqué Brendan dans une interview :\n\n  JS devait «&nbsp;ressembler à Java&nbsp;», mais en moins avancé, [il devait] être le petit frère simplet de Java, son partenaire-otage.  Et par-dessus le marché, je n’avais que dix jours pour pondre ça, ou on se retrouverait avec un truc pire que JS.\n  Brendan Eich\n\nJavaScript devait donc rester conscient des spécificités de la syntaxe de Java (JS 1.0 avait tous les mots-clés de Java réservés, et ses types standard copient souvent les conventions du JDK, par exemple autour de Math et Date), mais il devait aussi s’abstenir d’utiliser la syntaxe orientée-objet du langage, à une époque ou la POO (Programmation Orientée Objet) était encore considérée comme un sujet réservé aux professionnels…\nBrendan ne voulait pas pondre un langage diminué, mais devait trouver des ruses pour y glisser assez de puissance sans que celle-ci soit immédiatement visible au profane. Le langage devait rester simple et léger en apparence, tout en ayant assez de sophistication pour que des développeurs avancés soient à même d’en tirer des applications puissantes.\nSi les deux langages appartiennent à une famille syntaxique « de type C » (syntaxe des identifiants, accolades, opérateurs principaux, structures de contrôle…), ils ont des sémantiques extrêmement différentes. La philosophie de JavaScript est très fortement inspirée de langages objet ou fonctionnels « purs », au premier rang desquels [Self](http://en.wikipedia.org/wiki/Self_(programming_language)) et [Scheme](http://en.wikipedia.org/wiki/Scheme_(programming_language)), mais aussi certains aspects de SmallTalk et [LISP](http://en.wikipedia.org/wiki/Lisp_(programming_language)).\nJava est un langage compilé, statique (chaque variable est typée explicitement) et doté d’un typage fort (le type déclaré contraint les valeurs de façon étroite, et aucune conversion implicite n’est mise en place), là où JavaScript est interprété et dynamique avec un typage plus léger (d’où la distinction entre == et ===, similaire à celle de PHP).\nEn Java, tout code existe à l’intérieur d’une classe. JavaScript ne l’exige pas.\nJava, malgré près d’une décennie de débat stérile, n’a toujours pas de fonctions de premier ordre. JavaScript a des fonctions de premier ordre et, partant, des fonctions d’ordre supérieur.\nJava utilise un modèle d’héritage « clas",
		"description": "Quand les marketeux de Sun créent la confusion pour 30 ans chez tous les RH du monde.",
		"date": 1347840000,
		"image": "/assets/images/art-vid/art-js-not-java.jpg",
    "_tags": ["js"],
		"title": "JavaScript n'a rien à voir avec Java : petite histoire d'un marketing malheureux",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/javascript-n-a-rien-a-voir-avec-java/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "En 2005, alors que Ajax devenait tendance et qu’on commençait à faire du JavaScript un peu costaud dans les pages web, il n’y avait pas encore de framework renommé. Arrivé en premier et impressionant dès l’origine, Prototype est vite devenu le chouchou de la grande majorité des développeurs web.\nEn 2006 puis 2007, désormais doté d’une documentation solide et d’une équipe de développement (Prototype Core) compétente, motivée et très active, il était incontournable.\nAvance rapide sur 2012 : plus personne (ou presque) n’en parle. On entend encore un peu parler de MooTools, Dojo, YUI… Et le grand vainqueur est jQuery, ce framework à l’écosystème gigantesque et vivace, à tel point qu’on est obligé d’expliquer au plus grand nombre la différence entre jQuery et JavaScript.\nQue s’est-il passé ?\nCe petit article un peu nostalgique vous explique pourquoi Prototype a sombré et où il en est aujourd’hui.\n\nFull Disclaimer\nJe suis moi-même un ancien de Prototype Core. En 2006, avec Bien Développer pour le Web 2.0, je produisais la première documentation exhaustive du framework, alors en version 1.4.\nDurant l’hiver, j’étais l’un des trois co-auteurs du site officiel de documentation, et en janvier 2007 je rejoignais le noyau des développeurs pour produire, au fil des mois, les versions 1.5, 1.5.1 (qui était absolument géniale à l’époque) puis 1.6. En 2008, je publiais la référence, Prototype and script.aculo.us, chez les Pragmatic Programmers.\n2005–2008 : l’âge d’or\nC’était une période dorée. L’équipe était petite mais très active : Sam Stephenson, Andrew Dupont, Tobie Langel, Mislav Marohnić, Juriy Zaytsev et Thomas Fuchs, le créateur de script.aculo.us, plus votre serviteur.\nOn bossait beaucoup et ça se voyait, Prototype dominait complètement le marché des bibliothèques médianes, qui simplifiaient Ajax et le DOM mais aussi la création d’algorithmes compliqués et de systèmes de classes.\nLa décroissance\nEt puis, presque du jour au lendemain, jQuery a pris presque toute la place. Les raisons sont multiples, mais ses forces principales étaient évidentes :\n\nUne cible plus étroitement définie mais majoritaire sur le marché : les intégrateurs HTML/CSS qui ne veulent pas apprendre JavaScript trop en profondeur : ils veulent « juste » des effets visuels, des animations simples et de l’Ajax simplifié.\nUne syntaxe facile et laxiste, triviale à apprendre, ne demandant que très peu d’efforts et de rigueur\nUne équipe volumineuse\nUne vraie force de frappe marketing, avec des tonnes de docs, tutorials, meetups, événements communautaires puis conférences, bouquins…\n\nAlors que jQuery ne cessait de grandir, épaulée par le statut Mozillien de John Resig et une forte attention portée à sa communauté, pour atteindre rapidement de très nombreuses personnes dédiées à temps plein, Prototype, lui, voyait son équipe se réduire comme peau de chagrin.\nNous avions tous un boulot à temps plein à côté, nous étions peu nombreux, nous nous concentrions sur le code et n’accordions que très peu de temps à la visibilité de Prototype. Et jQuery l’a éclipsé.\nEncore aujourd’hui, beaucoup de gens qui sont « tombés dans Prototype » à l’époque continuent à l’utiliser, tout en connaissant aussi jQuery. Ils aiment Prototype pour son API claire, cohérente et élégante, ses nombreuses fonctions orientées algorithmes et programmation fonctionnelle (avec jQuery, il faut complémenter par Underscore.js, très fortement inspiré de Prototype, pour obtenir un équivalent).\nMais Prototype, aujourd’hui, c’est quelques jours par mois, voire par trimestre, du seul porteur du flambeau qui reste, le vaillant Andrew Dupont. Sa détermination sans faille me touche et m’émeut ; mais le projet n’en est pas moins dans un coma léger, parfois même profond.\nDes utilisateurs fidèles\nJ’ai moi-même arrêté de travailler à Prototype il y a presque 4 ans. Jusqu’à cet été cependant, il restait ma bibliothèque de choix pour tous mes développements front.\nQuand j’utilise jQuery, si j’apprécie la complétude de son offre Ajax/JSONP et certains aspects de son offre DOM, je peste contre les nombreux pièges inhérents au design de son API, pièges souvent silencieux et sournois à l’exécution.\nEt j’ai, évidemment, toujours Underscore.js en complément, car je ne pourrais me passer d’un each raisonnable, de filter, inject, flatten, without et j’en passe.\nDe la gratitude\nAlors oui, Prototype est pratiquement mort, malgré la persistence éminemment louable d’Andrew. Mais j’aimerais qu’on se rappelle que Prototype a été le premier. Sam a inventé ce positionnement de bibliothèque, a pondu des API dont l’influence se fait sentir partout, de ES5 à Underscore.js en passant par jQuery lui-même, que John a clairement dit avoir lancé « parce [qu’il] n’était pas totalement en phase avec Prototype ».\nAutour de la 1.5, on a fait des prouesses pour les premiers outils de type $$, en implémentant l’intégralité des sélecteurs CSS3 à la fois en DOM Level 3 XPath et en parcours classique.\nPrototype a permis des merveilles dès 20",
		"description": "Il était beau, il sentait bon le sable chaud, il a inspiré ES5… et puis il a quitté la scène.  Mais qu’est-il arrivé à cette magnifique lib ?",
		"date": 1349481600,
		"image": "/assets/images/art-vid/art-js-prototype.jpg",
    "_tags": ["js"],
		"title": "Mais qu'est-il arrivé à Prototype ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/mais-qu-est-il-arrive-a-prototype/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Qu’est-ce qu’on a comme types natifs en JavaScript ? Facile : Object, Number, String, Boolean, Array, Date, RegExp et Function.\nEt lorsqu’on instancie un objet en JavaScript, on fait généralement new LeType(…). Mais dans cet article, je vais vous expliquer pourquoi, à quelques petites exceptions près, pour les types natifs c’est soit inutilement lourd, soit carrément contre-productif.\n\nAllez, on se démonte les types un par un, d’accord ?\nObject\nDe deux choses l’une :\n\nsoit tu veux instancier un type à toi, et tu vas faire new TonType, pas new Object ;\nsoit tu veux bien un objet basique tout nu, et alors tu auras largement plus vite fait d’utiliser {} (ex. var obj = {};). La version new est inutilement verbeuse, car on a une syntaxe litérale disponible. Ce sera aussi le cas de plusieurs autres types natifs.\n\nNumber\nOK, donc tu veux créer un nouveau nombre. Explique-moi pourquoi tu irais faire new Number(42) au lieu de juste 42 ?!? Tu es payé(e) au caractère ? Évidemment pas.\nEn plus, les deux ne se comportent pas de la même façon dans certains cas. Par exemple, le protocole de conversion booléenne n’est pas le même : if (new Number(0)) passera alors que if (0) non.\nString\nLà aussi, on a une syntaxe litérale : les apostrophes ou guillemets (aucune différence dans le comportement). Aucune raison de t’embarasser d’un new String('foobar') lorsque l’argument, 'foobar', suffit.\nQui plus est, JavaScript va traiter différemment les objets String (issus d’un new String(…)) et les chaînes primitives (produites par un litéral). Ainsi, typeof new String('foo') produit 'object' et non 'string'. Et eval ne considèrera comme code source qu’une chaîne primitive, alors qu’un objet String sera juste renvoyé tel quel. Autant de raisons de ne jamais recourir à new String…\nBoolean\nOn est dans une situation similaire à Number : non seulement les deux litéraux réservés true et false sont suffisants, mais en plus le protocole de conversion booléenne va nous foutre dedans : if (new Boolean(false)) passera ! Une bonne raison de ne jamais recourir à new sur ce coup…\nArray\nDans la mesure où on a une syntaxe litérale (crochets et virgules, ex. [1, 2, 3]), il n’y a a priori jamais à utiliser new Array(1, 2, 3)…\nIl existe juste un cas, finalement assez rare, où le new est toutefois justifié : pour préallouer un tableau à une certaine taille, ce qui se produit si on utilise un unique argument numérique. Par exemple, new Array(1000000) va créer un tableau d’un million de cases, toutes pour le moment undefined. Encore une fois, c’est un cas de figure assez rare.\nDate\nPour le coup, new Date est parfaitement justifié, puisqu’on initialise très souvent un objet Date sur la base d’une valeur précise, que celle-ci soit un numérique (nombre de millisecondes depuis l’epoch, le 1er janvier 1970 à 0h GMT), une chaîne de caractère compatible ou une série de composantes année, mois, jour, etc. Il n’y a tout simplement pas de syntaxe litérale pour les dates, on doit donc recourir à new Date.\nIl existe toutefois un cas où je déconseille new Date : lorsqu’on veut juste récupérer la version numérique du moment présent. Plutôt que de faire new Date().getTime(), préférez Date.now() : non seulement c’est nettement plus compact et explicite, mais en plus ça évite de créer inutilement un objet Date à garbage-collecter ensuite…\nRegExp\nOn a ici deux cas de figure :\n\nLa regex est fixe, connue à l’avance. Il est alors inutile de passer par new RegExp, puisqu’on dispose d’une syntaxe litérale. /foo(?:bar)?/ig sera toujours plus court que new RegExp('foo(?:bar)?', 'ig')… Cependant, si la regex est bourré de slashes (/), je peux comprendre qu’au bout d’un moment on préfère éviter de tous les échapper : new RegExp('^https?://foo/bar/baz') peut sembler préférable à /^https?:\\/\\/foo\\/bar\\/baz/…\nLa regex n’est pas connue à l’avance. Par exemple, elle est calculée sur la base d’une saisie utilisateur, d’une réponse Ajax, etc. Auquel cas on n’a pas d’autre choix que de passer par new RegExp. Imaginons qu’on développe un fuzzy matcher qui cherche toutes les chaînes de caractères contenant ceux qu’on saisit, dans le bon ordre mais quelles que soient leurs positions, comme dans les éditeurs TextMate et SublimeText :\n\n\nFunction\nIl existe trois manières de créer des fonctions en JavaScript :\n\nAvec une déclaration : c’est ce qui se passe quand le mot-clé function est rencontré à un endroit où on attend une instruction. Il doit alors obligatoirement être suivi d’un identifiant qui nomme la fonction. Les déclarations de fonction sont hoisted, c’est-à-dire qu’elles sont interprétées comme si elles étaient placées en tout début de portée (donc de l’éventuelle fonction conteneur).\nAvec une expression : c’est le cas quand le mot-clé function est rencontrée alors qu’on attend une expression (par exemple, à droite d’un opérateur =, d’une parenthèse ouvrante, ou comme argument à une autre fonction). La fonction n’est pas obligatoirement nommée (et si elle l’est, ce nom n’est valable qu’à ",
		"description": "Répète après moi : tu n’utiliseras jamais `new` pour la plupart des constructeurs prédéfinis par JavaScript.  Voici pourquoi.",
		"date": 1353542400,
		"image": "/assets/images/art-vid/art-js-no-native-new.jpg",
    "_tags": ["js"],
		"title": "Pourquoi tu ne devrais jamais utiliser new sur les types JavaScript natifs",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/pourquoi-jamais-new-sur-natifs-en-js/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Quoi de plus simple, a priori, que de convertir un texte en nombre en JavaScript ? Souvent, on n’a même pas l’impression d’en avoir besoin. Et sinon, on recourt à parseInt ou parseFloat, vite fait…\nEt pourtant… Que de pièges, que de subtilités de fonctionnement nous attendent sur un sujet au premier abord aussi basique. Explorons tout ça ensemble.\n\n\n  Mise à jour du 29/12 13:46 : suite à des échanges avec le commentateur identifié comme « check_ca », j'ai décidé de compléter l'article pour parler de Number en tant que fonction, du cas des infinis, et proposer une version certes minusculement moins performante de cleanInt mais plus lisible et universelle.\n\nA-t-on besoin de convertir ?\nComme bien souvent, la vraie réponse est : ça dépend.\nDans la mesure où je vous recommande par ailleurs de toujours comparer avec === sauf cas spécifique bien identifié, vous aurez en effet besoin, si vous appliquez cette consigne, de convertir explicitement vos nombres « textuels » en nombres effectifs (type Number) pour obtenir une comparaison valide.\nToutefois, certains opérateurs qui n’ont de sens que sur les nombres (ou principalement sur les nombres) entraîneront automatiquement une conversion numérique de leurs arguments. On parle alors de protocole de conversion implicite. C’est notamment le cas des opérateurs arithmétiques, à l’exception du cas « String plus quelque chose ». Toutefois, l’enchaînement de protocoles de conversion, chaque opérande étant traité indépendamment et à tour de rôle, peut donner à terme des String là où on aurait cru des Number, ce qui n’est pas sans surprise…\n\nDans les exemples ci-dessus, on voit que l’opérateur + entraîne souvent des conversions amenant à String, mais propose aussi pas mal de cas où le résultat est, de façon inattendue parfois, un Number. Les opérateurs moins ambigüs, tels que - ou *, fonctionnent presque toujours en Number (par exemple, 3 - [] est toujours 3), quitte à renvoyer NaN (qui comme son nom ne l’indique pas est bien de type Number…).\nLe problème, évidemment, c’est qu’on ne va pas commencer à se souvenir de tous les cas de figure, opérateur par opérateur, et types d’opérande par types d’opérande. D’où la nécessité de clarifier parfois les choses en forçant explicitement le type de nos opérandes à Number, de façon contrôlée.\nPour ce faire, la majorité des auteurs de code JavaScript ont recours, suivant le besoin (entier ou flottant), à parseInt et parseFloat. À mon sens, c’est plus problématique qu’autre chose.\nMéfie-toi de parseInt et parseFloat\nLes deux ne se comportent pas exactement pareil. Comme leurs noms l’indiquent, le premier renvoie un entier (un Number tronqué sur sa partie entière) et l’autre un flottant (toujours un Number, mais non tronqué). Mais ce n’est pas tout. Par exemple, avant ES5 (testez sur une console JS qui ne force pas ES5, ou dans une REPL node par exemple), on obtenait ceci :\n\nC’est un problème bien connu : parseInt accepte en fait deux arguments : le texte et une base optionnelle (de 2 à 36) dans lequel ce texte encode le nombre. Mais avant EcmaScript 5, au lieu de supposer une base 10 (ce qui, de l’avis général, serait nettement plus utile), il devine. Aïe. En l’occurrence, il se base sur les syntaxes C/Java/JS/etc. de litéraux entiers, donc démarrer par 0x ou 0X indique un hexadécimal, sinon démarrer par 0 indique un octal ; les chiffres octaux valides allant de 0 à 7, le 8 est invalide.\nIncidemment, JSLint (comme JSHint, je crois) vous couineront à l’oreille s’ils vous voient faire un parseInt qui ne précise pas la base. Et ils auront raison.\nVous me direz : « mais alors, parseInt('08') devrait plutôt renvoyer NaN, non ?! ». Et je serais bien d’accord avec vous. Seulement voilà : parseInt et parseFloat se contentent d’ignorer la suite du texte dès qu’ils rencontrent un caractère invalide. Ce qui est un comportement pourri, mais toujours d’actualité.\nJe ne sais pas vous, mais moi, si je demande à l’internaute de saisir un nombre et qu’il me pond 42foobar, je ne veux pas « voir » 42, je veux me prendre un NaN. Pas de chance :\n\nAlors que faire ?\nLe protocole de conversion numérique de JavaScript\nIl se trouve que JavaScript est depuis toujours équipé d’un mécanisme qui convertit une entité quelconque en Number : c’est son protocole de conversion numérique, que la spec appelle affectueusement « ToNumber ». Il est déclenché implicitement lors d’expressions nécessitant un traitement numérique d’un opérande.\nLa manière la plus simple de transformer une valeur (ou undefined) en Number consiste probablement à la passer à l’opérateur + unaire (c’est-à-dire ne prenant qu’un opérande) : +truc. Bon point pour lui : il refusera tout caractère invalide. Voyez plutôt :\n\nComme vous pouvez le voir, le + unaire est un moyen rapide, concis et efficace de convertir ce qu’on veut en Number. Il ne change pas le signe éventuel et réagit à tout caractère invalide en retournant NaN. Il est donc en tous points supérieur à parseFloat.\nIl faut souligner qu’il existe",
		"description": "Un de ces sujets où on a l’impression, comme ça, superficiellement, que JS est vraiment débile parfois. Mais non.",
		"date": 1356480000,
		"image": "/assets/images/art-vid/art-js-number-conversion.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Convertir un texte en nombre en JavaScript",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/convertir-un-nombre-en-texte-en-javascript/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Au fil des formations, je remarque que de nombreuses bonnes pratiques que je signale en passant dans le code, par acquis de conscience, ne sont pas connues, ou pas comprises, ou juste surprenantes pour les stagiaires. C’est l’occasion de me souvenir que dans tous les domaines, ce qui peut paraître évident et « connu de tous » ne l’est pas forcément, et qu’il est toujours bon de remettre en lumière des savoirs dont on imagine, souvent à tort, qu’ils sont monnaie courante.\nVoici donc dix bonnes pratiques choisies parmi un large ensemble de candidates ; vous en connaîtrez sûrement certaines, mais probablement pas toutes. Je pensais qu’il en faudrait 10 pour faire un article un peu consistant, et au final c’est un mammouth qui aurait pu être découpé en plusieurs articles histoire de faire durer le plaisir… Mais je suis d’humeur généreuse et j’ai encore plein d’articles sous le coude, alors je vous livre tout ça d’un coup :-)\nN’hésitez pas à faire vos retours en commentaires !\n\n1. Court-circuiter les blocs plutôt que les imbriquer\nCourt-circuiter le code, en JavaScript, c’est recourir à return, break ou continue pour sauter tout ou partie du contexte en cours (fonction ou boucle), et s’épargner ainsi des blocs imbriqués inutiles, avec ce que ça suppose d’indentation supplémentaire…\nIl est certes primordial de bien indenter son code, quel que soit le langage. Dès qu’on ne se limite pas à un code trivial de 2-3 lignes, visualiser les dépendances logiques des conditions, boucles et fonctions devient impératif.\nToutefois, il est dommage d’indenter inutilement. Trop d’indentations imbriquées crée souvent un a priori négatif sur le code en donnant une vision faussée de sa complexité. Cela rend aussi le code moins lisible et facile à appréhender.\nVoyons quelques exemples.\n\nIci il est dommage d’avoir deux niveaux. Le cœur de code étant dans un if, il suffit de tester la condition inverse et de court-circuiter avec un return :\n\nLe même principe peut s’appliquer dans les boucles, en utilisant suivant les cas continue ou break. Ainsi, le code suivant :\n\n…deviendrait celui-ci :\n\nAu passage, vous ne le savez peut-être pas mais break et continue autorisent le recours à un label pour court-circuiter au-delà de leur boucle conteneur immédiate, et remonter ainsi de plusieurs niveaux (mais toujours au sein de la fonction courante). Voici un exemple de recherche dans une matrice, hors la diagonale. On ignore la diagonale en court-circuitant le tour courant avec un continue simple, mais si on trouve la valeur recherchée, on court-circuite l’ensemble des boucles pour aller directement à la suite de la fonction, au moyen d’un label sur la boucle externe et de son emploi dans le break interne :\n\nEnfin, il existe le fameux cas du « return else », un cas classique de superflu. Voyez plutôt :\n\nC’est parfaitement superflu, comme en atteste l’exemple plus haut : un return court-circuite la fonction conteneur, le else est donc sans intérêt : on peut utiliser directement le code qu’il contient.\nBref : l’indentation c’est bien, mais en faire trop c’est moins bien ! N’abusons pas des bonnes choses…\n2. Comparer avec les rvalues à gauche\nQu’est-ce qu’une rvalue ? En jargon d’analyse syntaxique (parsing), on désigne ainsi l’opérande droit d’un opérateur. Par symétrie, l’opérande gauche est appelé lvalue. Par exemple, dans x == 42, x est la lvalue et 42 la rvalue. Dans str += 3, ce seraient évidemment str et 3, respectivement.\nDans tous les langages où l’opérateur d’affectation (=) est un sous-ensemble de celui de comparaison (==), et où l’affectation est une expression, on risque de tomber dans le piège du égale manquant. Ainsi en JavaScript C, C++, Java, Ruby, etc. on peut se gaufrer comme suit :\n\nVous avez vu la blague ? Le = au lieu du == ? C’est un piège fréquent même pour les développeurs chevronnés : après tout, c’est « juste » une faute de frappe. Mais c’est tellement discret que ça peut être infernal à déboguer.\nSi vous avez un bon outillage associé à votre éditeur de code, votre compilateur ou votre interpréteur, il vous fera probablement remarquer qu’il y a ici baleine sous gravier. C’est par exemple le cas de JSLint et JSHint, tous deux fournis par exemple dans Sublime Text 2 au moyen de l’excellent plugin SublimeLinter.\nVous avez alors le choix :\n\nsoit il s’agit bien d’une affectation à la volée (pour utilisation de la valeur dans le bloc, par exemple), et vous pouvez rendre ça explicite en doublant les parenthèses ;\nsoit c’est une comparaison et vous rajoutez un =.\n\nToutefois, le souci principal c’est que ça puisse arriver (ce code s’exécute, il est valide ; il fait juste n’importe quoi…) alors que vous visiez une comparaison. C’est pourquoi dans tous ces langages j’ai le réflexe d’inverser, pour les comparaisons d’égalité uniquement (== et ===, en JavaScript), la lvalue et la rvalue. Ça donnerait ceci :\n\nVoyez-vous ce qui se passe ? Si j’oublie un =, l’affectation résultante n’est pas valide : je ne peux pas modifier le litéral de g",
		"description": "Quelques recommandations solides comme le roc pour améliorer drastiquement la qualité et la maintenabilité de ton code JS.",
		"date": 1358726400,
		"image": "/assets/images/art-vid/art-js-10-bps.jpg",
    "_tags": ["js"],
		"title": "10 bonnes pratiques JavaScript",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/dix-bonnes-pratiques-javascript/",
		"locale": "fr",
		"readingTime": "18 min"
	},	{
		"content": "Pourquoi Sublime Text ?\nJ’ai passé des années sur Emacs, puis sur Vim, puis sur TextMate. Étant un développeur web sur OSX faisant beaucoup de Rails, TextMate était un choix évident, avec la pléthore d’astuces et d’outils petits et grands pour l’écriture de code Rails que ses paquets renferment… En dépit de ses limitations (pas de split view, fuzzy finder lent à la mise à jour, plus d’évolution significative depuis des années), j’y suis donc resté obstinément, comme beaucoup.\nPendant ce temps, Sublime Text et sa version 2 (« ST2 » dans le reste de cet article) ont acquis petit à petit une renommée significative, au point que je voyais chaque jour davantage de profils similaires au mien qui passaient dessus et ne revenaient pas en arrière. Lorsque je m’y suis mis moi aussi, j’ai pris soin de chercher tout de suite des ressources approfondies sur ST histoire de ne pas le sous-utiliser pendant des mois voire des années, comme le font souvent trop de gens avec un nouvel outil.\nEt de fait, ça déchire. Il y a bien sûr quelques petites frustrations de-ci de-là par rapport à TextMate (les snippets et la complétion pour l’univers Rails sont loin derrière ceux de TextMate, malgré des paquets similaires), mais les avantages écrasent les inconvénients. Je suis surtout sensible à sa vitesse (le fuzzy finder est toujours à jour, instantanément, ce qui explose aussi bien celui natif à TextMate que le plugin PeepOpen, qui avait beaucoup de soucis), et l’outil est dispo sur OSX, Linux et Windows, ce qui permet de le standardiser dans une équipe multi-OS. Quant à la possibilité d’étendre soi-même l’outil, elle est similaire à celle de TextMate.\nAlors voyons en détail ce que j’adore chez ST, et comment je me le suis configuré.\n\nUn dernier point : je vous encourage fortement à enregistrer votre licence de Sublime Text. Bien sûr il est utilisable à 100% sans paiement (on se prend juste régulièrement une incitation à le payer), mais vu les énormes gains de productivité et de vitesse qu’il permet, je trouve tout-à-fait normal de rétribuer les auteurs. Et après tout, $70 (jusqu’à $50 pour les gros volumes), ce n’est pas cher payé pour un tel avantage.\nPour finir, épargnez-moi les trolls à rallonge dans les commentaires sur la supériorité de tel ou tel éditeur. Je fais toujours beaucoup de Vim, par exemple, notamment via des sessions SSH, et j’aime beaucoup cet éditeur (ST a d’ailleurs un mode Vintage qui lui rend hommage). Il ne s’agit pas ici de dire que l’un est meilleur que l’autre, d’autant que comme souvent, les meilleurs outils sont ceux qu’on maîtrise le plus… Restons sur le sujet, s’il vous plaît.\nPourquoi cet article ?\nJ’écris cet article parce qu’autant ST peut être extrêmement puissant et confortable, autant son installation par défaut (ST « nu », si vous voulez) n’en laisse pas paraître grand chose… La sidebar est totalement dénuée d’options utiles au clic droit, on n’a pas de transpose, etc. Et même ses fonctions natives puissantes, comme le Go To Anything, la Command Palette ou les Layouts, sont souvent bien peu utilisés, ou sous-employés.\nL’idée est donc de mettre en place ici une config « musclée », et de vous fournir également des liens vers des ressources externes de qualité sur ST lui-même, au travers notamment de screencasts, qui constituent toujours une des meilleures approches pour découvrir un éditeur, car l’aspect visuel et animé est important ici. Je peux affirmer que ces ressources m’ont vraiment permis d’avoir rapidement une utilisation efficace de ST, quelques jours à peine après avoir commencé à l’utiliser.\nÀ partir de zéro\nNote importante : si vous avez déjà ST d’installé et de personnalisé, il peut être préférable de sauvegarder vos réglages et paquets. Une approche un peu bourrine mais exhaustive consiste à sauvegarder son répertoire Packages entier, qui comprend et les paquets et les configurations par défaut (Default) et utilisateur (User). Vous trouverez ce répertoire facilement en utilisant la commande Preferences: Browse packages de ST (par exemple avec Tools &gt; Command Palette, puis tapez « browse »). Sur OSX par exemple, il s’agit classiquement de ~/Library/Application Support/Sublime Text 2/Packages.\nInstallation\nVous pouvez télécharger ST depuis son site officiel. L’installation est toute simple, et il ne vous reste plus qu’à le lancer une première fois pour qu’il crée les répertoires de configuration nécessaires.\nStructure de la configuration\nDeux principes gouvernent la configuration de ST :\n\nIl s’agit simplement de fichiers JSON, qu’on édite directement, et qui sont pris en compte immédiatement à la sauvegarde (sauf pour de rares manips, auquel cas c’est précisé par l’auteur du paquet)\nIl y a trois niveaux de configuration : globale et utilisateur et syntaxe.\n\nLe plus souvent, un paquet fournira les deux premiers niveaux : global et utilisateur. La configuration globale du paquet (ou de ST) fournit généralement le détail des options possibles, parfois commentées, en détaillant leurs va",
		"description": "Un article de référence sur l’utilisation avancée de ST en général, et dans le cadre du développement web en particulier.",
		"date": 1363046400,
		"image": "/assets/images/art-vid/art-st2-web.jpg",
    "_tags": ["outil"],
		"title": "Sublime Text 2 pour le dev web : config, trucs et astuces",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/sublime-text-dev-web-config-trucs-astuces/",
		"locale": "fr",
		"readingTime": "22 min"
	},	{
		"content": "Git propose 3 niveaux de configuration :\n\nLocale. Spécifique à chaque dépôt local, elle est stockée dans le .git/config. On y trouve notamment les trackings de branches, le remote, etc.\nGlobale. Spécifique à l’utilisateur, elle est stockée à la racine de son compte, dans le fichier ~/.gitconfig. C’est celle qui nous intéresse ici.\nSystème. Généralement stockée dans /etc/gitconfig, elle est partagée par tous les utilisateurs. Elle est rarement employée.\n\nLes priorités vont dans l’ordre usuel : du local au système.\nLa majorité des utilisateurs se contente de coller dans leur .gitconfig leur nom, e-mail et préférences d’éditeur. C’est là une sous-utilisation navrante. De très nombreux aspects quotidiens de Git sont paramétrables, et donc améliorables, au travers de la configuration.\nCet article explore ma configuration personnelle pour vous faire découvrir de nombreuses astuces utiles.\n\n\nCet article est complété par une seconde partie plus actuelle, accompagnée d’un épisode vidéo 📺.\n\nAvant toute chose, assurez-vous que vous utilisez un Git récent (2.22+). Plusieurs options de configuration évoquées ci-après n’ont fait leur apparition que récemment. Si une option semble ignorée chez vous, vérifiez soigneusement son nom et sa valeur, puis jetez un œil aux notes de version pour retrouver la version dans laquelle l’option est apparue.\nJe maintiens une version publique générisée de ma configuration dans ce Gist. Par « générisée », je veux dire que j’en retire, ou que j’y commente, quelques traitements qui me semblent délicats à activer par défaut, car ils concernent des comportements subtils de Git qu’il vaut mieux bien connaître avant de les appliquer.\nUn fichier de configuration Git est d’une syntaxe similaire à un bon vieux fichier INI : les sections sont délimitées par un en-tête [nom.section], et les lignes de propriété qui suivent appartiennent à la section. L’indentation est recommandée mais nullement obligatoire. La représentation linéarisée d’une propriété est section.nom, par exemple core.whitespace pour la propriété whitespace au sein de la section [core].\nVoici déjà le gist global :\nExaminons à présent les réglages un par un.\nIdentité par défaut pour les commits\nC’est la base de la base : identifier vos commits à venir. On utilise pour cela user.name et user.email. Évitez toutefois de pourrir la config Git d’un utilisateur de déploiement sur un serveur de prod avec ce genre de trucs, si vous êtes plusieurs personnes à pouvoir déployer. Préférez qualifier un éventuel commit en prod (ouh là là…) avec git commit --author=… afin de ne pas vous mélanger les pinceaux.\nColorisation\nDe nombreuses commandes Git sont capables de coloriser leur affichage à l’aide de codes ANSI VT lorsque le terminal le permet. La valeur auto a le même sens que dans de nombreuses autres commandes Linux (par exemple ls) : Git détectera s’il est utilisé en direct par un terminal VT capable de gérer les codes de couleur, et si c’est le cas, exploitera cette possibilité.\nLa propriété color.ui est un paravent générique pour l’ensemble des propriétés plus spécifiques de gestion de couleur, par exemple color.branch, color.diff, color.grep, color.interactive, etc. En gros, on veut de la couleur !\nAliases\nGit ne permet par défaut que les noms de commande complets (commit, checkout, etc.), ce qui fait parfois rager les Subversioniens débutant sur Git, qui cherchent en vain leur git ci. Outre qu’un prompt correctement configuré proposera une complétion avancée (ça fera l’objet d’un autre billet), la vraie raison est que Git permet de se créer autant d’aliases qu’on le désire, au moyen des réglages de la section [alias]. Chaque propriété a pour nom celui de l’alias et pour valeur la ligne de commande Git sans le git initial.\nMa configuration prévoit 3 aliases sans lesquels je ne saurais bosser :\n\nci pour commit\nst pour status\nlg pour un log textuel avancé qui, en ce qui me concerne, est tout-à-fait à la hauteur des logs graphiques (graphe de branches et fusions, références symboliques, tags et têtes de branches, SHAs, auteurs et horodatage relatif). Et le bonus, c’est qu’il marche dans un terminal, donc via SSH…\n\n\nPagination, whitespace et autres réglages « noyau »\nPar défaut, Git pagine tout ce qu’il affiche : si ça dépasse la hauteur du terminal, ça se prend un less dans la figure. Personnellement, je ne supporte pas ça : si je veux paginer, je | less moi-même ! En spécifiant via core.pager de passer par cat plutôt que less, je désactive de facto la pagination.\nLorsqu’il ouvre un éditeur (notamment pour les messages de commit ou la mise en place d’un rebase interactif), Git choisit l’éditeur comme ceci :\n\nVariable d’environnement GIT_EDITOR\nRéglage core.editor (c’est ce que je préfère)\nVariable d’environnement VISUAL\nVariable d’environnement EDITOR\nBinaire par défaut retenu à la compilation de Git ; en général, vi.\n\nSi le comportement par défaut n’est pas votre tasse de thé, il vous faut spécifier la ligne de commande à exécuter. Lorsque l’",
		"description": "Passage en revue détaillée des réglages incontournables pour une utilisation efficace de Git au quotidien.  Une référence.",
		"date": 1364947200,
		"image": "/assets/images/art-vid/art-git-config.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Une configuration Git aux petits oignons",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/configuration-git/",
		"locale": "fr",
		"readingTime": "11 min"
	},	{
		"content": "Pour un organisme de formation, le mois d’avril est l’échéance de dépôt du Bilan Pédagogique et Financier (BPF), pour lequel nous devons compulser toutes sortes de statistiques et compteurs sur nos stagiaires, sessions, heures de formations, origines des règlements, etc. C’est aussi amusant que de lire du COBOL à jeun.\nCeci étant dit, c’est l’occasion de faire le point sur l’évolution de notre activité de formation. Et comme Attitude, c’est avant tout la transparence, je me suis dit que ça pourrait vous intéresser de voir d’où nous sommes partis et où nous en sommes.\n(note : cet article est posté sur l’ensemble des sites Attitude)\n\nPratiquement 3 ans\nSi Delicious Insights n’existe que depuis août 2011, notre activité de formation a démarré bien avant cela, sous d’autres formes : dès le 2 juillet 2010, pour être précis. C’était la première formation Git au Quotidien, déjà chez Clever Age et à un tarif ubuesque pour les valeureux pionniers qui osaient l’aventure : 50€ la journée, déjeuner compris !\nLorsqu’en octobre j’expliquais l’idée derrière Git Attitude aux copains pendant Paris Web, ce bon vieux Jérémie Patonnier m’a dit sur un ton débonnaire et détaché : « mais pourquoi tu ne fais pas la même chose avec JavaScript ? ». Après m’être tapé la tête contre le mur de ne pas y avoir pensé dès le début, j’ai donc lancé JS Attitude avec tout d’abord JS Puissant et une première session bondée (16 personnes !) le 27 novembre, vendue en quelques jours, presque quelques heures…\nVoici un petit historique de jalons sélectionnés :\n\n\n\nDate\nJalon\n\n\n\n\n2 juillet 2010\nLancement Git Attitude (Git Quotidien)\n\n\n27 novembre 2011\nLancement JS Attitude (JS Puissant)\n\n\n19 février 2011\nPremier Git Avancé\n\n\n12 mars 2011\nJS Guru v1\n\n\nmai 2011\nPremières sessions intra-entreprises (Blablacar / Comuto, Intel)\n\n\n2 juillet 2011\nJS Guru v2\n\n\n26 août 2011\nImmatriculation de Delicious Insights\n\n\n25 février 2012\nJS Guru v3\n\n\naoût 2012\nNouvelle tarification (dont tarifs fidélité), passage des inter à l’Espace La Rochefoucauld\n\n\nseptembre 2012\nCréation du blockbuster JS Total pour Digitas / Vivaki\n\n\ndécembre 2012\nCréation de la formation CoffeeScript\n\n\n15 novembre 2012\nJe passe à temps plein sur Delicious Insights\n\n\n23 novembre 2012\nPremière formation en anglais (Kelkoo)\n\n\nmars 2013\nPremières formations intra à l’étranger (Bruxelles)\n\n\n\nQuelques chiffres\nJe vous passe l’évolution d’un exercice fiscal à l’autre, mais sachez qu’aujourd’hui, Delicious Insights, au travers de Git Attitude et JS Attitude, c’est :\n\n7 formations au catalogue (3 Git et 4 JavaScript)\n52 sessions déjà données, soit\n544 heures de formation à destination de\n444 stagiaires au sein de\nplus de 80 sociétés clientes (et de nombreux participants à titre personnel)\n\nParmi nos clients, un équilibre surprenant entre TPE/PME, agences (TBWA, MRM Worldwide, Fullsix / Ekino…), SSII (Atos, Valtech…) et grands comptes (SNCF, Orange, EADS, Dassault, Intel, Alcatel-Lucent, 4D, FNAC, l’OCDE, Météo France, MisterGoodDeal, PriceMinister…). Des clients situés dans 5 pays : France, Royaume-Uni, Belgique, Suisse et Luxembourg.\nDes stagiaires enchantés\nTous nos stagiaires ont l’occasion de faire un retour à chaud en fin de session, face à face, ainsi qu’un retour à froid via un formulaire en ligne proposant des évaluations tant quantitatives (notes de 1 à 5) que qualitatives (texte libre). Un bon tiers de nos stagiaires prennent le temps de le remplir (une proportion historique qui, toutefois, ne cesse de s’améliorer). Nous n’avons rien à cacher, alors allez donc consulter un rapport temps réel sur les retours qui nous sont faits.\nMerci à vous\nJe voudrais profiter de cet article pour remercier très chaleureusement tous les stagiaires qui nous ont fait confiance jusqu’ici, et leurs employeurs qui ont accepté de les envoyer dans nos formations. C’est un plaisir chaque fois renouvellé de vous transmettre tout ce qu’on peut, d’échanger avec vous et de lire vos retours !\nEt maintenant ?\nEh bien, on va commencer par finir l’exercice en cours (au 30 juin), et préparer la rentrée…\nJe souhaite rédiger davantage d’articles de fond, ainsi que de la retranscription de veille et des didacticiels sur diverses technos, sur les différents sites Attitude.\nJ’ai très envie de pouvoir mettre au catalogue des formations Node.js, Ruby et Rails, mais on verra si le temps de préparation ne fait pas trop défaut.\nOn va probablement élargir petit à petit le groupe de formateurs, aussi, en travaillant avec des personnes de confiance qu’on connaît de longue date, qui partagent notre philosophie, nos valeurs, et font preuve d’une expertise technique et d’une pédagogie à la hauteur de nos exigences.\nEnfin, le catalogue de formations va faire l’objet au fur et à mesure d’une déclinaison sous forme de screencasts qualitatifs payants, d’une heure environ chacun, avec des possibilités d’achat par lot (pour toute la série “Git au Quotidien” par exemple), les stagiaires bénéficiant automatiquement d’un fort rabais sur ces derniers.\n",
		"description": "Le point sur les quelques années de formation écoulées.",
		"date": 1366588800,
		"image": "/assets/images/art-vid/art-year-in-review.jpg",
    "_tags": [],
		"title": "Formations Attitude : un premier bilan",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/attitude-un-premier-bilan/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Dans l’univers des utilisateurs de Git, il y a ceux qui sont encore cantonnés à l’interface graphique (c’est bien triste, ils n’utilisent pas 2% de la puissance quotidienne de l’outil) et ceux qui sont passés à la ligne de commande (CLI, bravo à eux).\nMais même au sein de ces derniers, une part encore trop grande ne recourt pas à un prompt personnalisé pour disposer à tout moment d’informations importantes sur leur dépôt local et leur copie de travail, sans parler d’une complétion intelligente sur les commandes Git.\nCet article vise à vous aider à optimiser votre prompt quand vous êtes dans vos dépôts Git.\n\nC’est quoi un prompt ?\nC’est le texte qui est affiché avant chaque invite de commande dans une session shell. Par exemple, dans une invite de commande Windows classique, c’est généralement juste le chemin suivi d’un chevron fermant, du genre :\n\nSur les système Linux/Unix, la plupart des gens ont un prompt par défaut qui affiche leur identifiant, le nom de la machine, et le chemin courant, suivis d’un $ s’ils sont des utilisateurs classiques ou de # s’ils sont le super-utilisateur, root :\n\nSelon le shell utilisé (cmd ou PowerShell sous Windows, une pléthore sur Linux/Unix dont émergent principalement Bash et ZSH), ce prompt se configure de diverses façons, le plus souvent au moyen de variables d’environnement dédiées, voire d’une fonction shell spécifique.\nPourquoi un prompt personnalisé ?\nBeaucoup de gens configurent leur prompt pour ajuster l’ordre d’affichage des infos, en ajouter, coloriser des parties, indiquer automatiquement si la dernière commande a rencontré une erreur, etc.\nInformations immédiates sur l’état / le statut\nDans cet esprit d’informations complémentaires, il est possible de recourir à des fichiers spécifiques de Git pour y incruster plein d’infos utiles sur le dépôt courant, son index et sa copie de travail, afin…\n\nde gagner du temps (inutile de les demander explicitement)\nmais aussi d’éviter de nombreux pièges en remarquant en amont qu’on n’est pas dans l’état où on croyait (ex. il reste de l’untracked, y’a du modified, la branche active n’est pas la bonne, etc.).\n\nPour cela, on va personnaliser les variables qui gouvernent la construction du prompt à chaque invite de commande.\nComplétion intelligente\nIl ne s’agit pas du prompt à proprement parler, mais il est également possible de renseigner auprès de notre shell une gestion de complétion (généralement avec la touche Tab) pour les diverses commandes de Git, et même pour les arguments de ces commandes !\nCe confort supplémentaire n’est pas anodin, en ce qu’il rend de nombreux aliases (raccourcis) superflus, et accélère considérablement la saisie des commandes.\nLes cas déjà gérés\nSelon votre situation technique, vous avez déjà plus ou moins de choses qui sont configurées pour vous côté prompt et complétion.\nOh-my-Zsh\nPour ceux qui utilisent ZSH au travers de l’excellentissime projet Oh My ZSH, ils disposent automatiquement d’une prise en charge des dépôts Git et d’un grand nombre de thèmes (du sublime à l’immonde) pour personnaliser leur affichage.\nVous y noterez un recours fréquent aux caractères Unicode et à la palette 256 couleurs. Utiliser un terminal moderne est donc recommandé.\nmSysGit (Windows)\nCurieusement, les utilisateurs de Git sous Windows, au travers de mSysGit, sont déjà pas mal lotis puisque la complétion et le prompt sont déjà en place dans le Git Bash installé par l’outil.\nSeul bémol : la configuration par défaut omet certaines infos, notamment les untracked, il faudra donc personnaliser un peu le fichier .bashrc à la racine du compte utilisateur pour améliorer l’affichage obtenu. Vous verrez comment dans un instant.\nSe configurer ça à la main\nPour les utilisateurs de ZSH, vous êtes sensés être des utilisateurs avancés, je vous laisse donc aller fouiller dans les fichiers fournis par Oh My ZSH pour y trouver votre bonheur.\nLes utilisateurs de Bash auront besoin de trois choses :\n\nCharger les fichiers de prompt/complétion s’ils ne sont pas auto-chargés\nDéfinir les variables d’environnement contrôlant l’affichage par la fonction de prompt Git\nModifier la définition du prompt pour recourir à ladite fonction\n\nLe fichier de configuration du shell\nSuivant le système que vous utilisez et la façon dont vous ouvrez votre shell, Bash reconnaît trois fichiers de configuration, tous placés à la racine de votre compte utilisateur.\nCette racine est du style C:\\Documents and Settings\\TonPtitNom ou C:\\Users\\TonPtitNom sur Windows, /home/tonptitnom sur Linux/Unix et /Users/tonptitnom sur OSX.\nLes trois fichiers concernés sont .bashrc, .bash_profile et .profile. Linux/Unix utilise généralement les deux premiers : l’un contient les instructions d’initialisation tandis que l’autre se contente de lui déléguer le travail. OSX a tendance à favoriser .profile pour son Terminal.\nmSysGit n’en propose aucun par défaut, mais vous pourrez créer .bashrc manuellement (attention toutefois à la majorité des éditeurs Windows qui refuseront de créer un",
		"description": "Le retour du prompt Git haut de gamme, notamment dans Bash, cette fois-ci en s’appuyant sur les scripts officiels.",
		"date": 1369180800,
		"image": "/assets/images/art-vid/art-git-prompt.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Un prompt Git qui déchire",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/prompt-git-qui-dechire/",
		"locale": "fr",
		"readingTime": "9 min"
	},	{
		"content": "Je suis tombé récemment, sur StackOverflow, sur une excellente réponse de Bob Aman à une ancienne question du style « comment faire des URLs qui respectent bien les conventions de REST » ?\nEn fait, Bob ne s’est pas à proprement parler limité à REST, mais a fournit toute une série de principes directeurs pour la mise en place tant d’URLs cohérentes que de choix de verbes HTTP cohérents pour aller avec, ainsi que certains préceptes importants pour le comportement du serveur et la réponse HTTP qu’il renvoie.\nTout ça date déjà pas mal (octobre 2009, mais souvenez-vous que Rails a popularisé REST—qui est aussi vieux que HTTP, en fait—avec sa version 2, en 2006) mais à en juger par la large dominance des URLs !@# pourries que je vois partout, ça mérite carrément d’être répété jusqu’à plus soif.\n\nÀ noter que ceci n’est pas une simple traduction, mais que j’ai ajouté quelques compléments et bémols personnels.\nAu niveau des URLs elles-mêmes\n\n\nSaymal : n’utilisez pas de paramètres URL (query string) pour altérer l’état côté serveur. Ils ont un autre rôle conceptuel (voir plus loin).\n\n\nSaymal : ne mélangez pas la casse dans vos chemins, autant que possible. Préférez les minuscules.\n\n\nSaymal : n’exposez pas des éléments dépendants de l’implémentation dans vos URLs (.php, .jsp, .aspx, .cfm, etc.)\n\n\nSaymal : ne faites pas du RPC sur la seule base de vos URLs (Bob entend par là que vos URLs ne devraient normalement pas décrire une action mais une ressource, ce qui rejoint les principes de REST)\n\n\nSaybien : limitez l’espace de noms de vos URLs autant que possible (soyez cohérents, basés sur ressources, minimalistes dans les suffixes, etc.)\n\n\nSaybien : gardez vos segments de chemin raisonnablement courts\n\n\nSaybien : choisissez entre /resource et /resource/ ; faites des redirections 301 depuis la variante que vous n’avez pas retenue.\n\n\nSaybien : cantonnez vos paramètres de query string à de la sélection complémentaire au sein de la ressource ; typiquement pour la pagination, les recherches textuelles, etc.\n\n\nSaybien : sortez des URLs les informations qui devraient figurer en en-tête ou corps de requête HTTP\n\n\nIl y a naturellement quelques cas à la marge ; on en retrouvera la plupart (pour ceux que je considère légitimes, en tout cas) dans la discussion qui suit, laquelle porte cette fois-ci sur les verbes HTTP employés pour vos requêtes. À mon sens, l’URL et le verbe sont deux éléments indissociables dans les conventions que vous adoptez. Une requête HTTP exploite forcément l’un en conjonction avec l’autre.\nAu niveau des verbes HTTP\nAvant toute chose, il va de soi que ces règles sont conceptuelles et non strictement techniques : côté navigateur, vous simulerez en général le verbe hors-GET en faisant un POST avec un champ spécial (généralement _method), et côté serveur, suivant votre technologie, il faudra peut-être avoir recours au même subterfuge même si le client est capable d’émettre les véritables verbes…\n\n\nSaymal : n’utilisez jamais GET pour modifier l’état côté serveur ; c’est une excellente manière de vous tirer une balle dès que le Googlebot passe vous dire bonjour.\n\n\nSaymal : n’utilisez pas PUT à moins de mettre à jour l’intégralité de la ressource (pour le coup, je suis moyen d’accord ; il est vrai que PUT est sensé être idempotent et que le véritable verbe HTTP pour une mise à jour partielle est PATCH, mais si vous faites du PUT partiel c’est déjà nettement mieux qu’un bête POST, en vrai…)\n\n\nSaymal : n’utilisez pas PUT si vous n’avez pas une utilisation légitime de GET sur la même URL\n\n\nSaymal : n’utillisez pas POST pour récupérer une information à longue durée de vie ou en tout cas éminemment cachable par le client (les POST ne sont jamais cachés par les navigateurs, proxies, etc.)\n\n\nSaybien : utilisez GET pour tout ce qui s’y prête (c’est cachable, bookmarkable, etc.).\n\n\nSaybien : utilisez PATCH plutôt que PUT pour une mise à jour partielle (si tant est que votre couche serveur puisse le prendre en charge).\n\n\nSaybien : utilisez POST plutôt que PUT ou PATCH si vous avez un doute\n\n\nSaybien : préférez POST ou PATCH, suivant le cas, dès que vous faites un appel qui « sent le RPC » (déclenche une méthode modifiante de la ressource)\n\n\nSaybien : préférez PUT si vous accédez à une ressource composite ou hiérarchique\n\n\nSaybien : préférez DELETE pour toute suppression de la resource (qu’elle soit physique ou logique)\n\n\nSaybien : utilisez GET pour des traitements de calcul, sauf si votre requête est trop large, auquel cas utilisez POST\n\n\nAu niveau du comportement serveur et de sa réponse\n\n\nSaymal : ne mettez pas vos méta-données (benchmarking, authentification, quotas API, unités API dépensées, etc.) dans le corps de la réponse mais dans son en-tête\n\n\nSaymal : ne sortez pas vos méta-données dans une ressource à part, sauf si leur inclusion systématique entraîne un surpoids considérable.\n\n\nSaybien : utilisez un code réponse approprié. Notamment :\n\n201 Created après avoir créé une ressource ; celle-ci doit toujours exister a",
		"description": "Quelques conseils-clés sur la structuration intelligente de vos points d’accès HTTP(S) API.",
		"date": 1370390400,
		"image": "/assets/images/art-vid/art-http-bps.jpg",
    "_tags": [],
		"title": "Meilleures pratiques pour vos URLs, verbes HTTP et APIs",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/meilleures-pratiques-pour-vos-urls-verbes-http-et-apis/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "TL;DR\nUn git merge ne devrait être utilisé que pour la récupération fonctionnelle, intégrale et finale d’une branche dans une autre, afin de préserver un graphe d’historique sémantiquement cohérent et utile, lequel représente une véritable valeur ajoutée.\nTous les autres cas de figure relèvent du rebase sous toutes ses formes : classique, tri-partite, interactif ou cherry picking.\nDans cet article de fond, nous allons explorer en détail les sémantiques de merge et rebase, apprendre à choisir entre l’un ou l’autre, et donner des clés pour les utiliser au mieux afin d’obtenir un historique impeccable.\n\nMise à jour : la version anglaise de cet article est ici\nUn historique propre, compréhensible et utile\nUne des compétences les plus importantes d’un utilisateur de Git réside dans la capacité à garder un historique public de commits qui soit propre et sémantique. Et pour ce faire, on a recours à quatre outils principaux :\n\ngit commit --amend\ngit merge, avec ou sans --no-ff\ngit rebase, et notamment git rebase -i et git rebase -p\ngit cherry-pick (qui est fonctionnellement inséparable de rebase)\n\nJe vois souvent les gens mettre merge et rebase dans le même panier, sous le prétexte fallacieux qu’ils aboutissent tous les deux à « avoir les commits d’en face ramenés sur notre branche » (ce qui est d’ailleurs faux).\nPourtant, ces deux commandes n’ont pratiquement rien à voir. Elles n’ont pas du tout le même objectif et, de fait, on ne s’en sert absolument pas pour les mêmes raisons.\nJe vais tenter non seulement d’éclairer les rôles respectifs de merge et rebase, mais aussi de vous inculquer quelques réflexes et bonnes pratiques pour toujours produire un historique public qui soit à la fois expressif (concis mais clair) et sémantique (la visualisation de l’historique reflète les objectifs de l’équipe de façon optimale). Avoir un historique nickel constitue en effet une forte valeur ajoutée pour toute l’équipe : contributeurs qui le découvrent ou y reviennent longtemps après, chefs de projet, etc.\nDans quels cas utiliser merge ?\nComme son nom l’indique, merge réalise une fusion. On souhaite faire avancer la branche courante de sorte qu’elle incorpore le travail d’une autre branche.\nLa vraie question qu’il faut alors se poser, c’est : « que représente la branche d’en face ? »\nS’agit-il d’une branche locale temporaire, que j’avais juste faite par précaution, afin de conserver un master propre pendant ce temps-là ? Si c’est le cas, il est inutile, et même contre-productif, que cette branche reste visible dans l’historique, en formant un « aiguillage » identifiable.\nSi la branche récipiendaire (par exemple master) a avancé entre-temps et que la branche à fusionner n’en est donc plus un descendant direct, on la traitera comme une branche « ancienne » et on aura recours à rebase pour conserver un graphe linéaire. Mais si master n’a pas avancé entre-temps, je vais pouvoir faire un fast-forward, qui est un mode automatique de git merge.\nS’il s’agit d’une branche « connue », identifiée par l’équipe ou simplement par mon planning de travail, le raisonnement s’inverse. La branche peut par exemple représenter un sprint ou une story en méthodologie agile, ou encore un ticket d’incident (issue ou bug) précis, identifié dans notre gestion de tâches.\nIl est alors préférable, voire impératif, que l’étendue de cette branche demeure visible dans le graphe de l’historique. Ce sera le cas si la branche récipiendaire (par exemple master) a avancé depuis que la branche à fusionner en a dérivé, mais si master est restée inactive, la branche à fusionner en est un descendant direct, et il faudra alors empêcher Git de recourir automatiquement à l’astuce du fast-forward. Dans les deux cas de figure, on utilisera merge, jamais rebase.\nDans quels cas utiliser rebase ?\nComme son nom l’indique, rebase est là pour changer la « base » d’une branche, c’est-à-dire son point de départ. Elle rejoue une série de commits à partir d’un nouvelle base de travail.\nCe besoin survient principalement quand un travail local (une série de commits) est considéré comme partant d’une base obsolète. Cela peut arriver plusieurs fois par jour, quand on essaie d’envoyer au remote nos commits locaux, pour découvrir que notre version de la branche distante trackée (par exemple origin/master) date : depuis notre dernière synchro avec le remote, quelqu’un a déjà envoyé des évolutions de notre branche au serveur, du coup notre propre travail part d’une base plus ancienne, et l’envoyer tel quel au serveur reviendrait à écraser le travail récent des copains. C’est pourquoi push nous enverrait promener.\nUne fusion (ce que ferait pour nous git pull en interne) n’est pas idéale, car elle ajoute du bruit, des remous, dans le graphe de l’historique, alors qu’en fait c’est juste un coup de pas de bol dans la séquence de travail sur cette branche. Dans un monde idéal, j’aurais fait mon boulot après les autres, sur une base à jour, et la branche serait restée bien linéaire.\nCe besoin est a",
		"description": "La référence absolue sur ces deux commandes, leurs avantages et inconvénients respectifs, leurs philosophies et leurs bons cas d’utilisation.",
		"date": 1399161600,
		"image": "/assets/images/art-vid/art-git-merge-vs-rebase.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Bien utiliser Git merge et rebase",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/bien-utiliser-git-merge-et-rebase/",
		"locale": "fr",
		"readingTime": "18 min"
	},	{
		"content": "L’été se termine et notre 3ème exercice est clos. C’est traditionnellement le moment de faire le point sur l’année écoulée, et de regarder vers l’avenir avec les plans pour l’année suivante.\n(note : cet article est posté sur l’ensemble des sites Attitude)\n\nLes formations\nDelicious Insights, c’est de la formation avant tout.\nCette 3ème année a vu l’avènement tant espéré des formations Node.js et un resserrement volontaire de l’offre inter-entreprises, pour ne garder que 3 formations : Node, JS Total (passé en mensuel) et Git Total, qui a remplacé la découpe problématique Quotidien / Avancé.\nCette année a connu une augmentation notable des sessions intra-entreprises, ce qui fait que le nombre de stagiaires est nettement plus élevé que celui des clients… Les formations de cette 3ème année en quelques chiffres :\n\n238 stagiaires, dont 4 à titre particulier et un via Pôle Emploi\n31 sessions de formation, dans 8 villes de France\n3 formateurs, car 2 formateurs délégués débarquent (voir plus loin)\n92 clients, dont 87 sociétés\n\nAfin de faire face à une demande croissante et de me dégager du temps pour les autres projets (screencasts, articles, etc.) j’ai fait progressivement intervenir deux formateurs délégués dans les sessions JS Total inter-entreprises : Jonathan Blanchet et Jean-Pierre Vincent.\nJonathan et Jean-Pierre sont des freelances de longue date, très au fait des technos web et bons pédagogues ; l’idée à terme est de tourner à nous trois sur les JS Total inter, ainsi que de pouvoir proposer plus de dates JS Total en intra. D’abord simples assistants, ils sont aujourd’hui autonomes sur ces 4 jours très exigeants.\nEn revanche, j’assure toujours personnellement l’intégralité des sessions Node.js et Git Total.\nConférences\nLa transmission du savoir-faire et des connaissances, ça passe aussi par des rencontres et des présentations lors de conférences. À ce titre, notre 3ème année a amorcé un coup de fouet qui devrait continuer sur la 4ème…\n\nNous étions présents à 12 conférences dans 3 pays : JSConf.EU, BLEND Web Mix, Paris-Web, dotRB, FranceJS, dotJS, MS techdays, Mix-IT, Sud Web, dotScale, LaConf et JSConf.US.\nJ’étais orateur à 5 d’entre elles (BLEND Web Mix, FranceJS, MS techdays, Mix-IT et Sud Web), principalement autour de Node.js, avec 5 présentations et 1 atelier.\n\nDelicious Insights était également, pour la première fois, sponsor de Paris-Web (en plus du fait que j’assure l’application d’inscriptions et la traduction simultanée FR/EN). À ce titre, nous avions entre autres fait gagner une place aux conférences et offert des réductions sur nos formations aux participants.\nCe qu’on n’est pas arrivés à faire\nL’an dernier, on prévoyait déjà d’écrire davantage d’articles de fond, et au final seul un article (un bon gros poids lourd, il faut dire) est sorti, en bilingue : celui sur Git Merge vs. Rebase. Il faut clairement faire mieux, et diversifier la timeline des comptes Twitter aussi, en incluant de la veille et d’autres choses.\nOn prévoyait aussi déjà la mise en place des screencasts, et ça s’est limité au sondage sur les contenus et à l’établissement du planning approximatif de production (priorisation des contenus, étude tarifaire, etc.). Espérons que cette 4ème année fera mieux !\nEt pour notre 4ème année ?\nOn a évidemment plein de projets ! Des choses dans la continuité mais aussi du neuf…\nUne JS Total repensée\nAfin de rester au top, il est important que nos formations suivent l’état de l’art et se remettent régulièrement en question en termes de contenu et de choix pédagogiques.\nAssurée près d’une trentaine de fois depuis sa création il y a 2 ans, JS Total peut capitaliser sur un large retour d’expérience pour se réinventer une nouvelle fois. À partir de septembre, sa nouvelle mouture débarque, en deux temps probablement : septembre et octobre. La page de programme sera mise à jour très prochainement.\nNode.js peine toujours à démarrer en France\nAlors qu’il a conquis les US, le Royaume-Uni et l’Allemagne (pour ne citer qu’eux), Node.js peine toujours à démarrer en France, laquelle accuse son éternel retard d’adoption technique de 3 ans environ…\nBien que planifié prudemment toutes les 12 semaines environ, ses sessions n’ont que peu de stagiaires pour le moment, au point que celle de septembre risque actuellement l’annulation.\nC’est assez triste dans la mesure où Node.js est clairement une techno centrale pour les 10 ans à venir (au moins), et qu’on voit bien le plaisir, voire l’extase, que prennent les stagiaires à la (re)découvrir dans un contexte qualitatif !\nNous continuerons à la proposer toutes les 12 semaines pour le moment, en espérant que la France va enfin se réveiller sur le sujet.\nFormateurs délégués autonomes\nÀ partir de septembre 2014, les sessions JS Total seront assurées en rotation par Jonathan, Jean-Pierre et moi, selon les dispos de chacun. Ainsi, JP prend celle de septembre, Jonathan celles d’octobre et décembre, et moi celle de novembre, pour commencer.\nAutomne 2014 : plein de places à g",
		"description": "Déjà 3 ans ! Où en est Delicious Insights ?",
		"date": 1409011200,
		"image": "/assets/images/art-vid/art-year-in-review.jpg",
    "_tags": [],
		"title": "Retour sur l'année écoulée",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/bilan-e3/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Vous êtes nombreux à utiliser Git sans bien suivre ce qui change d’une version à l’autre. Parfois, vous vous contentez aussi de la version disponible sur votre distribution Linux, même quand celle-ci date un peu.\nFaisons le point sur les évolutions depuis Git 1.7, histoire de voir ce que vous loupez :-)\n\nMise à jour : la version anglaise de cet article est ici\nDéjà, où en suis-je et comment mettre à jour ?\nÀ l’heure où j’écris ceci, la version courante est la 2.1.0, qui date du 15/08/2014.\nLe site officiel maintient des builds officiels pour Mac et Windows (ce dernier étant souvent un poil en retard, par exemple là tout de suite c’est la 1.9.4), et bien sûr les sources pour ceux qui veulent compiler ça eux-mêmes.\nNotez que sur Mac, j’ai tendance à installer et mettre à jour via Homebrew, qui est généralement à jour sous 48h.\nVous pouvez tester votre version en cours :\n\nPour mettre à jour sur Windows, installez simplement le dernier download fourni par le site officiel.\nSur Mac, utilisez soit l’installeur officiel si vous passiez par là, soit une mise à jour Homebrew si vous êtes comme moi :\n\nSur Linux, si vous passez par les paquets officiels (ou des PPA enregistrés), utilisez la commande d’installation ou de mise à jour adaptée (généralement apt-get sur Debian/Ubuntu, yum sur Fedora, etc.).\nUn mot sur Debian et Ubuntu\nPour Debian et Ubuntu, les versions officielles accusent souvent un bon retard, surtout les LTS, en restant scotchées à leur version de sortie initiale :\n\n10.04 LTS « Lucid Lynx » a la 1.7.0 (septembre 2010)\n12.04 LTS « Precise Pangolin » a la 1.7.9 (janvier 2012)\n14.04 LTS « Trusty Tahr » a la 1.9.1 (mars 2014)\n\nJe ne saurais trop vous recommander d’enregistrer tout de suite le PPA officiel :\n\nSi vous n’avez pas la commande add-apt-repository, commencez par installer le paquet nécessaire :\n\nVous aurez ainsi la dernière version (le PPA est mis à jour sous 3-4 jours en moyenne après la sortie centrale).\nListe choisie des évolutions à connaître\nOn ne va pas juste paraphraser les release notes : je me concentre sur les nouveautés fonctionnelles (pas les correctifs et améliorations de performances), en choisissant celles qui me semblent présenter un intérêt particulier.\nSpécifiquement, je laisse de côté tout ce qui est foreign interface (interfaçage entre Git et les autres systèmes de gestion de version) et outils graphiques (gitk, git-gui, git-web), ainsi que les commandes de plomberie, pour me concentrer sur celles de porcelaine (celles que l’utilisateur normal est susceptible d’utiliser fréquemment).\nPlutôt que de dérouler un titre par version, je vous fais trois gros intervalles, volontairement calés sur les versions de base des Ubuntu LTS récentes.\nD’une manière générale, plus on avance dans les versions, plus les complétions Bash et ZSH et les prompts avancés s’améliorent. Par exemple, à bien des égards, le prompt Bash officiel fourni par __git_ps1 enterre fonctionnelement celui de Oh My ZSH.\nEntre 1.7.0 et 1.7.9\nIl y a eu un paquet de 1.7.x (12 !), mais le gros des modifs utiles est apparu dans la 1.7.2, qui a longtemps constitué mon « minimum vital ».\nPas mal de protections contres les pièges classiques des submodules ont fait leur apparition à cette période :\n\ngit diff et git status sont plus détaillés et explicites sur les modifs locales apportées aux submodules, ce qui contribue à réduire les risques d’oubli de commit/push sur ceux-ci. Diverses options et variables de configuration permettent de personnaliser ces nouveaux comportements.\ngit fetch --recurse-submodules fait son apparition en 1.7.4, histoire de gagner un peu de temps.\nJoli garde-fou depuis 1.7.7 dans git push en cas de commits locaux non pushés sur les submodules : git push --recurse-submodules=check.\nDepuis la 1.7.8, les dossiers Git des submodules ne sont plus directement dans leur checkout, mais dans le .git/modules/ du dépôt conteneur, et déréférencés par gitfiles (leur .git est un fichier texte contenant une ligne gitdir: chemin-du-dossier-git-déporté). Ça permet de recaler le commit utilisé d’un submodule au niveau parent sans avoir besoin d’en avoir fait le checkout ; dans la pratique, je trouve ça assez edge case, mais connaître ce déport de stockage évite les surprises en inspectant les dossiers de submodules…\n\nLes logs ont aussi connu des améliorations importantes :\n\nLa syntaxe de révision :/pattern, qui prenait jusqu’en 1.7.1 un texte simple, est interprétée comme regex depuis 1.7.2, et n’est plus limitée au seul début du message de commit (nettement plus pratique).\nApparition des colorations de git log --decorate en 1.7.2.\nApparition du pendant regex de git log -S : git log -G, en 1.7.4. Indispensable !\ngit log accepte des globs (ex. *.rb) comme chemins depuis la 1.7.5.\nApparition de log.abbrevCommit en 1.7.6, qui évite les SHA complets dans les logs mais en fait un peu partout…\n\nCôté fusions, rebases, push et pull, quelques trucs importants, voire centraux, ont débarqué :\n\nApparition du sympathique mode --kee",
		"description": "Git bouge pas mal ces temps-ci.  Petit tour d’horizon des nouveautés intéressantes, pour ceux qui ne suivent pas les notes de version.",
		"date": 1409184000,
		"image": "/assets/images/art-vid/art-git-recent-evos.jpg",
    "_tags": ["nouveautés","git"],
		"title": "Le point sur les évolutions depuis Git 1.7",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-evolutions-recentes/",
		"locale": "fr",
		"readingTime": "8 min"
	},	{
		"content": "Bien sûr, les tableaux JavaScript savent déjà se trier : on a une méthode sort() pour ça. Ça marche bien.\nOu pas.\n\nC’est vrai que de prime abord, tout semble être cool :\n\nLa fête du slip. Et pourtant\nRevoyons la scène au ralenti\n\n\nEeeeeh si.\nLOLWUT?\nSi on lit la doc (ce n’est pas un gros mot), on s’aperçoit que…\n\n  Le tableau est trié selon la valeur de point de code Unicode de chaque caractère, d'après la conversion en chaine de caractères de chaque élément.\n\nAh ben voilà.\nJavaScript étant dynamiquement typé, on n’a aucune garantie que les cellules du tableau renferment un type homogène, et même ainsi, aucune garantie que ce type ait un ordre naturel (qu’il réponde à &lt; par exemple).\nDu coup, Array traite tous les contenus, par défaut, comme le seul type vers lequel tous les autres ont un protocole de conversion : String. En gros, l’exemple de tout à l’heure est identique, fonctionnellement, à celui-ci :\n\nSauf que là, ça ne vous choque pas (ou moins).\nAlors je fais comment ?\nQu’à cela ne tienne Étienne, tu fournis ton propre comparateur externe, c’est-à-dire une fonction qui prend deux arguments–appelons-les a et b–et renvoie une valeur signée, avec la sémantique classique :\n\nDu négatif signifie que a apparaît avant b\nDu neutre (0) signifie qu’ils sont équivalents\nDu positif signifie que a apparaît après b\n\nPour un tableau numérique, il nous suffit donc de produire le signe nous-mêmes :\n\nVoilà qui est mieux. On peut bien sûr en faire une fonction utilitaire :\n\n(Les + préfixes garantissent le traitement en tant que Number des valeurs des cellules, comme ça, on trie numériquement même quand on a des String dans le tas, par exemple).\nSi vous aimez l’approche « j’étends les types natifs », ça se fait bien aussi (j’ai ça dans tous mes projets) :\n\nDu coup on est bons ?\nPour du numérique, oui. Si vous voulez trier correctement des textes, c’est autre chose. Regardez plutôt :\n\nAh. Voyez-vous, comme le disait la doc juste au-dessus, on compare les codepoints Unicode ; on parle de tri lexicographique.\nMais Unicode est une extension des jeux de caractère ISO, dans lesquels, pour des raisons historiques (toujours elles…) :\n\nLes majuscules sont avant les minuscules\nLes caractères nus sont avant les diacritiques (accentués, etc.)\nLes caractères simples sont avant les ligatures (genre œ ou æ)\nEt plein d’autres classements débiles\n\nDu coup, je vois plein de gens faire un putain d’aller-retour Ajax juste histoire de trier côté serveur une liste qui existait intégralement côté client ! Comme dirait un ami : « What the actual fuck? »\nC’est d’autant plus dommage que String a depuis longtemps (ES3) une méthode localeCompare, laquelle est un comparateur interne qui renvoie une valeur signée, en respectant la locale (pour simplifier, disons la langue) active. Celle-ci n’est pas nécessairement celle des données ou même du document, mais en pratique ça marche plutôt bien tout le temps.\n\nAaaah, beaucoup mieux. Comme toujours, rien ne vous empêche d’étendre Array si, comme moi, vous aimez ce genre d’approche :\n\nBons tris à tous !\n",
		"description": "Dans la série « les pièges inattendus de JS », voici `Array#sort`, son côté en-place et son amour de `String`.",
		"date": 1409270400,
		"image": "/assets/images/art-vid/art-js-sort-trap.jpg",
    "_tags": ["js"],
		"title": "Le piège de Array#sort",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/le-piege-de-array-sort/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Si vous en êtes encore à faire du substring(…), à vous galérer à passer des arguments du genre bidule.length - 1, à regretter que pop() et shift() ne sortent qu’un élément, ou à faire à la main des boucles de modification pour des portions de tableau, cet article est pour vous.\nEt sinon, il est pour vous aussi.\n\nSur quoi utiliser slice ?\nSur String et Array. Il a exactement la même sémantique sur les deux, ce qui est pratique : on peut écrire du code générique qui traite indifféremment un tableau classique, ou considère une String comme un tableau de caractères.\nLa signature est donc la même :\n\nLa position de fin est exclue, comme toujours (ex. substring(…)), afin de faciliter les boucles qui utilisent des pivôts (genre on réutilise la fin d’un tour comme début de l’autre, sans chevauchement).\nPar exemple :\n\nVous remarquez qu’on ne risque rien avec les caractères Unicode.\nArguments optionnels\nComme c’était aussi le cas de substring(…), slice(…) n’exige pas son 2ème argument : si celui-ci est omis, il vaut par défaut le length du sujet. En gros, on prend tout jusqu’à la fin :\n\nEn fait, même le premier argument est optionnel, et vaut zéro par défaut. Quel intérêt, puisque ça reprendrait tout le tableau ? On verra ça dans un instant.\nIndices négatifs\nC’est là que slice commence à envoyer du pâté. Saviez-vous qu’on peut utiliser des indices négatifs ? Pour les comprendre, c’est simple : -x correspond à sujet.length - x. Du coup, -1 correspond à la dernière position, -2 à l’avant-dernière, etc.\nImaginons que vous souhaitiez récupérer les deux derniers éléments de massivelyNamedArray :\n\nVous avez un nom de balise sous la main dans tagName et vous voulez en extraire les chevrons, garantis aux bords ?\n\nEn plus, dans le cas présent, ce 1/−1 est bien explicite par rapport au souhait d’origine, vous ne trouvez pas ?\nEn attendant Array.from…\nEn ES6, on aura le plaisir d’avoir enfin un Array.from(…) natif, un adaptateur universel qui prend un truc « genre tableau » (un tableau générique quoi : une propriété .length entière non négative, et des propriétés numériques) pour nous retourner un vrai tableau (une instance de Array).\nUn cas extrêment fréquent aujourd’hui consiste à pouvoir manipuler comme un tableau (en utilisant les méthodes traditionnellement dévolues à Array) l’objet automatique arguments, présent dans le contexte d’invocation de chaque fonction.\nHélas, pour le moment cet objet est de type Arguments au lieu d’être de type Array. C’était une décision débile, mais c’est comme ça. On ne peut donc pas faire, de base, un truc du genre arguments.map(…).\nDu coup, on cherche à obtenir une version Array de notre objet arguments. La manière la plus simple consiste à appeler la méthode slice des tableaux, mais avec arguments comme sujet (comme this, si vous préférez). En effet, toutes les méthodes de Array sont génériques : elles n’ont pas besoin que leur sujet soit véritablement un Array, juste qu’il adhère au contrat des tableaux génériques.\nÇa donne ça :\n\nC’est ici qu’on réalise l’intérêt d’un appel sans aucun argument à slice. Puisque ce dernier renvoit, de façon garantie, une instance de Array, on vient de s’en servir pour convertir un tableau générique en « véritable » tableau.\n(Bien sûr, si le premier argument avait été obligatoire, on aurait juste eu à faire .call(arguments, 0)…)\nsplice, le gros couteau suisse\nLa méthode splice est autrement plus puissante que slice, mais surtout, elle est mutative : elle modifie le tableau en place (alors que slice ne touche jamais au tableau d’origine).\nLa signature peut sembler étrange :\n\nIci, on a :\n\nLa position de départ, obligatoire (vraiment)\nLe nombre d’éléments qui vont être spliced ; donc une quantité, pas une position. On verra tout l’intérêt de ce choix plus tard. Cet argument est obligatoire, sauf dans Firefox, ou s’il est omis, il prend tout le reste du tableau à partir de la position de départ, incluse. Ce n’est toutefois pas présent dans le standard EcmaScript, alors évitez !\nD’éventuels éléments à insérer/remplacer, en lieu et place de ceux qui ont été spliced\n\nGrâce à cette signature apparemment hétéroclite, on peut facilement réaliser, en une fois, avec des performances optimales et moins de risques de bugs que si on se fadait notre propre boucle, n’importe quelle opération de modification.\nEt qui plus est, l’index peut là aussi être négatif !\nRetirer une partie du tableau\nIl suffit de ne préciser aucun élément de remplacement. Voyez plutôt :\n\nNotez que pour le dernier exemple, sur Firefox uniquement, on aurait pu faire names.splice(-2), mais ne prenez pas cette mauvaise habitude…\nRemplacer une partie du tableau\nFacile : on précise simplement les éléments de remplacement. Ils n’ont pas besoin d’être aussi nombreux que ceux remplacés : il peut y en avoir plus, ou moins…\n\nInsérer à un endroit du tableau\nPour insérer dans un tableau, il suffit de ne remplacer aucun élément : on précisera zéro comme deuxième argument, puis les éléments à insérer, en direct (pas s",
		"description": "Deux méthodes de `Array` qui sont bien plus puissantes que leur usage classique, mais à ne pas confondre entre elles.",
		"date": 1410220800,
		"image": "/assets/images/art-vid/art-js-slice-splice.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Les joies de slice et splice",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/slice-et-splice/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Vous croyez connaître Git ? Peut-être bien… Et pourtant, je parierais ma chemise[^1] que pas mal de petites options sympathiques vous sont inconnues.\nEn effet, au fil des versions de Git, beaucoup de petites options font surface, soit pour des raisons de confort, soit pour de la puissance brute. Mais comme ce n’est pas une nouvelle commande, ou pas trop mis en avant dans les annonces de sortie, ça passe sous le radar.\nJe vous ai sélectionné une trentaine d’options, répartie sur une quinzaine de commandes, qui rendent la vie plus belle quand on fait du Git. Voici une excellente manière de rentabiliser les prochaines minutes !\n\n(The English version of this is on Medium)\nJ’indique intentionnellement, le plus souvent, l’option que je vais détailler dans le titre de la section. Cependant, n’en profitez pas pour sauter le texte sous prétexte que vous avez déjà vu l’option : il se peut que je l’utilise sur une commande, ou pour une raison, que vous n’avez pas vue venir ! Et puis, j’ajoute souvent des infos complémentaires sur des options corollaires ou des variables de configuration associées.\nStaging / unstaging partiel avec -p\nVous avez ouvert un fichier pour une raison précise, par exemple passer ce fichu tracker en asynchrone… Et voilà que vous remarquez au passage que des rôles ARIA manquent à certains éléments d’UX, et aussi que le footer est toujours en dur au lieu de dépendre du layout, et que sais-je encore…\nAu moment de faire le commit, vous vous rendez compte que ce fichier contient une bonne demi-douzaine (si ce n’est plus) de modifications qui recouvrent plusieurs sujets bien distincts. À ce moment-là, trois possibilités :\n\nVous faites un bon gros commit fourre-tout dégueulasse, avec un message à base de « + » voire, si vous êtes d’humeur flemmasse, le bon vieux « Correctifs », « Plein de modifs », « Plein de trucs »… C’est gentil de pourrir l’historique comme ça, merci, merci bien.\nVous copiez-collez le fichier quelque part puis enquillez les Undo, si tant est que ça soit possible, pour ne garder ensuite que le premier sujet, committer, puis ré-appliquer le 2ème, committer, puis le 3ème… Tout ça à la main, bien entendu. Probabilité de gaufrage : 99%.\nVous nous lisez ou allez à nos formations, et vous connaissez -p !\n\nLa commande git add -p est en fait un affinage de git add -i : elle pré-sélectionne le mode patch de l’ajout interactif. Dans la pratique, vous indiquez aussi le fichier, pour faire bonne mesure. Par exemple :\n\nJ’en profite pour vous rappeler que git add ne sert pas à mettre sous gestion de version, mais plutôt à stager une modification, c’est-à-dire à la valider pour le prochain commit.\nLorsque vous faites un tel ajout, Git va auto-découper le contenu en hunks, en groupes de modifications, par proximité dans le fichier, en se basant sur les lignes inchangées pour faire sa découpe. Si vos modifs sont trop proches, il sera sans doute tenté de ne pas pré-découper, et vous devrez le faire vous-mêmes avec la commande s (Git vous proposera une pléthore de commandes par leur initiale en bas d’affichage ; dans le doute, utilisez ? pour afficher l’aide), pour split (découper).\nNotez que même si vous avez des modifs adjacentes (sur des lignes qui se suivent immédiatement, sans ligne inchangée pour la découpe), vous pouvez éditer à la volée le hunk pour l’amener à la version que vous voulez stager, en utilisant la commande e (edit) pour ce faire. C’est un peu comme du Photoshop express sur la photo du fichier qui part en stage. En fait, si vous savez d’entrée de jeu que le fichier que vous allez stager contient des modifs adjacentes à retoucher, vous pouvez utiliser -e au lieu de -p pour présélectionner ce mode retouche, mais vous n’aurez alors pas la découpe automatique des hunks pour vous.\nÀ l’issue de l’opération, votre fichier apparaîtra normalement à la fois staged et modified. C’est bien normal, car en effet :\n\nLa dernière version committée n’est pas la même que dans le stage : le fichier est donc staged\nLa version dans le stage n’est pas la même que celle dans le working directory : le fichier est donc modified.\n\nVous pouvez consulter le diff du stage pour ce fichier avec un git diff --staged index.html. Si vous voulez carrément voir le snapshot présent dans le stage, plutôt qu’une série de diffs : git show :0:index.html.\nDu coup, ayez soin de ne pas faire un git commit -a (par exemple git ci -am &quot;Tracker asynchrone&quot;), car ce -a va auto-stager toutes les modifs connues, écrasant au passage le stage « sculpté » que vous aviez mis en place.\nEnfin, peu de gens savent que git reset aussi a une option -p, qui a exactement la même UX que pour add, mais réalise évidemment l’inverse : elle unstage les hunks retenus. On l’utilise souvent pour redécouper le dernier commit effectué, en faisant:\n\nLes modifs qui nous sont alors présentées sont des annulations de celles réalisées par le dernier commit en date. On valide les annulations qu’on veut, on amende le commit (voir plus loin), puis on r",
		"description": "Histoire de faire moins du SVN en Git et plus du vrai Git, une grosse trentaine d’options CLI qui changent la vie avec Git au quotidien.",
		"date": 1410739200,
		"image": "/assets/images/art-vid/art-git-30-cli-options.jpg",
    "_tags": ["tutoriel","git"],
		"title": "30 options de commande Git qui gagnent à être connues",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/30-options-git-qui-gagnent-a-etre-connues/",
		"locale": "fr",
		"readingTime": "16 min"
	},	{
		"content": "Je suis comme vous, je reviens toujours à une petite boîte à outils essentielle, qui m’accompagne de projet en projet, chaque outil ayant maintes fois prouvé sa valeur. C’est notamment le cas pour les petites bibliothèques web front en JavaScript.\nJe me suis dit que ça pouvait vous intéresser de savoir lesquelles j’utilise.\n\njQuery (ou Zepto)\nÉvidemment. Pas trop besoin que je présente jQuery. Ça peut en surprendre certains, vu que je suis à la base un core committer de Prototype.js. Seulement voilà, avec le temps, l’énorme force de frappe de l’équipe (et de l’écosystème) jQuery, combiné à l’apparition d’Underscore (voir plus loin), a eu raison des quelques heures occasionnelles qui restent à Prototype.js (grâce aux vaillants efforts d’Andrew Dupont). On est bien loin de 2008…\nEn revanche, jQuery reste un gros mammouth en raison de ses nombreuses évolutions d’API… et de la compatibilité oldIE. Ceci dit, même jQuery 2, qui envoie péter oldIE, pèse toujours allègrement 241Ko (82Ko minifié, 29Ko gzippé), ce n’est pas rien.\nQuand Underscore est apparu (encore un super projet de Jérémy Ashkenas), les « Prototypistes » qui refusaient de passer à jQuery faute d’outils algorithmiques potables ont trouvé de quoi compenser, et ont pu sauter le pas.\nEn revanche, si je n’ai pas besoin d’IE 9, ou simplement pas besoin de trop de features pointues de jQuery, je m’allège direct en prenant plutôt Zepto, la p’tite lib conçue à la base pour les mobiles, mais désormais beaucoup plus largement compatible, pilotée par Thomas Fuchs (célèbre pour Script.aculo.us et Freckle, entre autres tas de trucs cool).\nÇa ne pèse que 54Ko (9.1Ko gzippé), l’API est compatible avec celle de jQuery (en gros, sauf cas de figure bien pointu, tu n’auras pas une ligne de ton code à changer), et ça défonce grave. J’aime.\nUnderscore\nLes gens l’adorent, et pas que côté Node (il est téléchargé par npm install environ 48 000 fois par jour, quand même)… Elle est par exemple bien connue de JSBin et JSFiddle, entre autres. Underscore est la p’tite lib d’algo et de programmation fonctionnelle toute clean de Jérémy Ashkenas, le jeune dieuhomme qui nous a aussi donné CoffeeScript et Backbone, par exemple.\nUnderscore fournit une implémentation clean, lisible, performante et très bien documentée d’une tonne de petits besoins algos et fonctionnels récurrents. C’est de l’ES3, donc ça tourne absolument partout. Finies, les boucles manuelles, les algos basiques qu’on se recode non-stop pour trier, filtrer, piocher, regrouper, découper… On trouve aussi plein de petites contribs annexes.\nEt en plus, avec deux syntaxes : une qui « fait objet » (_(sujet).method(…)) et l’autre qui reste procédurale (_.method(sujet, …)). Choose your weapons.\nPetites démos vite fait à l’arrache :\n\nQuand on vient de Prototype.js par exemple, qui contient pas mal de choses de ce type-là, jQuery seul nous fait nous sentir tous nus, avec un pauvre silex dans la main. L’arrivée d’Underscore a permis de sauter le pas, en remplaçant certes une lib par deux, mais pour un potentiel nettement supérieur au final.\nSi vous voulez la jouer super hipster et kool-aid drinker, vous pouvez plutôt prendre Lo-Dash, de JDD. Moi non.\nMoment (et Moments-Away)\nL’API Date de JavaScript est une sous-merde copiée-collée du JDK, pour des tas de raisons honteuses qui remontent à mai 1995, quand Netscape et Sun bossaient mains dans poil dans la main pour sortir JavaScript et Java dans le future Netscape Navigator 2.0.\nOn y retrouve les mêmes conneries systématiques : getYear() qui retire bêtement 1900, getMonth() qui démarre à zéro, getDay() qui ne renvoie pas le jour du mois mais celui de la semaine (et getDate() qui renvoie celui du mois)… Bref, la grosse lose.\nEt dès que tu veux formater ou parser une date, c’est un boxon monstre. Surtout quand tu joues avec les fuseaux horaires, ou que tu veux ajouter/retirer des durées variables (en gros, tout ce qui est basé sur des mois).\nSauf que. Sauf que.\nOn a cette petite merveille de Moment.js. Qui tue, qui est super-utilisée, super testée, qui marche partout (base ES3), qui est internationalisée à mort (mais tu peux n’intégrer que les langues qui t’intéressent), qui fait tout et le café.\nMicro-démo de rien du tout :\n\nLa page d’accueil fait une belle petite démo. Pense à choisir “français” un peu plus bas, pour voir ta langue en action. Et va donc jeter un œil aux sections de la doc (menu de droite) pour voir à quel point c’est cool et sympa.\nJ’aime tellement cette petite lib que j’ai même pondu une surcouche qui me donne accès aux syntaxes « façon ActiveSupport » que j’affectionne tant pour calculer des écarts de temps dans le passé ou l’avenir : Moments-Away. Z’allez voir si c’est pas mignon…\n\nBootstrap\nVu que j’utilise beaucoup Bootstrap comme framework CSS (notamment pour les backoffices, mais aussi souvent en frontal visiteur), je recours naturellement à eux pour des trucs comme les dialogues modaux, les popovers et tooltips, les onglets, etc.\nLeur lib intégrée me suff",
		"description": "Florilège de bibliothèques JS (front ou isomorphes) sans lesquelles on aurait bien du mal à bosser.",
		"date": 1411344000,
		"image": "/assets/images/art-vid/art-js-libs.jpg",
    "_tags": ["outil","js"],
		"title": "12 libs JS front que j’utilise tout le temps",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/libs-javascript-front/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Je suis comme vous, je reviens toujours à une petite boîte à outils essentielle, qui m’accompagne de projet en projet, chaque outil ayant maintes fois prouvé sa valeur. C’est notamment le cas pour les modules Node.js.\nJe me suis dit que ça pouvait vous intéresser de savoir lesquels j’utilise.\n\nUtilitaires généraux\nQuelques modules utiles vraiment partout tout le temps.\nunderscore\nQue je soie côté client ou serveur, si je suis en JavaScript, j’ai Underscore sous la main. Ça me simplifie trop l’algorithmique courante.\ndebug\nLorsqu’on souhaite gérer intelligemment ses messages de débogage, une plâtrée de console.debug ou même console.log n’est guère suffisante… Il est préférable de se caler sur les modules noyaux et conventions Node, et d’utiliser un flux de sortie contextualisé et sensible à la variable d’environnement DEBUG (les modules noyaux de Node utilisent NODE_DEBUG).\nOn crée un logger de debug contextualisé comme ceci :\n\nAprès quoi on s’en sert comme d’un appel console.debug, avec les mêmes paramètres, par exemple :\n\nCe qui est important, c’est que cet affichage en console est subordonné à la présence d’une valeur appropriée dans la variable d’environnement DEBUG. Celle-ci peut contenir un nombre quelconque de motifs séparés par des espaces ou virgules. Ces motifs peuvent se terminer par une astérisque (*) pour servir de préfixe uniquement.\n\nRemarquez la coloration (personnalisable à l’aide de codes prédéfinis), au passage, ainsi que les écarts, en millisecondes (ou en affichage complet UTC si la sortie standard n’est pas un TTY), entre les appels.\nÀ présent que la mode est à l’utilisation de modules Node côté client (via des outils comme browserify, par exemple), sachez que debug marche aussi dans les consoles des navigateurs, coloration comprise !\ncolors\nPuisqu’on parle de coloration, lorsqu’il s’agit de balancer des textes en couleurs quelque part (sorties standard ou d’erreur, fichiers texte…) je suis personnellement assez fan de colors. Le simple fait de requérir le module étend String.prototype avec des accesseurs enrobant la chaîne avec les codes VT256 nécessaires. On peut chaîner ces accesseurs, évidemment.\nOutre les couleurs de texte (ex. red, green) et de fond (ex. bgWhite, bgBlue), on trouve les codes habituels d’altération (ex. bold, underline) et même quelques enrobages pour le moins fantaisistes tels que rainbow, america et trap.\n\n\nUn autre module est encore plus populaire : chalk. Certes, il est très puissant, mais la plupart du temps je n’ai pas besoin de ses avantages, et l’approche de colors me parle davantage. Après, chacun ses goûts (et ses besoins)…\nmkdirp, rimraf et cpr\nL’API du module noyau fs laisse à désirer dès qu’on souhaite travailler récursivement : les opérations mkdir, unlink et copy, notamment, ne prévoient pas ce cas. Évidemment, npm a très vite vu apparaître des modules qui prennent ça en charge.\nC’est pratique quand on n’a par ailleurs aucun besoin riche sur les I/O et le filesystem, mais si vous utilisez par ailleurs une merveille comme q-io/fs (voir plus bas), vous aurez déjà accès à l’équivalent, en version basée promesses qui plus est, ce qui est toujours mieux.\nPromesses, I/O et flux\nLes promesses, c’est le bien. Et les I/O comme les flux méritent souvent une surcouche à leur API native.\nrsvp\nJe suis un fan absolu des promesses (et vous devriez, vous aussi). Il existe un bon paquet de modules sur npm pour travailler avec, notamment q, rsvp et bluebird.\nEn théorie, ce dernier est le plus rapide, mais on parle ici de différences extrêmements faibles, et tant que je n’aurai pas besoin de tenir la charge de PayPal ou Walmart, ça ne m’inquiète pas plus que ça.\nEn revanche, j’ai l’œil fixé sur ES6, qui a nativement les promesses, avec son type Promise. Et il se trouve que dans cette optique, rsvp m’intéresse parce que, de tous les modules de promesses, il est celui dont l’API colle au plus près à celle d’ES6. En fait, quand je suis en ES6, tout ce que j’ai à faire c’est de retirer cette ligne en haut de mon code :\n\nÉvidemment, ce côté future-proof m’intéresse. Et les performances restent excellentes. Et puis de toutes façons, comme tous ces modules collent à la spec Promises/A+, ils sont interopérables dans la joie (entre eux, mais aussi avec les promesses natives ES6, évidemment), ce qui est juste parfait.\nÉnormément de gens traitent leurs besoins de workflows asynchrones avec async, et ce module est certes intéressant et sympathique, mais pratiquement tous ces besoins sont couverts, et de façon infiniment plus lisible et maintenable, à coup de promesses…\nq-io\nDès qu’on a goûté aux promesses, on ne peut plus s’en passer, et on veut notamment s’en servir dès qu’on fait de l’I/O. Ça concerne notamment :\n\nL’accès au système de fichiers (ce qu’on ferait normalement par le module noyau fs)\nLes sockets (modules noyaux net et http, notamment)\n\nLes modules noyaux, et de nombreux modules tiers, restent sur une approche à base de callbacks Node, c’est à dire des fonctions de r",
		"description": "Pour faire suite à notre liste front/iso, voici un paquet de modules Node qui nous semblent incontournables.",
		"date": 1414022400,
		"image": "/assets/images/art-vid/art-node-modules.jpg",
    "_tags": ["outil","node","js"],
		"title": "26 modules Node.js que j’utilise tout le temps",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/libs-node-js/",
		"locale": "fr",
		"readingTime": "16 min"
	},	{
		"content": "(English version of this article here)\nIl vous est sûrement déjà arriver d’arbitrer un conflit quelque part dans votre dépôt, pour retomber sur exactement le même plus loin (à l’occasion d’un autre merge, par exemple). Et hop, il a fallu refaire l’arbitrage.\nC’est nul.\nPourtant, Git est tellement gentil qu’il offre un mécanisme pour vous éviter ça, au moins une partie du temps : rerere. D’accord, le nom n’est pas terrible, mais ça veut quand même dire Reuse Recorded Resolution, hein…\nDans cette article, on va explorer ensemble comment ça marche, quelles en sont les limites, et comment s’en servir au mieux.\n\nLe souci classique : les merges de contrôle\nUne situation qui bénéficie particulièrement de rerere, ce sont les merges de contrôle.\nVous avez une branche qui dure, ou va durer, assez longtemps ; par exemple, une branche fonctionnelle lourde. Appelons-là long-lived. Et naturellement, plus le temps passe, plus vous angoissez à l’idée de la fusion qui intègrera, à terme, cette branche dans la principale (généralement master), car au fur et à mesure, la divergence avec celle-ci s’épaissit…\nDu coup, pour alléger la tension et faciliter l’intégration à terme, vous décidez de procéder de temps à autre à un merge de contrôle : un merge de master dans votre branche, qui sans polluer master va vous permettre de savoir « où vous en êtes » en termes de conflits potentiels.\nC’est en effet pratique, et histoire de ne pas avoir à vous farcir les mêmes conflits à l’avenir, vous serez sans doute tentés de laisser le merge de contrôle une fois achevé, plutôt que de procéder, par exemple, à un git reset --hard ORIG_HEAD pour le retirer de l’historique (et du graphe).\nDu coup, au fil du temps, vous obtenez ce qu’on appelle un graphe en nervures ou en feuille d’arbre :\n\nC’est assez moche et ça pollue le graphe de vos branches. Après tout, normalement un merge ne doit survenir dans le graphe que pour intégrer une branche finalisée.\nMais si vous annulez le merge une fois celui-ci bouclé, vous allez devoir vous re-farcir ses arbitrages au prochain contrôle. Alors comment faire ?\nrerere à la rescousse\nC’est justement le rôle de rerere. Cette fonctionnalité de Git prend une empreinte de chaque conflit lorsqu’il survient, et prend une seconde empreinte pour votre arbitrage (résolution) du conflit lorsque le commit problématique est finalisé.\nPar la suite, si la même empreinte de conflit survient, rerere auto-résoudra celui-ci grâce à l’empreinte de résolution associée.\nActiver rerere\nrerere n’est pas seulement une commande, mais un comportement transverse de Git. Pour qu’il soit actif, il faut qu’au moins une des deux conditions suivantes soit remplie :\n\nLa configuration en vigueur indique rerere.enabled à true\nLe dépôt contient un référentiel rerere (le dossier .git/rr-cache existe)\n\nJe ne vois pas de cas où disposer de rerere est une mauvaise idée, aussi je vous invite à définir tout de suite ça en configuration globale :\n\nApparition d’un conflit\nImaginons maintenant que nous avons une divergence porteuse de conflits, par exemple master a fait évoluer le &lt;title&gt; de notre index.html d’une certaine façon, tandis que long-lived l’a modifié différemment.\nTentons un merge de contrôle :\n\n\nÇa ressemble à un conflit classique, mais notez bien l’avant-dernière ligne :\n\nRecorded preimage for ‘index.html’\n\nC’est elle qui nous indique que rerere a mémorisé l’empreinte du conflit. Et de fait, si on lui demande de quels fichiers il se préoccupe sur ce coup, il nous le dira :\n\nSi on examine notre dépôt, on trouve en effet une empreinte :\n\nCe fichier preimage contient en fait l’empreinte complète du fichier et de son conflit (le blob intégral, quoi).\nEnregistrer la résolution\nOK, arbitrons le conflit. Par exemple, je vais mettre un &lt;title&gt; combiné :\n\nJe peux alors vérifier la résolution que rerere va retenir une fois mon merge terminé :\n\nJe peux alors marquer ma résolution de la façon habituelle, avec git add. Après quoi git rerere remaining m’indiquera la liste des fichiers qu’il suit et que je n’ai pas encore résolus (en l’occurrence, aucun).\nEn tous les cas, pour que rerere prenne effectivement l’empreinte, je dois finaliser le commit en cours. Puisque je suis sur un merge, il m’appartient d’exécuter le commit manuellement :\n\nRemarquez bien la ligne :\n\nRecorded resolution for ‘index.html’.\n\nEt de fait, le snapshot du fichier est désormais présent en postimage dans le référentiel :\n\nJe peux donc me permettre d’annuler ce merge de contrôle, que je ne souhaite pas laisser dans mon graphe :\n\nRéapparition du conflit\nSupposons à présent que tant long-lived que master continuent à évoluer. Par exemple, dans la première, une CSS fait son apparition. Dans la seconde, la même CSS débarque (mais différente), ainsi qu’un fichier JS.\nArrive le moment où un nouveau merge de contrôle semble nécessaire. C’est reparti :\n\nOn a donc un conflit d’ajout simultané (add/add) pour la CSS, et le conflit déjà connu sur index.html. Mais regardez bien vers ",
		"description": "Fini, l’arbitrage manuel du même conflit à répétition : faites en sorte que Git s’en souvienne et rejoue vos arbitrages tout seul !",
		"date": 1415059200,
		"image": "/assets/images/art-vid/art-git-rerere.jpg",
    "_tags": ["tutoriel","git"],
		"title": "N’arbitrez vos conflits Git qu’une fois grâce à rerere",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-rerere/",
		"locale": "fr",
		"readingTime": "8 min"
	},	{
		"content": "On me demande souvent, en formation comme ailleurs, comment je fais ma veille technique côté JS / Web / Node. En particulier pour tomber sur des ressources de qualité, idéalement en français, mais en anglais à défaut, évidemment.\nJ’ai fini par publier un Gist sur le sujet, mais je me suis dit que ça méritait plus de détails, aussi voici un petit article dédié.\n\nLa veille pourquoi ?\nQuand on parle de veille, on parle essentiellement de se tenir au courant de ce qui arrive, ce qui sort, des tendances, bref, de notre « radar technologique ». Mais pour moi, il s’agit aussi de trouver les bonnes ressources lorsqu’on décide de sauter le pas et d’apprendre une techno bien particulière.\nEn tous les cas, il s’agit d’une compétence essentielle pour un développeur soucieux de son évolution professionnelle. Dans ce métier, on a des changements tous les jours, et nos générations techniques sont d’à peine 2 ans. Les meilleures pratiques évoluent sans cesse et les métiers se redéfinissent en permanence.\nMême si le champ de compétences nécessaire à du dev front est de plus en plus large, ce qui sert à justifier une hyper-spécialisation des métiers (genre expert web front responsive, expert web mobile, expert offline web, expert Compass, expert Angular…), je suis toujours très méfiant de cette approche en silos.\nJ’ai entendu dire que chez Air France par exemple, ils séparent nettement la veille (des gens qui ne font que ça) de la prod (des gens qui n’ont pas le droit de faire de la veille) et je trouve ça atroce. La veille est dangereuse si elle n’est pas informée par la prod : elle va s’enthousiasmer pour des conneries et louper le coche deux fois sur trois, minimum. À l’inverse, quelqu’un qui ne fait que de la prod est traité comme un ouvrier spécialisé du web, pas comme un artisan, et donc dévalorisé : son métier devient alimentaire, sa motivation chute, et le turnover augmente, tout comme le burnout.\nPeut-être n’avez-vous qu’une ou deux heures par mois à consacrer à la veille ; peut-être y consacrez-vous trop de temps, c’est-à-dire plus que ce que vous pouvez raisonnablement libérer par rapport à vos contraintes de production. L’important, c’est d’en faire. Pour rester curieux, pour évoluer, pour sortir de sa zone de confort, pour se sentir mieux !\nSe tenir au courant\nJe me tiens au courant de ce qui débarque, ou va débarquer, principalement au travers de deux canaux : les newsletters et Twitter.\nNewsletters\nCooper Press, une des boîtes de Peter Cooper, édite et maintient une série régulièrement étendue de newsletters hebdomadaires (le jour de livraison varie du lundi au vendredi suivant la newsletter) sur plein de sujets :\n\nJavaScript Weekly pour JS back et front\nFrontend Focus pour le web front\nReact Status pour tout ce qui touche à React\nRuby Weekly\nPostgres Weekly et, plus généralement, DB Weekly\n\n(Liste MISE À JOUR janvier 2018)\nOn y trouve quelques focus, des offres d’emploi, et toute une série de liens vers des articles, tutos et vidéos qui ont attiré leur attention durant les 7 jours écoulés.\nNaturellement, il y a une certaine mesure de recoupement entre certaines newsletters, mais je ne trouve pas ça gênant à l’usage. Je suis abonné à toutes celles que je vous ai citées ici, et ça reste agréable.\nTwitter\nJe me limite à 42 follows à tout instant, ce qui me force à des choix draconiens. Mais je vous conseille notamment :\n\nJake Archibald (@jaffathecake), Dev Evangelist chez Google, pour un humour ravageur et tout ce qui touche à l’offline : AppCache, ServiceWorker, et j’en passe ;\nUmar Hansa (@umaar) pour des astuces Chrome DevTools qui m’apprennent souvent quelque chose ;\nJérémie Patonnier (@JeremiePat) pour tout ce qui touche à la typographie, à SVG et à Mozilla ;\nes-discuss summaries (@esdiscuss) pour suivre l’évolution d’ES6, ES7, ES8… ;\nRemy Sharp (@rem), gourou CSS, auteur de JSBin et organisateur de Full Frontal, pour tomber sur des problématiques JS et CSS de fou ;\nPaul Irish (@paul_irish), Dev Evangelist chez Google, pour des astuces de tarés sur les Chrome DevTools et l’outillage front-end de façon générale ;\nRey Bango (@reybango), Dev Advocate chez Microsoft, pour les nouveaux trucs cools que sort MS côté dev web (comme par exemple, tout récemment, RemoteIE) ;\nJan Lenhardt (@janl), gros boss CouchDB et Hoodie, créateur de Mustache, co-organisateur de JSConf.EU, pour tout ce qui touche à ces projets et pour avoir un peu de gender diversity awareness dans votre timeline aussi ;\nChristian Heilmann (@codepo8), Dev Evangelist chez Mozilla, pour une tonne métrique de liens intéressants tous les jours.\n\nWeb Platform Daily\nDes gens bien se font ch… à agréger en un seul endroit tout un gros paquet de veille, tous les jours, en repérant les tendances, etc. C’est assez top et ça s’appelle Web Platform Daily.\nChaînes YouTube et vidéos de conférences\nGoogle maintient via ses comptes Google Chrome Developers et Google Developers une énorme série de vidéos didactices sans cesse actualisée, plus toutes les sessions de ",
		"description": "Pourquoi consacrer du temps à la veille, et comment la faire efficacement ?",
		"date": 1415145600,
		"image": "/assets/images/art-vid/art-tech-survey.jpg",
    "_tags": [],
		"title": "Ressources pour une veille technologique web front de qualité",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/veille-techno-utile/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Ce brave constructeur natif Date est honteusement issu d’un portage quasi ligne à ligne du java.util.Date de Java 1.0, aux petites heures de la nuit un soir de mai 1995. Et il se trimballe exactement les mêmes bugs et aberrations.\nPour ne pas se faire avoir, ou juste pour le plaisir d’en rire, petit tour des subtilités à ne pas oublier.\n\nA première vue tout va bien…\nOn peut créer une Date de tout un tas de façons :\n\nTout ça est dans le fuseau horaire (timezone) du navigateur (donc celui de l’OS, en général), à part le format RFC2822, qui peut préciser son fuseau. Si tu as des composantes UTC sous le coude, tu peux obtenir une epoch et l’utiliser pour construire un Date :\n\nPour rappel, l’UTC est désormais préféré au GMT, car il prend en compte les secondes bisextiles, et il est beaucoup plus précisément défini que GMT, qui remonte au XIXe siècle.\nPour récupérer les parties horaires, c’est tout tranquillou :\n\nTous ces accesseurs peuvent aussi être appelés avec UTC après le get, pour obtenir la valeur UTC de la composante (par exemple, getUTCHours() donnera ici 13).\nOn a aussi la conversion d’une Date vers sa valeur numérique, son epoch :\n\nIl s’agit d’ailleurs du protocole de conversion numérique officiel pour Date (la conversion d’un Date en Number, par exemple +d ou Number(d), appelle en fait getTime()).\nIl est aussi possible de récupérer directement l’epoch actuelle, sans créer un objet Date, depuis ES5 :\n\nAvant ES5, il fallait passer par un objet, en faisant new Date().getTime() par exemple.\nEnfin, on a des conversions String prédéfinies, certaines seulement depuis ES5 :\n\nOn peut aussi demander des formats plus adaptés à la langue active, en rajoutant Locale après le to. Par exemple, pour la totale en français :\n\nMais attention ça glisse\n\nEt là tu te dis…\n\nJe sais. Je sais. Un bon gros bordel.\nLOLWUT?\nEh oui, tout ça peut être tracé jusqu’à la libc, notamment time.h, pour l’histoire des mois qui démarrent à zéro :\nExternal declarations, as well as the tm structure definition, are contained in the\n&lt;time.h&gt; include file.  The tm structure includes at least the following fields:\n\n    int tm_sec;     /* seconds (0 - 60) */\n    int tm_min;     /* minutes (0 - 59) */\n    int tm_hour;    /* hours (0 - 23) */\n    int tm_mday;    /* day of month (1 - 31) */\n    int tm_mon;     /* month of year (0 - 11) */\n    int tm_year;    /* year - 1900 */\n    int tm_wday;    /* day of week (Sunday = 0) */\n\nLe JDK n’ayant pas pris la peine de compenser ces conneries (bien qu’il ait choisi de ne pas retranscrire la seconde intercalaire à 60), on retrouve les mêmes blagues.\nJe vous vois déjà venir, vous qui me ressortirez l’argument éculé « si mais partir de zéro c’est pratique pour les pointeurs et les tableaux ! », argument aussi ancien que spécieux, puisque le choix du zéro était juste pratique pour une certaine architecture matérielle et n’est pas sans défauts, il fait d’ailleurs toujours débat, comme par exemple dans cet article.\nLa vérité, c’est qu’aucun système humain au monde ne numérote janvier à zéro. Personne. Nulle part. Ça fait juste chier tout le monde, ce mois à zéro, c’est tout là haut dans le Panthéon des Décisions Techniques Pourries™, juste au même niveau que ces crétins d’itérateurs jQuery qui collent l’index avant la valeur dans leurs arguments de rappel.\nD’autant que les mois qui démarrent à zéro alors que les jours non, c’est parfaitement incohérent.\nNotez également la merveilleuse définition de l’année « moins 1900 », le truc hyper résistant dans l’avenir (future-proof) une fois qu’on atteint l’an 2000. Soit les mecs avaient une foi immodérée dans la vitesse du progrès info et l’obsolescence du code (ha ! dites ça aux COBOListes en 2014 !), soit ils croyaient que Terminator c’était vrai et qu’on allait tous crever avant, je sais pas. En tous les cas pour avoir la vraie année, il faut getFullYear() (qui devrait plutôt s’appeller getUnfuckedYear(), mais c’est plus long).\nEt puis year % 100 c’était trop hacker pour eux, en fait, pour obtenir l’année sur 2 chiffres de façon fiable.\nQuant aux accesseurs écrivains (setters, genre setHours(…)), il acceptent juste n’importe quoi et font du rollover sur les unités supérieures, pas très fiable d’ailleurs. Ça touche d’ailleurs toute forme de création de Date, que ce soit new Date ou Date.UTC :\n\nPaye ton #facepalm. Le JDK a d’ailleurs déprécié les accesseurs écrivains depuis 15 ans, je serais vous, j’éviterais de m’en servir.\nLà où tu peux pas pardonner au JDK, c’est d’avoir décrété que day était le wday, le jour de la semaine, plutôt que le jour du mois. Même si les Britanniques réfèrent parfois au jour du mois sous le nom date (d’où ici le getDate() pour le jour du mois, super logique quand tu l’appelles sur un type Date), tous les anglophones sur cette planète se réfèrent aux composantes de la date sous les noms day, month, year.\nEncore un point pour les obfuscateurs. C’est vrai, une API qui passe sa vie à tendre des pièges, ça crée de l’emploi. Demandez donc ",
		"description": "Les moments WTF de JS sont de retour avec son constructeur natif `Date`, qui a tous les mêmes bugs que son homologue Java, hélas…",
		"date": 1416960000,
		"image": "/assets/images/art-vid/art-js-date-lol.jpg",
    "_tags": ["js"],
		"title": "Le type Date en JS : LOLWUT?!",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-date-lolwut/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "(English version of this article here)\nLes branches, c’est formidable. Ça permet d’avoir des versions complètement différentes d’un même fichier selon le contexte.\nSeulement voilà, dans certains cas rares, il arrive que vous souhaitiez versionner un fichier, qui change de branche à branche, mais le préserver quand vous fusionnez une branche vers la vôtre.\nLe cas classique, ce sont les fichiers non-sensibles mais dépendants de l’environnement d’exécution (développement, staging, production), parce qu’ils indiquent des URLs, domaines ou numéros de port qui varient suivant le contexte :\n\nconfiguration d’envoi e-mail qui utiliserait une gestion locale hors production (par exemple l’excellent mailcatcher)\nconfiguration de logs qui serait en fichiers locaux en dev, mais consolidée vers un service central autrement\netc.\n\nCe genre de fichiers gagne à être versionné, naturellement. Mais lorsqu’on fusionne une branche vers la nôtre (par exemple, on récupère master pour faire un [merge de contrôle](/fr/articles/git-rerere/#le-souci classique : les merges de contrôle)), comment garder notre version à nous juste pour ceux-là, sans avoir à faire à chaque fois des manips spéciales ?\nC’est tout simple, en fait. Voyons ça.\n\nPour conserver notre propre version d’un fichier lors d’une fusion (forcément entrante : git merge fusionne vers la branche courante), on fait appel à une fonction peu connue de Git (mais qu’on explore le 3ème jour de Git Total, naturellement) : les attributs Git.\nLes attributs Git\nCe mécanisme permet d’associer à des fichiers ou dossiers (on utilise en fait des schémas de glob, tels que secure/* ou *.svg) des propriétés techniques particulières.\nCes informations sont généralement versionnées, comme celles du .gitignore, mais sont stockées dans .gitattributes (et tout comme .gitignore a un équivalent strictement local dans .git/info/exclude, on a .git/info/attributes).\nLe format est simple : chaque ligne qui n’est ni vide ni un commentaire (démarre par #) est au format schema-de-glob info-attribut (le nombre d’espaces n’ayant aucune importance).\nUn attribut peut être activé (présent sans valeur spécifique), désactivé (présent mais négatif), valué (défini avec une valeur précise) ou absent. Dans ce qui nous intéresse ici, on utilisera un attribut valué.\nOutre qu’on peut créer nos propres attributs à des fins de scripting personnalisé, ou regrouper des combos classiques en meta-attributs, Git fournit de nombreux attributs prédéfinis qui font des trucs de dingue…\nPilotes de fusion[^1]\nCelui qui nous intéresse ici est l’attribut merge, qui permet de définir un pilote de fusion (merge driver), c’est-à-dire une commande qui va décider comment procéder à la fusion d’un fichier précis.\nCet attribut a généralement une valeur automatique en fonction de la nature détectée du fichier : on utilisera normalement le pilote text pour des fichiers textuels, binary pour les autres.\nIl est toutefois possible de construire son propre pilote (on le définit dans la configuration classique de Git, par exemple notre .gitconfig) pour l’associer par attributs à certains fichiers, auquel Git passera jusqu’à 3 arguments, dans l’ordre qu’on veut : la version d’origine du fichier (ancêtre commun), la nôtre, et celle d’en face (la branche qu’on fusionne).\nLa clé du truc, c’est qu’un tel pilote est censé déposer son résultat dans notre propre fichier à l’issue d’un traitement réussi (code de retour zéro). Du coup, un pilote qui ne touche pas aux fichiers et renvoie zéro laisse notre fichier local tranquille lors de la fusion.\nEureka !\nOn n’a même pas besoin d’écrire un script vide ou qui ferait juste exit 0, car tout environnement Bash/zsh/etc. a déjà une telle commande, qui est souvent un builtin du shell : true. Utilisons-la donc.\nMise en place\nCommençons par définir un pilote de fusion qui privilégierait toujours notre propre version d’un fichier, en reposant sur la commande existante true. Appelons-le ours, pour être dans l’esprit des stratégies de fusion similaires :\n\nSi vous avez déjà un dépôt Git pour tester, pas de souci, pourrissons-le (?!). Sinon, on s’en fait un p’tit vite fait :\n\nÀ présent, ajoutons un fichier .gitattributes à la racine de notre dépôt, qui dirait que notre fichiers email.json exploite ce pilote plutôt que celui standard :\n\nEt voilà, on est prêts !\nPréparation d’une démo\nMettons-nous en situation de test, avec d’abord un fichier qui va bouger des deux côtés :\n\nPuis faisons une branche demo-prod et mettons-y du taf mixte :\n\nEnfin, revenons sur notre branche précédente, et ajoutons du taf mixte :\n\nC’est parti !\nOK, nous sommes prêts à tester. Si on tente de fusionner notre branche actuelle dans demo-prod, on devrait fusionner normalement demo-shared (qui ne devrait pas avoir de conflit), mais conserver la version de production de email.json :\n\nVictoire ! \\o/\nMerci à Scott Chacon qui, dans le chapitre dédié aux attributs de son livre Pro Git, décrit cette astuce ; et à Julien Hedoux, qui en me posant la questio",
		"description": "Savais-tu que lors d’une fusion entrante, tu peux demander à Git de préserver ta version courante de certains fichiers ?",
		"date": 1417132800,
		"image": "/assets/images/art-vid/art-git-merge-preserve.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Préserver certains fichiers au merge",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/preserver-certains-fichiers-au-merge/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Ouh, le vilain bug que vous venez de remarquer ! Hélas, impossible de repérer tout de suite son origine dans le code, et apparemment il ne date pas d’hier… Comment faire pour éviter de devoir repasser tout l’historique au peigne fin ?\nDans cet article, nous allons voir comment Git nous assiste pour isoler au plus vite l’origine d’un bug, même très loin en arrière dans l’historique.\n\n(English version of this article here)\nLa bonne façon de parcourir un historique\nUn historique, c’est une liste triée. Le critère de tri ? Le temps ! Les commits partent du plus ancien vers le plus récent, même s’ils peuvent bifurquer puis se rejoindre au fil du graphe des branches et des fusions.\nLorsqu’on cherche quelque chose au sein d’une liste triée, il serait dommage de simplement commencer au début pour avancer vers la fin… Vous avez probablement déjà joué au jeu du « plus petit, plus grand » : vous devez trouver un nombre entre 1 et 100, par exemple. Dans un tel cas, je m’inquièterais pour une personne qui commencerait à 1, ou vers 100, pour ensuite piocher au hasard. Instinctivement, la plupart des gens commencent au milieu, à 50, et si on leur répond « plus petit », piochent ensuite au milieu du sous-ensemble ainsi défini, donc à 25, etc.\nCe type d’algorithme porte un nom : c’est une dichotomie (parfois appelée recherche dichotomique). Il permet de trouver ce qu’on cherche au maximum en [log2(n)] coups, soit pour un ensemble [1, 100], au maximum en 7 coups. C’est encore bien plus impressionnant lorsqu’on étend l’intervalle de façon significative : pour [1, 1 000 000 000], il ne faudrait au pire que 27 coups ! Un sérieux gain de temps…\nIl est possible d’appliquer ce principe à la recherche du premier commit qui, dans un historique de commits (c’est-à-dire une liste temporellement ordonnée de commits), a introduit un bug.\nEn anglais, cet algorithme se nomme binary search, mais c’est son exploitation mathématique, nommée bisection, qui a donné son nom à la commande git bisect.\nMéthodologie\nLa commande git bisect exploite toute une série de sous-commandes.\n\nOn démarre avec un git bisect start. Il est possible de préciser d’entrée de jeu un commit foireux (généralement le HEAD et un autre qui est bon), sinon on les indiquera ensuite :\nUn git bisect bad identifie le premier commit problématique connu (si on n’ajoute rien, c’est le HEAD, ce qui est normalement le cas)\nUn git bisect good identifie un commit qui n’avait pas le problème (le plus proche possible de nous, mais au pire on ira le chercher loin pour ne pas galérer)\nÀ partir de là, la dichotomie commence : Git fait un checkout au milieu (ou à peu près) de l’intervalle, nous dit où on en est, et demande le verdict : suivant le cas, on répondra par un git bisect bad ou git bisect good (plus rarement, git bisect skip).\nAu bout d’un moment, si on n’a pas répondu n’importe quoi ni laissé trop de cas indéterminés, Git nous indiquera le premier commit fautif.\nOn pourra alors abandonner le bisecting avec un git bisect reset.\n\nPratiquons ensemble\nAfin de pratiquer, nous allons utiliser un dépôt que je vous ai préparé aux p’tits oignons, avec des tas de messages de commit bien lourdaux et quatre contributeurs que vous allez sans doute reconnaître…\nTélécharger le dépôt d’exemple\n\nDécompressez-le où bon vous semble ; il crée un dossier bisect-demo dans lequel vous n’avez plus qu’à ouvrir une ligne de commande (sous Windows, préférez le Git Bash). Ce dépôt contient plus de 1 000 commits répartis sur environ un an et, quelque part là-dedans, un bug s’est glissé.\nEn effet, si vous exécutez ./demo.sh, il affiche un KO tout penaud. Alors qu’il devrait afficher glorieusement OK. Ce souci remonte à assez loin, et nous allons utiliser git bisect pour le débusquer.\nIci on n’a aucune idée du dernier commit valable, alors on va prendre le commit initial, d7ffe6a. Vérifions que demo.sh y a une bonne tête :\n\nEn effet, ça devrait aller…\nArmés de cette information, nous pouvons donc démarrer le bisecting :\n\nNotez qu’on pouvait aussi lancer la procédure en une seule commande :\n\nÀ partir de là, nous n’avons plus qu’à tester à chaque fois, et répondre par good ou bad :\n\nRemarquez l’affichage final :\n\nEt de fait, le listing qui suit fait bien état d’une modification à demo.sh.\nIci, si nous en croyons notre prompt, nous sommes en effet sur bisect/bad, donc sur le commit fautif. Ça n’avait rien d’obligatoire, ça dépend entièrement du cheminement de la dichotomie, car une fois le fautif identifié, bisect ne fait pas automatiquement de checkout dessus.\nDe toutes façons, un git show 465194a nous montre que c’est bien là que le problème est survenu :\n\nN’oublions pas d’arrêter le bisecting pour revenir à notre HEAD original, avec un git bisect reset :\n\nEt voilà, alors que le commit fautif était 881 positions en amont, il ne nous aura fallu que 10 tests successifs pour l’isoler ! Même quand le protocole de test est rapide, comme ici, on gagne beaucoup de temps. Imaginez quand le test est plus lent (compila",
		"description": "Tu peux passer des jours à chercher à la main, et mal, l’origine d’un bug dans une boîte noire.  Ou tu peux automatiser tout ça avec `bisect`.",
		"date": 1418083200,
		"image": "/assets/images/art-vid/art-git-bisect.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Git Bisect : débusquer rapidement l'origine d'un bug",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-bisect/",
		"locale": "fr",
		"readingTime": "9 min"
	},	{
		"content": "Entre les formations, la veille et les contributions open-source, j’ai l’occasion d’examiner énormément de code JavaScript écrit par des tiers. Je suis peut-être un intégriste sur la qualité et la lisibilité du code, mais j’y trouve souvent les mêmes défauts.\nPeut-être votre code est-il, lui aussi, coupable de certains d’entre eux ? Dans cet article, nous allons passer en revue les usual suspects et donner des pistes d’amélioration pour chacun.\n\nGlobales en pagaille\nFaute d’enrobage dans un module (qu’il s’agisse d’un module formel, type CommonJD, AMD ou ES6, ou d’une simple IIFE), votre script pollue l’espace de noms global avec tout plein d’identifiants, et pas que ceux que vous aviez volontairement exposés.\nIl y a entre 500 et 1 000 identifiants globaux dans votre navigateur, suivant le type et la version de celui-ci, inutile d’en rajouter, les gens…\nPour éviter ça, utilisez des modules, ou a minima enrobez votre code dans une Immediately-Invoked Function Expression (IIFE) et n’exposez que le strict nécessaire (souvent rien) :\n\nEt surtout, n’oubliez pas les var pour déclarer vos variables. Sans quoi, fuite de global (mais le mode strict, tout comme les linters de type JSHint, vont vous gronder si vous en oubliez).\nIdentifiants flemmards\nCe n’est pas parce qu’on n’a pas toujours une complétion haut de gamme pour JavaScript qu’il faut retomber sur des identifiants pourris genre i, j, k, xs, gpco et que sais-je encore…\nMême avec un éditeur lambda, on a au moins la complétion sur les identifiants du fichier. Et la plupart des éditeurs ont du multi-curseur ou du Local Rename. Préférez donc, par exemple, index, column, row, positions, getParentContainerOffset…\nVotre code sera lu bien plus souvent qu’il sera écrit. La lisibilité des identifiants est indispensable pour une maintenabilité correcte.\nBlocs / callbacks imbriqués trop profond\nTrop de développeurs oublient l’intérêt des court-circuits de type return, break et continue, et imbriquent les blocs jusqu’à plus soif :\n\nJe vous conseille de configurer votre JSHint avec &quot;maxdepth&quot;: 3 pour vous faire asticoter quand vous tombez dans ce genre de travers.\nPar exemple, le code précédent peut être réécrit comme ceci :\n\nSi malgré tous vos efforts, vous avez encore plus de 3 niveaux d’imbrication, c’est sans doute un signe que votre fonction fait trop de choses, et qu’elle devrait être découpée en sous-fonctions.\nOn retrouve un principe similaire avec le callback hell, également connu sous le nom de Pyramid of Doom :\n\nIl existe de nombreuses manières de résoudre ce genre de problèmes. Suivant le contexte et les usages souhaités, on peut passer par une bibliothèque comme Async, recourir aux promesses, ou simplement découper en sous-fonctions déclarées localement, ce qui a l’avantage supplémentaire de les nommer, améliorant ainsi les stack traces au débogage :\n\nLes déclarations de fonctions étant hoisted (interprétées avant tout le reste de la portée), on peut appeler une fonction « avant » sa déclaration locale, ce qui permet de dérouler l’algo principal avant les sous-fonctions, ou simplement de refléter le déroulé du code « de haut en bas ».\nSi certaines fonctions ont besoin d’infos acquises aux niveaux d’appel précédents, il suffit par exemple de stocker ces infos dans la closure principale. Par exemple :\n\nFonctions anonymes non triviales\nLa plupart des développeurs ne nomment pas leurs fonctions de rappel (gestionnaires d’événements, timers, etc.), y compris quand celles-ci contiennent du code non trivial (ou appellent des fonctions non triviales).\nPour rappel, le nom d’une fonction, accessible via sa propriété name, est ce qui apparaît entre function et (. Du coup, function( crée une fonction anonyme.\nLes dernières versions d’ECMAScript font évoluer la définition automatique du nom pour prendre en compte toute une série de contextes lexicaux (propriété d’objet, affectation à une variable, etc.) et réduire le nombre d’anonymes de façon organique. Les navigateurs modernes tentent des approches similaires. Mais outre que ce n’est pas garanti sur tous les navigateurs à prendre en charge, ça ne couvre pas le cas classique de la fonction anonyme de rappel :\n\nDu coup, prenez l’habitude de nommer intelligemment vos expressions de fonctions.\nC’est également pratique pour contextualiser immédiatement des fonctions associées à des propriétés standardisées, notamment dans la surcharge de fonctions héritées, par exemple dans un contexte MVC. Dans le code suivant :\n\n…même dans Chrome, dont la runtime V8 tente de nommer automatiquement les fonctions que vous avez définies, ça donnera au mieux des noms générés du genre Backbone.View.extend.afterRender. Pas terrible, car ça sera pareil pour toutes nos sous-classes de Backbone.View (et puis ce segment .extend, c’est du bruit).\nIl nous suffit de les nommer correctement pour avoir directement un nom pertinent dans les piles d’appel :\n\nSignatures à rallonge\nJe pleure toujours des larmes de sang en regardant la signature de",
		"description": "C’est toujours les mêmes horreurs dans le code JS qu’on rencontre.  Quelques anti-patterns classiques et leurs solutions.",
		"date": 1419552000,
		"image": "/assets/images/art-vid/art-js-clusterfucks.jpg",
    "_tags": ["js"],
		"title": "14 trucs !@# dans votre JS",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/clusterfucks/",
		"locale": "fr",
		"readingTime": "10 min"
	},	{
		"content": "Si vous avez déjà utilisé les submodules, vous en êtes certainement revenus avec quelques cicatrices, en jurant (mais un peu tard) qu’on ne vous y reprendrait plus… Les submodules ont en effet l’art de nous faire nous arracher les cheveux, avec leurs pièges omniprésents à la moindre manipulation. Pourtant, ils ne sont pas dénués de mérites, il faut juste savoir comment les prendre.\nDans cet article, nous allons les explorer en détail, en commençant par vérifier qu’ils sont la bonne solution à votre problème, puis en réalisant l’ensemble des manipulations courantes pas à pas, ensemble, pour en illustrer les bonnes pratiques.\n\n(English version of this article here)\nLes submodules, comme les subtrees, visent à exploiter le code d’un dépôt tiers quelque part au sein de l’arborescence de votre propre dépôt. L’objectif est généralement de bénéficier d’une maintenance centralisée du code tiers à travers tout un tas de dépôts conteneurs, sans avoir à se taper du copier-coller malhabile et peu fiable.\nAfin de simplifier la suite du texte, nous appellerons « module » ce code tiers, présent quelque part dans l’arborescence des dépôts conteneurs. Pour le code du projet utilisant le module au sein de son arborescence, on parlera de « conteneur ».\nNe vous trompez pas de solution\nIl existe des cas de figure dans lesquels cette présence physique du module au sein du code conteneur est impérative, dictée par la technologie à l’œuvre dans le conteneur. Par exemple, les thèmes et plugins WordPress, Prestashop, etc. sont souvent de facto installés par leur simple présence à des endroits convenus de l’arborescence du projet, et c’est là leur seule « installation » possible.\nDans de tels cas, recourir aux submodules (ou aux subtrees) est sans doute la bonne solution, si tant est que vous deviez en effet versionner votre code et collaborer avec des tiers autour de celui-ci (ou que vous deviez le déployer ailleurs que sur votre machine) ; pour un cas strictement local et non versionné, des liens symboliques suffisent probablement, mais ce n’est pas le contexte de cet article.\nEn revanche, dès lors que la technologie employée par le conteneur permet une notion de packaging et de gestion formelle de dépendances, vous devriez absolument utiliser celle-ci à la place : elle vous fournit une gestion correctement découpée, sans effets de bords ou pièges similaires à ceux qui jonchent les submodules, et vous permet qui plus est de bénéficier de facilités de type versions sémantiques (semver) pour vos dépendances.\nPour rappel, voici les principaux langages et leurs mécanismes de gestion de dépendances / référentiels de paquets/modules :\n\n\n\nLangage\nOutil / Référentiel\n\n\n\n\nClojure\nClojars\n\n\nErlang\nHex\n\n\nGo\nGoDoc\n\n\nHaskell\nHackage\n\n\nJava\nMaven Central\n\n\nJavaScript\nnpm, Bower\n\n\n.NET\nnuget\n\n\nPerl\nCPAN\n\n\nPHP\nComposer / Packagist / Pear\n\n\nPython\nPyPI\n\n\nRuby\nBundler / Rubygems\n\n\nRust\nCrates\n\n\n\nSérieux, si vous pouvez plutôt gérer vos interdépendances de code en packagant proprement vos modules « centralisés » et en déclarant vos dépendances via les bons outils, faites-le. Vraiment. Je vous jure. Ça vous épargnera un monde de galères (et ça ne nécessite pas forcément de passer par un référentiel public, ce qui permet d’y recourir pour du code privé aussi).\nMais si vous avez l’obligation d’incorporer le code directement au sein de votre source conteneur, alors il vous reste le choix entre submodules et subtrees.\nSubmodules ou subtrees ?\nEn général, les subtrees sont meilleurs. Voilà qui vous vend admirablement cet article, hein ? Le fait est que les submodules et les subtrees sont radicalement différents, et pour tout dire opposés, en termes de concepts et de fonctionnement.\nLa plupart des gens recourent aux submodules pour une variété de raisons ; ceux-ci sont présents depuis longtemps en Git, disposent d’une commande dédiée (git submodule) et d’une doc détaillée, et leur fonctionnement est souvent analogue aux externals de Subversion, ce qui les rend faussement familiers. La mise en place d’un submodule est également très simple (un bête git submodule add), surtout en comparaison à la mise en place d’un subtree. On ne réalise qu’après que des pièges potentiels nous attendent tous les jours, pour tout le monde.\nC’est justement parce que les submodules font souffrir tant de Gitteurs que nous avons choisi de couvrir ceux-ci d’abord, et les subtrees ensuite (dans notre prochain gros article de fond).\nToujours est-il que parfois, les submodules constituent le bon choix. C’est notamment le cas lorsque la codebase est massive et qu’on ne veut pas forcément tout récupérer à chaque fois, en particulier dans des projets tentaculaires. On recourt alors aux submodules pour ne pas exiger la récupération de pans entiers du code pour tout le monde. Divers projets open-source massifs y ont recours précisément pour cette raison (ou en raison d’une forte modularisation qui n’est pas nativement prise en charge par l’écosystème du langage principal) : voyez par exemp",
		"description": "Enfin, les meilleures pratiques autour des submodules Git, démos et manips à l'appui !  Workflows, commandes, options et réglages.",
		"date": 1419984000,
		"image": "/assets/images/art-vid/art-git-submodules.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Comprendre et maîtriser les submodules Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-submodules/",
		"locale": "fr",
		"readingTime": "24 min"
	},	{
		"content": "Ayé, on est en janvier. Et comme de coutûme, c’est l’occasion de faire un petit bilan de l’année passée, de ce qu’on espère / vise pour l’année qui s’ouvre.\nNe dérogeons pas à la tradition : que retenons-nous de 2014, et quel 2015 imaginons-nous pour JS Attitude ?\n(note : cet article est posté sur l’ensemble des sites Attitude)\n\nCôté business\nNous avons l’habitude de faire nos bilans business plutôt pendant l’été, car nos exercices fiscaux courent du 1er juillet au 30 juin, et nous les calons sur nos bilans comptables… Mais ça n’empêche pas de brosser les grandes lignes, surtout avec la rentrée automnale qui a vu pas mal de changements débarquer.\n2014, c’est pour nous une belle progression de toutes les métriques d’affaires : nombre d’apprenants, nombre de sessions, nombre d’intras, nombre de sociétés clients, chiffre d’affaires… Non seulement notre 3e exercice avait engrangé un joli CA, mais le 2e semestre 2014 a battu tous les records, augurant un 4e exercice remarquable !\nDepuis octobre, nous donnons également la version complètement remaniée (« 2015 ») de notre formation blockbuster JS Total, sachant que nous continuons à explorer beaucoup de nouvelles approches, technos et frameworks, pour aller toujours plus loin, de façon toujours plus efficace et pertinente, sans pour autant allonger la durée.\nDécembre 2014 a aussi connu un événement pour nous : la première session Node.js complète ! Même si la France accuse toujours un retard hallucinant dans l’adoption de Node (malgré des meetups mensuels Node assez remplis, à Paris en tout cas) et que la session de début février n’a toujours pas d’inscrits, ça nous a fait bien plaisir !\nLe CPF\n2015 démarre avec l’énorme foutoir qu’est le remplacement du DIF par le CPF (Compte Personnel de Formation). Celui-ci est en théorie plus facile à utiliser par les gens tout au long de leur carrière (au travers de changements d’emploi notamment). Le taux forfaitaire horaire a lui aussi bien augmenté, même si à 13 € HT, il reste très en-dessous des tarifs de formation qualitatives. Dans la pratique, son utilisation est limitée à des listes de formations éligibles, établies branche par branche de façon totalement opaque et arbitraire. Les organismes de formation, eux, n’ont absolument pas été solicités pour soumettre leurs catalogues.\nEn informatique notamment, secteur pourtant prioritaire du nouveau dispositif, on est en droit de craindre que les personnes chargées d’établir ces listes (dont on ignore l’identité) n’aient pas le plus petit début de compétence pour juger de la légitimité de telle ou telle formation, mais qu’elles n’aient de toutes façons même pas les formations existantes à examiner.\nÇa va donner quoi ? Je vous parie ma chemise qu’on va se retrouver avec les formations universitaires et des grandes écoles (CIF uniquement donc, pas DIF court classique), les catalogues des éditeurs logiciels et des quelques gros mammouths du métier, sans doute à l’issue de déjeuners arrosés et de parties de golfs, alors que naturellement, ces formations sont toutes bien loin de l’état de l’art.\n\nRésultat : les personnes qui ont le plus besoin d’une formation moderne, haut de gamme, conforme à l’état de l’art, à savoir les demandeurs d’emploi et les personnes en requalification professionnelle, qui n’ont que le DIF et la prise en charge par Pôle Emploi comme moyens d’accès, ne trouveront aucune formation de ce type parmi celles autorisées. Et la France perpétuera son tragique retard dans la formation IT haut de gamme.\n\nÀ l’exception notable de la branche Métallurgie, aucune branche n’a d’ailleurs encore rendu sa copie, alors que l’échéance initiale était à la rentrée 2014. Même les modalités concrètes sont encore, pour la plupart, totalement floues, sans parler du financement. Bref, une « révolution » traitée comme d’habitude, le manteau dans la porte, et qui va faire sans doute bien plus de mal que de bien, au moins dans ses moutures initiales.\nPour beaucoup de petits organismes valables, cette réforme va avoir un impact sensible, et négatif, sur leur CA. Je sens des fermetures en pagaille d’ici 2016. Heureusement pour nous, 90% de nos inscriptions le sont dans le cadre des Plans de Formations des entreprises, et ne sont donc pas concernées. Mais on va quand même se manger, potentiellement, 10% de manque à gagner, et surtout, ce qui est plus grave, on ne va pas pouvoir former ces dizaines de personnes qui en ont vraiment besoin.\nEt sinon, le business en 2015 ?\nTout n’est pas noir, et eaucoup de belles choses arrivent :\n\nLa production des screencasts a enfin démarré. Un screencast « court » (environ 30 minutes) gratuit va débarquer d’ici fin janvier, et les poids-lourds, payants, vont commencer à sortir au plus tard en février. On a énormément hâte de vous montrer ça !\nÀ partir de mai au plus tard, Delicious Insights vous accueillera dans nos propres locaux plutôt qu’en centre externe. Ça restera dans le centre de Paris, et ce sera encore plus confortable et qualitatif qu’aujourd",
		"description": "Ayé, 2014 est derrière nous ; Delicious Insights fait le point sur cette année riche d’événements.",
		"date": 1421020800,
		"image": "/assets/images/art-vid/art-2014-in-review.jpg",
    "_tags": [],
		"title": "2014 est terminée, vive 2015 !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/bilan-2014/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "La version 5 d’ECMAScript, le standard sur lequel se base JavaScript, a introduit un mode d’interprétation particulier du code, appelé le mode strict. Le mode traditionnel est qualifié de « mode négligé » (sloppy mode).\nCe mode s’active au travers d’un marqueur particulier dans nos codes, ignoré par les runtimes antérieures. En plaçant nos codes dans ce mode d’interprétation, nous avons la possibilité de découvrir plus vite, plus tôt, des sources d’erreurs potentielles.\nCet article décrit comment activer ce mode, et quelles en sont les conséquences précises sur l’interprétation de notre code JavaScript.\n\nActiver le mode strict\nLe mode strict s’active en ajoutant une expression String spécifique au code, obligatoirement avant toute autre instruction ou expression (mais des commentaires peuvent la précéder) :\n\n(Suivant votre style dominant, vous pouvez utiliser des apostrophes ' ou guillemets &quot;).\nLe mode s’applique à la portée courante. On a donc trois cas de figure :\n\nLe fichier complet. C’est dangereux si ce fichier n’est pas enrobé en tant que module par votre système de build, car alors vous activez le mode strict au niveau global, ce qui a de fortes chances de casser des scripts tiers, bibliothèques, etc.\nLe « script complet », c’est-à-dire le code passé à eval, à new Function, à un gestionnaire d’événement en attribut inline (beuark !) ou à setTimeout (mais préférez une référence de fonction, quand même). Le mode strict qui figurerait dans un tel script est alors limité au script lui-même.\nLa fonction courante. C’est le cas dans une fonction explicite (par exemple une IIFE ou une fonction classique) ou si votre fichier est enrobé en tant que module automatiquement (par exemple dans un contexte CommonJS ou module ES6).\n\nUn impact extrêmement important de cette approche est qu’elle permet à des scripts non-stricts et à des scripts stricts de coexister dans la même page, chacun avec sa sémantique d’analyse et d’exécution. Il est ainsi possible de migrer incrémentalement votre base de code vers du strict, et de continuer à utiliser des scripts tiers pas encore stricts.\nHistoire que ça passe pour tout le monde, dans nos exemples de code pour cet article, on enrobera systématiquement l’ensemble par une IIFE :\n\nEt si mon script ne passe pas ?\nC’est là tout l’intérêt du truc : si votre code ne satisfait pas le mode strict que vous lui avez donné, la runtime JS va tout simplement refuser de l’exécuter. Elle ne se contente pas d’avertissements, elle fait péter une erreur spécifique, histoire de comprendre ce qui se passe. Toute la portée concernée refuse donc de s’exécuter.\nDu coup, ça vous pète à la gueule en développement, bien visible, ce qui est exactement le but recherché : vous voulez identifier le problème le plus tôt possible, pas un de ces jours alors que c’est déjà déployé en production.\nMoins d’erreurs sournoises\nUn premier volet du mode strict consiste à hurler sur des sources usuelles d’erreurs plutôt fourbes.\nLitéraux octaux « à l’ancienne »\nLa plupart des runtimes JavaScript autorisaient les litéraux octaux « façon C » : si c’était préfixé par un zéro, c’était de l’octal. Au moins, c’était cohérent avec le comportement pourri de parseInt :\n\nC’est d’autant plus débile que depuis ES3, soit tout de même le siècle dernier (1999), les litéraux octaux ne sont plus obligatoires dans les runtimes, ils sont juste là, si l’implémenteur le souhaite, par compatibilité avec ES1 et ES2… (voir ES-262-3, annexe B, section B.1.1).\nVous me direz que quand on tape un litéral pareil on sait ce qu’on fait, mais en fait on trouve souvent des préfixes zéros pour homogénéiser / aligner les valeurs, genre :\n\nEn mode strict, c’est fini :\n\nNotez qu’avec ES6, on récupère des litéraux octaux explicites (0o42), et tant qu’à faire des litéraux binaires, que j’ai toujours adorés en Ruby (0b100010). Elle est pas belle la vie ?\nFuite de globales\nC’est une des vraies verrues de JavaScript : si on oublie le var, paf la globale. C’est juste trop moche, comme fonctionnement… Évidemment, les linters type JSHint vont chopper ça tout de suite (réglage undef), mais ça reste un avertissement de linting, rien qui vous saute à la gueule à coup sûr…\nDémonstration :\n\nLe mode strict va te taper sur les doigts quand tu fais une bourde pareille :\n\nÀ mort les globales ! (Surtout quand on ne fait pas exprès…)\nÉchecs silencieux d’écriture ou suppression de propriétés\nAutre source de bugs bien fourbes et sournois : les opérations sur objets qui échouent silencieusement. Par exemple, l’écriture sur une propriété en lecture seule, ou la suppression d’une propriété non configurable (donc non supprimable).\nPar exemple :\n\nIl est également possible de supprimer des références simples (non qualifiées), ce qui est plus souvent dangereux qu’utile :\n\nMais en mode strict, pas moyen d’échouer en douce :\n\n…ni de supprimer des références simples :\n\nVoilà qui est plus conforme à l’excellent principe de fail-fast.\nthis global\nEn JavaScript, les méthodes n’appart",
		"description": "Mode strict ou laxiste ?  Découvrez comment faire pour que JS vous aide davantage en vous rattrapant par le col le plus tôt possible.",
		"date": 1421193600,
		"image": "/assets/images/art-vid/art-js-es5-strict.jpg",
    "_tags": ["js"],
		"title": "Le mode strict de ES5+",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/es5-strict/",
		"locale": "fr",
		"readingTime": "11 min"
	},	{
		"content": "Il y a un mois, nous explorions en détail les submodules ; nous vous avions alors dit que notre prochain article de fond serait sur les subtrees, qui constituent l’alternative.\nComme précédemment, nous allons donc explorer le sujet en détail, en réalisant l’ensemble des manipulations courantes pas à pas, ensemble, pour en illustrer les bonnes pratiques.\n\n(English version of this article here)\n\n  Mise à jour 29/04/2016 : les exemples à base de l’outil tiers git-stree, désormais déprécié en faveur de git-subrepo, ont été remplacés par des exemples avec cet outil plus abouti.\n\nVoici l’article promis ! Si vous n’avez pas lu le précédent, je vous y encourage fortement, ne serait-ce que pour bien avoir des éléments de comparaison, et reposer la problématique.\nNotamment, il est important que vous ayez bien vérifié que [vous n’avez pas le choix](/fr/articles/git-submodules/#ne-vous trompez pas de solution) et qu’il faudra utiliser soit les submodules soit les subtrees, plutôt qu’une gestion de dépendance versionnée (qui est toujours préférable, quand elle est faisable).\nNous brosserons également systématiquement des parallèles avec les submodules ; si vous avez lu l’article en question, ça vous aidera à mieux internaliser ces informations.\nOn reprendra ici la terminologie du précédent article : nous appellerons « module » ce code tiers, présent quelque part dans l’arborescence des dépôts conteneurs. Pour le code du projet utilisant le module au sein de son arborescence, on parlera de « conteneur ».\nFondamentaux des subtrees\nPetit rappel de terminologie d’abord : en Git, un dépôt est local. La version distante, qui ne sert qu’à l’archivage, à la collaboration et au partage, est appelée un remote. Dans la suite de cet article, quand vous lisez « dépôt » ou « dépôt Git », il s’agit d’un dépôt local interactif, c’est-à-dire d’un répertoire de travail (working directory) avec un .git à sa base.\nAvec les subtrees, pas de dépôts imbriqués : on n’a qu’un dépôt, le conteneur, comme pour une codebase classique. Donc un seul cycle de vie, et aucune particularité à gérer pour les commandes et workflows habituels. Elle est pas belle la vie ?\nTrois approches distinctes : choisissez !\nIl existe trois manières de manipuler vos subtrees ; même s’il reste possible de mélanger certaines approches, d’une façon générale je vous recommande de partir avec une et de vous y tenir, pour éviter les problèmes.\n« À la main »\nGit ne fournit pas de commande native subtree, contrairement à ce qui se passe pour les submodules. Les subtrees ne sont pas tant une fonctionnalité qu’un concept, une approche de gestion fournie par Git. Ils reposent sur l’utilisation adéquate de commandes de porcelaine classiques (notamment merge et cherry-pick) et d’une commande de plomberie[^1] (read-tree).\nCette approche marche partout, elle est assez simple, finalement, mais nécessite une bonne compréhension du fond pour exécuter certaines démarches avancées. Nous l’utiliserons comme point de base, car en nous offrant le contrôle fin sur les opérations, elle nous donne toute liberté sur la gestion de nos historiques, branches et graphes…\nLe script de contrib : git subtree\nEn juin 2012, dans la version 1.7.11, Git s’est mis à inclure un script de contrib tiers, git-subtree.sh, dans la distro officielle ; ils ont qui plus est calé leur installation binaire pour qu’une copie soit présente en git-subtree dans les binaires mis à disposition par l’install, de sorte que git subtree était utilisable, ressemblant à une commande « native ».\nÇa s’arrête toutefois là, car la « documentation » n’est pas une page man, et n’est donc pas installée comme telle. Les appels usuels (man git-subtree, git help subtree ou git subtree --help) sont inopérants. Un git subtree tout court nous donne just le synopsis, sans plus d’informations. Seul le fichier texte lié en début de paragraphe fournit les infos, et il est planqué au fin fond du dossier contrib/ de votre installation Git.\nCe script, que j’appellerai par souci de concision git subtree dans la suite de cet article, a le mérite d’être robuste et de proposer des syntaxes familières (add, pull, push…) par-dessus des opérations parfois complexes. Il offre toutefois quelques opérations (genre split) et notions (genre --ignore-joins/--rejoin) qui sont assez déroutantes au premier abord, sans parler de son approche très personnelle du --squash…\nMais surtout, il maintient une branche dédiée au subtree, qui va fusionner dans la branche courante à chaque git subtree pull ou git subtree merge. Ce qui veut dire qu’elle va nous pourrir le graphe de l’historique en permanence, et ça, moi, j’ai énormément de mal.\nAutre inconvénient : elle ne permet pas de choisir les commits locaux sur le subtree qu’on veut backporter avec un git subtree push : c’est tout ou rien. Alors qu’un intérêt des subtrees c’est justement de pouvoir faire des modifs locales custom autant que des fixes à portée générale.\nToutefois, elle a le mérite d’être là depuis longtemps ",
		"description": "Enfin, les meilleures pratiques autour des subtrees Git, démos et manips à l'appui !  Workflows, commandes, options et réglages.",
		"date": 1422576000,
		"image": "/assets/images/art-vid/art-git-subtrees.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Comprendre et maîtriser les subtrees Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-subtrees/",
		"locale": "fr",
		"readingTime": "19 min"
	},	{
		"content": "Ah, vous croyez que vous êtes au top parce que vous utilisez Grunt, Gulp, Broccoli ou même Glou ? Eh ben non, pas forcément, voire carrément pas. Du tout. Voilà déjà 4 ans que Brunch existe, et sur bien des scenarii courants, il bat tout ce petit monde à plate couture.\nEnvie d’en savoir plus, et de voir plein d’exemples ? C’est par ici.\n\nUPDATE: This article has been translated to English and adapted to become the official Brunch Guide (EN/FR). Only the Guide will be maintained and updated looking forward.\nBrunch ?! C’est quoi, Brunch ?\nBrunch est un builder. Pas un exécuteur de tâches générique, mais un outil spécialisé dans la production de fichiers finaux pour la production, à partir de tout un tas de fichiers de développement.\nCe type de besoin est extrêmement fréquent chez les devs front et les designers front, qui ont souvent besoin de faire un peu les mêmes choses : partir d’une arborescence de fichiers LESS ou SASS pour produire un ou plusieurs CSS minifiés, pareil pour du JS, des images et leurs sprites, etc.\nBrunch face aux autres\nL’immense majorité des personnes qui automatisent ce type de tâches utilisent soit Grunt, soit Gulp (et parfois Broccoli ou Glou). Bien qu’extrêmement populaires, et arrivés sur le marché plus récemment que Brunch, ces solutions lui sont souvent inférieures dans les scenarii d’utilisation courants.\nJ’utilise Brunch depuis juin 2012 (autour de sa version 1.3 ; il remonte au printemps 2011), et jusqu’à présent, il constitue encore pour moi une alternative très supérieure aux autres acteurs apparus depuis.\nAfin de bien cerner ce qui distingue Brunch des autres solutions du marché, nous allons aborder différents aspects techniques et architecturaux, qui constituent chacun des choix de conception autour desquels se répartit l’écosystème.\nAprès quoi, on se tapera tout plein de démos sur du code concret, n’ayez crainte.\nExécuteurs de tâches vs. outils de build\nLe marché est dominé par des exécuteurs de tâches génériques. Ces outils fournissent un mécanisme de description de tâches, et de dépendances entre ces tâches. Il peut s’agir de n’importe quoi : copier un fichier, en produire un, envoyer un e-mail, compiler quelque chose, lancer les tests, faire un commit Git… absolument ce que vous voulez.\nC’est une notion très ancienne ; un des premiers exécuteurs de tâche génériques connus était Make (et ses fameux fichiers Makefile) ; dans l’univers Java, on a d’abord eu Ant, et comme si ça n’était pas assez verbeux, on a désormais l’énorme mammouth sclérosé qu’est Maven ; Ruby de son côté a Rake, etc.\nParce que ces exécuteurs sont génériques, il ne leur est que rarement possible d’optimiser automatiquement pour des scenarii spécifiques, ou même de mettre en place des conventions par défaut. Toute tâche nécessite l’écriture d’un volume non trivial de code et/ou de configuration, et doit être invoquée explicitement aux bons endroits.\nQui plus est, toute tâche—et même tout comportement de fond, comme la surveillance des fichiers pour mettre à jour le build—nécessite l’écriture d’un plugin, son chargement, sa configuration, etc.\nBrunch est un outil de build.\nBrunch est fondamentalement spécialisé dans le build d’assets, ces fichiers qui seront utilisés à terme par la plate-forme d’exécution, en général le navigateur. Il fournit donc d’entrée de jeu un certain nombre de comportements et fonctionnalités. On y trouve notamment :\n\nla catégorisation des fichiers sources : JavaScript, Feuilles de style, Templates ou « divers » ;\nla concaténation intelligente de ces fichiers vers un ou plusieurs fichiers cibles ;\nl’enrobage en modules des fichiers catégorisés JavaScript ;\nla production des source maps associées ;\nla minification des fichiers produits si on est en « mode production » ;\nla surveillance des fichiers sources pour mettre à jour le build à la volée.\n\nToutes ces fonctionnalités sont rendues possibles grâce à la spécialisation de l’outil, mais restent très simples d’emploi (le plus souvent, carrément automatiques) grâce à un jeu habile de conventions, que nous verrons tout à l’heure.\nTraitements de fichiers vs. pipelines\nLa faiblesse principale de Grunt est la même que pour Make, Ant et Maven, qui l’ont inspiré : il repose entièrement sur la notion de fichiers. Toute tâche qui manipule du contenu part d’un fichier pour aboutir à un autre.\nCette approche est extrêmement limitative dès qu’on touche à des workflows fréquents, où la modification d’un unique fichier source peut impacter plusieurs destinations, par exemple une concaténation, la source map associée, un manifeste AppCache… Dans Grunt, on passe son temps à produire des fichiers temporaires pour les étapes intermédiaires de traitement, ce qui est un foutoir sans nom.\nL’autre inconvénient majeur de cette approche, c’est qu’elle est désastreuse en performances : on passe sa vie à fermer et rouvrir les mêmes fichiers, à les relire autant de fois que nécessaire, même pour une seule passe de build.\nL’alternative, c’est la pipeline : ",
		"description": "Pour du *build* pur d’application web front, Brunch a longtemps été le must absolu (avant que ne survienne Webpack).  Voyons à quel point ça envo(yait) du bois.",
		"date": 1425427200,
		"image": "/assets/images/art-vid/art-brunch.jpg",
    "_tags": ["tutoriel","outil","js"],
		"title": "Pourquoi je préfère Brunch",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/brunch-mon-builder-prefere/",
		"locale": "fr",
		"readingTime": "41 min"
	},	{
		"content": "Après des mois de préparation, de mise en place, d’enregistrement et de post-production, la première série de nos cours vidéo GitHub est enfin sortie !\nEn février 2015, O’Reilly et GitHub Training nous ont demandé si nous pouvions produire une série de cours vidéo exhaustive sur GitHub. L’occasion était trop belle et nous avons naturellement sauté dessus ! Il existe en fait deux séries :\n\nLearning GitHub, qui comprend 69 vidéos regroupées en 13 chapitres, pour un total de 4h52. Elle couvre déjà énormément et fera découvrir beaucoup de choses aussi bien aux parfaits débutants qu’aux utilisateurs déjà chevronnés. Elle vient de sortir.\nMastering Advanced GitHub, qui devrait comprendre 43 vidéos regroupées en 5 chapitres, pour un total d’environ 4 heures. Elle explore les GitHub Pages, les fonctions cachées, l’intégration avec des services tiers, l’API et les subtilités de facturation et de la gestion des organisations. Actuellement en production, elle devrait paraître en février 2016.\n\nNous avons travaillé en étroite collaboration avec GitHub Training pour être sûrs que nous ne laisserions rien au hasard, rien de côté. Notez que GitHub a entre-temps changé son look par défaut, ce qui peut produire un léger décalage (onglets titrés en haut vs. onglets icôniques sur la droite), mais le contenu reste 100% valable.\nNous sommes extrêmement heureux de voir le produit fini enfin sorti, et même s’il a loupé le coche des Black Friday / Cyber Monday, il est là pour Noël !\nVous pouvez le découvrir dès à présent :\n\nSur le site classique O’Reilly\nSur leur site dédié InfiniteSkills\n\nOn espère que vous allez adorer !\n",
		"description": "Notre cours vidéo très complet sur GitHub est paru chez O’Reilly !  Alors, y’a quoi dedans ?",
		"date": 1450396800,
		"image": "/assets/images/art-vid/art-git-github.jpg",
    "_tags": ["annonce","cours vidéos","git"],
		"title": "Notre cours vidéo GitHub est sorti !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/learning-github/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "La commande git reset est un outil formidable souvent mal compris et peu maîtrisé. Elle ouvre pourtant la voie à un large éventail de solutions et d’astuces pour optimiser notre travail et nos workflows.\nIl est important de connaître son contexte pour pouvoir l’utiliser à bon escient. Pour bien attaquer cet article et comprendre git reset il nous faudra donc réviser quelques fondamentaux de Git.\ngit reset permet d’agir sur notre historique de versions et notre travail en cours. Pour cela il nous faut savoir :\n\ncomment est construit cet historique ;\ncomment Git s’organise autour de notre travail en cours ;\ncomment convertir/archiver ce travail en historique ;\npar quels procédés on peut se repérer/naviguer à travers les branches (l’espace) et les versions (le temps).\n\n\nLes fondamentaux\nSHA-1 (prononcez « cha-wouane »)\nDans le contexte de Git, le SHA-1 est utilisé comme référence technique désignant un objet, principalement un commit. Du point de vue technique, il s’agit de la somme de contrôle du contenu des fichiers archivés et d’un en-tête. Pour plus de détail, vous pouvez consulter la documentation en ligne.\nHEAD : « Vous êtes ici »\nFaisons simple : HEAD est un pointeur, une référence sur notre position actuelle dans notre répertoire de travail Git. C’est un peu comme notre ombre : elle nous suit où qu’on aille ! (ça marche aussi avec « notre tête », mais l’image aurait été un peu étrange…)\n\nPar défaut, HEAD pointe sur la branche courante, master, et peut être déplacé vers une autre référence : autre branche, tag/étiquette, commit…\nTechniquement, il s’agit d’un simple fichier comprenant une ligne qui désigne notre position : .git/HEAD.\n\nOn peut voir le contenu technique de ce qu’il référence avec la commande cat-file :\n\nDans cet exemple, HEAD pointe vers le dernier commit de la branche master. La commande cat-file nous donne les méta-données de ce commit (auteur, message, tree/arborescence de contenus…).\nLorsque nous utilisons git reset nous allons agir directement sur HEAD en le positionnant selon notre souhait. Toutefois, si nous avons une branche active (cas majoritaire), c’est elle qui sera repositionnée et HEAD, qui la référence, suit automatiquement.\nUn mot sur ORIG_HEAD\nSi vous avez jeté un œil au répertoire .git situé à la racine de votre projet, vous aurez peut-être remarqué un fichier nommé ORIG_HEAD. Ce dernier fonctionne un peu comme HEAD, au détail près qu’il ne comprend qu’une seule ligne qui sera toujours un SHA-1/commit, jamais une référence nommée (branche, tag…).\n\nLe but de ce fichier est de noter le dernier emplacement de HEAD avant une opération potentiellement dangereuse (fusion, rebase, checkout…).\nDe cette manière, si un problème intervient lors d’une opération de ce type, Git nous permettra de revenir sur sa position précédente en effectuant un git reset --merge ORIG_HEAD.\nGardez dans un coin de votre tête cette référence, elle pourra être utile lors de son utilisation avec git reset.\nLes zones\nSi vous ne le savez pas déjà, un des avantages majeurs de Git réside dans l’aspect local des travaux réalisés : un dépôt Git gère son cycle de vie local indépendamment de la connectivité avec son dépôt distant. On gagne ainsi en performance, mais pas seulement…\nNous nous concentrons ici sur la partie « travail local ».\nEn complément de cet article, je vous recommande cet excellent support interactif illustrant les zones.\nGit gère les versions de vos travaux locaux à travers 3 zones locales majeures :\n\nle répertoire de travail (Working directory / WD)\nl’index ou stage (nous préférerons le second terme)\nle dépôt local (git directory / repository)\n\nLes deux zones restantes (stash/remise et remote/dépôt distant) ne nous intéressent pas ici.\n\nLe répertoire de travail\nIl désigne votre arborescence de fichiers, c’est-à-dire l’ensemble des fichiers et répertoires que vous manipulez indépendamment de Git et que vous auriez créé avant même d’avoir initialisé votre dépôt local (via git init).\nDans la pratique, cette initialisation ne fera que créer et pré-remplir un sous-répertoire .git à la racine de votre répertoire de travail.\nLe stage\nIl s’agit de la zone de validation désignant les travaux que vous souhaitez voir apparaître dans votre prochain commit.\nOn ajoute un travail au stage à l’aide de la commande git add ….\nVous pourrez être confronté à différents noms pour cette zone :\n\nindex (surtout dans les documentations françaises et les pages de manuel de Git)\nstage / staging area / staged files\ncache / directory cache / current directory cache\n\nOn retrouve notamment la dénomination alternative index dans le nom du fichier technique binaire qui le représente dans notre répertoire de travail : .git/index.\nLa commande de plomberie git ls-files --stage permet de voir l’équivalence textuelle simplifiée de son contenu, à savoir la liste des chemins racine actuellement suivis/trackés par Git, ainsi que leurs permissions et SHA-1.\n\nDans la pratique ce fichier possède plus d’informations pour permettre entre",
		"description": "La commande <tt>git reset</tt> est un outil formidable souvent mal compris et peu maîtrisé.  Elle ouvre pourtant la voie à un large éventail de solutions et d’astuces pour optimiser notre travail et nos <em>workflows</em>.",
		"date": 1462924800,
		"image": "/assets/images/art-vid/art-git-reset.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Git reset : rien ne se perd, tout se transforme",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-reset/",
		"locale": "fr",
		"readingTime": "15 min"
	},	{
		"content": "Au-delà des commandes et du cycle de gestion usuel des révisions, Git nous permet des traitements complémentaires à certaines commandes afin d’épauler les utilisateurs.\nCet article est un complément à la documentation officielle et à la page de manuel.\n\nLe principe\nL’objectif des hooks est simple : il s’agit de fournir des enrobages à certaines commandes pour permettre l’injection de scripts (Bash, Node.js, Perl, Python, PHP…). De cette manière nous pouvons automatiser et donc fiabiliser une partie du travail côté client (machine de l’utilisateur) mais aussi côté serveur.\n\nIls sont “par défaut” présents dans chaque répertoire projet dans le sous-répertoire .git/hooks.\nLeur nom est conventionnel et chaque fichier de script doit être exécutable (chmod +x .git/hooks/…).\nLeur emplacement fait qu’ils peuvent être supprimés ou désactivés par l’utilisateur sur un poste local.\n\nAinsi les hooks locaux n’ont pas une vocation de contrôle, mais plutôt de soutien.\nÀ cela s’ajoute le fait qu’un utilisateur peut demander à ce que certains hooks ne soient pas déclenchés, avec l’option --no-verify (pre-commit et commit-msg seulement).\nGit fournit à chaque initialisation de projet un ensemble de scripts de démonstration possédant l’extension .sample (ex. : .git/hooks/pre-commit.sample). Pour les activer, il vous suffit de retirer cette extension (ex. : .git/hooks/pre-commit).\nBloquant … ou pas !\nUn hook peut être bloquant, c’est-à-dire qu’il peut interrompre la commande qu’il enrobe.\nPar convention, tout hook avant commande pre-[commande] est bloquant. Comme décrit précédemment, certains sont cependant contournables en utilisant l’option --no-verify : pre-commit et commit-msg.\nLes seuls vraiment bloquants sont :\n\nCôté client : prepare-commit-msg, pre-rebase, pre-apply-patch, pre-push, pre-auto-gc\nCôté serveur : pre-receive, update\n\nLe code de sortie des scripts bloquants est analysé pour savoir si oui on non le traitement doit être interrompu. On ne réinvente pas la roue, on utilise les codes de sorties standards qu’on peut résumer ici à :\n\n0 (zéro) : tout est OK, on ne bloque pas,\n≥1 : erreur, on bloque le traitement.\n\nPar exemple, si nous produisons une sortie exit 1 dans un script de pre-commit alors le commit ne sera pas effectué.\nVoici un exemple concret d’utilisation :\nUn script bloquant tout commit tant que\n\ndes marqueurs de conflits persistent,\ndes chaînes de caractères TODO ou FIXME sont detectée.\n\n\nCôté client/machine locale\nIl s’agit des hooks disponibles uniquement sur les machines des utilisateurs.\nCeux-ci ne sont pas partagés au sein d’un projet, et il n’existe malheureusement à l’heure actuelle aucune option de type hooks.shared=true permettant ce comportement.\nDeux alternatives permettent néanmoins de produire en partie ce comportement :\nInitialisation du dépôt via un gabarit de projet\nLorsque vous initialisez votre dépôt projet, vous pouvez dire à Git d’utiliser un gabarit d’arborescence de projet type grâce à l’option --template=&lt;template directory&gt; :\n\nLors de la création du projet : git init --template=&lt;template directory&gt;\nLors du clone : git clone --template=&lt;template directory&gt;\n\nCette approche vous permet de définir plusieurs gabarits et de charger celui qui vous intéresse à l’initialisation ou à la récupération d’un projet.\nUtilisation d’un répertoire déporté de hooks\nDepuis Git 2.9 on peut définir par projet ou au global un paramétre de configuration permettant de spécifier le chemin du répertoire contenant les hooks : core.hooksPath=&lt;hooks directory&gt;.\nAinsi on peut gérer un projet de hooks centralisé et partagé et aussi gérer communément les hooks nécessaires à une équipe. On limite la maintenance et les erreurs, et on économise le temps que nous devions passer précedemment à copier/coller ceux-ci !\nLes hooks disponibles sont les suivants :\n\nAutour des commits :\n\npre-commit : avant la création du commit, avant même l’édition du message (ex. : linting, tests unitaires courts) ;\nprepare-commit-msg : avant la création du commit, au moment où l’on va avoir la main sur l’édition du message (ex. : permet l’injection d’un message pré-calculé) ;\ncommit-msg : juste avant la création du commit, mais après l’édition du message (ex. : contrôle du contenu du message et réécriture à la volée) ;\npost-commit : une fois le commit créé (ex. : notification) ;\n\n\nAutour de l’application d’un patch (hooks lancés autour de la commande git am) :\n\napplypatch-msg : avant l’application du patch (vérification du message de patch) ;\npre-applypatch : après l’application du patch, mais avant la création du commit (ex. : validation du contenu du patch appliqué) ;\npost-applypatch : une fois le patch appliqué et le commit créé (ex. : notification de l’auteur du patch) ;\n\n\nAutres opérations :\n\npre-rebase : avant le démarrage de la commande git rebase (ex. : interdire le rebase de la branche master ou de commits déjà poussés sur le serveur) ;\npost-checkout : après l’exécution d’un git checkout et ses appels impli",
		"description": "Gagnez en sérénité et en qualité en automatisant certains traitements.",
		"date": 1492128000,
		"image": "/assets/images/art-vid/art-git-hooks.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Git Hooks ou la revanche du crochet Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Notre formation JS Total, c’est un peu notre best-seller, une marque à elle toute seule. C’est la seule formation que nous planifions tous les mois en inter-entreprises ! Et pourtant, nous avons fini par sauter le pas et la renommer, avec les risques que ce changement entraîne. Pourquoi cela ?\n\nUn peu d’histoire…\nHistoriquement, nos formations « Total » expriment leur ambition de vision à 360° de l’écosystème concerné. Au début nous avions des formations d’une journée, plus ciblées : JS Puissant, pour le langage pur, JS Guru, pour les single-page apps (basées Backbone et Underscore, à l’époque), JS Blindé, pour les tests et l’industrialisation… Lorsqu’on a mis au point la « liste au Père Noël » qui devait couvrir, sur 4 jours, tout ce périmètre et d’autres choses encore, il a semblé naturel de l’appeler « JS Total ».\nNotre univers de formation Git a connu la même évolution, avec « Git Quotidien » et « Git Avancé » qui ont fusionné et se sont développés dans « Git Total ».\nIl aurait en revanche été illusoire d’espérer couvrir une part assez large de l’écosystème Node en 4 jours pour oser l’appeler « Node Total », on est donc resté sur « Node.js » pour celle-ci 😉\nLes soucis arrivent\nLe nom « JS Total » avait toutefois plusieurs problèmes, qui se sont fait jour au fil du temps :\n\nLe nom peut laisser croire qu’on se concentre sur le langage seul, intégral, ce qui n’est pas le cas, et a fait quelques déçus.\nCorollaire de ce premier point : le nom ne retranscrit pas du tout le périmètre et l’objectif actuel de la formation, qui vise à fournir toutes les billes essentielles pour réaliser des applications web front-end modernes et conformes à l’état de l’art.\nAu moins une fois par trimestre, on a quelqu’un qui nous commande une « Total JS », qui est en fait le nom d’un framework qu’on n’aime pas particulièrement… (Remarquez, c’est déjà mieux que lorsqu’une fois par an environ on nous demande une « Java Total »…)\nUne formation dédiée à 100% du langage est justement sur le point de sortir, qui s’appellera pour le coup logiquement « ES Total » ; il y aurait clairement eu conflit de perception si on gardait « JS Total » pour celle-ci.\n\nOn a cherché longtemps un nom plus adapté, conscients qu’à ce stade beaucoup de gens connaissent la « marque » JS Total et font leurs recherches là-dessus pour nous trouver, et qu’il allait donc falloir gérer la transition aussi intelligemment que possible.\nLe nouveau nom\nOn n’a pas trouvé un truc 100% coup de cœur ; le cahier des charges du nom est difficile : raisonnablement court, représentatif, avec peu de risques de mauvaise interprétation, pas de conflit avec les noms des autres formations actuelles et à venir…\nAu final, Web App Modernes s’est imposé. Si le contenu avait été plus centré sur les Progressive Web Apps, on aurait sans doute retenu ça, mais on estime que l’absence au programme de certains points-clés des PWA (tels que les App Shells et Page Shells, par exemple) nous interdit ce raccourci quelque peu opportuniste.\nCadeau bonus, l’abréviation du nouveau nom donne « WAM ! », ce qui décrit finalement assez bien la sensation cérébrale ressentie en fin de formation par les apprenant·e·s arrivé·e·s à saturation 😉\nAlors voilà, il n’y a plus de JS Total, il y a désormais Web App Modernes. Longue vie au nouveau nom !\n",
		"description": "La formation « JS Total » devient « Web App Modernes » : pourquoi ?",
		"date": 1506124800,
		"image": "/assets/images/art-vid/art-jst-wam.jpg",
    "_tags": ["formations","annonce","js"],
		"title": "JS Total devient Web App Modernes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/jst-devient-wam/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Vous les avez réclamées à cor et à cri, les voici : nos deux nouvelles formations ES Total et Webpack ! Petite présentation rapide…\n\nES Total : spécial balèzes\nNos formations JS historiques dédient depuis déjà 2 ans l’essentiel de leur première journée à remettre tout le monde à niveau sur une bonne partie d’ES2015 (« ES6 »), mais évidemment, en quelques heures il y a des limites à ce qu’on peut voir.\nRégulièrement, quelqu’un nous exprime le souhait, voire un véritable besoin de production, pour une formation qui couvrirait, en détail, 100% du langage, et ce naturellement dans sa dernière génération : ES2017, ES2018, etc. Oui, ça contient plein de petites subtilités cachées, de fonctionnalités obscures et de points hyper avancés, mais une véritable demande existe !\nDe notre côté, fans de JavaScript comme on l’est, en particulier de certains aspects un peu niche qu’on n’a justement jamais l’occasion de voir en formation, ce genre d’appel du pied ne pouvait pas nous laisser éternellement de marbre…\nVoici donc ES Total.\nTout, tout, tout, vous saurez tout sur JavaScript\nOn a donc ressorti toutes les docs et specs de référence sur le langage, dans sa version la plus récente (ES2017), et on a pondu un déroulé capable de traiter tout ça dans ses moindres recoins. Les générateurs ? Évidemment. Les proxies ? Tu m’étonnes. Les symboles système ? Un peu, mon neveu. Les tagged template strings ? Carrément.\nRien n’est laissé au hasard. On dirait un quiz sadique : est-ce que undefined est une clé de Map valide ? Quelles parties de l’API sont inaccessibles sur la variante weak ? Quels sont les avantages et inconvénients d’un return await ?\nRetour vers le futur\nMais on ne s’est pas arrêtés là. Chez Delicious Insights, nous suivons de près l’évolution d’ECMAScript, le standard qu’on appelle communément « JavaScript » (voilà pourquoi ES Total), et à notre petit niveau, nous y contribuons même. Des tas de nouveautés sont dans les tuyaux, souvent déjà utilisables, ou à tout le moins testables, grâce aux initiatives des principaux moteurs JavaScript et aux transformées de Babel.\nAlors vous trouverez aussi tout ce dont on sait que ça va sortir dans la prochaine édition, et mêmes quelques pépites qui ne seront 100% officielles que plus tard encore ! Champs privés, nouveautés de RegExp, Temporal, Observables natifs… Il y a de quoi jouer !\nEn savoir plus sur ES Total, la formation JS qui envoie du bois\nWebpack : super-pouvoirs\nIl y a eu Grunt, Gulp, Brunch, Broccoli, Browserify, Rollup… Au final, dans le monde des bundlers, ces outils destinés à produire quelques fichiers optimaux à partir de tout un tas de fichiers assets de développement, Webpack s’est imposé comme la référence incontournable. Plus performant, plus optimisant, plus personnalisable, plus pratique au développement… ses avantages sont légion.\nAttention chérie, ça va bundler\nToutefois, Webpack a souffert à ses débuts d’une documentation certes foisonnante mais mal structurée et parfois lacunaire, et son abondance de possibilités en a intimidé beaucoup, leur faisant rapidement perdre pied à coup d’exemples obsolètes et de didacticiels communautaires contradictoires.\nVers l’infini et au-delà !\nIl n’en reste pas moins que Webpack est inégalable pour la production efficace de bundles applicatifs web front-end finement optimisés et taillés sur mesure pour les besoins spécifiques de chaque appli. Et en s’y prenant bien, on peut facilement garder la maîtrise et la compréhension de sa configuration, même pour des cas très complexes.\nCette formation part de zéro et donne toutes les clés pour construire, pas à pas, des configurations Webpack qui restent maintenables, composables et réutilisables au fil de leur croissance, depuis des cas tout simples jusqu’à des besoins extrêmement riches.\nC’est juste que « Webpack Total » sonnait mal\nPar ailleurs, notre formation ne se contente pas d’optimiser les performances de chargement et de temps de démarrage des applis web finales, mais s’intéresse aussi à l’expérience de développement obtenue, en accélérant tout ce qui peut l’être : boucle de feedback développeur, vitesse des builds incrémentaux, temps de production des builds finaux, etc.\nOn y apprend même à réaliser nos propres loaders et plugins Webpack, c’est vous dire combien son programme est exhaustif !\nUn savoir-faire désormais incontournable partout où on produit du JS riche destiné aux navigateurs.\nEn savoir plus sur Webpack, la formation qui fait autorité\nDépêchez-vous !\nPour leur démarrage, ces formations sont prévues à raison d’une session inter-entreprises par trimestre. Le rythme pourra s’accélérer si le besoin s’en fait sentir. Chacune a pour le moment une session inaugurale prévue, en février 2018. Les places vont partir vite, alors dépêchez-vous de vous inscrire !\n\nProgramme et inscription pour la formation ES Total\nProgramme et inscription pour la formation Webpack\n\nAu plaisir de vous former !\n",
		"description": "Découvrez nos 2 nouvelles formations : 100% de JavaScript dernière génération et une plongée profonde dans Webpack…",
		"date": 1506297600,
		"image": "/assets/images/art-vid/art-est-wp.jpg",
    "_tags": ["formations","annonce","js","outil"],
		"title": "ES Total et Webpack : 2 nouvelles formations !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/es-total-et-webpack/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Précédemment dans « Workflow Git »…\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques\nCorriger des bugs\nDéfinir les conventions d’un projet (cet article)\n\nDéfinir les conventions d’un projet\nLa définition ou l’utilisation de conventions au sein d’une équipe, d’une entreprise ou d’une communauté favorise la pérénité des projets qui y adhèrent.\nLes bénéfices sont multiples :\n\nOn uniformise les travaux effectués ;\nOn favorise la lecture et l’analyse de l’historique du projet ;\nOn fournit un socle pour automatiser certaines tâches ;\nOn réduit le coût d’entrée/d’apprentissage du contexte projet pour un acteur connaissant ces conventions ;\nOn optimise la création et la gestion de nouveaux projets basés sur des règles existantes ;\n\nFaciliter la lecture de l’historique\nCommits\nLe bon nommage des messages de commits est souvent un signe de qualité de la gestion du projet et du bon découpage des tâches.\nLe but est de définir un schéma logique d’écriture de ces messages, car Git n’impose aucune contrainte.\nOn trouve de nombreuses initiatives qui proposent des normalisations.\nL’une des plus connues est probablement le conventional changelog.\nElle consiste à fournir en première ligne une description concise de la tâche couverte par le commit, puis des informations complémentaires dans les paragraphes suivants.\nOn facilite ainsi la lecture du log d’une part, la génération automatique du changelog (ou release notes) d’autre part, en listant la première ligne de chaque message d’un point A de l’historique à un point B (en général ces points sont définis par des tags).\nVoici un squelette d’exemple de message de commit conventionnel :\n\nOn obtient alors des historiques faciles à analyser :\n\nOn peut alors imaginer créer un aperçu des changements effectués sur le projet (release notes) en regroupant les commits par thématique :\n\nDes outils tels que commitizen et commitlint peuvent vous assister dans la construction de vos messages de commit.\nBranches\nNous avons déjà marqué notre souhait de d’identifier les sous-ensembles de développement en utilisant des branches.\nAu même titre que pour les commits, l’organisation et la lecture de celles-ci sera facilitée si leurs noms sont conventionnels.\nVoici un exemple de convention basé sur le GitLab flow :\n\nBranche de développement principale : master.\nBranche de pré-production pour tests fonctionnels et intégration : pre-production.\nAutres branches : &lt;contexte&gt;/(&lt;périmètre&gt;/)&lt;fonction&gt; (périmètre optionnel)\nBranches de fonctionnalités créées depuis master : contexte feat.\nExemple feat/ux/a11y : périmètre « expérience utilisateur », fonction « accessibilité ».\nBranches de correctifs créées depuis production : contexte hotfix.\nExemple hotfix/42-form-submit : ici un numéro de ticket est utilisé avec un nom décrivant la fonction impactée (le périmètre n’est pas nécessaire).\n\nATTENTION : l’utilisation du délimiteur « / » dans les noms de branches ne vous permettra pas avec Git d’utiliser les noms intermédiaires.\nPar exemple si vous créez une branche feat/ux/a11y, vous ne pourrez pas créer de branche feat/ux. Préférez alors un autre séparateur : feat-ux, feat-ux-a11y.\nVersions logicielles\nLes ensembles d’évolutions d’un projet peuvent être identifiés à l’aide des tags (de préférence annotés).\nNous avions vu précédemment le Semantic Versioning qui est une convention très répandue.\nCes noms identifiables permettent dès lors des automatisations telles que la génération automatique d’un changelog entre deux versions majeures ou mineures.\nStyle de code\nL’uniformisation d’un projet passe également par des choix stylistiques et structurels au sein des fichiers sources, ainsi que leurs règles de nommage.\nEt comme on ne réinvente pas la roue, on peut utiliser des conventions de style déjà existantes :\n\nCoding Style de Mozilla\nGoogle style guides\net bien d’autres…\n\nVous pouvez également encourager l’utilisation d’outils pour analyser le code, voire automatiser ces analyses :\n\nLinters : analyse statique de code (ex : StandardJS, BuddyJS, Prettier, JsBeautifier pour JavaScript)\nCode quality : algorithmes, fuites mémoires… (ex : SonarQube, Code Climate, Snyk, Plato, Stylelint)\n\nGestion de projet\nLe cycle de vie d’un projet implique de définir des objectifs fragmentables en tâches qui seront affectées aux différents intervenants.\nLa définition des tâches constituant un projet peut aujourd’hui être directement intégrée dans les interfaces de serveur Git (GitHub, GitLab, Bitbucket). On crée alors un ticket ou issue pour chaque tâche.\nCertains systèmes vont même au-delà de la simple définition de tickets en offrant des interfaces de gestion de projet avancées (échéances/milestones, dates butoirs, étiquettes/labels, kanban board…). Ceci évite la multiplication des logiciels et des éventuelles passerelles entre ceux-ci.\nQu’ils soient intégrés ou non dans votre serveur Git, vos tickets peuvent suivre des conventions de nommage",
		"description": "Des conventions pour mieux nous guider et automatiser certaines tâches",
		"date": 1506902400,
		"image": "/assets/images/art-vid/art-git-workflows-conventions.jpg",
    "_tags": ["git"],
		"title": "Workflow Git : définir les conventions d’un projet",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-workflows-conventions/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Précédemment dans « Workflow Git »…\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques\nCorriger des bugs (cet article)\nDéfinir les conventions d’un projet\n\nGérer les bugs\nEn parallèle de la gestion de projet « standard » nous avons souvent à gérer la maintenance des projets.\nPour nous organiser efficacement il nous faut distinguer les bugs des revues fonctionnelles :\n\nRevue fonctionnelle (non urgent) : traitée comme une feature branch standard ou au sein d’une branche existante;\nBug critique et urgent : nécessite une organisation dédiée, à part du flux standard, mais sur le modèle du feature branching. Le terme souvent employé à cet effet est hotfix (en français « correctif à chaud » passe moins bien 😊 ).\n\nL’isolement des corrections sur des branches nous aidera à :\n\ntraiter nos corrections en plusieurs commits si cela s’avère nécessaire ;\nutiliser les mécanismes de validations nous permettant de nous assurer de la qualité des corrections ;\nfavoriser la lecture de notre historique ;\nextraire des correctifs pour les appliquer ailleurs.\n\n\nRécupération des correctifs\nUne fois nos correctifs traités nous devrons parfois reporter certains d’un endroit à un autre.\nGit propose deux approches à cet effet :\n\nl’extraction (git format-patch) pour envoi éventuel par e-mail (git sendmail) et application ultérieure sur notre projet ou un autre (git apply/git am);\nla duplication instantanée sur un même projet avec git cherry-pick;\n\nNous discuterons ici de la seconde approche uniquement, la première étant rarissime dans des workflows usuels centrés sur les pull requests et prédatant l’existence de systèmes type GitHub, GitLab, etc. Elle reste toutefois très prisée dans les cercles du développement système bas niveau, car elle se prête un peu mieux aux signatures numériques et à leur outillage historique.\nSi vous êtes intéressé par la première, nous vous recommandons de parcourir cette section du « Git book ».\nSi nous nous inscrivons dans une logique de versions actives multiples comme vu précédemment avec une release-2 et une release-3, il n’est pas impossible qu’un problème sur la version 3 ne soit également présent sur la version 2 (ou inversement selon l’endroit où le bug est détecté en premier lieu). On aimerait alors reporter un ou plusieurs correctifs sans devoir reproduire le code manuellement.\nOn commencera alors par créer une branche de correction depuis l’endroit où l’on a détecté le bug (disons 3.1.0) pour y effectuer nos commits de correction.\n\nUne fois nos correctifs apportés, validés, fusionnés dans release-3 et tagués (3.1.1) pour être déployés, nous nous apercevons que le bug concerné est également présent dans notre version 2. Nous souhaitons alors reporter les correctifs dans release-2.\n\n\nDe même que pour la 3 nous passons à travers nos étapes de validation pour aboutir à un déploiement de cette nouvelle version 2.2.1.\nIl en va de même pour un éventuel report sur notre branche de développement principale master :\n\nOn se retrouve alors avec une version de master à jour et sur laquelle on pourra mettre à jour les branches en cours de développement si celles-ci nécessitent l’intégration des correctifs, grâce à la commande git rebase.\nL’exemple suivant montre une branche fonctionnelle en cours de développement nommée feat-subject-1 basée sur le tag de version 3.0.0 de master. Cette dernière ayant évolué suite à l’application d’un correctif, nous « rebasons » feat-subject-1 sur master pour bénéficier de la mise à jour : git rebase master feat-subject-1.\n\nSi la stratégie de rebase ne nous satisfait pas, nous pouvons à la place appliquer git cherry-pick.\n\nNote : notez que notre branche étant en cours de développement nous pouvons y reporter directement les correctifs sans passer par une sous branche.\nCas particulier des commits multiples\nLors de rares occasions vous aurez à gérer une branche de correction intégrant plusieurs commits.\nAdmettons par exemple que notre branche hotfix-3.1.1 ait intégré 3 commits : x, y et z. Nous souhaitons récupérer l’intégralité sur une branche hotfix-2.2.1 pour fusionner dans release-2, mais sans créer de bruit/commit inutile.\nDeux approches sont alors possibles pour faciliter le report :\nLa branche de correction n’a pas été fusionnée\nDans ce cas vous avez la possibilité de regrouper vos commits pour n’en produire qu’un définitif à l’aide du squash :\n\nReste alors à cherry-picker le commit unique de hotfix-3.1.1 sur la branche hotfix-2.2.1.\nLa branche a été fusionnée\nOn souhaite alors récupérer la totalité des commits x, y et z pour ne produire qu’un commit unique sur la branche destinataire :\n\nEt voilà, le tour est joué !\nEt maintenant ?\nAllez explorer le reste de cette série d’articles !\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques\nCorriger des bugs (cet article)\nDéfinir les conventions d’un projet\n\n",
		"description": "Oh non, la prod’ est H.S., comment corriger et s’assurer de la qualité des corrections",
		"date": 1506902400,
		"image": "/assets/images/art-vid/art-git-workflows-fix-bugs.jpg",
    "_tags": ["git"],
		"title": "Workflow Git : corriger les bugs",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-workflows-fix-bugs/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Précédemment dans « Workflow Git »…\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques (cet article)\nCorriger des bugs\nDéfinir les conventions d’un projet\n\nLivrer et maintenir des versions publiques\nSelon le type de projet que nous menons, nous pouvons souhaiter la mise en place d’un système de numérotation des versions.\nUne pratique très répandue dans le développement logiciel a été formalisée dans ce sens et nommée Semantic Versioning.\nElle comprend à 3 niveaux de numérotation : X.Y.Z\n\nX / majeure : version sans compatibilité ascendante ;\nY / mineure : pour les évolutions fonctionnelles n’introduisant pas d’incompatibilité ;\nZ / patch : pour les correctifs.\n\nSi nous reprenons l’exemple de l’article précédent et que nous considérons feature-1 et feature-2 comme deux évolutions fonctionnelles mineures, et que master était précédemment dans une version stable 1.0.0, alors voici ce que nous obtiendrions :\n\nVersions multiples\nSi nos projets intègrent de la maintenance applicative, nous pourrons être amenés à gérer des versions majeures en parallèle, jusqu’à la fin de leur maintenance.\nPrenons l’exemple d’un socle logiciel que nous développons. Celui-ci a été vendu dans sa version 1.0.0 au moment T1 à plusieurs clients bénéficiant d’évolutions jusqu’à T2 et d’une maintenance jusqu’à T4. Un plan est déjà prévu pour produire une version suivante 2.0.0.\nLa stratégie commerciale de notre société n’intègre pas les migrations entre versions majeures pour nos clients. Aussi, lorsque nous aurons développé la version 2.0.0 du logiciel à T2, nos clients/utilisateurs précédents ne pourront pas en bénéficier par simple mise à jour.\n\nIl nous faudra alors gérer indépendamment la maintenance de notre version 1.0.0, puis celle de notre 2.0.0 lorsqu’elle aura été livrée.\nPlusieurs stratégies peuvent alors être mises en place :\n\nl’isolement complet des versions sous forme de projets distincts (plus complexe et limité) ;\nl’utilisation de schémas de branches de releases.\n\nDans notre exemple, nous utilisons cette seconde stratégie : nous créons sur notre projet à l’endroit de notre tag 1.0.0 une branche que nous nommons release-1. Cette branche ne sera jamais fusionnée vers sa branche parente, mais sera abandonnée au terme de sa maintenance (suppression de l’étiquette de branche : git branch -D release-1 et git push --delete release-1).\nNous entamons alors un cycle de projet distinct sur cette branche avec sous-branches fonctionnelles et sous-branches correctives.\n\nNote : une fois une branche de release arrivée au terme de sa maintenance, nous pourrons vouloir tagger le dernier emplacement de cette branche puis supprimer son étiquette de manière à ne pas polluer le reste de notre affichage de log Git par exemple (exemple dans le schéma avec le tag 1.3.0 (encore une convention à définir 😅* ).*\nCette approche de gestion des releases peut varier et nous pouvons vouloir gérer des branches dites de release afin de produire une nouvelle version (mineure et/ou majeure).\nPar exemple, la branche release-2.0.0 serait créée à partir du tag 1.0.0 de master et contiendrait le travail qui aboutira à la version 2.0.0 une fois fusionnée sur master.\n\nEt maintenant ?\nAllez explorer le reste de cette série d’articles !\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques (cet article)\nCorriger des bugs\nDéfinir les conventions d’un projet\n\n",
		"description": "Une nouvelle évolution de notre logiciel est terminée, comment l’identifier ?",
		"date": 1506902400,
		"image": "/assets/images/art-vid/art-git-workflows-releases.jpg",
    "_tags": ["git"],
		"title": "Workflow Git : gérer les versions publiques",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-workflows-releases/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Précédemment dans « Workflow Git »…\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle (cet article)\nLivrer et maintenir des versions publiques\nCorriger des bugs\nDéfinir les conventions d’un projet\n\nDévelopper des fonctionnalités en parallèle\nQue nous travaillions seul ou à plusieurs, il est un réflexe important à acquérir et qui consiste à isoler systématiquement chaque ensemble de développement. Cet isolement se fait à l’aide des branches.\nL’inconvénient que cela pose dans un workflow centralisé, c’est l’aspect mono-branche du dépôt partagé (souvent en SVN/CVS) qui rend difficile la parallélisation des tâches.\nAdmettons que nous ayons au sein d’une équipe des groupes de développeur·se·s travaillant chacun·e à un sous-ensemble fonctionnel du projet :\n\nEstelle et Xavier sur feature-1,\nJonathan et Marie sur feature-2.\n\nAvec un dépôt central mono-branche unique, avoir une version stable à un instant donné relève de l’impossible, puisque quand feature-1 sera terminée, il est fort probable que feature-2 soit encore en cours de développement et donc pollue le projet, empêchant un déploiement en production.\n\nEn isolant alors le développement de chaque lot sur une branche dédiée, on s’assure que les lots rapatriés sur la branche centrale/de production (ici master) seront terminés.\nCe principe est couramment appelé Feature Branching car il encourage la création d’une branche par fonctionnalité.\nCréation de la branche feature-1 par Estelle et partage via le dépôt distant :\n\nXavier récupère la nouvelle référence de branche pour pouvoir travailler dessus également :\n\nEstelle et Xavier réalisent alors des tâches sur cette branche, déclinant au besoin des sous-branches sur leur poste/en local.\nEn parallèle, Jonathan a également créé une branche.\nIl commence à travailler dessus et produit quelques commits avant de la partager sur le dépôt central pour que Marie puisse également y participer :\n\nMarie récupère cette branche et y contribue :\n\n\nUne fois le travail terminé par l’un des deux groupes, disons feature-2 par Marie et Jonathan, cette branche pourra être fusionnée sur sa branche de départ, à savoir master.\nMarie se charge de ce travail :\n\nElle en profite également pour supprimer l’étiquette de branche locale et son équivalent distant (cela ne supprime pas l’historique, juste l’emplacement du nom de branche) :\n\n\nLa branche master est alors dans un état stable et ne contient que feature-2, pas feature-1.\nUn déploiement de l’application est donc envisageable depuis la branche master.\nMarie et Jonathan peuvent ensuite débuter de nouvelles tâches pour d’autres sous-ensembles fonctionnels sur des branches dédiées bien entendu.\nQuant à Xavier et Estelle, ils pourront fusionner leur branche dans master quand celle-ci sera terminée. En cas de conflits avec les modifications apportées par feature-2, une fusion manuelle pourra s’avérer nécessaire. Heureusement, pour l’essentiel des différences, les algorithmes de Git effectueront un traitement automatique.\nNote : l’option --no-ff force la conservation de la « bosse » de la branche feature-2dans l’historique (à savoir son point de départ et d’arrivée depuis et dans master), à l’instar du « fast-forward » , option par défaut (--ff). Cette option peut-être modifiée dans la configuration globale (git config --global merge.ff false) ou locale au projet (git config merge.ff false).\nBien nommer ses branches\nPour ne pas nous perdre dans nos schémas de branches il est important de définir des conventions de nommage tout comme nous l’avions vu précédemment pour nos commits.\nLe dernier article de cette série vous aidera à formaliser ces besoins et définir vos conventions.\nEt maintenant ?\nAllez explorer le reste de cette série d’articles !\n\nObjectifs et principes généraux\nDévelopper des fonctionnalités en parallèle (cet article)\nLivrer et maintenir des versions publiques\nCorriger des bugs\nDéfinir les conventions d’un projet\n\n",
		"description": "Développer des fonctionnalités en parallèle, limiter la concurrence et favoriser la qualité, ça n’est pas bien difficile !",
		"date": 1506902400,
		"image": "/assets/images/art-vid/art-git-workflows-parallel-features.jpg",
    "_tags": ["git"],
		"title": "Workflow Git : développer des fonctionnalités en parallèle",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-workflows-parallel-features/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Choisir ou définir un workflow…\nQuand on démarre avec Git, on commence toujours par la technique, les commandes, les subtilités techniques…\n…Puis vient le moment du workflow. Celui où on essaie de mettre la méthodologie au propre, d’être cohérents sur la durée, de rationaliser tout ça. Et là, c’est un peu souvent le chantier. Git en soi est suffisamment flexible et ouvert pour ne pas imposer de workflow particulier, de sorte qu’on en trouve une pléthore, sans même parler des workflows « maison ».\nAinsi, en raison principalement de son antériorité, le Git Flow de Vincent Driessen est encore souvent sur le devant de la scène, même si, à l’usage, il s’avère souvent trop compliqué, avec des aspects contextuellement superflus. GitHub, GitLab et BitBucket, les 3 principaux éditeurs de solutions autour de Git, proposent tous peu ou prou la même approche : GitHub Flow, GitLab Flow, etc. qui se concentrent sur le recours aux pull/merge requests et la notion de feature branching, sans aller beaucoup plus loin (mais c’est déjà pas mal).\nNous avons donc décidé de pondre une petite série d’articles illustrant nos recommandations en matière de workflow de développement basé Git.\nDans cette série…\n\nObjectifs et principes généraux (cet article)\nDévelopper des fonctionnalités en parallèle\nLivrer et maintenir des versions publiques\nCorriger des bugs\nDéfinir les conventions d’un projet\n\nObjectifs\nOn cherche à…\n\nfaciliter le travail en équipe ;\noptimiser notre propre travail (bosser plus vite, sans gaspillage d’effort) ;\ngagner en qualité ;\nfaire converger la gestion de projet et le développement.\n\nEn pratique, les besoins du workflow varieront d’un contexte projet à l’autre, en termes de complexité de la gestion projet et des ressources humaines. Les principales questions qui déterminent l’ampleur de nos besoins sont :\n\nQuel type de projet doit-on développer ? (logiciel avec releases, projet client « one shot »…)\nDans quel laps de temps ?\nQuelles sont les technologies utilisées, quelle est l’architecture technique du projet ?\nQuel est le nombre d’intervenants ? Comment utilisent-ils Git ? (CLI, GUI, interfaces web…)\nQuelle est la méthodologie en place ? (Agile, Scrum, cycle en V…)\n\nPar exemple, nul besoin d’un workflow complexe pour pondre un site institutionnel client mono-techno sur 1 mois à 3 intervenants (1 développeuse, 1 intégratrice, 1 chef de projet). C’est pourquoi tous les articles de cette série ne seront pas forcément pertinents pour tous les projets.\nPrincipes généraux\nQuel que soit le besoin, technique ou opérationnel, auquel on répondra à l’aide de Git, on veillera toujours à respecter quelques principes fondateurs, qui vont orienter le détail de nos manipulations.\nVous pouvez tout à fait opter pour une mise en place progressive de ces savoirs et approches : une bascule brutale de méthodologie n’est pas toujours aisée ni pertinente…\n1. Produire un historique clair\nAussi bête que cela paraisse, il n’est pas facile de produire un historique clair. La principale difficulté est d’encourager les membres d’une équipe à produire des commits dits atomiques. Ce terme vise à exprimer qu’un commit doit contenir un ensemble de travail cohérent et exploitable.\nPour cela il faut respecter certaines règles élémentaires :\n\ndécouper les tâches les plus fines possible sans entremêler des sujets et faire de chacune un commit;\nnommer ce travail de la manière la plus concise possible en une ligne, complétée éventuellement d’une description plus exhaustive (lignes suivantes).\n\nLes commits produits doivent pouvoir être analysés et exploités par nos collègues (ou vous même dans 3 mois). Ils devront pouvoir être extraits pour être appliqués sur un autre projet ou un autre endroit de notre projet (ex : report de correctif de bug).\nPour faciliter la mise en place de règles spécifiques ou conventions de nommage des commits au sein d’une équipe, on trouve des solutions d’aide à la saisie telles que commitizen, exploitable avec des conventions pré-établies comme le conventional changelog.\nAinsi on réduit le facteur d’erreur lié à une saisie 100% manuelle.\n2. Isoler les lots de développements\nNous pouvons étendre nos conventions pour modéliser les sous-ensembles thématiques/fonctionnels sous forme de branches.\nOn isole leur développement en créant une branche pour chaque lot. Nos conventions décriront l’organisation des branches tout comme leurs noms.\nLes avantages sont alors multiples :\n\nOn améliore la lecture de l’historique ;\nOn parallélise les développements des lots fonctionnels ;\nOn facilite les processus de qualité en encourageant des validations lors des fusions/fermetures de branches.\n\n3. Refléter la méthodologie du projet\nIl peut s’avérer très utile de retranscrire notre méthodologie projet au sein de notre schéma de branche.\nPrenons l’exemple de Scrum\nDans notre équipe, nous considérons que chaque epopée/epic représente un ensemble fonctionnel livrable.\nCes épopées sont ensuite découpées en sprints successifs, eux mêmes découpés e",
		"description": "Travailler seul ou à plusieurs, gagner en qualité et en performance… comment améliorer notre façon de travailler ?",
		"date": 1506902400,
		"image": "/assets/images/art-vid/art-git-workflows-generality.jpg",
    "_tags": ["git"],
		"title": "Workflow Git : objectifs et principes généraux",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-workflows-generality/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Les sessions du 2e trimestre 2018 sont arrivées, avec en particulier 2\nsessions Webpack, celle inaugurale de février ayant tout vendu en quelques\njours !\n\nNouvelles dates Q2\nAvril\n\n04–06/04/2018 : Webpack\n10–13/04/2018 : Web Apps Modernes\n\nMai\n\n02–04/05/2018 : ES Total\n16–18/05/2018 : Git Total\n22–25/05/2018 : Web Apps Modernes\n28–31/05/2018 : Node.js\n\nJuin\n\n06–08/06/2018 : Webpack\n19–22/06/2018 : Web Apps Modernes\n27–29/06/2018 : Git Total\n\nPour rappel : les dates Q1\nJanvier\n\n16–19/01/2018 : Web Apps Modernes\n23–26/01/2018 : Node.js\n31/01–02/02/2018 : Git Total\n\nFévrier\n\n07–09/02/2018 : ES Total\n21–23/02/2018 : Webpack\n28/02–02/03/2018 : Git Total\n\nMars\n\n13–16/03/2018 : Web Apps Modernes\n27–30/03/2018 : Node.js\n\nAu plaisir de vous former !\n",
		"description": "Tout plein de nouvelles dates de formations pour le 2e trimestre 2018 : Webpack, ES Total, Git, Node.js, Web Apps Modernes…",
		"date": 1512345600,
		"image": "/assets/images/art-vid/art-est-wp.jpg",
    "_tags": ["formations","annonce"],
		"title": "Les sessions Q2 2018 sont arrivées !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/nouvelles-dates-q2-2018/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Lorsque je développe et que je partage mon historique sur des projets, j’aime me rassurer en me disant que ce que je produis est clair, utile et aussi optimal que possible.\nAuparavant, quand je regardais un historique, je constatais parfois qu’il était difficile à lire, à analyser, donc pas ou peu exploitable. Désormais, je vise des commits de qualité, pas un ramassis de fix stuff en mode fourre-tout !\nPar « commit de qualité », j’entends 2 choses :\n\nje veux un contenu et un code optimaux ;\nl’historique résultant doit être précis et exploitable.\n\nBien entendu, en bon fainéant, je ne souhaite pas devoir me poser ces questions pour chaque commit, donc je vais automatiser un max.\nÇa tombe bien, pour ça j’ai Git et ses hooks :\n\npre-commit : pour analyser, éventuellement retravailler mon code ;\ncommit-msg : pour vérifier mon message de commit ;\npre-push : dernière vérification avant partage (envoi au serveur).\n\n\nMettre en place tout ça facilement et partager…\nEn revanche, Git peine à nous proposer l’automatisation de la mise en place au sein d’un projet ou d’une équipe (malgré la 2.9 et son git config core.hooksPath …).\nPour palier à ça on va utiliser npm et un super module nommé husky (version 7) dont le but est d’enrober les hooks (en les créant si nécessaire) et d’intégrer leur gestion dans un sous-répertoire .husky à la racine du projet (husky fait appel implicitement à core.hooksPath).\nPour te faciliter la tâche on t’a gentiment créé un gabarit de projet GitHub 😘 : deliciousinsights/dev-automation.\nSi tu préfères une mise en place « à la mano », voici comment procéder :\nDans ton terminal :\n\nPuis, toujours dans ton terminal, selon l’outillage que tu souhaites mettre en place, indique à husky quels scripts tu veux exécuter, pour quelles actions Git :\n\nUn avantage non négligeable d’avoir les scripts husky intégrés au projet tient à ce que je peux désormais appeler des scripts propres au projet. Si j’ai créé des scripts dans un sous-répertoire git-hooks je peux les appeler depuis ma configuration husky. Voici un exemple pour le pre-commit :\n\nNote : je tiens à préciser qu’il n’est pas nécessaire de travailler avec du JavaScript pour mettre en place husky. L’avantage de cette approche est qu’elle fonctionne partout 😁.\nAnalyser le code avant le commit\nJe ne sais pas pour toi, mais j’ai beau essayer d’être un super-héros-développeur, parfois je fais un peu n’importe quoi… J’oublie des choses dans mon code, j’oublie certaines conventions qu’on est censés utiliser au sein des projets (typiquement le formatage du code).\nPeu m’importe les raisons, le résultat est le même : mon code ne respecte pas les conventions, avec des trucs qui traînent dedans qui ne devraient pas y être. Et en regardant un peu autour de moi je m’aperçois que ne suis pas le seul à faire ce genre d’erreur (ça rassure de savoir qu’on est tous capables de faire des erreurs 😅).\nReste donc à trouver des outils pour nous guider et nous corriger.\nMon deuxième cerveau (alias Christophe, mon boss) m’avait déjà trouvé un outil formidable capable d’auto-formater mon code dans plein de langages (JS, CSS, HTML, SCSS, Markdown, JSX…) : Prettier. On l’utilisait déjà dans notre éditeur VSCode (à la sauvegarde, on préfère). Mais au cas où il déconnerait, ou si un contributeur à mes projets décide d’utiliser un autre éditeur sans Prettier, alors je veux garantir que son code soit quand même reformaté.\nL’idée est simple : il faut exécuter Prettier sur le code qui va être commité quelle que soit la personne qui contribue. Plusieurs modules npm existent à cet effet, mais un des rares qui fasse bien le travail (à savoir traiter juste les contenus stagés) est lint-staged (j’utilisais auparavant precise-commits, mais le projet n’est malheureusement plus maintenu).\nDans ton terminal :\n\nIl me reste encore à éviter de laisser traîner des trucs dans mon code. Pour ça je n’ai pas trop trouvé d’outil me permettant de configurer et d’étendre le comportement/l’analyse au sein de mon projet, alors j’ai créé le mien 🤘, et pour faire original je l’ai appelé git-precommit-checks.\nCet outil me permet d’empêcher le commit de se terminer (donc d’être créé) dès lors que dans les ajouts/modifications on trouve des marqueurs de conflits, des console.log… dans mes fichiers JS, etc. Des messages d’errreur sont affichés sur la sortie standard pour décrire l’origine des problèmes et les fichiers concernés.\nJe regarde également si j’ai laissé des FIXME ou TODO, auquel cas j’affiche juste un avertissement sans bloquer le commit.\n\nIl faut ensuite créer le fichier git-precommit-checks.config.js dans lequel tu définiras tes règles. Voici un exemple :\n\nUne fois ceci en place, voici le type d’affichage qu’on peut obtenir dans le terminal en tentant un commit avec des textes filtrés :\n\nGarantir un message bien rédigé\nBon là c’est plus difficile… ou pas !\nChez Delicious Insights on a choisi pour nos messages de commits de suivre la norme des commits conventionnels (héritée du conventional changelo",
		"description": "Optimisez vos contenus et messages de commit grâce aux hooks Git.",
		"date": 1546473600,
		"image": "/assets/images/art-vid/art-git-hooks-commit.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Hook’il est mon beau commit ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-commit/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "On voulait lancer une activité de cours vidéos depuis longtemps, en parallèle à nos formations présentielles. C’est désormais chose faite, avec le premier cours de ce qui sera, on l’espère, une longue série : Faire du JavaScript asynchrone moderne.\n3h de vidéos sur 3 parties, plus de 40 exemples de code : des callbacks nus à async/await en passant par le débogage et les promesses, on couvre tout (et en profondeur).\nDans cet article, nous avons voulu vous expliquer la génèse de ce projet et vous donner quelques infos sur la suite…\n\nUne envie de longue date\nHistoriquement, Delicious Insights a toujours fait de la formation présentielle. Nous tenons absolument à ce format, qui est le seul à permettre une interaction riche avec nos apprenant·e·s, non seulement afin de permettre la transmission dense de savoirs complexes, mais aussi parce que ça nous fournit tout un tas de retours d’expériences différents qui enrichissent notre propre compréhension du marché, notre vision des problématiques, et la contextualisation de nos explications.\nEt puis humainement, c’est ce qu’il y a de plus sympa 😀. On limite nos sessions à 10 personnes, volontairement, pour que la qualité humaine et pédagogique soit préservée. Il y aura toujours du présentiel chez Delicious Insights, ça fait partie de notre ADN.\nCeci étant dit, ce format strictement présentiel présentait des limites en termes de contenu et de marché (et de sa volatilité récente), mais aussi des frustrations : avoir la formation présentielle comme seul axe de revenu se faisait au détriment des travaux non-rémunérateurs que nous voulons pouvoir effectuer plus largement : contributions open-source, articles, présentations en conférences, etc.\nBien sûr, des articles techniques et présentations en conférence permettent de toucher un plus grand public, et sur des sujets variés. Et de fait, nous voulons dégager du temps pour ces contributions gratuites ainsi que pour l’open-source. Mais tout ça ne viendrait pas compenser le manque à gagner qu’un nombre moindre de sessions entraînerait.\nIl était donc indispensable de varier nos canaux de revenus, un excellent moyen étant la production de contenus numériques payants. Dans ce contexte, les cours vidéos étaient clairement favoris, car ils avaient de nombreux avantages :\n\nOn a déjà une bonne expérience de la production de contenus vidéos (même si la forme reste professionnalisable).\nLe format est très flexible et se prête aussi bien à des cours longs (10+ heures) qu’à des formats chirurgicaux (≤ 1h).\nLe coût de production ne nécessite pas de gros volumes de vente pour, au moins, être à l’équilibre.\nLa déclinaison VF / VA est facile et permet d’adresser à moindre coût le marché mondial IT, très largement supérieur au marché francophone (et plus enclin à payer).\nC’est du revenu 100% passif : une fois le produit publié et le marketing lancé, le coût résiduel est négligeable (même en incluant le support, les mises à jour et les piqûres de rappel marketing).\nÇa facilite la collaboration avec des expert·e·s externes sur des sujets précis, car ça nécessite moins de dispos et d’engagement de leur part que de la formation catalogue en présentiel.\n\nDes sujets à foison\nPour le coup, ce ne sont pas les sujets qui manquent ! On a une solide expertise sur un paquet de trucs, par exemple l’accessibilité la CI/CD, Git, GitHub, GraphQL, JavaScript, Node.js, les performances web, React, Redux, Ruby &amp; Rails, la sécurité, l’utilisation avancée des terminaux / lignes de commande, les tests automatisés, VS Code, Webpack…\nLe plus dur, c’est de choisir, finalement, quels cours attaquer en priorité !\nLe choix du premier cours\nPour diverses raisons, notre premier cours devait répondre à de multiples critères :\n\nNe pas nécessiter de recherches supplémentaires\nPouvoir être produit en moins de 3 semaines\nÊtre transverse / universel, afin de toucher un public le plus large possible\nApporter une solution à un vrai point de faille chez le public cible (ex. nombreuses incompréhensions / manque de maîtrise)\nTenir dans un format « moyen » (≤ 3h) afin de proposer un tarif équilibré (≤ 30 € TTC)\n\nDu coup, parmi le vaste champ des possibles, un gagnant s’est vite imposé, et ça a donné Faire du JavaScript asynchrone moderne.\n\nOn y couvre en détail, sur 3h de vidéos et avec plus de 40 exemples de code, des aspects suivants :\n\nCallbacks nus et « façon Node »\nDébogage asynchrone\nPromesses\nasync/await\n\nAfin de satisfaire l’ensemble des critères, on a en revanche choisi d’en exclure trois sujets connexes : la bibliothèque async.js (tout de même évoquée), les générateurs (pas à proprement parler asynchrones, mais y’a un rapport quand même) et les observables (façon RxJS). On en parlera sûrement un jour… dans d’autres cours 😉.\nEn français… et en anglais\nLe cours a débuté vendredi 14 juin 2019 avec une version française uniquement. Le site anglophone pour nos screencasts, et la version anglaise du cours, devraient a priori être disponibles d’ici la fin juin 2019.\nSi vous",
		"description": "Notre premier cours vidéo est sorti ! 3h et 40+ exemples de code pour seulement 29€, le cours haut de gamme de référence.",
		"date": 1560470400,
		"image": "/assets/images/art-vid/art-screencast-async.jpg",
    "_tags": ["annonce","cours vidéos","js"],
		"title": "Faire du JS asynchrone : notre nouveau cours vidéo",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/screencast-js-asynchrone/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Le log de Git est un outil formidable pour analyser l’historique des commits et resituer un contexte. Il nous permet aussi bien de suivre un projet dans sa globalité que dans ses détails : fonctionnalités, correctifs, fichiers et répertoires, auteurs, dates…\nMême si de nombreuses interfaces graphiques proposent ce type d’analyse, aucune n’exploite le potentiel complet de la commande. C’est pourquoi cet article décrira exclusivement l’utilisation de git log dans le terminal.\nMais avant de rentrer dans les descriptions techniques, concentrons-nous sur les cas d’utilisations.\n\nLe log pour quoi faire ?\n\nAfficher un historique pour se resituer\n\nLimiter la profondeur/le nombre de commits affichés\nLimiter le suivi à certains fichiers et répertoires\nVoir les modifications introduites par chaque commit\n\n\nVoir l’historique récent des branches\n\ncibler une branche dédiée\ncibler un motif de branche (feat/*)\n\n\nVérifier le travail terminé\n\nVoir les fusions effectuées\nLister les commits entre 2 versions\n\n\nRechercher\n\nDans les métadonnées du commit : dates, auteur, message…\nDans les modifications introduites par les commits :\n\nles ajouts et suppressions du texte recherché\nles changements survenus autour d’un texte connu (sur la même ligne)\n\n\nDans un fichier précis, les évolutions d’un fragment (typiquement le corps d’une fonction/méthode)\n\n\nObtenir des statistiques pour le projet\n\nCette liste n’est pas exhaustive et il existe de nombreuses règles d’affichage et de filtrage que nous n’explorerons pas ici.\nNotez pour la suite que la plupart des options décrites sont cumulables.\nConfiguration : définir un comportement optimal par défaut\nAvant de commencer à explorer les détails de la commande, il nous faut configurer deux choses importantes :\n\nle suivi par défaut des renommages des fichiers à travers l’historique ;\nun alias pour un log graphique, essentiel à une utilisation agréable dans le terminal.\n\nSuivi des renommages\nVous aurez parfois besoin d’analyser les évolutions d’un fichier à travers votre historique et ce indépendamment des éventuels renommages ou déplacements qu’il aurait pu subir.\nCe suivi peut s’effectuer avec l’option git log --follow, mais autant ne pas avoir à y penser et la configurer pour être systématique :\n\nUn affichage agréable et pratique : git lg\nL’affichage par défaut du log est compliqué, difficilement exploitable. C’est un frein à l’utilisation de Git en ligne de commande.\nOn va donc définir un alias git lg qu’on utilisera la plupart du temps à la place du git log standard et qui nous présentera un historique arborescent et synthétique, facile et agréable à lire :\n\nEt voilà le résultat, plaisant non 🤩 ?\n\nAlternative sans alias\nSi vous préférez redéfinir le comportement d’affichage par défaut du log, vous pouvez renseigner les clés de configuration suivantes :\n\nÇa ne vous dispensera cependant pas de l’option --graph. C’est pourquoi je pense que l’alias reste plus avantageux.\nMaintenant qu’on a un log tout beau tout propre on va pouvoir s’attaquer aux aspects utiles de la commande.\nAfficher un historique pour se resituer\nLe comportement du log par défaut consiste à afficher l’historique de la référence courante depuis son tout premier commit. C’est loin d’être idéal, aussi voudra-t-on souvent restreindre cet affichage aux X derniers commits. Voici un exemple qui n’affiche que les 10 derniers commits depuis la position courante de HEAD :\n\nIl est fréquent de ne vouloir afficher que les commits modifiant un ou plusieurs fichiers ou répertoires :\n\nÇa marche même avec des globs 🤘 :\n\nEt pour voir les contenus modifiés par chacun des commits :\n\nL’affichage vous paraîtra peut-être long/volumineux car il présente le contexte des modifications. Heureusement la commande log bénéficie des options d’affichage de sa cousine diff. Vous pouvez par exemple :\n\nn’afficher que les noms des fichiers : --name-only (--name-status pour savoir s’il s’agit d’un·e ajout/modification/suppression).\nafficher les modifications sur la même ligne (plutôt que sur deux lignes) avec l’option --word-diff ou --word-diff-regex=… ;\nfiltrer sur les modifications (M), ajouts (A), suppressions (D)… avec par exemple --diff-filter=AD ;\nrestreindre les lignes de contexte en ajoutant l’option --unified=0 (0 indique ici qu’on ne souhaite pas de ligne de contexte) ;\n\nMon conseil pour l’affichage des patches/diffs : installez diff-so-fancy, cet utilitaire vous fournira un affichage concis et pratique.\nEt les branches dans tout ça ?\nLe comportement du log par défaut n’affiche que l’historique de la référence courante. On peut cependant cibler des branches particulières :\n\nOn reste cependant dans un listing explicite, qui ne permet du reste pas de globbing. Pour afficher toute une catégorie de branches nous pouvons utiliser au choix :\n\nl’option --branches pour afficher les branches locales ;\n\n\n\nl’option --all pour afficher en plus les branches distantes, les tags, les stashes et d’une façon générale toute référence nommée connue du dépôt.\n\n\nLa premi",
		"description": "Apprenez à lire votre log et y rechercher des informations utiles",
		"date": 1560816000,
		"image": "/assets/images/art-vid/art-git-log.jpg",
    "_tags": ["tutoriel","git"],
		"title": "git log : qui suis-je ? D’où viens-je ? Où vais-je ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-log/",
		"locale": "fr",
		"readingTime": "9 min"
	},	{
		"content": "Chez Delicious Insights on a une expertise Git reconnue, notamment avec notre formation Git Total. Les années passant on a écrit pas mal de choses sur différents sujets, on avait même un site “git-attitude” dédié. Ce qui manquait et qu’on nous a régulièrement demandé, c’est un fil conducteur pour parcourir nos articles (mais pas que) et apprendre Git. En résumé un guide d’apprentissage de Git. Il est donc temps qu’on s’y colle !\n\nOn va droit au but et on commence avec de la configuration :\nInstallation et configuration\nPour l’installation, on propose un guide qu’on met régulièrement à jour.\nEnsuite il faut apporter quelques touches de personnalisation pour optimiser le comportement de Git. On paie ici le prix de la rétro-compatibilité souhaitée par la communauté. En gros toutes les nouveautés qui modifient des comportements de Git sont de base désactivées et doivent être consciemment activées via la configuration.\nNotre objectif ici n’est pas de te décrire le fonctionnement ni même le détail de la conf, pour ça tu as accès à notre configuration partagée qu’on a gentiment documentée, et sinon l’article (qui commence à dater un poil) « Une configuration Git aux petits oignons ».\nSi tu es utilisateur·rice du terminal (hors ZSH) tu voudras probablement le tuner pour avoir certaines informations dans le prompt sans avoir à faire par exemple un git status. Voici l’article qui va bien : « Un prompt Git qui déchire ».\nComme on est sympas on t’a fait un petit script qui permet de gérer la configuration et la personnalisation du prompt. On ne garantit pas qu’il marche pour tout le monde, alors au pire, tu suis la procédure des articles référencés précédemment.\nPour travailler avec un serveur Git, il est important de pouvoir automatiser la connexion. Pour ça on passe par ce qu’on appelle des clés asymétriques. Pour tout savoir là-dessus, lis donc l’article « Comprendre et maîtriser les clés SSH », un de nos plus gros succès !\nApprendre Git\nGit est très utilisé, populaire, tout ça tout ça… Du coup on trouve pléthore de docs plus ou moins bien fichues, mais il reste parfois des zones d’ombre, ou simplement certains sujets qui sont mal traités à notre goût. C’est ça qui a motivé l’écriture de la plupart de nos articles.\nAvant de foncer tête baissée…\n… je te fais quelques recommandations pour préparer ton apprentissage.\nGit est un support, un outil dont il faut retenir avant tout les concepts fonctionnels. Les aspects techniques sont secondaires, tout comme les commandes. Tu les retrouveras dès lors que tu auras bien en tête à quoi te sert Git et ce que tu souhaites en faire.\nPour bien apprendre, voici les étapes clés qu’on te recommande :\n\nComprendre les concepts clés et tes attentes :\n\n\nles zones, les états des fichiers\nce que tu veux mettre dans une révision/un commit (un ou plusieurs fichiers, une partie des modifs d’un fichier…)\nce que tu veux retranscrire dans un historique (à quoi doit ressembler «graphiquement» l’histoire de ton projet, et pourquoi ?)\nisoler / paralléliser du travail (intérêt fonctionnel des branches)\ntravailler seul·e ou à plusieurs\n\n\nLes commandes de base\n\n\npour construire un commit, un historique (add, commit, restore)\npour analyser un historique (état des fichiers status, modifications apportées diff, lecture de l’historique log)\npour manipuler les branches (visualiser, créer branch, travailler switch/restore, fermer et intégrer un travail merge)\npour modifier un historique (derniers commits reset, ou plus large rebase)\n\n\nPlus dans le détail des commandes (options avancées, astuces…)\n\nMaintenant, les ressources utiles\nPour la base, tu peux regarder notre cours vidéo gratuit « Les concepts clés de Git », que tu peux aussi retrouver sur notre chaîne Youtube « Apprendre Git ».\nUne fois que tu as compris l’essentiel des mécanismes de base inhérents à Git, tu vas devoir apprendre les commandes usuelles. Tu peux alors choisir différentes approches :\n\nUn démarrage rapide avec le “everyday Git” qui résume les commandes les plus couramment utilisées ou avec cette “cheatsheet” dynamique imabattable !\nTu peux parcourir le « Pro Git Book », documentation fonctionnelle officielle.\nOu tu peux tenter d’apprendre à l’aide d’un tutoriel, en mode pas à pas.\n\nSi tu veux manipuler et visualiser certains comportements de Git, on te propose 2 ressources géniales :\n\nExplain Git With D3\nLearn Git Branching\n\nApprendre plus et mieux\nAprès ça tu vas probablement vouloir creuser certains sujets essentiels :\nComment visualiser mon historique et y trouver une info précise, l’évolution d’une méthode sur la semaine écoulée, les derniers commits d’un membre de l’équipe… Ça, c’est lié au log Git. Tu peux donc regarder l’article suivant, et même si tu n’es pas utilisateur·rice du terminal, tu y découvriras l’étendue de la puissance du log : « git log : qui suis-je ? D’où viens-je ? Où vais-je ? ».\nComment manipuler mon historique, en commençant par apprendre à défaire les choses, mais sans angoisse, car avec Git on ne supprime ",
		"description": "Découvrez nos ressources et notre méthodologie recommandée pour apprendre tout ce dont vous avez besoin au sujet de Git, de l’installation aux usages avancés, des fondamentaux aux astuces d’expert !",
		"date": 1581897600,
		"image": "/assets/images/art-vid/art-git-guide.jpg",
    "_tags": ["git"],
		"title": "Notre guide pour apprendre Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/apprendre-git/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Aaaah, le this en Javacript. Ce n’est pas que le sujet soit affreusement compliqué, c’est surtout que personne ne fait l’effort d’apprendre les quelques notions fondamentales du truc ; du coup, tout le monde se trimballe son modèle mental erroné, hérité de ses précédents langages.\nOn se plaint surtout du fait qu’en JavaScript, on a tout le temps l’impression de « perdre » son this. Le corollaire de ça est intéressant : si nos fonctions ne sont pas intrinsèquement liées à un this figé, cela veut dire que nous pouvons appeler une fonction avec un this spécifique, explicite, à notre goût. Eh oui, en JavaScript, this fait partie du contrat d’appel de la fonction, au même titre que ses arguments. Ce qui ouvre une foule de possibilités sympathiques.\n\nCe n’est pas ce que vous croyez\nÀ une exception près, JavaScript ne définit pas automatiquement this lors de l’appel d’une fonction. En fait, en mode strict et faute d’une définition explicite, à part l’exception en question, this sera toujours undefined. Voilà !\nPeu importe d’où vient la fonction, comment elle a été déclarée, etc. En JavaScript, this est défini au moment de l’appel de la fonction, et non par sa déclaration.\nCette fameuse exception, quelle est-elle ? Elle survient lorsqu’une fonction « traditionnelle » (déclarée avec le mot-clé function ou en syntaxe concise de méthode) est appelée avec la forme que j’appelle « sujet, verbe, complément » :\n\nSujet : un objet est utilisé au début de l’expression\nVerbe : on indexe une propriété de l’objet, propriété dont la valeur est notre fonction ; notez qu’il peut s’agir d’une indexation directe (opérateur .) ou indirecte (opérateur []), ça n’a aucune importance.\nComplément : on appelle la fonction obtenue immédiatement, à la volée dans l’expression (avec l’opérateur () contenant les éventuels arguments).\n\nPrenons par exemple le code suivant :\n\nSi je fais :\n\nÇa fonctionne bien. En décomposant l’expression, on trouve bien :\n\nLe sujet : wife\nLe verbe : greet\nLe « complément » : l’appel à la volée avec ()\n\nDans ce cas et dans ce cas seulement, JavaScript définit (entre autres) this dans le cadre de cet appel (techniquement, il remplit 4 entrées supplémentaires du Function Environment Record pour l’appel) en se basant sur le sujet. Dans le cas qui nous occupe, this vaudra wife, du coup dans la construction du texte, this.name vaudra wife.name, donc 'Élodie'.\n« Perdre » son this\n100% des autres cas reviennent en fait à référencer la fonction sans l’appeler, en tout cas au sein du terme d’expression concerné. Les possibilités sont infinies, par exemple :\n\nLe plus énervant, c’est lorsqu’on est dans une fonction de rappel depuis un contexte dont le this était le bon : la fonction de rappel est, par définition, passée sans être appelée à la volée ; c’est le mécanisme qui reçoit la fonction de rappel qui, justement, l’appellera le moment venu. Et là, kaboom !\n\nDéfinir this : une partie du contrat d’appel\nFinalement, en JavaScript, this fait partie du contexte d’invocation de la fonction, de son « contrat d’appel » en fait, au même titre que ses arguments (et notamment l’identifiant arguments, cette saleté) ou que super.\nMais alors, cela veut-il dire qu’on va pouvoir appeler une fonction en contrôlant explicitement son this ? Absolument !\nPrenez la signature complète de Array#forEach par exemple :\n\nIl est apparemment possible d’indiquer à forEach quel this utiliser le moment venu quand elle appellera notre fonction de rappel. Formidable !\n\nMais comment donc forEach fait-elle ? Elle n’a sous la main qu’un identifiant dont la valeur est notre fonction de rappel, sans autre indication. Comment l’appelle-t-elle pour préciser un this en plus des arguments ?\nDéfinir this quand on connaît les arguments\nElle pourrait utiliser une des méthodes disponibles sur toutes les fonctions : call.\nAlors oui, j’ai bien dit que les fonctions ont des méthodes. En JavaScript, les fonctions sont des objets, elles aussi. Ce sont des instances de Function, spécifiquement. Elles disposent donc de propriétés, qui sont soit des données (name et length, notamment), soit des fonctions (call, apply et bind, spécifiquement). Respire, tout va bien. Ce n’est pas sale, ton code change.\nAu lieu de simplement faire :\n\n…elle ferait plutôt ceci :\n\nLa méthode call d’une fonction permet de l’appeler en précisant d’abord le this à utiliser, puis les arguments éventuels. Note que ceux-ci sont passés individuellement, il faut donc en connaître la liste avant.\nAinsi, une implémentation naïve de forEach pourrait ressembler à ce qui suit. Afin de ne pas t’embrouiller davantage, on n’écrit pas une fonction censée exister comme méthode de tableau (this serait alors le tableau, ça rajoute de la confusion ici), on va lui faire prendre le tableau en premier argument.\n\nDéfinir this quand on ne connaît pas les arguments\nMais si on veut écrire un code générique, qui forcerait le this quels que soient les arguments ? C’est d’ailleurs ce que fait la méthode bind des fonctions : elle ",
		"description": "JavaScript ne lie pas intrinsèquement vos fonctions à des \"this\" précis… mais ça veut dire qu’il vous permet de les appeler explicitement avec un \"this\" donné !  À quoi ça sert, et comment faire ?",
		"date": 1582588800,
		"image": "/assets/images/art-vid/art-call-apply.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Appeler une fonction JavaScript avec un this explicite",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/call-et-apply-en-javascript/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Le 4 mai prochain, nous lancerons une série « 19 pépites de JS pur », avec un article quotidien (pas trop long, idéal pour grignotter…) sur un aspect du langage JavaScript pur ; astuce, meilleure pratique, capacité méconnue, démontage d’une idée reçue, démystification… : 19 raisons de revenir et de nous suivre pour ne rien rater !\n\nY’aura quoi ?\nOuh là, plein de trucs. Y’a du léger, y’a du lourd, y’a du réflexif…\n(Mise à jour 18 mai 2020 : les 15 premières sont listées dans l’ordre, et les 4 dernières annoncées.)\n\nDédoublonner efficacement un tableau\nExtraire efficacement une sous-chaîne de texte\nFormater proprement un nombre\nArray#splice\nStrings et Unicode\nCourt-circuiter plusieurs niveaux de boucles\nInverser deux valeurs avec la déstructuration\nRetirer facilement les « valeurs vides » d’un tableau\nVive les séparateurs numériques !\nTrier proprement des textes\nExtraire les emojis d’un texte\nDéfinir proprement des paramètres nommés optionnels\nconst is the new var\nUtiliser des captures nommées\nObject spread vs. Object.assign\nConvertir un objet en Map et réciproquement\nLa boucle for-of : s’il ne devait en rester qu’une…\nSimuler une classe abstraite avec new.target\nDes indices de tableaux négatifs grâce aux proxies\n\nComment faire pour être notifié·e ?\nRien de plus simple ! Tu peux, au choix (ou les deux) :\n\nT’inscrire à notre newsletter ; vu qu’on essaie de ne pas spammer dessus, on ne mailera pas quotidiennement, hein, mais on enverra un récap hebdomadaire. C’est aussi un bon moyen de te tenir au courant de nos offres spéciales, nouvelles sessions de formation, nouvelles formations, cours vidéos etc. (Il va de soi qu’on préfèrerait fermer boutique que revendre tes données).\nNous suivre sur Twitter ; c’est le moyen le plus simple… à condition qu’on ne soit pas noyé dans ta timeline, y’a toujours un risque !\n\nOn est impatients de lancer ça, et on a hâte d’avoir tes retours !\n",
		"description": "Chaque jour une pépite JavaScript, pendant 19 jours !",
		"date": 1587945600,
		"image": "/assets/images/art-vid/js-nuggets.jpg",
    "_tags": ["tutoriel","js"],
		"title": "19 pépites JavaScript !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-nuggets/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Cet article ouvre la série « 19 pépites de JS pur », qui contient un article quotidien (pas trop long, idéal pour grignotter…) sur un aspect du langage JavaScript pur ; astuce, meilleure pratique, capacité méconnue, démontage d’une idée reçue, démystification… : 19 raisons de revenir et de nous suivre pour ne rien rater !\n\nLa série des 19\nExtrait de la liste des articles :\n\nDédoublonner efficacement un tableau (cet article)\nExtraire efficacement une sous-chaîne de texte\nFormater proprement un nombre\n…au-delà, c’est la surprise ! (mais les 19 sont déjà calés)…\n\n\n« Dédoublonner » ?\nDédoublonner, ou dédupliquer (en anglais, deduplicate, un doublon étant un duplicate) : l’action de retirer dans une liste toutes les occurrences surnuméraires de valeurs, pour ne conserver au final que des valeurs uniques.\nLa liste n’est pas obligatoirement triée et les valeurs ne sont pas obligatoirement d’un type uniforme. L’implémentation peut par ailleurs choisir de préserver l’ordre (d’être « stable ») des valeurs d’origine conservées, ou pas.\nLe genre de mots qu’on utilise assez peu dans la vie de tous les jours.\nÀ l’ancienne\nPas tellement d’autre choix que de traverser toute la liste.\nSi on ne peut pas supposer qu’elle était triée (et que les valeurs ne sont pas forcément des Strings) c’est encore plus moche : à chaque fois, on devra parcourir le résultat courant pour voir si la valeur n’y existe pas déjà ! Un parcours dans un parcours : l’algo est quadratique, de complexité O(n²). En gros, si tu as un tableau de mille éléments, tu fais un million de tours… Une implémentation un poil naïve (surtout vu qu’on est manifestement en ES2015+) pourrait ressembler à ça :\n\nSi tu te sens désarçonné·e par for…of ou Array#includes(…), donc plutôt ES3 (pré-2009) dans l’esprit, tu as cette version-ci, encore plus lente :\n\nSi tu peux supposer que items est « triée » à la base (les valeurs identiques sont adjacentes), tu gagnes beaucoup en évitant de reparcourir result à chaque fois. Ton algo passe de quadratique à linéaire (O(n), donc mille éléments donnent mille tours) :\n\nBon, c’est pas la fête. Si tes valeurs sont toutes des Strings, tu peux optimiser un peu la vérification d’existence, mais à peine, en utilisant un objet comme dictionnaire, et en mettant les clés dedans, pour tester avec seen.hasOwnProperty(item) ou plus basiquement seen[item], mais c’est pas fou (changer la « forme » de seen à chaque ajout de valeur rencontrée pour la première fois pète pour l’essentiel les optimisations de consultation).\n« Oui, mais Lodash ! »\nAbsolument ! Lodash a depuis longtemps uniq et ses copains (uniqWith, uniqBy, sortedUniq, etc.). On ne l’a d’ailleurs pas attendu, puisque Prototype.js le faisait déjà en 2005.\nComme un·e boss\nBien sûr, si vous avez des besoins avancés (comparateur maison, clé dérivée, etc.) vous aurez besoin de Lodash ou consorts. Mais pour le cas de base : dédoublonner les valeurs nues, l’astuce, depuis ES2015, consiste à passer par un Set.\nSet est un des deux nouveaux types de collection, avec Map, qui a fait son apparition en 2015 dans la bibliothèque standard du langage. Ce type, qu’on retrouve dans de nombreux écosystèmes, représente un ensemble, au sens mathématique. Il est en particulier caractérisé par deux aspects :\n\nIl n’a pas d’ordre intrinsèque\nToutes les valeurs sont uniques\n\nEn pratique, undefined, null et NaN sont des valeurs comme les autres. Set utilise pour ses comparaisons le pseudo-algorithme SameValueZero défini par la spécification de JavaScript. C’est comme l’égalité stricte (opérateur ===, qui vérifie d’abord que le type est le même, et le cas échéant compare les valeurs), à un détail près : -0, 0 et +0 sont considérés identiques. Je doute que ce micro-détail vous gêne 😉\nIl se trouve qu’un Set peut être construit sur base d’un itérable quelconque. Il y a des tas d’itérables (ce qui rend notre code encore plus générique et utile !), mais Array est sans doute le plus connu.\nOn pourrait donc faire :\n\nConstruire un Set en lui passant un itérable constitue en quelque sorte la variante optimisée d’un peuplement manuel, qui parcourerait l’itérable (avec un for…of justement) et appellerait add(…) à chaque fois, mais sémantiquement, c’est pareil. Avantage sympathique : l’ordre est donc préservé, l’algo est « stable » de ce point de vue.\nLa définition de add(…) veut qu’elle ignore tout argument qui serait déjà présent dans le Set. En interne, l’implémentation utilise des structures de données optimisées pour le stockage et la vérification d’existence, faute de notion d’ordre. C’est pourquoi un set.has(x), qui est généralement en O(log(n)), est potentiellement beaucoup plus performant qu’un arr.includes(x), lequel est en O(n). Tu préfères quoi, 3–4 tours ou mille tours ?\nBon, mais on se retrouve avec un Set, pas un joli Array sur lequel on aurait plein de méthodes pratiques… Comment retomber sur nos pattes ?\nUn Set est un itérable lui aussi, ce qui veut dire qu’on peut le spreader avec l’opérateur ..., de sorte q",
		"description": "Découvrez la manière optimale de dédoublonner un tableau depuis ES2015…",
		"date": 1588550400,
		"image": "/assets/images/art-vid/js-nugget-1.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Dédoublonner efficacement un tableau",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-retrait-doublons/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Voici le deuxième article de notre série quotidienne « 19 pépites de JS pur ». Cette fois-ci, nous allons parler d’extraire une portion de chaîne de caractères, et voir que pas moins de 3 méthodes se tirent la bourre… mais qu’une seule mérite votre attention 😉\n\nDans la série…\nExtrait de la liste des articles :\n\nDédoublonner efficacement un tableau\nExtraire efficacement une sous-chaîne de texte (cet article)\nFormater proprement un nombre\nArray#splice, le couteau suisse\n…au-delà, c’est la surprise ! (mais les 19 sont déjà calés)…\n\nLe truand : substr(…)\nLe savais-tu ? Les chaînes ont une méthode substr. Non, tu le savais pas ? Eh bah tant mieux ! On ne peut pas lui faire confiance, et en prime elle n’est pratique.\n\nElle n’est pas vraiment officielle. Elle figure à l’annexe B de la spec, qui est certes «normative» depuis ES2015 mais n’était qu’«informative» auparavant, et concerne les parties du langage et de sa bibliothèque qui n’ont jamais été très propres et sont activement découragées, parfois depuis bien longtemps (pour substr, ça remonte à ES3, en 1999, les gens).\nElle a une signature inhabituelle : substr(index, longueur). Oui, longueur. Pas deux index, mais un index et une longueur.\nElle a des implémentations incompatibles. En particulier, alors qu’elle autorise explicitement les index négatifs pour partir de la fin (ça c’est bien !), cet aspect ne marche pas sur JScript, le moteur JS d’Internet Explorer avant la 9.0.\n\n\nEn plus, elle a un nom bien pourri, bien tronqué n’importe comment, qui n‘est pas sans rappeller les jours sombres des premières versions de PHP (nl2br, oui, je pense à toi, et à bien d’autres).\nBref, jette-moi ça aux oubliettes.\nLa brute : substring(…)\nBeaucoup de monde utilise substring. Beaucoup de monde. Beaucoup trop de monde. C’est un peu comme cette !@# de parseInt : tout le monde se dit que non, en fait, ça va, je gère. Et juste quand tu mets ton truc le plus critique de ta vie en prod’, paf le chien. Le bug caché. Le piège sournois.\nBon, au moins, le nom est clair, rien à dire. Et les arguments sont des index, c’est cool.\nMAIS— !\n\nLes index ne peuvent pas être négatifs (pas de confort d’indexation de fin de chaîne)\nY’a une Grosse Blague™ si le deuxième est inférieur au premier.\n\n\nTu as deviné ? Et oui, si le deuxième index est inférieur au premier, ça les inverse ! What could go wrong?! Évidemment, c’est carrément ce que tu veux, comme quand new Date(2020, 0, -6) te donne Noël 2019, c’est logique, quoi !\nAllez, recalé !\nLe bon : slice(…)\nLe voilà, notre copain ! Tu connais sûrement slice sur les tableaux, eh bien il existe aussi sur les chaînes, avec exactement la même API, ce qui est pratique : on a bien assez d’API distinctes à mémoriser, alors quand on peut réutiliser… Pas mal de points positifs, donc :\n\n100% API-compatible avec le slice de Array\nDonc deux index, autorisant le négatif tous les deux (et comme d’hab le deuxième est exclusif)\nPas d’inversion à la noix si le second est inférieur au premier\n\nBref, que du bonheur ! 😍\nIl y a aussi deux aspects sympa, mais qu’il partage avec les deux précédents, ce ne sont donc pas à proprement parler des avantages sur eux, mais je les liste quand même :\n\nSi on omet le deuxième index, on va jusqu’au bout de la chaîne\nSi on omet même le premier argument, on démarre au début de la chaîne\n\n\n\n« Oui mais c’est pas kawaï ! »\nTu l’as compris, slice est mon ami. Et pourtant, comme toute l’API traditionnelle de String, il trébuche souvent sur Unicode. On y reviendra bientôt (Spoiler Alert), mais les chaînes JS sont, comme en Java (argh !), encodées en UCS-2 / UTF-16LE, et ce que l’API appelle à tort des caractères (charAt, charCodeAt, etc.) sont en fait des code units de 16 bits (2 octets). Ça suffit amplement pour les caractères latins, les chiffres, la ponctuation occidentale classique, mais dès qu’on franchit un certain niveau de codepoints Unicode, par exemple avec certains idéogrammes chinois, kanjis japonais ou carrément Emoji, ça ne tient plus, et il nous faut une surrogate pair :\n\nEt oui, '😍' comprend en fait deux code units. Normalisée en source ASCII, elle s’écrirait '\\ud83d\\ude0d'. Super, hein ? Un Emoji, mais une chaîne de « longueur » 2. Un codepoint, deux code units qui forment une surrogate pair. Du coup :\n\nAlors comment faire pour extraire un segment en « parlant de codepoints » ? Si tu en as vraiment besoin, tu peux profiter du fait que depuis ES0215 les String sont itérables par codepoints, et non par code units. Fais-en un tableau, slice le tableau, et recompose la chaîne :\n\nOuf ! Bon après quand tu as des combinaisons de codepoints à coup de ZWJ (Zero-Width Joiners), ça ne suffira pas toujours…\n\n…mais quand même, avec un peu de chance on peut réunir toute la famille :\n\nTout est bien qui finit bien !\n",
		"description": "Vous découpez des Strings en JS ? Jetez donc aux orties substring et surtout substr ! Seul slice assure votre salut !",
		"date": 1588636800,
		"image": "/assets/images/art-vid/js-nugget-2.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Extraire efficacement une sous-chaîne de texte",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-string-slice/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Voici le troisième article de notre série quotidienne « 19 pépites de JS pur ». Cette fois-ci, nous allons parler des formatages de nombres, et voir qu’on a désormais à disposition des capacités de dingue !\n\nDans la série…\nExtrait de la liste des articles :\n\nDédoublonner efficacement un tableau\nExtraire efficacement une sous-chaîne de texte\nFormater proprement un nombre (cet article)\nArray#splice\nStrings et Unicode\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\n« Formater »… mais encore ?\nÇa veut tout et rien dire, ça… Perso, je vais distinguer 3 grands besoins de formatage :\n\nUn nombre fixe de décimales (affichage technique)\nUn changement de base numérique (idem)\nUne représentation « humaine » ancrée dans un contexte linguistique (locale). Nombre classique, valeur monétaire, pourcentage, espace disque… les cas sont innombrables.\n\nPour les deux premiers cas, on a des solutions depuis toujours, mais comme personne ne lit la doc et que beaucoup de gens ont bien du mal à réaliser qu’en JavaScript, même les valeurs numériques primitives peuvent se comporter comme des objets (“autoboxing”), on a tendance à ne pas savoir que c’est là.\nLes vieux planqués\nLe type Number propose parmi ses méthodes d’instance deux méthodes fort utiles, souvent réimplémentées à tort manuellement.\nAttention, contrairement à des grammaires plus permissives comme celle de Ruby, celle de JavaScript ne permet pas d’utiliser le point d’indexation directe sur un littéral numérique entier : un point après un préfixe numérique littéral sera considéré comme le séparateur décimal qui suit la partie entière :\n\nEn pratique ce n’est pas un problème : si on a la valeur en littéral, autant avoir le formatage voulu en littéral plutôt que le calculer ! En général, le nombre est référencé par un identifiant, donc pas de souci :\n\ntoFixed()\nPour des raisons d’alignement et autres, on a souvent besoin de caler un affichage numérique en décimales fixes. Et là, faute de savoir que c’est déjà possible, je vois souvent des réimplémentations à deux balles, genre :\n\nAlors qu’en fait on a ça depuis ES3 (1999) !\n\nAu passage, ne confonds pas avec toPrecision(…), qui donne le nombre de chiffres significatifs au total (à gauche et à droite de la virgule).\nBon, c’est pas mal mais ça fournit quand même un littéral technique, sans formatage linguistique (séparateur de milliers, séparateur décimal)… Donc quand ça suffit, tant mieux, mais parfois il faudra pousser plus loin (on y vient).\ntoString(radix)\nAutre besoin récurrent dans un contexte technique : choisir la base d’affichage. Mais si, tu sais bien : octal, hexadécimal, binaire… On vise là sans doute un format technique plus qu’un affichage pour des utilisateurs finaux, mais va savoir.\nLà aussi, c’est la fête de la réimplémentation maison, mais en fait, pour des bases 2 à 36 (oui oui, 36), c’est déjà là depuis JS 1.1 (oui, 1.1 ! En 1996, dis donc ! Étais-tu seulement né·e ?!)… Comme tous les objets, les Numbers ont une méthode d’instance toString(), sauf que chez eux elle accepte une base (radix) optionnelle, par défaut 10.\n\nEt hop ! (Gerflor)\n« Je détiens la toute-puissance ! » : Intl\n(+5 points si tu as la référence. Oui, je sais, c’est pas le texte exact mais ça faisait un trop long titre sinon…)\nPour les formatages « propres », à destination de Vrais Gens™, avec un contexte linguistique (ce qui fait partie de la localisation de l’affichage, ou L10n), on a longtemps dû sortir l’artillerie lourde avec Moment.js ou autres modules dont le corpus de localisation est super lourd (près d’1Mo, paie ton bundle !).\nAujourd’hui, on recourt plus proprement à des solutions comme Format.JS, ce qui est sympa mais n’est en fait qu’une surcouche d’une API native, fournie par les moteurs JavaScript depuis un bon moment : l’espace de noms Intl.\nECMA-402\nCette partie de la « bibliothèque standard » de JavaScript fait l’objet d’un standard à part, l’ECMA-402, lequel est géré par le même comité technique (TC39) que l’ECMA-262, le standard de JavaScript lui-même.\nL’idée est de permettre à notre code JS d’accéder à l’énorme corpus de règles de formatage, parfois très finaudes, d’une langue à l’autre, pour les nombres et dates. Il y a en fait énormément de cas, variations, points de détail… Et tout ça constitue ce qu’on appelle la CLDR (pour Common Locale Data Repository), qui fait partie de l’ICU (International Components for Unicode), et figure normalement parmi les bibliothèques présentes dans chaque OS, maintenues plusieurs fois par an.\nDans le cas qui nous occupe, on s’intéresse surtout à la classe Intl.NumberFormat, qui permet de créer des formateurs numériques extrêmement détaillés et versatiles.\nnew Intl.NumberFormat(…).format(n) vs. n.toLocaleString(…)\nDepuis ES5.1 (2010), la méthode d’instance historique toLocaleString() sur Number (qui n’acceptait auparavant aucune option et renvoyait juste un format par défaut basé sur le locale en vigueur) a été revue pour accepter toutes les options de new Intl.NumberFormat",
		"description": "Formater un nombre en JS aux petits oignons ?! C’est super facile en fait !",
		"date": 1588723200,
		"image": "/assets/images/art-vid/js-nugget-3.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Formater proprement un nombre",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-formatage-nombre/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Voici le quatrième article de notre série quotidienne « 19 pépites de JS pur ». Aujourd’hui on se penche sur une méthode qui est là depuis toujours ou presque (JS 1.2, 1997) : Array#splice(…), le couteau suisse du triturage performant de tableau.\n\nDans la série…\nExtrait de la liste des articles :\n\nExtraire efficacement une sous-chaîne de texte\nFormater proprement un nombre\nArray#splice (cet article)\nStrings et Unicode\nCourt-circuiter plusieurs niveaux de boucles\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nsplice ou slice ?!\nNe pas confondre.\n\nslice([from[, until]]) est une opération idempotente / non-mutative, qui ne touche pas au tableau d’origine et renvoie un nouveau tableau basé sur l’intervalle décrit.\nsplice(from[, count[, item…]]) est une opération mutative, qui altère le tableau d’origine en « remplaçant » un segment donné par un nouveau. Comme un épissage ARN, quelque part (et de fait, le terme anglais splicing désigne l’épissage, qu’on parle de gènes, de pellicules de film ou de câbles électriques). On coupe-colle, quoi. C’est le CRISPR des tableaux JavaScript.\n\nRemarque que si slice existe aussi, à l’identique, sur le type String, ce n’est pas le cas de splice, puisqu’une String est par définition immuable.\nPour supprimer\nLe « véritable » nom du 2e argument est deleteCount. Ça annonce la couleur : attention chérie, ça va splicer. Si on se limite à deux arguments (voire un), splice supprime du contenu, à partir de la position from (1er argument), lequel autorise les valeurs négatives (comme dans slice).\n\nAvec un 2e argument positif, ça vire le nombre d’éléments indiqué (ou jusqu’au bout si le tableau n’est pas assez long).\nSans 2e argument, ça vire jusqu’à la fin du tableau.\n\nEn tout cas, splice renvoie le segment supprimé, toujours sous forme d’un tableau, qu’il y ait zéro, un ou plusieurs éléments dedans.\n\nPour remplacer\nIl est possible de préciser, sous forme d’arguments individuels, des éléments à insérer en remplacement de ceux supprimés. Ce qui est intéressant, c’est que leur nombre est libre : pas besoin qu’il soit identique à la taille du segment remplacé !\n\nEt si les éléments de remplacement sont fournis comme un tableau ? Pas de souci, on a le spread, comme toujours :\n\nPour insérer\nSi tu as bien suivi, tu as peut-être réalisé qu’en fait le remplacement est le cas général :\n\npour supprimer, il suffit de ne pas fournir de remplaçants\npour insérer, il suffit de ne pas retirer de segment\n\nEh oui, si count est à zéro mais qu’on fournit des éléments de « remplacement », forcément, on insère.\n\nPas sur les tableaux typés…\nTu es jeune et bigarré·e et tu fais des tableaux typés ? Ah, ça va poser souci, parce que ceux-ci ont une taille fixe ! Du coup splice est l’une des rares méthodes de Array qui n’y est pas disponible.\n…mais quand même sur les pseudo-tableaux\nComme toutes les méthodes de Array, splice n’exige pas d’être appelée sur un « véritable » tableau : il suffit que son sujet soit un « pseudo-tableau » (array-like), c’est-à-dire propose une propriété length numérique (entière positive ou nulle) et des propriétés numériques entre 0 et length - 1.\nBon, tu devrais pas trop en avoir besoin là comme ça, mais c’est quand même rigolo :\n\nCopain bonus : copyWithin\nUn cas de triturage assez courant consiste à vouloir recopier une partie d’un tableau ailleurs… dans le même tableau. Copier-coller interne, quoi.\nOn peut bien sûr faire ça avec splice, mais ça suppose un slice en prime :\n\nMais bon, c’est pas beau, hein… Depuis ES2015, on a copyWithin pour ce genre de cas. La signature est copyWithin(to[, from[, until]]). Attention, to doit être au sein du tableau (inférieur à length), sinon rien ne se passe.\n\nPour ce type de besoin, c’est imbattable en performance, alors voilà, c’est cadeau.\nBack to the future\nAu fait, je te parlais déjà de slice et splice en 2014 😉\nEnvie d’en savoir plus ?\nNos formations envoient du gros pâté, en présentiel ou à distance (FOAD), en inter-entreprises ou en intra rien que pour ta boîte ! Qui plus est, pendant la crise du Covid-19, les salarié·e·s peuvent être formé·e·s gratuitement ! Ce serait vraiment trop bête de ne pas en profiter !\n",
		"description": "Connais-tu Array#splice, la manière la plus performante de triturer un tableau en JavaScript ?",
		"date": 1588809600,
		"image": "/assets/images/art-vid/js-nugget-4.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Array#splice, ce couteau suisse",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/array-splice/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Voici le cinquième article de notre série quotidienne « 19 pépites de JS pur ». L’occasion de se pencher sur la relation riche et complexe entre les chaînes de caractères JavaScript (le type String) et Unicode. Parce que le temps du ISO-Latin-15 / Windows-1252 est bel et bien révolu, les gens…\n\nDans la série…\nExtrait de la liste des articles :\n\nFormater proprement un nombre\nArray#splice\nStrings et Unicode (cet article)\nCourt-circuiter plusieurs niveaux de boucles\nInverser deux valeurs avec la déstructuration\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nUne relation compliquée…\nÀ la base, le type String « est Unicode », nous dit-on. Après tout, on peut en effet y mettre n’importe quel glyphe défini par Unicode, ça fonctionne. Mais en pratique, le choix d’encodage retenu, ainsi que la terminologie de son API, posent quelques problèmes.\nIncidemment, tout ce qu’on va voir dans cette section, ou presque, est tout aussi vrai dans le type String de Java, puisque les deux ont été pondus en même temps, quasi à l’identique. (Mais JavaScript ne ressemble absolument pas à Java, ne me faites pas dire une énormité pareille !)\nUTF-16\nLes chaînes de caractères en JavaScript sont encodées en UTF-16 (ou en UCS-2, selon l’implémentation ; la différence est négligeable). Chaque position dans la chaîne référence donc une donnée sur 16 bits, ou 2 octets. Ça suffit certes à encoder les code points Unicode de U+0000 à U+FFFF, mais pas au-delà (alors qu’il y en a une pelletée au-delà, avec en pratique environ 144 000 glyphes). Ce bloc de 16 bits est appelé en anglais code unit, et en français codet.\nAinsi, les Emojis, mais aussi de nombreux alphabets ésotériques ou anciens (tel que l’ougaritique ou le phénicien), ainsi que de nombreux jeux de graphiques (tuiles de Mahjongg (si !), dominos, cartes à jouer…) sont au-delà du 16-bit, et nécessitent donc l’utilisation de deux valeurs conjuguées, lesquelles sont chacune invalides prises individuellement : l’ensemble s’appelle une surrogate pair. Bon, c’est vrai, c’est surtout du graphisme étendu et des langues mortes (mais genre, mortes), mais quand même.\nCaractère, codepoint, codet et surrogate pair\nDans nos esprits, un « caractère » désigne une entité complète ; une « case » de la table Unicode, en quelque sorte, ce qu’on appelle un codepoint.\nEn fait, cette analogie est erronée, car de nombreux codepoints ne représentent pas un caractère complet, mais plutôt des éléments techniques invisibles (tel que le point de césure où le combinateur de largeur nulle) ou des signes diacritiques (ex. l’accent aigu).\nMais bon, en gros, pour nous, un idéogramme chinois, un chiffre géorgien, un pictogramme babylonien ou un émoji sont tous « un » caractère, dans le cadre de l’examen d’un texte.\nEn pratique pourtant, en raison de l’encodage UTF-16 / UCS-2, de nombreux codepoints vont nécessiter une surrogate pair, donc deux codets, ce qui, dans l’API JavaScript de String, veut dire « deux char ». Une longueur de 2, en fait.\nEh oui ! charAt désigne un codet, pas un codepoint. Pareil pour charCodeAt, basé codet, ou length, qui donne le nombre de codets. Et d’une façon générale toutes les API de String sont basées codet… Regarde un peu :\n\nAh oui, remarque la séquence d’échappement \\uXXXX, qu’on peut utiliser depuis toujours dans les littéraux String (tu l’as aussi en CSS), elle autorise 4 chiffres hexadécimaux, donc juste 16 bits, un codet, pas un codepoint ! Tu fais comment pour poser un Emoji non littéral ? Tu dois récupérer son codepoint, obtenir la surrogate pair puis taper le tout : '\\ud83d\\ude05' === '😅'.\nC’est joliment le bordel tout ça, non ?\nEn fait y’a quand même des trucs qui marchent bien, hein, notamment toLocaleUpperCase(), localeCompare(…) et leurs amis, qui sont au courant des questions d’encodage (et peu impactées en pratique), c’est déjà ça…\nES2015 : codepoints littéraux\nES2015 (anciennement « ES6 ») a apporté beaucoup d’améliorations relatives à Unicode.\nPrenons d’abord la question des séquences d’échappement : devoir calculer la surrogate pair dès qu’on était au-delà des 16 premiers bits était bien pénible, alors qu’on obtient facilement le codepoint qui nous intéresse.\nOn a donc une nouvelle séquence d’échappement Unicode, avec des accolades : \\u{…}. Elle prend le codepoint complet, ce qui est tout de suite plus pratique.\n\nPerso, je préfère poser le caractère littéral sauf s’il est invisible (comme '\\u202f', le narrow no-break space utilisé comme délimiteur de groupe et séparateur d’unité en formatage numérique français, ou encore un vrai caractère invisible, comme le soft hyphen \\u00ad, le trait d’union conditionnel qui indique un point de césure). Dans un tel cas, utiliser la séquence d’échappement explicite a le mérite d’être identifiable en lisant le code.\nES2015 : API orientée codepoints\nOn trouve par ailleurs trois nouvelles méthodes sur String relatives à Unicode.\ncodePointAt(index)\nComme charCodeAt(index), sauf que si, à la position donnée (qui est en codets)",
		"description": "Tout ce qu’il faut savoir pour traiter correctement les codepoints Unicode avancés dans les Strings JavaScript.",
		"date": 1588896000,
		"image": "/assets/images/art-vid/js-nugget-5.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Strings et Unicode en JavaScript",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-strings-unicode/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Voici le sixième article de notre série quotidienne « 19 pépites de JS pur ». L’occasion de revenir sur une capacité très ancienne du langage, mais à utiliser avec beaucoup de dicernement : les instructions étiquettées.\n\nDans la série…\nExtrait de la liste des articles :\n\nArray#splice\nStrings et Unicode\nCourt-circuiter plusieurs niveaux de boucles (cet article)\nInverser deux valeurs avec la déstructuration\nRetirer facilement les « valeurs vides » d’un tableau\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nÇa fait un bail\nDepuis JS 1.2 (1997), il est possible d’étiquetter (label) des instructions. C’est notamment le cas des boucles : for numérique, for…in, while et do…while (et depuis ES2015, for…of). L’idée est de permettre le court-circuit multi-niveaux, notamment lors de boucles imbriquées.\nIl est naturellement possible de faire du code dégueulasse avec ça (façon goto, qui n’existe cependant pas en JS), mais on va se concentrer sur les usages orientés boucles.\n(Tu trouveras des explications complémentaires sur la toujours excellente doc du MDN, notamment pour les blocs étiquettés, lorsque tu as plusieurs blocs successifs, ce qui rend return impraticable alors que tu veux néanmoins éviter d’enrober la suite d’un bloc dans un if.)\nCourt-circuiter avec break\nIl est fréquent, lorsqu’on a des boucles imbriquées, de vouloir court-circuiter plusieurs niveaux de boucles d’un coup. Imaginons que tu cherches une valeur dans une matrice à 2 dimensions ; dès que tu l’as trouvée, tu vas vouloir sortir de la boucle interne (au sein d’une ligne) et de la boucle externe (qui passe d’une ligne à l’autre).\nSi tu fais ça sans étiquettes et que tu as du code à exécuter qui suit tes boucles, ça peut être un peu pataud :\n\nLe secret (qui, comme tous les secrets, se découvre en lisant la doc, rogntudjuu !), c’est qu’on peut étiquetter les boucles, et utiliser n’importe quelle étiquette « en vigueur » comme opérande du break. L’étiquette est complètement libre, ça peut même être un identifiant existant (mais c’est pas hyper lisible). On utilise souvent outer ou top pour la boucle la plus externe. Pour le code précédent, ça donnerait par exemple :\n\nDéjà mieux non ? Un exemple que j’aime bien, qu’on retrouve dans le MDN, concerne un tableau de prédicats (de tests vrai/faux, quoi) et une série de valeurs, et on cherche à déterminer si toutes les valeurs passent tous les tests. Il va de soi que dès qu’un test échoue, on peut lâcher l’affaire :\n\nMoi j’aime bien 😊\nCourt-circuiter avec continue\nOn peut évidemment faire pareil avec continue, pour ne pas simplement sauter au prochain tour de la boucle courante, mais au prochain tour d’une boucle englobante !\nSi on varie l’exemple précédent, disons qu’on veut toutes les valeurs qui passent tous les tests. Dès qu’un test échoue, inutile de continuer sur la liste des tests pour la valeur courante, on peut passer directement à la valeur suivante, et redémarrer le parcours des tests pour celle-ci.\n\nC’est choupi.\nLe piège des étiquettes cachées\nDepuis l’apparition des fonctions fléchées avec ES2015, on constate une résurgence des étiquettes… mais pas volontaire !\nSupposons que, pour des besoins de compatibilité avec une API tierce, tu veuilles transformer une liste de nombres en liste d’objets avec ce nombre comme propriété value. Tu pourrais être tenté·e de faire ça :\n\nSauf que non. Tu te retrouves avec un tableau de 9 undefined. La classe à Dallas™. En fait, tu as bien pris l’habitude de la syntaxe concise pour les fonctions fléchées qui renvoient simplement une valeur (et c’est bien !), mais tu as négligé le double-sens des accolades.\n\nTa fonction de rappel évalue n, n’en fait rien et ne renvoie rien (donc renvoie undefined).\nC’est un piège courant lorsqu’on fait des fonctions fléchées concises qui veulent renvoyer un littéral objet : il faut s’assurer que les accolades désignent un littéral objet. Ici, par défaut, elles désignent le bloc de fonction.\nPour que des accolades représentent un littéral objet, elles doivent apparaître là où la grammaire du langage exige une expression. Le moyen le plus simple de déclencher un tel contexte grammatical sans altérer la sémantique du code consiste à enrober par des parenthèses :\n\nDans un contexte contemporain, on trouve par exemple souvent ce genre de blague dans les sélecteurs / mapStateToProps avec Redux (ou d’autres bibliothèques de gestion d’état applicatif, qui ont le même type de besoin).\nPréfère des fonctions et return\nPour finir, ce type de code est généalement peu lisible et risque de laisser un goût déplaisant dans la bouche… Dans la plupart des cas, préfère définir de petites fonctions utilitaires pour réaliser les parcours imbriqués, et utilise ce bon vieux return pour le court-circuit. L’exemple de break étiquetté peut être réécrit avantageusement comme suit :\n\nLes boucles imbriquées étiquettées sont à préférer pour des raisons de performance pure, et encore, après avoir copieusement profilé le code pour vérifier que la p",
		"description": "Parfois, le meilleur moyen de court-circuiter des boucles imbriquées ce sont les étiquettes d’instruction !",
		"date": 1588982400,
		"image": "/assets/images/art-vid/js-nugget-6.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Court-circuiter plusieurs niveaux de boucles",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-labels/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Voici le septième article de notre série quotidienne « 19 pépites de JS pur ». Tu utilises encore une variable temporaire pour en inverser deux autres ? Tu T’y Prends Mal™ !\n\nDans la série…\nExtrait de la liste des articles :\n\nStrings et Unicode\nCourt-circuiter plusieurs niveaux de boucles\nInverser deux valeurs avec la déstructuration (cet article)\nRetirer facilement les « valeurs vides » d’un tableau\nVive les séparateurs numériques !\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nÀ l’ancienne\nDe nombreux algorithmes nécessitent l’inversion de variables. On en retrouve dans les calculs de hash, dans les tris, dans les séquences mathématiques… Bref, on a ce besoin depuis que la programmation existe (et ça fait quand même, rien que sous sa forme moderne, environ 70 ans). Mais les premiers langages de programmation répandus n’ont pas de mécanisme dédié pour ça, on va donc devoir passer par une variable temporaire.\nDisons qu’on veut inverser les valeurs de A et B. La danse à trois pas sera toujours la même, et vu qu’on ne parle que d’affectations, la syntaxe sera quasiment identique dans tous les langages répandus :\n\nOn « sauvegarde » la valeur initiale de A dans, disons, TMP.\nOn copie la valeur de B dans A.\nOn copie la valeur antérieure de A (sauvegardée dans TMP), dans B.\n\nEn somme, un code de haute volée propre à gagner des prix :\n\nBon, c’est pas foufou tout ça.\nPetit rappel sur la déstructuration\nLe terme déstructuration désigne de façon générale le fait d’aller récupérer d’un coup plusieurs données au sein d’une donnée structurée.\nEn dépit de l’énooooorme respect (et de l’éternelle gratitude) que j’ai pour les traducteur·rice·s français·es du MDN, je n’aime pas leur choix du terme « décomposition » pour ça, alors que le terme « déstructuration » était déjà très installé dans le lexique informatique français. C’est sémantiquement valide, mais ça nage à contre-courant de l’usage…\nJavaScript distingue depuis ES2015 deux types de déstructuration :\n\nLa déstructuration positionnelle, basée comme son nom l’indique sur les positions des valeurs au sein de la donnée source. Celle-ci peut être n’importe quel itérable, et le plus souvent il s’agira d’un tableau. On la reconnaît car elle est encadrée par des crochets ([…])\nLa déstructuration nominative, basée sur les noms des propriétés au sein de la donnée source, qui peut être n’importe quel objet. L’ordre n’importe donc pas. On la reconnaît car elle est encadrée par des accolades ({…}).\n\nOn ne peut pas déstructurer null ou undefined, mais pour tout le reste, ça passe.\nEnfin, on peut placer une déstructuration partout où il y a affectation, qu’elle soit…\n\nexplicite (opérateur d’affectation =, par exemple au sein d’une déclaration), ou\nimplicite (paramètres dans une signature de fonction, ou au sein justement d’une autre déstructuration, car on peut bien entendu les imbriquer)\n\nExemples de déstructuration positionnelle :\n\nExemples de nominatif :\n\nEt du coup…\nAllez, on inverse deux variables a et b, OKLM :\n\nEt voilà.\nJ’aimerais te dire « j’ai pas plus court », mais en fait certains langages ont un parser suffisamment avancé pour lever d’éventuelles ambiguïtés et permettre ça sans délimiteurs (genre Ruby : a, b = b, a 😍). Mais, hé, on n’a plus de variable temporaire, et l’intention est tout de suite plus claire !\nAu fait, on n’est pas du tout limités à deux valeurs, hein ! Imaginons que tu veuilles faire une rotation de valeurs, sur un trio par exemple. Aucun souci :\n\nL’émotion 🤗\nEnvie d’en savoir plus ?\nNos formations envoient du gros pâté, en présentiel ou à distance (FOAD), en inter-entreprises ou en intra rien que pour ta boîte ! Qui plus est, pendant la crise du Covid-19, les salarié·e·s peuvent être formé·e·s gratuitement ! Ce serait vraiment trop bête de ne pas en profiter !\n",
		"description": "Si tu utilises encore une variable temporaire pour en inverser deux autres, tu t’y prends mal™",
		"date": 1589068800,
		"image": "/assets/images/art-vid/js-nugget-7.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Inverser deux valeurs avec la déstructuration",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-inversion-destructuree/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Voici le huitième article de notre série quotidienne « 19 pépites de JS pur ». Besoin d’apurer un tableau ? On a tout un tas de solutions, et certaines sont… particulièrement concises !\n\nDans la série…\nExtrait de la liste des articles :\n\nCourt-circuiter plusieurs niveaux de boucles\nInverser deux valeurs avec la déstructuration\nRetirer facilement les « valeurs vides » d’un tableau (cet article)\nVive les séparateurs numériques !\nTrier proprement des textes\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nRappels sur filter\nDepuis ES5 (2009), le type Array est doté de tout un tas de méthodes itératives directement inspirées du module Enumerable de Prototype.js :\n\nforEach pour appeler une fonction de rappel sur chaque élément (globalement déconseillé maintenant qu’on a for…of) ;\nmap pour produire un tableau dérivé via une fonction de transformation ;\nevery et some pour déterminer si un prédicat (fonction vrai/faux) est satisfait par tout ou partie du tableau ;\nreduce et reduceRight pour produire une valeur consolidée sur la base de toutes les valeurs du tableau (une somme, une concaténation, etc.) ;\nEnfin, filter pour produire un tableau dérivé ne retenant que les valeurs ayant satisfait un prédicat.\n\nÀ l’exception de reduce et reduceRight qui en prennent 3, toutes les autres acceptent deux arguments :\n\nLa fonction de rappel (pour filter, le prédicat, donc) ;\nLe contexte : si la fonction de rappel s’attend à un this particulier, mais que la passer par référence « perdrait » ce this (en gros, elle est déclarée avec le mot-clé function ou comme méthode concise), ce deuxième argument optionnel permet de recaler le contexte correctement (ce qui est fort utile et performant).\n\n(Et, soit dit en passant, les fonctions de rappel pour celles-ci acceptent non pas un mais 3 arguments : la valeur, son index, et le tableau complet. Ça peut être super pratique…)\nPetits exemples :\n\n« Vide » ?\n« Retirer les valeurs vides », mais encore ? Qu’est-ce qu’une valeur « vide » ? En fait ça va largement dépendre de ton besoin (même si « ça dépend », ça dépasse).\nLe plus souvent, tu auras sous la main un tableau de valeurs numériques (où zéro ne serait pas acceptable) ou de chaînes (où les chaînes vides ne seraient pas valides). Dans les deux cas, false, null, NaN, undefined ne seraient pas valides non plus.\nC’est là le cas bien pratique que nous verrons tout à l’heure. Mais quid si ton cas est différent ? Si tu veux bien zéro ? Ou false ? Ou si même les chaînes blanches (uniquement constituées de whitespace) sont à virer ?\nPas de souci, j’ai une série de petits prédicats tout mimi pour toi.\nQuelques prédicats utiles\n\n\n\nValeur à tester\nPrédicat\n\n\n\n\nundefined\nx === undefined ou typeof x === 'undefined'\n\n\nnull ou undefined\nx == null (attention : égalité laxiste !)\n\n\nchaîne vide ('')\nConsidérer booléen, ou x === ''\n\n\nchaîne blanche\nx.trim() comme booléen, ou x.trim() === ''\n\n\nTexte convertissable en nombre (hors NaN)\nNumber\n\n\nNombre « utilisable » (ni NaN ni infini)\nNumber.isFinite (ES2015)\n\n\nNombre entier\nNumber.isInteger (ES2015)\n\n\nNombre entier fiable1\nNumber.isSafeInteger (ES2015)\n\n\n\n1 Tous les Number en JS utilisent le standard IEEE 754 : ce sont des nombres à virgule flottante 64-bit, qui n’ont que 15 chiffres de précision globale. Au-delà d’une certaine limite, les entiers sont ramenés à leur valeur représentable la plus proche. Essaie d’évaluer 9999999999999999 dans ta console ou REPL Node, et même ensuite 1234567890123456789…\nSi tu traites des textes, mais veux considérer les falsy values (du genre null, undefined, false ou NaN) comme des chaînes vides, tu peux faire un String(x || '') (car String(undefined) renverrait 'undefined', notamment).\nSi tu considères aussi les chaînes blanches comme vides en prime : String(x || '').trim() est ton ami. Exemples :\n\nBesoin de rejeter plutôt que de garder ?\nTu as parfois sous la main un prédicat tout prêt, peut-être très compliqué à écrire, et pas de bol, il teste l’inverse de ce que tu veux : il dit « oui » pour ce que tu veux virer, et « non » pour ce que tu veux garder. Seulement voilà, tu n’as que filter sous la main, pas reject.\nNe vas surtout pas réécrire le prédicat toi-même en inversant sa logique (si le prédicat est complexe, ça peut vite être casse-gueule). Le plus simple est d’utiliser un inverseur :\n\nEt si ça t’arrive souvent, tu peux génériser l’inversion :\n\nÉvidemment, Lodash a ça : _.negate…\nLe cas pratique : Boolean !\nOn évoquait tout à l’heure le cas finalement très répandu d’un tableau de valeurs numériques (où zéro ne serait pas acceptable) ou de chaînes (où les chaînes vides ne seraient pas valides). Dans les deux cas, false, null, NaN, undefined ne seraient pas valides non plus.\nLorsque tu veux filtrer toutes les falsy values, y’a un moyen hyper simple :\n\nC’est un peu l’équivalent du data.compact qu’on trouverait dans d’autres langages (ex. Ruby) : ça virera évidemment null et undefined, ce qui est en général ce qu’on veut, mais aussi au passage false, NaN",
		"description": "Besoin d’apurer un tableau ?  On a tout un tas de solutions, et certaines sont… très concises !",
		"date": 1589155200,
		"image": "/assets/images/art-vid/js-nugget-8.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Retirer facilement les « valeurs vides » d’un tableau",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-retrait-valeurs-vides/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Voici le neuvième article de notre série quotidienne « 19 pépites de JS pur ». Aujourd’hui nous parlons d’une extension syntaxique pour les littéraux numériques qui amène enfin dans JavaScript un petit élément de confort que de nombreux autres langages proposaient déjà : la découpe visuelle des valeurs pour en repérer plus facilement les composantes ou l’échelle de grandeur.\n\nDans la série…\nExtrait de la liste des articles :\n\nInverser deux valeurs avec la déstructuration\nRetirer facilement les « valeurs vides » d’un tableau\nVive les séparateurs numériques ! (cet article)\nTrier proprement des textes\nExtraire les emojis d’un texte\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nLe problème\nÇa se passe de commentaire :\n\nLa solution\nDe nombreux langages ont adopté le séparateur numérique _ (underscore) dans leurs littéraux numériques. Note bien que le séparateur ne change strictement rien à la valeur finale, il est juste là pour plus de lisibilité du code source, avec peu ou prou les mêmes contraintes de bon sens que dans les autres langages le proposant :\n\nPas en début ou en fin de littéral (let n = _10_ : non, deux fois non !)\nPas en fin de partie entière ni en début de partie flottante ou exposant dans un littéral flottant (let n = 5_._0e_10 : non, non et non !)\nPas de séparateurs adjacents (const FEE = 15__00 : non !)\n\n\nJ’ajoute que ça marche aussi pour les littéraux BigInt (type introduit en ES2020), pour lesquels c’est particulièrement utile.\n\nAttention…\nAfin de Ne Pas Casser Internet™, les fonctions Number, parseInt et parseFloat ne reconnaîtront pas ces séparateurs, préservant ainsi la compatibilité ascendante, sacro-sainte en JavaScript.\nDès maintenant ?\nTechniquement c’est au stade 3 et ne devrait donc pas être officiel avant ES2021. Mais outre que Babel transpile (tu m’étonnes, super simple), c’est déjà natif depuis Firefox 70, Chrome 75, Edge 79, Safari 13, Opera 62 et Node 12.5. Et on le trouve naturellement en TypeScript aussi.\nDonc je dirais oui 😚\n",
		"description": "Marre de devoir compter à la main les chiffres d’un nombre pour en connaître l’échelle ? Marre de devoir les découper à la main pour isoler les composants ? Voici enfin les séparateurs numériques !",
		"date": 1589241600,
		"image": "/assets/images/art-vid/js-nugget-9.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Vive les séparateurs numériques !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-separateurs-numeriques-pepite/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Voici déjà le dixième article de notre série quotidienne « 19 pépites de JS pur ». On revient ici sur un thème récurrent : trier intelligemment (et proprement) des tableaux de données, qui sont parfois d’un formatage complexe. Et pourtant, il n’est que rarement utile de faire un aller-retour serveur ou de recourir à une bibliothèque, la bibliothèque standard recèle des compétences insoupçonnées !\n\nDans la série…\nExtrait de la liste des articles :\n\nRetirer facilement les « valeurs vides » d’un tableau\nVive les séparateurs numériques !\nTrier proprement des textes (cet article)\nExtraire les emojis d’un texte\nDéfinir proprement des paramètres nommés optionnels\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\n\nArray#sort(…)\nVous la connaissez tous : la méthode sort(…) de Array. Tu l’as sûrement déjà utilisée, c’est tout facile :\n\nLes yeux fermés…\nAttention, c’est mutatif !\nLe premier piège, c’est que sort(…) est mutative : elle modifie le tableau en place, plutôt que d’en générer un autre. Ce n’est pas la seule méthode mutative de Array : on trouve aussi copyWithin, fill, pop, push, reverse, shift, splice et unshift. Mais ça reste minoritaire (9 méthodes sur 32), et comme on prend vite l’habitude de l’inverse (tableau d’origine intact), ça peut surprendre :\n\nC’est ainsi pour des raisons de performance : la majeure partie du temps, on veut trier le tableau d’origine. Si ça gêne, rien n’empêche de le dupliquer d’abord, hein :\n\nTant qu’on parle de tri, t’as remarqué tout à l’heure ? reverse() est mutative aussi… pour les mêmes raisons. Mais on verra plus loin que je ne conseille pas sort(…).reverse() pour trier à l’envers, hein !\nTrier des nombres\nRegarde-moi ça :\n\n\nHé hé, le bon gros piège. Comme en JavaScript le typage est dynamique, sur les tableaux classiques (type Array, par opposition aux tableaux typés numériques), on peut très bien avoir des valeurs de types multiples : String, Number, etc.\nDu coup, pour trier tout ça, il faut un moyen de représenter toutes les valeurs de façon homogène. Et le seul type vers lequel tous les autres peuvent converger, c’est String (d’où le fait que tous les objets ont une méthode toString()).\nC’est ce que fait sort() par défaut : il convertit les valeurs en String avant de les comparer, par un bon vieil opérateur &lt;, en plus.\nPas glop.\nAlors que faire ? Il nous suffit de fournir notre propre comparateur, bien sûr ! sort(…) accepte un argument optionnel qui sera une fonction de comparaison :\n\nElle reçoit deux arguments : deux valeurs du tableau à comparer\nElle renvoie un nombre négatif si le premier arrive avant, positif si le premier arrive après, neutre (zéro) s’ils sont considérés équivalents.\n\nSi tu viens de Java, c’est comme si tu implémentais l’interface java.util.Comparator, quoi. En moins chiantverbeux.\nPour un tri croissant, il suffit de renvoyer la différence entre les deux nombres en fait : si a est plus petit, le résultat sera négatif, donc a arrivera avant. Pour un tri décroissant, on ferait b - a plutôt : on inverse le signe, quoi !\n\nMerveilleux.\nTris de texte avancés\nY’a pas que les nombres qui peuvent poser problème. Par défaut, la comparaison entre les chaînes est lexicographique : elle utilise l’ordre de la table de caractères (les codepoints Unicode, donc). Sauf que c’est pas un ordre naturel pour les gens, ça :\n\nWTF ?! Je doute fort que quiconque, parmi tes utilisateurs, se satisfasse de ce résultat tout moisi inattendu. L’ordre de tri linguistique adopte en général des règles de traitement particulières pour les diacritiques (ex. les accents graves, les cédilles), la casse (majuscules / minuscules), la ponctuation, etc. Ici, il n’en est rien.\nLe corpus de ces règles, qui varient parfois drastiquement d’une locale à l’autre, s’appelle la collation. Tu as peut-être déjà vu ça en SQL, quand tu définis tes tables, tes colonnes ou que tu écris ta requête, afin que ton order by sur les champs textuels donne quelque chose de raisonnable. C’est un concept assez universel en traitement de données.\nEh ben str1 &lt; str2, la collation, il s’en bat le flanc.\nRespecter la locale\nOptons donc pour autre chose.\nString#localeCompare(…)\nA minima, on va recourir à la version basique de localeCompare(…), une méthode de String depuis ES3 (1999). Elle compare deux chaînes en respectant les règles de la locale en vigueur, et renvoie -1, 0 ou 1. Même quand on n’a que ça sous la main et qu’on ne peut donc pas spécifier une locale explicite, c’est largement mieux que rien, d’autant que la majorité des locales convergent, en pratique, sur leurs règles de tri :\n\nC’est déjà franchement cool, mais dès lors qu’on est sur un moteur qui implémente ECMA-402, le standard pour l’API Intl (qui fait partie intégrante de la bibliothèque standard de JavaScript), cette méthode gagne en puissance, en servant de raccourci pour les fonctionnalités disponibles dans Intl.\nC’est en pratique dispo depuis IE11, Firefox 60, Chrome 74, Edge 15, Safari 10, Opera 61 et Node 0.12 ! Ça va…\nOn a",
		"description": "Trier des tableaux de données complexes en JS, c’est souvent vu comme du mission impossible… pourtant, les possibilités natives sont énormes !",
		"date": 1589328000,
		"image": "/assets/images/art-vid/js-nugget-10.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Trier proprement des textes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-tri-tableaux/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "En route pour le onzième article de notre série quotidienne « 19 pépites de JS pur ». Et aujourd’hui, on va parler d’emojis. Ils emojis sont partout, mais pas simples à identifier, extraire, regrouper, etc. au sein d’une chaîne de caractères. Leur liste est en augmentation constante, et dans les String JavaScript, ils sont systématiquement représentés par des surrogate pairs, en raison de leurs codepoints élevés… Heureusement, une nouveauté ES2018 nous change la vie !\n\nDans la série…\nExtrait de la liste des articles :\n\nVive les séparateurs numériques !\nTrier proprement des textes\nExtraire les emojis d’un texte (cet article)\nDéfinir proprement des paramètres nommés optionnels\nconst is the new var\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nEmojis, Unicode et surrogate pairs\nDans notre article de « pépite » n°5, « Strings et Unicode en JavaScript », on a déjà parlé en détail de la gestion d’Unicode dans le type String. On a vu notamment que le texte y est encodé en UTF-16, avec des codets de 16 bits (2 octets), ce qui nécessite, pour les codepoints au-delà de U+FFFF, la combinaison de deux codets successifs, individuellement invalides, en ce qu’on appelle une surrogate pair.\nC’est notamment le cas des Emojis, dont la quasi-totalité des codepoints utilisent la plage U+1Fxxx ainsi que de nombreux modificateurs allant jusqu’aux plages U+Exxxx.\nUne telle diversité fait qu’évidemment, repérer de manière fiable les Emojis dans une String est assez pénible « à la main » ; la regexp « classique » pour y parvenir serait particulièrement chaude (et pas hyper performante)…\nLe drapeau Unicode des regexps\nDepuis ES2015, on a le drapeau u sur les regexp, qui active la prise en charge d’Unicode.\nAvant ES2018, ça permettait « juste » de pouvoir utiliser la syntaxe de littéral codepoint (c’est à dire \\u{XXXXX}) en plus de la syntaxe historique de littéral codet (\\uXXXX). Mais depuis ES2018, on a la possibilité d’établir des correspondances, positives ou négatives, sur les propriétés Unicode.\nLes propriétés Unicode\nLe standard Unicode assigne à chaque codepoint toute une série de propriétés. Ce sont des catégories croisées, si tu préfères. Par exemple, prenons le glyphe U+2778 : ❸ (affectueusement dénommé Dingbat Negative Circled Digit Three). Il a entre autres les propriétés suivantes :\n\nScript : Common / Zyyy(voici une [liste issue de la spec ES](https://tc39.es/ecma262/#table-unicode-script-values) et [une autre de l’excellent site Compart](https://www.compart.com/en/unicode/scripts))\n\nGeneral Category : Other_Number / No(voici [liste spec ES](https://tc39.es/ecma262/#table-unicode-general-category-values) et [liste Compart](https://www.compart.com/en/unicode/category)).\nDu coup, il est aussi dans `Number` / `N`, une catégorie plus générique.\n\n\nAu fait, la plupart des valeurs de propriétés existent en forme longue (telle que Other_Number) et courte (ex. No). Comme toujours, préfère la version lisible (longue) pour produire un code un peu plus maintenable…\nUnicode Property Escapes à la rescousse !\nES2018 nous amène donc une nouvelle syntaxe dans les regexps pour correspondre à des propriétés Unicode : les Unicode Property Escapes. La syntaxe est \\p{…}. Comme toujours avec les séquences d’échappement dans une regexp, on a la version positive en minuscule, et la version négative en majuscule (\\P{…}). Exactement comme \\s dit « whitespace » et \\S dit « tout sauf du whitespace ».\nLes propriétés peuvent être binaires (oui/non ; liste spec ES) ou plus générales (toutes les autres, telles que General_Category ou Script). Pour les binaires, préciser leur nom suffit ; pour les autres, il faudra préciser aussi une valeur.\nNombre de valeurs de scripts ou de catégorie peuvent être utilisées directement comme « propriétés binaires » dans la syntaxe. Par exemple, on peut tout aussi bien dire \\p{Emoji} que \\p{Script=Emoji}. Ainsi, parmi les « binaires » bien utiles, on retrouve Alphabetic, Uppercase, Lowercase, Number (notamment Decimal_Number), Diacritic, Emoji, White_Space (qui couvre plus de cas exotiques que le \\w traditionnel)…\nVoici donc notre solution pour extraire toute séquence d’Emojis dans un texte !\n\nMais évidemment ça peut être super cool pour plein d’autres besoins :\n\n(Eh oui, qu’ils soient ASCII, double-barrés mathématiques, indo-arabes ou kannada, ça reste des chiffres décimaux…)\nLa doc du MDN est comme toujours excellente (mais j’ai lié la version originale anglophone ici car la VF n’est qu’au tout début de son effort de traduction).\nCadeau bonus : le drapeau singleline/dotall\nParmi les nombreuses améliorations de la syntaxe de regexp apportées depuis ES2018, cette même édition nous a aussi apporté le très attendu drapeau s, pour “single line” (également connu sous le nom “dotall”), qui permet à la classe de caractère quelconque . (point) de correspondre aussi aux sauts de lignes et retours chariots :\n\nAvant ça, on était obligés de recourir à des hacks pas très lisibles (à la place du .), tels que [^] (cl",
		"description": "Les emojis sont partout, mais pas simples à identifier, extraire, regrouper, etc. au sein d’une chaîne de caractères.  Ils sont en augmentation constante, utilisent systématiquement des surrogate pairs…  Comment faire ça vite et bien ?",
		"date": 1589414400,
		"image": "/assets/images/art-vid/js-nugget-11.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Extraire les emojis d’un texte",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-extraire-emojis/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Voici le douzième article de notre série quotidienne « 19 pépites de JS pur ». Connais-tu la notion de « paramètres nommés » ou “keyword parameters” ? C’est très pratique mais ça n’existe pas à proprement parler en JavaScript. Heureusement, on a depuis longtemps des solutions, qui sont devenues encore plus pratiques à mettre en œuvre avec ES2015…\n\nDans la série…\nExtrait de la liste des articles :\n\nTrier proprement des textes\nExtraire les emojis d’un texte\nDéfinir proprement des paramètres nommés optionnels (cet article)\nconst is the new var\nUtiliser des captures nommées\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nPas de « vrais » paramètres nommés…\nDe nombreux langages ont une fonctionnalité communément appelée « paramètres nommés » (“keyword parameters” en anglais), qui offre un confort indiscutable, car on peut alors :\n\nnommer les paramètres pour lesquels on passe un argument, ce qui clarifie l’appel ;\npasser uniquement les arguments dont on a besoin ;\nne plus dépendre de l’ordre déclaratif lors de l’appel.\n\nExemple en Ruby :\n\nOn trouve ça en Kotlin, Python, Swift… En C#, n’importe quel argument peut être nommé à l’appel (à condition qu’il n’y ait pas d’argument anonyme ensuite). Bref, c’est courant.\nEn JavaScript, on n’a pas formellement ça. Dans un appel de fonction, on passe simplement les arguments dans l’ordre des paramètres : l’association est implicite et positionnelle.\nSans forcément tomber dans les signatures de l’enfer, ça peut très facilement donner des trucs pas lisibles :\n\nUne règle d’or dit que si on a plusieurs arguments consécutifs de même type sans ordre naturel, ou qu’on dépasse 3 arguments (fussent-ils intuitifs), on nomme les paramètres. OK, mais alors en JS comment faire ?!\nLe hash d’options, une solution ancienne\nAvant que Ruby n’ait formellement les paramètres nommés, il trichait avec un argument Hash, la syntaxe nous permettant d’omettre les accolades du Hash à l’appel. En JavaScript aussi on passera par un hash d’options (un objet, quoi), sauf que les accolades restent nécessaires.\nÇa fait très longtemps qu’on fait comme ça. Après tout, jQuery.ajax(…) a 35 options, tu imagines le boxon si on devait les renseigner positionnellement ?!\nBon, quand on faisait ça à l’ancienne, c’était un peu pénible :\n\nOutre la verbosité, la signature ne nous renseignait en rien ; si on n’avait pas de la doc détaillée (ou une définition de types soignée), on était foutus, il fallait regarder le code. Qui plus est, le code commençait justement par du « bruit » plutôt que par l’opérationnel.\nDéstructuration nominative de l’argument\nL’arrivée de la déstructuration nominative en ES2015 a certes permis de clarifier un peu les choses :\n\nAu moins, la signature est plus descriptive (et on va la retrouver dans la complétion automatique, etc.). Même sans définition de types soignée, la plupart des EDI et éditeurs avancés vont nous proposer la complétion sur les options.\nValeurs par défaut\nES2015 apporte aussi les valeurs par défaut. Celles-ci ne sont utilisées que si la donnée d’origine est à undefined, ce qui est souvent ce qu’on veut, mais pas toujours. Si par exemple tu considères null, 0 ou false comme invalides, il faudra retravailler manuellement tes arguments. Mais bon, ici :\n\nLà aussi, ces infos remonteront en complétion auto lors de l’appel, ce qui est toujours utile.\nEt si je ne veux rien passer ?\nLe piège classique survient quand ta fonction accepte, en pratique, un appel sans arguments. Par exemple, toutes les options ont une valeur par défaut (ou pour celles qui n’en ont pas, undefined est considérée acceptable). Tu aimerais alors pouvoir faire un appel sans argument :\n\nLe souci c’est que ta signature déstructure son argument, alors qu’il n’est pas possible de déstructurer null ou undefined, d’où la TypeError.\nComprends bien que si un de tes arguments est obligatoire (par exemple, timeout), d’une part tu n’y mettras pas de valeur par défaut, d’autre part il est acceptable de faire planter l’appel vide comme ci-dessus.\nMais s’il est souhaitable d’autoriser un appel vide ? Il suffit de fournir une valeur par défaut à l’argument lui-même :\n\nIci, faute d’un objet passé, on utilisera l’objet vide. Il est alors déstructuré, et vu qu’il n’a aucune des propriétés correspondant à tes options, les valeurs par défaut individuelles sont exploitées.\nPourquoi mettre les valeurs par défaut dans la déstructuration ?\nOn me demande parfois pourquoi ne pas plutôt mettre les valeurs par défaut dans l’objet par défaut de premier niveau, comme ceci :\n\nOutre la répétition des noms d’options, le problème ici c’est que le jour où tu passeras des options, leur objet remplacera ton objet par défaut. Seule la déstructuration s’exécute, et tu n’auras plus de valeurs par défaut pour les options non fournies.\n\nDonc mets toujours tes valeurs d’option par défaut dans la déstructuration. En prime, c’est plus court à écrire.\nBack to the future\nJe te parlais déjà des hashes d’options en 2013 😉\n",
		"description": "JavaScript n’a pas de paramètres nommés ? Pas de problème ! La déstructuration nominative nous fournit une solution… mais attention aux cas à la marge.",
		"date": 1589500800,
		"image": "/assets/images/art-vid/js-nugget-12.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Définir proprement des paramètres nommés optionnels",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-parametres-nommes-optionnels/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Pour le treizième article de notre série quotidienne « 19 pépites de JS pur », nous abordons un sujet un peu controversé : les rôles respectifs des trois mots-clés déclaratifs génériques var, let et const (car pour les deux autres, function et class, y’a pas débat).\n\nDans la série…\nExtrait de la liste des articles :\n\nExtraire les emojis d’un texte\nDéfinir proprement des paramètres nommés optionnels\nconst is the new var (cet article)\nUtiliser des captures nommées\nObject spread vs. Object.assign\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nAvant / après ES2015\nAvant ES2015, JavaScript n’avait que deux mots-clés déclaratifs : var et function. Par ailleurs, l’unité de portée n’était pas le bloc (les paires d’accolades), contrairement à de nombreux langages, mais la fonction (et à défaut, la portée globale).\nÇa surprend, quand tu viens d’autres langages ; et il n’est jamais bon, pour un langage de programmation, d’avoir un comportement inattendu : c’est une source infinie de bugs.\nDu coup, les trois nouveaux mots-clés déclaratifs d’ES2015 (let, const et class) ont le bloc courant comme portée, ce qui est plus aligné avec le paradigme majoritaire en programmation. Leurs déclarations n’existent qu’entre la ligne déclarative et la fin du bloc, fut-il implicite (une boucle sans accolades de blocs a tout de même un bloc implicite).\nLe hoisting de var : un antipattern\nPar ailleurs, les deux mots-clés historiques sont hoisted : ça signifie que l’interpréteur JavaScript va considérer la déclaration (mais pas l’initialisation éventuelle) comme positionnée en début de portée, indépendamment de son emplacement. Pour être précis, les var seront hoisted d’abord, et les function ensuite.\nC’est en fait une tentative d’optimisation préemptive de la toute première implémentation du moteur, qui n’a plus rien à faire ici en 2020, ou 2015, ou même 2009. En fait, c’est même piégeux. Regarde un peu ça :\n\nC’est contre-intuitif au possible. Ce code ne devrait même pas être syntaxiquement valide. À défaut, il devrait lever une ReferenceError dès la première ligne de la fonction. Et pourtant, non ! À cause du hoisting, le code réellement exécuté est celui-ci :\n\nIl n’y a absolument aucun intérêt au hoisting des variables. Aucun. Zéro. Zilch. En fait, le consensus aujourd’hui est que var n’a pas sa place dans du code JS moderne (ES2015+).\nAu minimum, il devrait donc être remplacé par let, qui a deux avantages :\n\nIl n’est pas hoisted, donc toute tentative de le référencer avant sa déclaration lèvera une ReferenceError, comme on pourrait s’y attendre.\nSa portée est le bloc courant, ce qui correspond là aussi davantage aux attentes.\n\nMais alors, pourquoi cet article parle-t-il de const, et pas de let ?\nLa réaffectation, ce cas rare\nIl y a une seule différence entre let et const : le second ne permet pas la réaffectation. Une déclaration const doit être initialisée à la volée, et ne peut plus être réaffectée (avec par exemple =) par la suite.\nPourquoi préférer const ?\nEn pratique, l’écrasante majorité des déclarations ne sont pas réaffectées par la suite ; la raison est simple : modifier la sémantique d’un identifiant au fil du code crée la confusion (ce qui réduit la maintenabilité) et augmente les bugs. Il arrive qu’une réaffectation soit justifiée (affectation asynchrone, affinage progressif d’une donnée, etc.), mais c’est un cas très minoritaire.\nEn revanche, il est tout à fait possible de réaffecter par erreur. Pourquoi ? Le plus souvent, suite à un copier-coller mal mis à jour, ou à une complétion de code maladroite.\n\nEn préférant const par défaut, on est rattrapés par le col immédiatement lorsqu’on tente de réaffecter un identifiant par erreur. Si on a configuré ESLint (voir plus loin), on repère ça immédiatement (quelques secondes après avoir tapé le code, ou lors du commit au plus tard, si tu as mis des hooks adaptés en place). Sinon, on aura une erreur à l’exécution (si le moteur JS prend en charge const correctement).\n\nOn a tendance à garder notamment let pour la boucle for numérique, mais le for numérique devrait être rarissime maintenant qu’on a l’excellente boucle for…of (spoiler alert : une pépite en parlera en détail). Pas de réaffectation (genre i++) ? Pas besoin de let !\n\nAttention aux paramètres\nDans une fonction, les paramètres de la signature ne sont pas déclarés par let ou const , donc fais-y gaffe…\nconst ≠ immuable\nUn autre point important : non réaffectable ne veut pas dire immuable. En particulier, si l’identifiant référence un objet, il reste parfaitement possible de modifier l’objet. C’est juste qu’on ne peut pas réaffecter l’identifiant.\n\nSi tu souhaites « geler » un objet, tu as plusieurs niveaux de verrouillage possibles ; en premier niveau, la bibliothèque standard fournit depuis ES5 Object.preventExtensions(), Object.seal() et Object.freeze(), par ordre croissant de verrouillage. Pour geler récursivement, il faut aller chercher des utilitaires comme deep-freeze-strict, par exemple. C’est imagin",
		"description": "Faut-il encore utiliser “var” ?  Faut-il juste le remplacer par “let” ? Et “const” dans tout ça ?  Dans cet article, nous t’expliquons pourquoi “const” devrait être ton mot-clé déclaratif le plus fréquent.",
		"date": 1589587200,
		"image": "/assets/images/art-vid/js-nugget-13.jpg",
    "_tags": ["tutoriel","js"],
		"title": "const is the new var",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/const-is-the-new-var/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Déjà le quatorzième article de notre série quotidienne « 19 pépites de JS pur », et nous reparlons expressions rationnelles (regex) pour mettre en lumière une des nouveautés les plus agréables à leur sujet dans ES2018 : les groupes de capture nommés.\n\nDans la série…\nExtrait de la liste des articles :\n\nDéfinir proprement des paramètres nommés optionnels\nconst is the new var\nUtiliser des captures nommées (cet article)\nObject spread vs. Object.assign\nConvertir un objet en Map et réciproquement\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nPetit rappel sur les groupes\nDans une expression rationnelle, on utilise un groupe pour appliquer un quantificateur ou une alternative à plus d’un caractère.\nPar exemple, pour dire « au moins une fois la lettre “b” », on écrirait simplement b+. Mais pour dire « au moins une fois le texte “ba” », on ne peut pas dire ba+ : ça, ça voudrait dire « la lettre “b”, suivie d’au moins une fois la lettre “a” ». On crée donc un groupe autour du texte, sur lequel le quantificateur s’applique : (ba)+.\nDe la même façon, baba|bébé signifie « “baba” ou “bébé” », mais pour dire « “salut”, suivi de “baba” ou “bébé”, suivi de “!” » il faudra dire salut (baba|bébé) ! afin de restreindre le périmètre de l’alternative, sans quoi on dirait « “salut baba” ou “bébé !” ».\nGroupes capturants\nPar défaut, les groupes sont capturants : la portion du texte examiné qui leur correspond in fine est isolée dans un groupe de capture numéroté. Le groupe zéro est toujours là : c’est la correspondance intégrale de l’expression. Les groupes à partir de un (1) sont les groupes capturants. Ainsi, si on examine le “match result” (un Array étendu pour l’occasion) produit par l’expression dans le code ci-dessous, on y trouve notamment des propriétés 1, 2 et 3 qui correspondent aux trois groupes capturés.\n\nLes groupes capturants sont aussi pratiques pour faire des backrefs (back references) : indiquer dans le motif qu’on doit trouver « le même texte source que celui qui a correspondu à un emplacement antérieur de l’expression ». Par exemple, imaginons que tu veuilles correspondre à un attribut HTML, dont la valeur peut être délimitée par une apostrophe (') ou un guillemet (&quot;). L’important, c’est qu’on ait le même délimiteur des deux côtés. Tu peux faire une backref en utilisant le numéro de capture voulu :\n\nIci la correspondance de délimiteur (['&quot;]) est dans le premier groupe capturant : pour faire une backref, on utilisera donc \\1.\nDans le même ordre d’idée, si on utilise la regex avec l’API String#replace et qu’on précise un schéma de remplacement textuel, on peut y référencer un groupe avec la notation $numéro. Par exemple :\n\nGroupes non capturants\nNote que ces numéros sont vite casse-gueule : dès qu’on ajoute un niveau de groupe quelque-part, ça décale tout le reste ! Imagine qu’on veuille préciser que le numéro de téléphone a potentiellement “tel:” devant, ça décale tout le reste :\n\nSi ça se trouve, on ne s’intéressait même pas au fait que le protocole “tel:” soit présent ou non, au final, on voulait juste l’intégrer à la correspondance, sans mettre le boxon dans les numéros de capture. On pourrait alors utiliser un groupe non capturant, en démarrant par (?: au lieu de simplement ( :\n\nSpécialisations de groupe\nD’une façon générale, toute spécialisation de groupe démarre par (? :\n\n(?: pour les groupes non capturants,\n(?= pour les tests de succession (lookaheads),\n(?! pour les tests de succession négative (negative lookaheads),\n(?&lt;= pour les recherches arrières (lookbehinds),\n(?&lt;! pour les recherches arrières négatives (negative lookbehinds),\n\nLes groupes de capture nommés\nDe nombreux langages ont une meilleure façon de capturer les groupes : en les nommant. C’est plus lisible et plus résistant à l’évolution de l’expression : pas de décalage par inadvertance, comme avec les numéros.\nES2018 ajoute enfin ça ! L’API correspondante est multiple :\n\nOn définit un groupe de capture nommé avec (?&lt;nom&gt;expr) (donc entre chevrons, avant l’expression de correspondance).\nOn peut faire une backref avec \\k&lt;nom&gt;.\nLe match result est doté d’une propriété groups, qui devient un objet dont les propriétés ont les noms des groupes de capture.\nLe motif textuel de remplacement dans String#replace permet $&lt;nom&gt; pour référencer les groupes de capture.\n\nEt pour la petite histoire, ces groupes restent numérotés par-dessus le marché (mais OSEF).\nReprenons nos exemples précédents en mode « capture nommée » :\n\nMoi je dis 😍.\nC’est dispo où ?!\nNativement : pas dans IE11, on s’y attendait bien, mais pas dans Firefox (ça traîne de ouf depuis 3 ans, ils attendent d’avoir fini de récupérer la lib de regex issue de v8…), sinon à partir de Chrome 64, Edge 79, Safari 11.1, Opera 51 et Node 10.\nHeureusement, Babel transpile (notamment avec les presets env et latest).\nCadeau bonus : String#matchAll(…)\nUn des soucis récurrents avec String#match (et sa réciproque RegExp#exec), c’est qu’on ne pouvait pas avoir",
		"description": "ES2018 amène enfin les captures nommées aux expressions rationnelles, et c’est le bonheur !",
		"date": 1589673600,
		"image": "/assets/images/art-vid/js-nugget-14.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Utiliser des captures nommées",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-captures-nommees/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "En avant pour le quinzième article de notre série quotidienne « 19 pépites de JS pur », pour remettre au clair les rôles et spécificités respectives de la syntaxe object spread officialisée avec ES2018, en comparaison de l’API Object.assign(…) formalisée dans ES2015. Car ce n’est pas « bonnet blanc, blanc bonnet ».\n\nDans la série…\nExtrait de la liste des articles :\n\nconst is the new var\nUtiliser des captures nommées\nObject spread vs. Object.assign (cet article)\nConvertir un objet en Map et réciproquement\nLa boucle for-of : s’il ne devait en rester qu’une…\n…au-delà, c’est la surprise ! (mais la liste est déjà calée)…\n\nDe extend(…) à assign(…)\nOn a toujours eu besoin, en JavaScript, de pouvoir copier des propriétés (et leurs valeurs) d’un objet vers un autre. Que ce soit pour construire une série d’options, caler un descripteur ou d’autres cas d’utilisation, c’est un scénario fréquent.\nVu que c’est un peu pénible à bien faire manuellement (boucle for…in, garde-fou hasOwnProperty(…), et j’en passe), on a rapidement vu des fonctions utilitaires pour ça dans les bibliothèques tierces, et finalement dans la bibliothèque standard du langage.\nL’histoire de Object.assign(…) est déjà ancienne :\n\nDès 2004, Prototype.js popularise Object.extend(…).\nOn retrouve ça rapidement avec jQuery 1.0 et jQuery.extend(…) (le plus souvent appelé $.extend(…)), qui généralise la signature pour autoriser non plus un seul objet source, mais autant de sources qu’on veut, ce qui deviendra la signature de référence ; jQuery étend rapidement (1.1.4) sa sémantique en permettant sur demande une fusion récursive en plus de celle par défaut, superficielle.\nUnderscore et Lodash proposent évidemment _.extend(…), là aussi avec un nombre quelconque d’objets sources (chez Lodash, on a aussi _.assign(…), beaucoup plus ancien et plus proche de ce que standardisera ES2015).\nEn 2015, la bibliothèque standard du langage récupère, avec ES2015, Object.assign(…), qui copie toutes les propriétés énumérables propres (own enumerable properties) des sources vers la destination (en ayant le bon goût d’ignorer les arguments sources undefined, ce qui facilite notre code au passage).\n\nExemples rapides d’appels :\n\nES2018 et le object spread\nEn concevant sa syntaxe JSX, React a proposé une extension vite très populaire : le spread des props, qui permet d’exploiter sous forme de props individuelles un objet les contenant :\n\nES2015 permettait certes le spread sur itérable (notamment sur Array), mais pas sur objet quelconque : il a fallu attendre ES2018 pour les Rest/Spread Properties. La syntaxe est utilisable exclusivement au sein d’un littéral objet, qui crée donc forcément un nouvel objet. Comme le spread sur itérable, on peut l’utiliser plusieurs fois au sein du littéral, et l’ordre n’a d’importance qu’en cas d’homonymie de propriétés spreadées : le dernier spread gagne.\n\nAvec le spread sur objet, il devient facile de créer rapidement un objet dérivé d’un autre, ce qui rend cette syntaxe particulièrement populaire dans l’écriture de réducteurs immuables, par exemple avec Redux :\n\nLa différence subtile\nTu pourrais croire que les deux codes ci-dessous sont, au final, équivalents :\n\nDans cet exemple précis, tu n’auras en effet pas de différence opérationnelle. La cible du Object.assign(…) est un nouvel objet vide de type Object, sans accesseurs écrivains particuliers.\nEn revanche, lorsque ton code à base de Object.assign(…) écrit dans un objet plus avancé, doté d’accesseurs écrivains, ça n’a plus rien à voir : la deuxième version crée un nouvel objet de type Object, elle n’écrit pas dans result. Du coup, non seulement tu changes peut-être le type technique de l’objet (qui pouvait être une instance d’une classe à toi), mais tu zappes les garanties et comportements éventuels que ses écrivains mettaient en place.\n\nAlors voilà, c’est pas tout à fait pareil. Mais c’est rarement un problème. Garde juste à l’esprit qu’un object spread te renvoie toujours un nouvel objet, de type Object, et qui ignorera donc superbement le type et les écrivains de l’objet d’origine.\nTu as aussi le cas où tu dois modifier l’objet d’origine, parce que le reste du code repose sur des comparaisons d’identité ; auquel cas, seul assign(…) est envisageable…\nÀ chaque situation son approche : assign(…) ou spread.\nC’est dispo où ?!\nPour Object.assign(…), à partir de Chrome 45, Firefox 34, Opera 32, Edge 12, Safari 9 et Node 4.\nPour le spread sur objet, à partir de Chrome 60, Firefox 55, Opera 47, Edge 79, Safari 11.1 et Node 8.3.\nNaturellement, core-js et polyfill.io polyfillent le premier, et Babel transpile le second.\n",
		"description": "À l’heure où tout le monde semble opter pour la syntaxe “object spread”, y’a-t-il encore une place pour l’API Object.assign(…) ?  Y’a-t-il seulement une différence ?  Bien sûr que oui !",
		"date": 1589760000,
		"image": "/assets/images/art-vid/js-nugget-15.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Object spread vs. Object.assign",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-object-spread-assign/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Voici déjà le seixième article de notre série quotidienne « 19 pépites de JS pur ». On parle aujourd’hui d’un des types de collection apparus avec ES2015 : Map. Quand l’utiliser plutôt qu’un simple objet, et comment passer aisément de l’un à l’autre ?\n\nDans la série…\nExtrait de la liste des articles :\n\nUtiliser des captures nommées\nObject spread vs. Object.assign\nConvertir un objet en Map et réciproquement (cet article)\nLa boucle for-of : s’il ne devait en rester qu’une…\nSimuler une classe abstraite avec new.target\n…surprise !\n\nObject, le dictionnaire simple\nEn JavaScript, pour associer des clés à des valeurs, on a toujours eu ces bons vieux objets (et dès JS 1.1, les littéraux objets) :\n\nEt au fil des versions (ES3, ES5, ES2015…) on a rajouté plein d’API statiques pour examiner l’objet :\n\nSuper ! Mais alors, à quoi bon Map ?\nMap : quels intérêts ?\nRecourir à des objets simples pour nos dictionnaires est certes très pratique et concis, mais y’a quand même des limitations nettes :\n\nLes clés sont forcément de type String (ou, depuis ES2015, Symbol) : impossible d’utiliser un objet à nous, ou un objet hôte (nœud du DOM, requête fetch, etc.) comme clé.\nConfusion entre propriétés héritées et propriétés propres (sans parler de leur énumérabilité). En pratique, comme on utilise souvent des objets simples, on n’hérite que de peu de choses depuis Object (toString, valueOf, hasOwnProperty et quelques autres), avec des noms dont le risque de collision sur nos clés est faible. Mais tout de même, pour se blinder, il faudra soit partir d’un Object.create(null) plutôt qu’un {}, soit utiliser systématiquement des API adaptées (telles que Object.getOwnPropertyNames(…), hasOwnProperty(…), etc.).\nPas d’API simple de purge. Pas de Object.clear(…) ou équivalent : si on veut préserver l’identité du conteneur tout en le « nettoyant », il faut se galérer un peu.\nL’ordre d’itération n’est pas garanti. Même si en pratique l’ordre utilisé par for…in, Object.keys() et consorts est le plus souvent l’ordre chronologique d’ajout, la spécification ne l’impose pas et des variantes existent.\nL’itérabilité n’est pas là par défaut. Un objet simple n’est pas itérable (au sens ES2015) par défaut, ce qui empêche de l’utiliser facilement avec le spread, la déstructuration positionnelle, la boucle for…of ou tout autre mécanisme de consommation d’un itérable (notamment de multiples API standard).\nLes performances souffrent en scénario de mutation intense. Pour pouvoir correctement optimiser les indexations de l’objet (l’accès à ses propriétés), qu’elles soient directes ou indirectes, les moteurs JS ont besoin que la « forme » (shape) de ce dernier ne change pas souvent : la plupart du temps, changer la forme purge tous les caches d’optimisation de lookup. Du coup, si on ajoute/supprime beaucoup dans le conteneur, la performance de consultation va souffrir.\n\nC’est pourquoi la bibliothèque standard accueille depuis ES2015 le nouveau type Map. Au prix d’une API un peu plus explicite (et d’un besoin de conversion pour (dé)sérialiser en JSON), on gagne pas mal de choses :\n\nClés de n’importe quel type (même undefined est une clé acceptable)\nPerformance optimale\nItérable par défaut\nAPI plus riche (dont la purge)\n\n\nComment convertir entre les deux ?\nTu peux avoir besoin, de temps en temps, de passer d’une Map à un objet simple. Par exemple, pour le sérialiser en JSON avant de l’envoyer sur le réseau ou de le persister sur disque (et réciproquement : revenir à une Map après récupération réseau ou lecture depuis le disque).\nSi ta Map a des clés qui ne sont ni des String ni des Symbol, ça va poser problème, tu t’en doutes. Mais dans le cas contraire, il existe un one-liner pour chaque sens :\n\nEn ES2019, on a enfin Object.fromEntries(…), la réciproque du Object.entries(…) de ES2017 (attendu de longue date lui aussi), qui lui-même nous simplifiait la vie par rapport au Object.keys(…) de ES5 (2009).\nEn pratique, ça se polyfille très bien (via les canaux habituels : core-js, polyfill.io, etc.), donc même sur IE9+ tu l’aurais (et tu pourrais faire polyfiller Map, aussi).\nSi tu veux absolument te limiter à du ES2015 sans polyfiller (mais pourquoi ?! Tu aimes souffrir ?), y’a moyen de le faire en une expression… mais v’là l’expression. Ça implique map.entries(), Array.from, reduce, les descripteurs de propriétés et Object.create. Comme on dit dans la littérature académique, je le « laisse en exercice pour le lecteur ».\nC’est dispo où ?!\n\nObject.entries(…) est native depuis Chrome 54, Edge 14, Firefox 47, Opera 41, Safari 10.1 et Node 7.\nMap est native à partir Chrome 38, Edge 12, Firefox 36 (mais 20 pour ce dont on a besoin !), Opera 25, Safari 8 et Node 4.\nObject.fromEntries(…) est native à partir de Chrome 73, Edge 79, Firefox 63, Opera 60, Safari 12.1 et Node 12.\n\nEncore une fois, ça se polyfille très bien.\nEnvie d’en savoir plus ?\nNos formations envoient du gros pâté, en présentiel ou à distance (FOAD), en inter-entreprises ou en intra rien que pour ta boîte ! Q",
		"description": "Parfois, un objet simple suffit.  Parfois, on voudra un Map.  Mais pourquoi, et comment passer aisément de l’un à l’autre ?",
		"date": 1589846400,
		"image": "/assets/images/art-vid/js-nugget-16.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Convertir un objet en Map et réciproquement",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-object-map/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Bienvenue dans le dix-septième article de notre série quotidienne « 19 pépites de JS pur ». On va parler aujourd’hui d’une de mes fonctionnalités préférées du langage : la boucle for…of. Encore largement sous-exploitée voire méconnue, celle-ci remplace avantageusement la majorité des for numériques, des forEach, et offre encore de nombreux avantages supplémentaires.\n\nDans la série…\nExtrait de la liste des articles :\n\nObject spread vs. Object.assign\nConvertir un objet en Map et réciproquement\nLa boucle for-of : s’il ne devait en rester qu’une… (cet article)\nSimuler une classe abstraite avec new.target\nDes indices de tableaux négatifs grâce aux proxies\n\nOur story so far…\nHistoriquement, JavaScript a 4 boucles :\n\nLe for numérique, hérité du C et très répandu dans d’autres langages. Sa syntaxe parfaitement imbitable pour les débutants, mais bon, elle est ce qu’elle est…\n\n\n\nLe for…in, qui n’a rien à voir avec les trucs similaires dans d’autres langages. Elle sert spécifiquement à itérer sur les propriétés énumérables de l’objet, qu’elles soient héritées ou non :\n\n\n\nLe while, présent dans énormément de langages historiques. Au lieu de suivre une séquence, il utilise juste une condition de bascule, évaluée en amont (on peut donc ne jamais entrer dans la boucle) :\n\n\n\nLe do…while, similaire mais qui évalue la condition à la fin : on a donc au moins un tour de boucle.\n\n\nÀ part le for…in, on retrouve les 3 autres dans un très grand nombre de langages de programmation.\nQue fait for…of ?\nES2015 formalise une notion critique : les itérables. Le protocole d’itérabilité d’un objet est clairement défini (via le symbole prédéfini Symbol.iterator), et de nombreux objets prédéfinis sont itérables : les tableaux naturellement, mais aussi les chaînes de caractères, les Map, les Set, les NodeList… Qui plus est, de nombreux objets proposent plusieurs itérateurs au-delà de leur itérabilité par défaut.\nLa boucle for…of fournit le seul mécanisme de consommation d’itérables sur lequel votre code a le plein contrôle : on peut consommer juste ce qu’on veut, et la quantité peut elle-même être dynamique, définie algorithmiquement.\nPar exemple, pour consommer un bon vieux tableau, en se concentrant comme le plus souvent sur les valeurs, pas les index, c’est nettemment plus agréable :\n\nComme toutes les boucles, on peut y utiliser break, continue, return, etc. Mais c’est nettement plus générique que le for numérique : ça marche même sans index / position (ex. un Set), et on n’a pas besoin de penser à optimiser en mettant la longueur en cache…\nEn profiter pour utiliser const\nTu as remarqué comme j’ai pu préférer const avec le for…of ? C’est parce que je n’ai rien à réaffecter : je travaille directement sur la valeur, pas sur un index que je dois manuellement faire grimper. Du coup, autant le déclarer const pour s’éviter des risques.\nDéstructurer à la volée\nLorsque l’itérateur que tu consommes émet plusieurs valeurs, n’hésite pas à déstructurer à la volée. Par exemple, plutôt que de faire ça :\n\nOn préfèrera faire ça :\n\nPenser aux itérateurs complémentaires\nDe nombreux itérables proposent, outre leur itérabilité par défaut, des itérateurs complémentaires. La plupart proposent au moins trois itérateurs : keys(), values() et entries(). Lorsque la notion de clé n’existe pas (comme pour un Set), les clés sont… les valeurs. On peut bien sûr avoir des itérateurs spécifiques plus « métier ».\nPar exemple, disons que tu veux consommer un Array grâce à for…of, tout en récupérant aussi les index à la volée. C’est parfaitement possible :\n\nCompatible évaluation paresseuse !\nLe vrai point fort de for…of, c’est que grâce au fait qu’il consomme des itérables quelconques pas forcément en entier, mais plutôt au fil de l’eau, c’est le principal moyen de consommer des calculs paresseux (lazy evaluation), notamment des itérables infinis, tels que des séquences mathématiques ou cryptographiques, des générateurs procédureaux de valeurs, etc.\nImaginons un générateur matérialisant la suite de Fibonacci :\n\nLa suite n’a pas de fin : si j’essaie un Array.from(…) ou un spread dessus, je suis foutu. Je peux en revanche récupérer les premiers termes par déstructuration positionnelle :\n\nMais comment consommer au fil de l’eau, une quantité inconnue à l’avance ? Il faut une boucle, dont on puisse sortir à la demande. Par exemple, pour afficher tous les termes inférieurs à 100 :\n\nToutes les primitives d’évaluation paresseuse (un concept très présent en programmation fonctionnelle) sont implémentables comme ça, par exemple la limitation en amont de quantité avec take :\n\n(Si tu fais du RxJS, ça devrait te parler…)\nPerformance\nTu trouveras tout et son contraire en ligne côté benchmarks de performance entre les différents types de boucles. Le plupart ne sont pas représentatifs. Il faut garder à l’esprit deux choses :\n\nTant qu’on n’est pas sur des énormes tableaux (millions d’éléments au moins), la différence est négligeable.\nMême au-delà, si la boucle n’est pas transpilée (cf. plus ",
		"description": "Oubliez le for numérique : la boucle for…of, apparue en ES2015, est votre nouvelle meilleure amie… et tellement plus polyvalente !",
		"date": 1589932800,
		"image": "/assets/images/art-vid/js-nugget-17.jpg",
    "_tags": ["tutoriel","js"],
		"title": "La boucle for-of : s’il ne devait en rester qu’une…",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-for-of/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Déjà l‘avant-dernier article de notre série quotidienne « 19 pépites de JS pur ». Aujourd’hui on parle du bien peu connu new.target, apparu en ES2015, qui nous permet par exemple de simuler des classes abstraites…\n\nDans la série…\nExtrait de la liste des articles :\n\nConvertir un objet en Map et réciproquement\nLa boucle for-of : s’il ne devait en rester qu’une…\nSimuler une classe abstraite avec new.target (cet article)\nDes indices de tableaux négatifs grâce aux proxies\n\nAttends, new c’est pas un opérateur ?!\nMais si. Il n’empêche, JS a quelques cas très particuliers de syntaxe, et notamment new.target, qui est légale (au sein des fonctions) et désigne l’opérande passé à new lors de l’instanciation de l’objet courant.\nÉvidemment, si la fonction courante n’est pas exécutée dans le contexte d’un objet (s’il n’y a pas de résolution possible de this), ça vaudra undefined.\nFunction Environment Record\nChaque exécution de fonction est dotée d’un function environment record (FER), qui liste l’ensemble des bindings (associations de noms à des valeurs) accessibles en vertu de l’appel de fonction. À tout instant, l’évaluation d’une référence traverse une série d’environment records en vigueur, qui représentent peu ou prou les portées actives.\nUne fonction non fléchée dispose dans son FER de quatre bindings spécifiques définis par son mode d’appel : this, arguments, super et new.target. (Une fonction fléchée n’a rien de tout ça, son code ira donc pêcher ces références dans le FER de la fonction non fléchée englobante la plus proche.)\nÀ quoi ça sert ?\nUn des scénarios les plus courants concerne les classes abstraites. Pour rappel, en POO, une classe abstraite sert de base à une hiérarchie de classes, mais est incomplète en elle-même : tu n’es pas censé·e l’instancier directement.\nPrenons la hiérarchie archi-rebattue des formes géométriques ; elles ont certes toutes quelques points communs, comme un point d’origine et une méthode de dessin, qui justifient une classe de base commune Shape. Mais une « forme » en elle-même ne nous renseigne pas sur la forme concrète à dessiner, de sorte qu’instancier new Shape(…) n’aurait pas de sens !\nOn n’a pas de mot-clé abstract implémenté pour dire ça, mais on peut le simuler en testant dans le constructeur que l’opérande passé à new n’était pas la classe de base (c’est-à-dire Shape) mais une sous-classe (par exemple Square) :\n\nC’est dispo où ?\nDispo nativement à partir de Chrome 43, Fireofx 41, Opera 33, Edge 13, Safari 11 et Node 5.\nBabel et TypeScript transpilent évidemment.\n",
		"description": "Connais-tu new.target ?!  Grâce à cette référence très particulière, tu peux par exemple facilement implémenter des classes abstraites en interdisant certains usages de l’opérateur new…",
		"date": 1590019200,
		"image": "/assets/images/art-vid/js-nugget-18.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Simuler une classe abstraite avec new.target",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-new-target/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Les meilleures choses ont une fin : voici le dernier article de notre série quotidienne « 19 pépites de JS pur ». On finit en beauté avec une utilisation sympathique des proxies, cette fonctionnalité éblouissante d’ES2015 : autoriser les index négatifs dans les tableaux.\n\nDans la série…\nExtrait de la liste des articles :\n\nLa boucle for-of : s’il ne devait en rester qu’une…\nSimuler une classe abstraite avec new.target\nDes indices de tableaux négatifs grâce aux proxies (cet article)\n\n« Proxy » ?!\nOui, oui, calme-toi. Rien à voir avec les proxies réseau. Je sais combien les PALC (Proxy À La Con™) d’entreprise constituent une expérience traumatisante…\nUn proxy, c’est par définition un intermédiaire. Et là c’est exactement ça : un objet qui intercepte toutes les manipulations possibles d’un autre, et choisit au cas par cas de laisser passer, altérer, interdire…\nPoint très important : un proxy n’altère jamais l’objet d’origine : c’est un enrobage de cet objet, qui n’empêche en rien ton code d’utiliser l’original directement s’il a une référence dessus. L’idée est de transmettre à du code tiers, lorsqu’on le souhaite, uniquement la référence du proxy.\nLes tableaux et les indices négatifs\nPour rappel, les indices négatifs partent de la fin : -1 est le dernier élément, -2 l’avant-dernier, etc. Super pratique.\nL’API de Array autorise les indices négatifs :\n\nslice(from, to) permet des valeurs négatives.\nsplice(from, count[, ...items]) permet un from négatif.\n\nMalheureusement, la sémantique générale de l’opérateur d’indexation indirecte d’un objet, […], impose que la propriété dont le nom est évalué entre les crochets existe avec ce nom-là. Et les propriétés numériques des tableaux ne sont pas négatives.\n\nÇa manque grave, non ? Alors ajoutons-les !\nIt’s a trap!\nUn proxy est défini sur la base de deux choses :\n\nUne cible (target) : l’objet d’origine, qu’on va enrober\nUn gestionnaire (handler), qui est un simple objet doté de certaines méthodes prédéfinies, appelées « trappes » (traps). Un gestionnaire vide revient donc à ne rien modifier, ce qui rend le proxy superflu…\n\nLe langage définit une trappe par interaction possible avec un objet. On a par exemple has, qui intercepte l’opérateur in de test d’existence de propriété, ou apply, qui intercepte, pour les objets fonctions, le fait de les appeler (avec l’opérateur (…)).\nLa syntaxe générale est simple :\n\nNous, on va s’intéresser aux trappes get et set, qui interceptent la lecture et l’écriture de propriété. On ne poussera pas le bouchon jusqu’à assurer une cohérence intégrale via notamment les trappes has, ownKeys et deleteProperty, parce qu’en vrai, on manipule rarement des tableaux autrement que par indexation ou par leur API dédiée. Mais si tu veux t’amuser, n’hésite pas…\nImplémenter la lecture\nOK, commençons par la lecture. L’idée est simple :\n\nOn prend le nom de la propriété demandée (ce nom sera, techniquement, une String ou un Symbol, qui sont les deux seuls types de noms de propriété autorisés par le langage).\nSi le nom représente un entier négatif (ce qu’on ne pourra pas tester sur un symbole, donc gaffe), on le convertit en son équivalent positif en…\n\nen faisant un véritable Number\nl’ajoutant à length\n\n\nPour finir, on délègue à l’implémentation native de la lecture de propriété.\n\nEt comment fait-on ça, justement ? La meilleure pratique pour les proxies consiste à utiliser l’API Reflect, apparue en même temps, qui fournit un accès plutôt bas niveau à chaque interaction native correspondante aux trappes. Ainsi, pour notre trappe get, on utiliserait Reflect.get, qui a exactement la même signature.\nVoyons ça :\n\nElle est pas belle la vie ?!\nImplémenter l’écriture\nOK, pour l’écriture on fait exactement pareil, mais pour la trappe set :\n\nEt voilà le travail !\nC’est dispo où ?\nLes proxies sont natifs à partir de Chrome 49, Firefox 18, Opera 36, Edge 12, Safari 10 et Node 6.\nEn revanche, contrairement à ce que je vous dis d’habitude, ça ne se transpile pas. Ce n’est tout simplement pas simulable en ES5. Donc soit c’est natif, soit il faut ruser de fou à coup d’accesseurs dans les descripteurs de propriété, ce qui est plus lourd, plus lent, et surtout pas du tout dynamique (il faut que les propriétés soient connues et enrobées à l’avance, ce qui dans notre cas serait une pure tannée).\nEnvie d’en savoir plus (sur les proxies) ?\nSi le sujet vous botte, je l’ai exploré bien en détail (et avec plein d’exemples marrants, utiles ou les deux) dans une présentation que j’ai donnée, entre autres, à Fronteers 2019 (les slides sont ici).\nNotre super formation de dingues ES Total les explore également en profondeur.\nEnvie d’en savoir plus (en général) ?\nNos formations envoient du gros pâté, en présentiel ou à distance (FOAD), en inter-entreprises ou en intra rien que pour ta boîte ! Qui plus est, pendant la crise du Covid-19, les salarié·e·s peuvent être formé·e·s gratuitement ! Ce serait vraiment trop bête de ne pas en profiter !\nThat’s a wrap!\nPfiou ! Et voilà, 19 jours, 19 artic",
		"description": "Les proxies sont une fonctionnalité merveilleuse de ES2015.  Cet article explore une utilisation sympathique : les index de tableau négatifs.",
		"date": 1590105600,
		"image": "/assets/images/art-vid/js-nugget-19.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Des indices de tableaux négatifs grâce aux proxies",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-index-proxies/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Retour des cours vidéos à seulement 10€, nouvelles formations ultra-pointues, nouvelles sessions présentielles, accès gratuit à nos formations… la suite de 2020 s’annonce pleine de bonnes surprises !\n\nDeux nouvelles formations au catalogue\nPour la rentrée 2020, nous avons le plaisir de porter deux nouvelles formations assurées par des pointures reconnues dans leurs domaines :\nPerformances Web\n Conçue et animée par Jean-Pierre Vincent, un des plus grands experts francophones sur la performance front-end, cette formation de 3 jours au programme intense, alimentée par de nombreux retours d’expérience en production réelle et dotée de nombreux travaux pratiques, couvre l’intégralité des points d’optimisation en détaillant leur mesure, leur exécution et leur monitoring par la suite.\nDestinée à toutes les parties prenantes du front-end (intégration, développement, gestion de projet), elle fournit les nombreuses compétences et la vision à 360° indispensables à l’obtention de performances haut de gamme, avec tous les bénéfices que cela entraîne.\nC’est la seule formation francophone pointue dans ce domaine ! La prochaine session aura lieu du 4 au 6 novembre 2020.\nDécouvrir Performances Web\nSwiftUI avec John Sundell\n C’est John Sundell, une pointure internationale sur le développement iOS/OSX et plus spécifiquement Swift et SwiftUI, qui propose cette formation de 2 jours au programme riche et parfaitement à jour sur les dernières annonces Apple à la WWDC 2020.\nDestinée aux développeur·se·s d’applications mobiles (iOS) ou desktop (OSX) désireux·ses de tirer le meilleur parti des dernières possibilités fournies par Apple, elle explore l’ensemble des savoir-faire et astuces d’expert autour de SwiftUI. Les sessions se tiennent en anglais.\nLà non plus, vous ne trouverez rien de comparable sur le marché ! La prochaine session se tiendra les 29 et 30 septembre 2020, et les places partent vite !\nDécouvrir SwiftUI avec John Sundell\nLe retour des cours vidéos à 10€\nVous avez adoré cette opération que nous avons tenue de mi-mars au 11 mai derniers : tous nos cours vidéos étaient disponibles à seulement 10 € TTC l’unité, soit une réduction pouvant aller jusqu’à −70% !\nProgrammation asynchrone moderne, « Git Undo », fonctionnement de this, merge vs. rebase… vous êtes nombreux·ses à avoir fait un grand chelem !\nNous savons bien que la reprise n’est pas immédiate, et nombre d’entre vous, notamment les freelances, n’avez pas encore retrouvé la situation habituelle. Enfants encore à la maison, projets suspendus, télétravail… Les raisons sont nombreuses qui créent un contexte propice à l’apprentissage autonome.\nNous avons donc décidé de relancer cette offre jusqu’à la rentrée, donc jusqu’au dimanche 6 septembre à minuit.\nAvec le code habituel (CHEZMOI), vous pouvez acheter n’importe lequel de nos cours vidéos payants pour seulement 10 € TTC !\nAttention : la plate-forme réinitialise le code actif après chaque achat : si vous n’achetez pas tout en un bloc, pensez à le resaisir ensuite lors du paiement, ou réutilisez simplement le lien ci-dessous pour le réactiver dans votre session.\nJe profite de cette super offre !\nToutes nos sessions septembre–décembre 2020\nOn vous propose un planning riche pour la rentrée !\nSauf indication contraire, toutes les sessions seront présentielles.\nDelicious Insights prend la santé de ses équipes et apprenant·e·s très au sérieux, et outre un nettoyage systématique et soigneux des locaux, nous fournirons naturellement les équipements nécessaires en cas de besoin : masques sanitaires, gel hydroalcoolique, etc. Si de nouvelles vagues devaient empêcher la tenue présentielle de sessions, celles-ci seront automatiquement basculées en distanciel, sans rien perdre en qualité. Les horaires seront alors susceptibles d’être adaptés, notamment en cas de confinement ou fermeture des écoles.\n\n9–11 septembre : Git Total\n17–18 septembre : Architecture CSS\n22–25 septembre : Web Apps Modernes\n29–30 septembre : SwiftUI avec John Sundell NOUVEAU (distancielle)\n13–16 octobre : Node.js\n21–23 octobre : ES Total\n\nÇa fait tard ? Il y en a une distancielle mi-juillet\n\n\n4–6 novembre : Performances Web NOUVEAU\n18–20 novembre : Webpack\n\nÇa fait tard ? Il y en a une distancielle lundi prochain\n\n\n25–27 novembre : Git Total\n1–4 décembre : Web Apps Modernes\n9–11 décembre : ES Total\n15–18 décembre : Node.js\n\nVenez vous former gratuitement !\nLe dispositif FNE Formation a été progressivement étendu depuis le début de la crise du Covid-19.\nAujourd’hui et jusqu’à au moins la fin 2020, il permet de financer 100% des coûts pédagogiques de formation pour les salarié·e·s en CDI ou CDD des sociétés ayant recours à l’activité partielle. Pour les présentielles, peut même prendre en charge les coûts de transport et d’hébergement.\nLe financement couvre aussi bien les personnes en activité partielle (lors de la formation) que celles à temps plein (mais il est préférable alors d’inclure au moins une personne en activité partielle parmi les apprenant·e·s, p",
		"description": "De nouvelles formations, sessions, financements et offres pour l’automne 2020 !",
		"date": 1593043200,
		"image": "/assets/images/art-vid/art-update.jpg",
    "_tags": ["formations","annonce"],
		"title": "Plein de bonnes nouvelles pour la suite de 2020 !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/annonces-automne-2020/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Vous avez adoré cette opération que nous avons tenue au printemps puis à la rentrée : tous nos cours vidéos étaient disponibles à seulement 10 € TTC l’unité, soit une réduction pouvant aller jusqu’à −70% !\nProgrammation asynchrone moderne, « Git Undo », fonctionnement de this, merge vs. rebase… vous êtes nombreux·ses à avoir fait un grand chelem !\nÀ l’occasion du CyberMonday 2020, nous relançons cette offre jusqu’à la fin 2020, donc jusqu’au 31 décembre à minuit.\nAvec le code CYBERMONDAY20, vous pouvez acheter n’importe lequel de nos cours vidéos payants pour seulement 10 € TTC !\nAttention : la plate-forme réinitialise le code actif après chaque achat : si vous n’achetez pas tout en un bloc, pensez à le resaisir ensuite lors du paiement, ou réutilisez simplement le lien ci-dessous pour le réactiver dans votre session.\n🎁 Je profite de cette super promo ! 🎁\n",
		"description": "Pour le Cybermonday 2020, retrouvez tous nos cours vidéos à seulement 10€ !",
		"date": 1606176000,
		"image": "/assets/images/art-vid/art-update.jpg",
		"title": "Cybermonday : le retour des cours vidéos à 10€ !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/cybermonday-2020/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Grosses promos sur les sessions de décembre, cours vidéos à 10€, accès gratuit à nos formations… l’hiver sera chaud !\n\nDes promos en or 🎁🤩\nLes quelques places restantes à nos sessions de décembre sont massivement discountées : −30% pour tout le monde !\nÀ l’heure où nous publions cet article, ça concerne :\n\n1 place restante à la Web Apps Modernes des 1–4 décembre (1260€ au lieu de 1800€)\n4 places restantes à la Architecture CSS des 3–4 décembre (700€ au lieu de 1000€)\n7 places restantes à la ES Total des 9–11 décembre (1050 au lieu de 1500€)\n5 places restantes à la Node.js des 15–18 décembre (1400€ au lieu de 2000€)\n\nTarifs uniques HT par personne, quel que soit le nombre d’inscrit·e·s dans votre convention (ou dans la session). Les tarifs affichés sur les pages formations sont les tarifs publics usuels, mais en choisissant votre session le tarif de la convention appliquera automatiquement la promotion.\nLe distanciel dans la joie\nLe contexte sanitaire est très changeant, on déconfine, on reconfine… et même si les modalités du confinement actuel autorisent toujours les Organismes de Formation à recevoir leur public, en pratique le distanciel est très fortement recommandé (et les publics préfèrent le plus souvent jouer la prudence).\nUne simple connexion Internet d’au moins 1Mbps, un laptop et un endroit raisonnablement calme suffisent.\nDelicious Insights s’est adaptée à ces modalités dès mars 2020, et nous sommes en train de mettre en place une plate-forme dédiée, maison, à même d’offrir une excellente expérience de formation synchrone à distance, en conservant des horaires de type présentiel (7h/j). Nous avons hâte de vous présenter le résultat, mais on peut déjà vous donner quelques mots-clés : duos de formateurs, quizzes, concours, jeux, pair programming et sous-groupes, environnement intégré, exercices complémentaires optionnels, chat, slides interactifs, modalités multiples, segments courts…\nEn attendant, nous continuons à tirer le meilleur parti des solutions en place et de la qualité pédagogique et d’animation de nos intervenants afin de rendre acceptables ces horaires en distanciel.\nToutes nos sessions de décembre 2020 à mars 2021\nOn vous propose un planning riche pour l’hiver !\n\n1–4 décembre : Web Apps Modernes à −30% !\n3–4 décembre : Architecture CSS à −30% !\n9–11 décembre : ES Total à −30% !\n15–18 décembre : Node.js à −30% !\n25–26 janvier : SwiftUI with John Sundell\n27–29 janvier : Git Total\n1–5 février : Performances Web\n2–5 février : Web Apps Modernes\n2–5 mars : Node.js\n10–12 mars : ES Total\n16–19 mars : Web Apps Modernes\n\nLes formations Webpack ne sont plus proposées qu’en intra-entreprise.\nVenez vous former gratuitement !\nLe dispositif FNE Formation mis en place au printemps a cédé le 20/11/2020 la place au FNE Formation Rebond, dont les modalités sont légèrement différentes.\nCôté restrictions, il concerne désormais uniquement les salariés en activité partielle (et non plus leurs collègues, qui bénéficiaient auparavant du principe de mixité du public), et est généralement plafonné à 70% (AP de droit commun) ou 80% (AP de longue durée) des coûts pédagogiques.\nCôté extensions, il peut désormais couvrir les formations internes et AFEST, et supprime le plafond de traitement de 1500€ TTC par personne.\nEn pratique renseignez-vous bien auprès de votre OPCO : certains, comme AKTO, complètent la prise en charge pour la maintenir à 100% ! 🎉\nLes dossiers doivent être déposés d’ici le 31/12/2020, pour des actions se tenant entre maintenant et le 30/06/2021.\nLa prise en charge se fait toujours par subrogation auprès de votre OPCO habituel. Votre société n’a pas à avancer les fonds, et ce mécanisme n’empiète même pas sur les budgets habituels de son Plan de Développement des Compétences (anciennement Plan Formation).\nVoici quelques exemples d’actualité sur ce sujet par les OPCO :\n\nChez ATKO (anciennement FAFTT, FAFIH, INTERGROS, OPCALIA et OPCA Transport et services pour la délégation Propreté)\nChez Atlas (anciennement FAFIEC)\nChez Afdas\n\nN’attendez plus et lancez dès maintenant vos demandes de financement pour les prochaines sessions ! Le dispositif n’est pas rétroactif, il faut donc que l’accord écrit soit obtenu avant la session, et ça prend parfois un peu de temps…\n",
		"description": "De nouvelles formations, sessions, financements et offres pour l’hiver 2020-2021 !",
		"date": 1606176000,
		"image": "/assets/images/art-vid/art-update.jpg",
    "_tags": ["formations","annonce"],
		"title": "Plein de bonnes nouvelles pour les prochains mois !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/annonces-hiver-2020-2021/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "À chaque nouvelle version mineure de Git son lot de nouveautés. Git 2.30 est sortie le 28 décembre 2020 et apporte quelques petites choses utiles. Voici notre sélection de celles qu’on trouve sympa.\n\nDes userdiff à jour\nVous ne le savez peut-être pas, mais Git embarque une partie d’analyse syntaxique pour certains langages, ce qui lui permet de proposer des diffs avec un affichage adapté au contexte (en en-tête des blocs). Dans cette nouvelle version, les affichages de diff ont été améliorés pour CSS, PHP et Rust.\nVoyez dans l’exemple qui suit le contexte des blocs CSS donnés avant chaque hunk (portion de bloc modifiée). Prenez le dernier bloc : la différence affichée n’inclut pas la définition de la règle CSS correspondante. Néanmoins l’en-tête de diff nous donne cette info : footer a:visited.\n\nFiltrer les blocs de diff à l’aide d’une expression rationnelle\nOn se retrouve parfois avec des diffs importants dont ne souhaitons pas visualiser la totalité. Pour éviter ça, il existe depuis longtemps des options de configuration pour spécifier certains comportements.\nPar exemple on peut spécifier quels problèmes d’espacements Git doit considérer. On peut passer sous silence les différences d’espacements en fin de lignes et lignes vierges en fin de fichier avec la configuration globale git config --global core.whitespace -trailing-space.\nGit 2.30 apporte un autre comportement utilisable uniquement en ligne de commande afin de ne pas afficher les blocs de modifications (hunks) qui comprendraient certains contenus désignés par une expression rationnelle.\nVoici un exemple basé sur l’exemple du diff CSS décrit avant : je ne souhaite pas afficher les blocs contenant des modifications sur les largeurs (width) et les marges (margin).\ngit diff -I'(width|margin)'\n\nForcer le push sans écraser\nPour éviter de rendre vos collègues furax 😤 parce que vous avez forcé le push, peut-être utilisiez-vous déjà git push --force-with-lease (qu’on préfèrerait avoir en option de forçage courte plutôt que --force qui écrase sans se poser de question).\nCe --force-with-lease est très pratique à un petit détail près : si on fait une synchro fetch avec le dépôt distant avant le forçage, on peut malgré tout écraser le travail des autres. Une nouvelle option complémentaire s’ajoute donc pour éviter cela : --force-if-includes. Bon clairement ça devient lourd de multiplier les options pour un comportement qu’on peut juger normal, mais l’évolution progressive de Git et son besoin en compatibilité ascendante impose ces pratiques. Heureusement on a toujours les aliases pour nous aider à gérer tout ça plus facilement : git config --global alias.push-with-lease 'push --force-with-lease --force-if-includes'.\nPour mieux comprendre l’intérêt de cette option, revoyons l’action au ralenti :\n1. Camille partage ses commits\nAprès avoir réalisé un premier commit sur la branche dev, Camille le partage.\n\n2. Noah bosse et partage à son tour\nNoah crée 2 commits de son côté sur cette même branche dev puis récupère les nouveautés publiées par Camille (pull)…\n\n…avant de partager à son tour ses commits.\n\n3. Pendant ce temps, Camille travaille\nCamille produit 2 nouveaux commits…\n\n…puis récupère les derniers ajouts de Noah, mais sans les appliquer localement (fetch). C’est ce dernier point qui ouvre une brèche dans les protections de --force-with-lease.\n\nCamille tente alors d’envoyer son travail avec l’option de forçage “douce”, pensant qu’en cas d’oubli de synchronisation son historique n’écrasera pas celui sur le serveur.  Et là, c’est le drame ! Le fetch précédent rend caduc ce qu’on attendait de l’option, les commits de Noah sont écrasés sur le serveur.\n\nL’emploi du complément d’option --force-if-includes aurait évité cette perte en interdisant l’envoi, indiquant le rejet et la raison : remote ref updated since checkout (référence du dépôt distant mise à jour depuis la dernière application locale).\n\nÉvolution de la liste des worktrees : affichage du statut verrouillé\nLes worktrees permettent de travailler en simultané sur plusieurs branches d’un même dépôt local en créant une copie de l’espace de travail pointant sur le même dépôt local, mais sur une autre branche.\nPar exemple la commande git worktree add -b dev ../project-dev créera un répertoire projet au même niveau que notre répertoire projet actuel après avoir créé une nouvelle branche dev pour travailler dessus.\n\nUn worktree peut ne pas être toujours accessible (placé sur un support intermittent comme un partage réseau, un disque dur externe ou une clé USB). Dans ce cas vous aurez peut-être choisi d’empêcher les opérations de nettoyage qui pourraient être déclenchées par Git en verrouillant ce worktree :\n\nCette information de verrouillage n’était jusqu’à présent pas disponible à l’affiche des la liste des worktree. Git 2.30 a donc fait évoluer celui-ci : git worktree list.\n\nTout savoir sur Git 2.30\nIl y a toujours plus à dire sur une nouvelle version. Aussi pouvez-vous consulter directement la release note.\n",
		"description": "Git 2.30 est sortie en décembre 2020 et nous apporte quelques petites nouveautés intéressantes",
		"date": 1611014400,
		"image": "/assets/images/art-vid/art-git-2.30.jpg",
    "_tags": ["nouveautés","git"],
		"title": "Quoi de neuf dans Git 2.30 ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-2-30/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Les hooks sont tout bonnement géniaux quand il s’agit de nous assister et d’automatiser la qualité du travail qu’on produit. Malheureusement l’architecture de Git fait défaut en ne facilitant pas le partage des hooks et de leur configuration.\nC’est là qu’intervient husky !\n\nHusky : quoi et pourquoi ?\nHusky est un module npm (JavaScript) dont le but est de se greffer “par-dessus” les hooks Git pour que ces derniers soient automatiquement intégrés et partagés au sein d’un projet.\nIl existe de nombreuses alternatives mais très peu couvrent l’intégralité des hooks disponibles (la plupart ne traitent que du pre-commit). D’autre part husky possède un avantage non négligeable : il est portable car Node.js est disponible à peu près partout (principe du JavaScript universel).\nAvant de commencer : la version de husky traitée ici est la version 7 produite en juillet 2021 mais le fonctionnement décrit était présent dès la version 6.\nLe principe de fonctionnement de husky est plutôt simple :\n\nil crée un répertoire .husky à la racine du projet,\nil renseigne ce répertoire dans notre configuration Git locale (git config core.hooksPath '.husky')\nil y place, à notre demande, des fichiers en équivalence des scripts de hooks (fichiers pre-commit, prepare-msg, commit-msg etc).\n\nCes fichiers suivent le même format. Ils possèdent un en-tête particulier et listent ensuite les appels aux scripts demandés :\n\nMise en place dans un projet\nSa mise en place est rapide :\n\nPas de bol, npm n’existe pas sur ma machine\nLa commande npm n’est pas disponible ? Assurez-vous d’avoir Node.js sur votre machine, au besoin installez-le (ça intègre automatiquement npm) :\n\nRetentez ensuite la commande (vous aurez peut-être besoin de relancer un terminal frais, avec un chemin (PATH) à jour).\nAstuce supplémentaire si vous n’utilisiez pas Node jusque-là dans le projet : pensez à dire à Git d’ignorer le répertoire node_modules :\n\nConfiguration générale et ajout de hooks\n\nÀ partir de là husky est intégré, sauf qu’on n’a renseigné aucun hook. Cette étape doit être faite au cas par cas, selon les hooks qu’on souhaite utiliser :\n\nVoici un exemple pour afficher sur la sortie standard (terminal) un message de félicitation dès qu’un commit a été créé (ça ne sert à rien, mais ça fait du bien 🙃) :\n\nQuand vous avez fini de configurer tout ça et d’ajouter les hooks qui vous semblent pertinents au projet, n’oubliez pas de partager tout ça en intégrant au projet :\n\nÀ l’usage ça donne quoi ?\nLes cas pratiques sont nombreux et dépendront parfois des technologies que vous utilisez. Deux approches sont possibles et complémentaires :\n\nl’intégration de scripts au sein même du projet (préférable pour du “spécifique projet”) ;\nl’utilisation de scripts externes (propres à l’entreprise ou externes), facilement réutilisables d’un projet à l’autre.\n\nCette seconde approche est la plus répandue car il est rare de devoir réaliser des tâches spécifiques à un projet et qui n’ont pas d’utilité pour d’autres projets. Il est également plus aisé et rapide (donc moins coûteux) d’utiliser de l’outillage existant plutôt que de devoir développer ses propres scripts (et tant qu’à faire on évite de réinventer la roue ⚙).\nPour vous aider à mettre en place les automatisations qui vous intéressent, on vous a préparé une petite série d’articles par thème :\n\nDu code bien formaté sans effort avec husky et lint-staged\nSauvez vos commits grâce à husky et git-precommit-checks\nAméliorez vos messages de commits avec husky et commitlint\nNormez vos branches avec husky et validate-branch-name\n\nLa ligne de commande c’est mignon, mais dans mon éditeur ça donne quoi ?\nTout dépend de la capacité de votre éditeur à vous transmettre l’information contenue dans la sortie d’erreur d’un hook (pour les hooks bloquants s’entend).\nPar exemple pour VSCode, si on utilise son interface graphique pour créer notre commit, alors on obtiendra une modale d’erreur qui nous indiquera la première ligne de la sortie standard (très peu utile 😬) et un bouton nous permettant d’accéder à l’ensemble des informations affichées sur la sortie standard (donc tout ce qu’on aurait eu via le terminal en direct). On garde ainsi toute l’utilité de l’outillage.\n",
		"description": "Les hooks Git sont géniaux, mais pas partagés ! Heureusement husky est là pour nous aider.",
		"date": 1630886400,
		"image": "/assets/images/art-vid/art-git-hooks-husky.png",
    "_tags": ["tutoriel","outil","git"],
		"title": "Gérez facilement les hooks Git avec husky",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-et-husky/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Les règles de mise en forme du code sont souvent source de conflit au sein des équipes. N’avez-vous jamais été témoin d’une discussion houleuse sur l’indentation ? (2 espaces, 4 espaces, 1 tabulation ?) Peu importe l’issue du débat, cela apporte peu à la qualité du code produit et génère une perte de temps en conflits et arbitrages inutiles du code.\nL’uniformisation des outils et éditeurs permet de palier à ce type de problème. Mais si l’outillage fonctionne mal ? Si un membre de l’équipe refuse une partie de l’outillage ? Si cette personne préfère son éditeur à celui proposé à l’équipe, par exemple Nano contre VSCode ? Imposer une solution semble malvenu.\nPour plaire à tout le monde tout en garantissant la bonne application du formatage, on peut alors utiliser les hooks Git via husky pour exécuter en pre-commit l’outillage de mise en forme et d’analyse statique (autrement appelé linter).\nPour bien faire les choses, nous voulons que seuls les ajouts et modifications soient analysés et reformatés. Pour cela, nous allons utiliser le module npm lint-staged.\n\nPrincipes de fonctionnement de lint-staged\nOn ne souhaite analyser que le travail stagé (ajouté à Git avec git add …, mais pas encore commité), et au sein de ça, uniquement des fichiers spécifiques.\nLint-staged est conçu pour n’examiner que le travail stagé. En revanche, il nous incombe de lui dire quels fichiers traiter et avec quels outils. Pour cela, nous renseignons nos règles sous forme de motifs glob dans un fichier de configuration qui peut prendre plusieurs formats. Chez Delicious Insights, on a tendance à préférer les formats .js, souvent plus souples et qui permettent les commentaires et une configuration dynamique. On renseignera donc notre configuration dans un fichier lint-staged.config.js.\nOn peut ainsi travailler dans un projet multi-technos et demander l’application de règles différentes par cet unique outil 🤩 !\nMise en place\nLa procédure de mise en place de husky est décrite dans notre article « Gérer facilement les hooks Git avec husky ». Concentrons-nous ici sur son intégration avec lint-staged.\nComme pour tout module utile lors du développement du projet, ça s’installe comme ceci :\n\nOn configure dans le fichier lint-staged.config.js l’appel aux outils souhaités :\n\nEt on fait en sorte que ça soit appelé lors du pre-commit :\n\nCas classique d’utilisation : Prettier et ESLint\nCes deux outils très populaires dans l’univers du développement JavaScript et web vont nous permettre d’analyser le code (ESLint) et de le formater automatiquement (Prettier). Ils sont d’ailleurs cités en exemple dans la documentation de lint-staged.\nSi ces outils ne sont pas déjà présents dans votre projet, il vous suffit de les installer, ça ne prendra qu’un instant :\n\nPour Prettier, une configuration par défaut existe mais vous pouvez choisir de spécifier vos préférences dans le fichier prettier.config.js à la racine du projet également :\n\nIl ne reste qu’une chose à faire : dire à lint-staged qu’on veut automatiser le recours à ces outils en pre-commit. On va donc éditer notre fichier lint-staged.config.js et renseigner une règle assez large (libre à vous d’ajouter/modifier ça pour y mettre vos règles) :\n\nEt voilà, il n’y a plus qu’à voir ce que ça donne !\nPrenons l’exemple de code JavaScript et CSS mal formatés. Tout ça est ajouté à Git en premier lieu avec un git add …, et au moment du commit on va voir lint-staged qui donne la main à Prettier pour reformater tout ça avant de finaliser le commit.\n\nPour aller plus loin 🐱‍🏍\nVous pouvez combiner cette automatisation avec d’autres utilitaires pour gagner en qualité et en confort de développement :\n\nGérez facilement les hooks Git avec husky\nSauvez vos commits grâce à husky et git-precommit-checks\nAméliorez vos messages de commits avec husky et commitlint\nNormez vos branches avec husky et validate-branch-name\n\n",
		"description": "Formater le code et repérer de mauvais motifs sont des tâches souvent gérées par notre éditeur. Mais qu’en est-il si cet outillage est désactivé ou si on travaille dans un autre éditeur ?",
		"date": 1630886400,
		"image": "/assets/images/art-vid/art-git-hooks-lint-staged.png",
    "_tags": ["tutoriel","outil","git"],
		"title": "Du code bien formaté sans effort avec husky et lint-staged",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-et-lint-staged/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Au-delà de la mise en forme du code et du respect des bonnes pratiques, on souhaite que nos commits ne contiennent pas n’importe quoi. Pour les fichiers non versionnables, on a déjà le fichier .gitignore. Mais qu’en est-il pour les fichiers qu’on souhaite versionner ? Comment empêcher l’ajout de contenus indésirables ?\nC’est là qu’intervient git-precommit-checks et son exécution automatique au moment du commit grâce à husky, dont nous avons couvert la mise en place dans un précédent article.\nComment ça marche ?\ngit-precommit-checks est un module npm à installer sur vos projets et à exécuter en pre-commit. Il analyse uniquement les ajouts et modifications des fichiers ajoutés en vue du commit (stagés suite à un git add …). Il nous permet soit de stopper le commit en cas de détection d’un contenu non souhaité, soit d’afficher une alerte sur la sortie standard, si on considère que certains contenus sont « tolérables » mais méritent d’être signalés.\nContrairement à un outil d’analyse statique (linter), il n’est pas limité à un langage source. C’est à nous de lui décrire les textes recherchés, éventuellement les motifs de fichiers concernés, et le message à afficher.\nMise en place\nPour l’installation, rien de bien difficile :\n\nLà, sur le papier tout est bon, sauf qu’on n’a renseigné aucune règle d’analyse. C’est le moment de vous poser avec votre cahier et votre crayon et de noter les choses qui vous semblent pertinentes pour votre projet.\nQuand vous êtes prêt·e, vous pourrez créer la configuration dans le fichier git-precommit-checks.config.js (en pratique vous pouvez la renseigner sous d’autres formats, mais le JS est souvent plus lisible).\nVoici un exemple pour vous inspirer :\n\nVoyons voir ce que ça donne une fois en place :\n\nPour aller plus loin 🐱‍🏍\nL’automatisation autour du commit est précieuse pour nous permettre de nous concentrer sur notre travail sans craindre pour autant de faire des erreurs ou d’oublier des choses. La vérification des contenus n’est pas la seule chose utile à mettre en place, libre à vous de compléter avec d’autres assistances :\n\nGérez facilement les hooks Git avec husky\nDu code bien formaté sans effort avec husky et lint-staged\nAméliorez vos messages de commits avec husky et commitlint\nNormez vos branches avec husky et validate-branch-name\n\n",
		"description": "Parce qu’il arrive qu’on laisse traîner du code pourri, des logs, des marqueurs de conflits ou des commentaires qu’on voulait temporaires etc, il est préférable d’éviter de commiter tout ça. C’est là qu’intervient git-precommit-checks.",
		"date": 1630886400,
		"image": "/assets/images/art-vid/art-git-hooks-checks.png",
    "_tags": ["tutoriel","outil","git"],
		"title": "Sauvez vos commits grâce à husky et git-precommit-checks",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-et-validation-de-contenus/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "La constitution d’un historique Git lisible et utile passe par la bonne rédaction des messages de commits. Mais comment savoir si un message est bien rédigé, quelle longueur de ligne est pertinente, comment hierarchiser l’information ?\nDe nombreuses personnes se sont posé ces questions et ont tenté de normer la structure de ces messages. Il existe donc différentes conventions. Que vous adhériez ensuite à une convention existante ou que vous décidiez de créer la vôtre, comment garantir qu’elle sera bien appliquée et respectée ?\nDites bonjour à commitlint !\nÀ quoi ça sert ?\nCommitlint est, comme son nom l’indique, un linter de (message de) commit, c’est-à-dire qu’il va analyser le texte qui lui sera transmis. L’idée est donc de déclencher cette analyse à chaque commit et d’interdire la finalisation du commit si le message ne satisfait pas nos contraintes.\nPar défaut commitlint cherchera à ce que vous respectiez la structure suivante, issue d’une convention globale appelée conventional commit :\n\nCette structure est généralement suffisante (très souple avec des règles optionnelles) et bénéficie de nombreux outillages basés sur le vocabulaire qu’elle propose (automatisation des publications de versions, génération automatique des notes de version, etc.).\nOn trouve quelques alternatives, comme gitmoji qui recourt aux emojis pour permettre une interprétation plus visuelle de notre historique.\nSi toutefois l’emploi d’une convention existante ne satisfaisait pas vos besoins, vous pouvez créer votre propre série de règles, soit en passant par un module indépendant réutilisable, soit en intégrant à même le projet votre configuration.\nInstallation et configuration\nIl s’agit de modules npm qu’on va associer à la phase de développement afin de les partager au sein du projet :\n\nPour la configuration, vous pouvez choisir d’installer le module qui répondra le mieux à vos attentes (ou de créer le vôtre) :\n\nconfig-angular-type-enum\nconfig-angular\nconfig-conventional\nconfig-lerna-scopes\nconfig-patternplate\n\nOn crée ensuite le fichier de configuration local commitlint.config.js pour dire à commitlint quelle configuration charger :\n\nEt pour que tout ça s’exécute automatiquement à chaque message de commit renseigné, on demande à husky de le charger via le hook commit-msg :\n\nConfigurer pour l’intégration continue\nIl est possible que vous souhaitiez configurer commitlint ailleurs que sur les postes utilisateurs pour forcer vos contraintes pour tous les acteurs, même celles et ceux qui décideraient de contourner commitlint ou qui simplement ne l’auraient pas installé. Un cas d’exemple serait la sous-traitance d’une partie de votre projet à un prestataire. Vous n’avez donc pas la garantie ni même les moyens d’assurer le bon respect de vos règles. Cependant vous avez la main sur l’intégration continue. Reste alors à y mettre en place commitlint.\nÀ l’usage, ça donne quoi ?\nComme on l’a dit, tout ça va s’exécuter automatiquement quand on fera nos commits ; nous serons stoppés si un message ne remplit pas nos critères :\n\nPeut-on être aidé·e plutôt (et plus tôt) lors de l’écriture ?\nLe contrôle en sortie est toujours utile, mais bénéficier d’une assistance pour rédiger le message constitue un complément appréciable. Il est fort probable que (comme moi) vous oubliiez les critères et le vocabulaire mis en place. C’est pourquoi commitlint propose l’intégration avec un assistant.\n\nCet assistant s’appelle commitizen. Pour l’associer à commitlint on doit configurer la passerelle dans le fichier package.json. On devra ensuite utiliser npx cz à la place de notre habituel git commit :\n\nNote : si vous voulez une “meilleure” intégration avec Git, vous pouvez installer commitizen en global avec npm install --global commitizen afin de pouvoir faire git cz (voire juste cz) au lieu de npx cz.\nVoici ce que ça peut donner :\n\nEn bonus appréciable vous pouvez modifier les textes de l assistant. Par exemple pour les traduire :\n\nCertains éditeurs proposent également des extensions. Pour VSCode par exemple, vous serez probablement séduit·e par le lint live ou par l’assistant de saisie de commits conventionnels.\nRésumons tout ça\nCommitlint, associé à husky et commitizen, nous permet de qualifier et normer au mieux nos messages de commits. On gagne alors en confort grâce à l’automatisation, on uniformise et gagne en qualité grâce au respect de la convention, on favorise la lisibilité et le suivi du projet avec un historique désormais clair et efficace.\nOn peut par la suite chercher des solutions complémentaires pour continuer l’automatisation d’une partie de nos process.\nMais avant ça, peut-être n’avez-vous pas encore automatisé tout ce qui est source d’erreurs dans votre travail avant sa publication/son partage ? Voici nos autres articles sur le sujet qui pourraient vous servir :\n\nGérez facilement les hooks Git avec husky\nDu code bien formaté sans effort avec husky et lint-staged\nSauvez vos commits grâce à husky et git-precommit-checks\nNormez vos branches avec ",
		"description": "Entre lisiblité de l’historique et automatisation du changelog, bien rédiger vos messages de commits offre de nombreux avantages à vos projets.",
		"date": 1630886400,
		"image": "/assets/images/art-vid/art-git-hooks-commitlint.png",
    "_tags": ["tutoriel","outil","git"],
		"title": "Améliorez vos messages de commits avec husky et commitlint",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-et-commitlint/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Lorsqu’on utilise un outil de gestion de versions (qui sait gérer les branches), on en vient très vite à se poser la question : comment nommer au mieux mes branches ?\nIl n’existe (hélas ?) pas de convention ou de standard comme on peut le voir pour les commits. Cependant il est recommandé de nommer soigneusement vos branches pour identifier facilement le thème global traité par un ensemble de commits. On définit donc généralement une convention.\nComment faire en sorte que cette convention soit respectée ?\nLocalement, Git ne nous donne pas la possibilité d’intercepter l’ensemble des scénarios de création pour vérifier le nom de la branche. Cependant nous pouvons intercepter l’évènement de “partage” des branches pour garantir qu’on ne crée pas sur le dépôt distant une branche mal nommée (c’est finalement plus utile, car l’intérêt d’un nommage soignée réside surtout dans la collaboration). On peut mettre ça en place avec le hook de pre-push et l’utilitaire validate-branch-name. Et pour que ça marche pour tout le monde sur le projet sans avoir à y penser, on utilise husky, que nous avons détaillé par le passé.\nFonctionnement de validate-branch-name\nvalidate-branch-name analyse la branche que vous tentez de pousser (git push) et stoppe l’opération si les contraintes ne sont pas respectées.\nOn peut renseigner ces contraintes dans un fichier de configuration. Sinon les motifs autorisés par défaut seront utilisés et vérifieront que :\n\nles branches correspondent exactement à master ou develop ;\nsinon que les branches sont préfixées par feature, fix, hotfix ou release, suivi d’un slash (/).\n\nMise en place\nTout comme husky, il s’agit d’un module npm pour la phase de développement :\n\nPuis on définit selon nos règles la configuration dans le fichier .validate-branch-namerc.js :\n\nPlus tard, quand on tentera de partager une branche mal nommée, on se fera rattraper par le col et notre push sera rejeté, nous encourageant à bien nommer notre branche :\n\nRecommandations de convention\nÀ défaut d’un guide en ligne pour une convention bien établie, je vous fais un résumé de ce qui pourrait s’en rapprocher, basé sur mon propre vécu et les retours d’expérience dont on m’a fait part.\nJe vous encourage, pour bien définir vos catégories de branches (et donc leur nommage), à vous interroger sur les grands rôles ou thèmes qui seront utiles à votre projet.\nNote : vous remarquerez peut-être qu’une partie des recommandations qui suivent sont similaires à des workflows documentés tels que le GitLab flow ou le Git flow. C’est logique si on considère que les noms de nos branches doivent faire écho à notre gestion de projet.\nQuels environnements ?\nÀ l’initialisation d’un projet, Git crée par défaut une branche main (anciennement master). Cette branche peut prendre le rôle que nous désirons et peut même être renommée. Elle est le plus souvent utilisée comme tronc commun des développements ou comme branche de production.\nOutre cette branche déjà existante à la création du projet, on retrouvera souvent des branches pour les “environnements” suivants :\n\nproduction : celle qui sert à l’extraction / la génération de nos livrables ;\npreproduction / staging : permet des vérifier le livrable avant fusion dans la production (assurance qualité) ;\ndevelop / main : branche de développement stable (jouera parfois le rôle de preproduction pour limiter la profondeur des branches).\n\nCertains projets ont plusieurs versions de production à un instant T. Leur maintenance nécessitera des branches dédiées : release-X.X.X (pour éviter la confusion avec d’éventuels tags nommés vX.X.X).\nQuelles étapes traverse mon projet ?\nLa plupart des projets de développement passent par des étapes de création, d’amélioration et de correction. On isole ainsi deux grands rôles pour lesquels nous pourrions utiliser des préfixes dans notre convention :\n\nfeat/ pour la création et l’amélioration des fonctionnalités (en raccourci de feature) ;\nfix/ ou hotfix/ pour la gestion des corrections (problèmes liés à la production).\n\nLe suffixe prendrait ensuite une valeur contextuelle, intégrant éventuellement la référence équivalente au thème dans vos outils de gestion de projet (exemple d’une référence d’un ticket ou d’un projet dans GitHub ou GitLab) : fix/24-restore-form-validation.\n_Note : je recommande généralement l’usage du slash (/) pour la découpe de contextes / préfixe (un seul niveau suffit généralement, mais on peut imaginer feat/gdpr/notice, par exemple), et réserver les tirets voire soulignés (- ou _) pour les segments du nom, afin de ne pas se limiter à un seul mot (comme dans l’exemple de correctif du paragraphe précédent)._\nCas particuliers de la mise à jour des dépendances\nPeut-être utilisez-vous un service comme dependabot qui analyse les dépendances de votre projet et vous propose automatiquement une mise à jour via une branche (et une pull request). Il ne s’agit dans ce cas pas d’une fonctionnalité ni d’un réel correctif. La branche ainsi proposée est alors préfixée bump/. ",
		"description": "Les noms de branches sont critiques pour comprendre correctement les travaux en cours, et comprendre les fusions dans l’historique : voyons comment garantir leur qualité.",
		"date": 1630886400,
		"image": "/assets/images/art-vid/art-git-hooks-branch.png",
    "_tags": ["tutoriel","outil","git"],
		"title": "Normez vos branches avec husky et validate-branch-name",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-hooks-validation-des-noms-de-branches/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Le code de nos applications est de plus en plus riche et les appels API de plus en plus fréquents. Pour gagner en sérénité, en pérennité et en qualité on essaie de mettre en place des tests pour couvrir a minima les fonctionnalités critiques. Les bibliothèques de tests se sont largement démocratisées ces dernières années et on constate (enfin) une vraie culture des tests en entreprise (même de petite taille).\nLa simplification des outils n’y est pas pour rien. Côté JavaScript, Jest a su séduire un très large public, notamment par ses aspects « tout en un » et « zéro config ». Il fait office, à l’heure où j’écris ces lignes, de référence aussi bien pour les tests front-end que back-end.\nCependant la mise en place de tests d’appels API est souvent perçue comme une épine dans le pied. Certaines questions reviennent fréquemment : que doit-on tester exactement ? Comment tester ? Comment faire en sorte que ces tests soient maintenables et leur mise en place reproductible ?\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nIdéalement on souhaite décorréler nos tests des simulations d’appels API (mocks). En d’autre termes, on veut écrire nos tests comme si l’appel réseau était réalisé normalement. Sauf qu’en pratique on ne va pas appeler ni monter à la main un serveur localement juste pour simuler ces appels API, ça serait lourd et fastidieux (et on va encore moins appeler un serveur distant d’API, hein 😅 !).\nHeureusement on bénéficie d’un truc génial pour intercepter nos requêtes au niveau réseau depuis le navigateur et nous renvoyer la réponse qu’on souhaite (jouant en quelque sorte le rôle d’un proxy) : les service workers. C’est hyper bien quand on est dans le navigateur, sauf qu’avec Jest on peut aussi être dans du Node.js, ou il resterait lourd de simuler toute la couche réseau d’un navigateur pour exécuter nos tests d’appels API front.\nQue ce soit pour gérer dans le navigateur en dev (avec Storybook par exemple) ou côté Node.js, il existe une solution fabuleuse qui nous permet de mettre en place nos mocks quasiment sans effort : MSW (Mocked Service Worker).\nCet article vous montre comment mettre en place MSW (0.35) avec Jest (27) et quelles bonnes pratiques adopter. Le contexte est celui d’une page web réalisant des appels API REST via la fonction fetch (MSW mocke aussi facilement GraphQL, notez bien). Les tests étant exécutés par Jest (donc via Node.js), MSW ne sera pas utilisé en mode navigateur (avec un service worker) mais en mode serveur.\nUn article complémentaire décrit la mise en œuvre de MSW avec Storybook pour réutiliser les mêmes mocks dans vos guides de style et revues visuelles.\nL’application de démonstration utilisée pour ces deux articles est disponible sur GitHub.\nAvant propos : pourquoi ne pas simplement mocker fetch ?\nKent C. Dodds, formateur JavaScript et auteur de l’excellent écosystème Testing Library, explique tout cela très bien dans son article “Stop mocking fetch”.\nEn résumé, il est préférable d’éviter de simuler le comportement du client car l’usage que nous en faisons pourrait devenir obsolète si l’API venait à changer. En d’autres termes, on a plus intérêt à laisser l’intégralité de notre code s’exécuter comme tel et intercepter les appels « autour ». C’est exactement ce que fait MSW pour nous !\nPrincipes de fonctionnement\nOn peut utiliser MSW pour simuler nos appels API aussi bien dans le navigateur que côté Node.js (via Jest dans notre cas).\nDans un navigateur moderne, MSW nous fournira un service worker qui fera office de proxy interceptant les requêtes de l’application et retournant les réponses que nous aurons défini.\n\nCôté Node.js ou vieux navigateurs (ex. IE11) MSW agira différement car il n’a pas les services workers. Il va donc augmenter le comportement des bibliothèques natives, tels le module noyau https ou le constructeur XMLHttpRequest. Autrement dit, il s’incruste dans les appels à ces API et s’assure de retourner les bonnes valeurs simulées pour les URLs demandées.\n\nInstaller et configurer MSW\nEn bon module JavaScript, son installation se fait via :\n\nNous devons ensuite définir nos mocks. La doc MSW nous recommande de regrouper leurs définitions au même endroit, par exemple dans un répertoire src/mocks/. On viendra par la suite exposer ces jeux de données de tests via un module unique, classiquement src/mocks/handlers.js.\nLa suite de la procédure et des exemples décrits dans cet article traitent du mocking d’API REST. Si toutefois votre cas d’usage est lié à des appels GraphQL, sachez que MSW convient également mais que la mise en place est légèrement différente. Et si par un malheureux hasard vous faites du SOAP 🤢… vous avec l’habitude de souffrir et continuerez, MSW ne peut rien pour vous 😫.\nDéfinir les requêtes interceptées et leurs mocks\nNotre module handlers doit exporter un tableau contenant un mock spécifique par requête interceptée.\n\nPour que ces mocks puissent être utilisés, nous indiquons à",
		"description": "On vous explique comment mettre en place facilement une infrastucture simulant des appels API depuis vos tests et sans devoir recoder la Terre entière. Bonus appréciable : vous pourrez réutiliser  cette même infrastructure pour Storybook.",
		"date": 1631491200,
		"image": "/assets/images/art-vid/art-js-jest-msw.jpg",
    "_tags": ["tutoriel","outil","js","tests"],
		"title": "Simulez vos appels réseau pour vos tests Jest avec MSW",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/jest-msw/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Storybook, c’est génialissime pour développer des composants d’interface utilisateur, faire du BDD ou simplement illustrer une bibliothèque de composants UX.\nPour la plupart des composants ça se passe en général très bien. Sauf qu’à un moment on se retrouve confronté·e à un problème de taille : créer des scénarios d’affichage pour un composant qui consomme des données depuis une API.\nEn réalité on peut laisser ces appels API se faire, ça fonctionnera très bien tant qu’on a un serveur démarré joignable pour servir cette API. Sauf qu’en cas de panne réseau ou de serveur manquant, ou si l’API dudit serveur n’est pas encore prête, ou tout un tas d’autres raisons qu’il serait trop long d’énumérer, bah on est marron 😨 !\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nIdéalement on préférera pouvoir travailler avec Storybook et nos composants sans contrainte. Si on prend un peu de recul, on comprend qu’on a besoin que Storybook nous permette de charger des réponses de démo pour répondre aux appels de nos composants.\n\nEt chevauchant fièrement dans les plaines JS arriva MSW (Mock Service Worker), triomphant !\n\nComme je l’explique dans notre article sur Jest et MSW, il est préférable d’éviter de mocker les modules de l’application et de court-circuiter une partie de notre logique pour renvoyer nos jeux de données de test. On a plus intérêt à capturer les appels API une fois « sortis » de l’application, ça nous évite la surprise d’un changement de comportement d’un module utilisé en interne. C’est à ça que MSW va nous servir.\nEn bonus très appréciable, MSW nous permet de mutualiser nos mocks entre nos tests et nos développements.\nFonctionnement\nMSW nous fournit un service worker côté client (processus d’arrière plan dans le navigateur) qui capture toutes les requêtes réseau que notre code tente de faire. Dès lors qu’une requête correspond à l’une de celles qu’il écoute, il retournera la réponse simulée en conséquence.\nCe qui est plutôt cool là-dedans, c’est que tout est fait pour qu’on se concentre uniquement sur les jeux de données de test.\nVous pouvez voir ça comme un proxy réseau, mais local à la page.\n\nPour nos exemples…\nHistoire d’aller au plus direct nous construirons nos composants en HTML/JS natifs. La procédure décrite ici n’est pas spécifique à une technologie et peut donc s’appliquer pour tout le spectre des bibliothèques/frameworks avec lesquels Storybook fonctionne.\nNous allons mettre en place des composants qui consomment des données via des appels REST à l’API JSON Placeholder et affichent…\n\nla liste des billets de blog (composant src/components/Posts.js) ;\nle détail d’un billet de blog (composant src/components/Post.js).\n\nLes appels API sont centralisés dans un module src/api.js dont voici le contenu :\n\nEt voici en exemple le code du composants POSTS qui affichera sous forme d’un tableau des éléments récupérés :\n\nMettons en place Storybook\nSi ça n’est pas déjà fait, vous pouvez installer et pré-configurer Storybook en lançant la commande npx sb init qui vous demandera dans quel contexte vous souhaitez l’utiliser (dans le cadre de cet article j’ai répondu html).\nNote : à l’heure où j’écris ces lignes Webpack 5 est la version majeure en place mais Storybook fonctionne encore avec la version 4 par défaut. Vous pouvez néanmoins forcer leur version expérimentale (entamée en mars 2021) en faisant un npx sb init --builder webpack5.\nTestez que tout roule en lançant npm run storybook.\nOn reviendra à la configuration de Storybook par la suite pour le coupler à MSW, mais d’abord…\nMettons en place MSW\nLa mise en place de MSW côté navigateur demande, outre son installation, la création du service worker, son démarrage, la création et l’exposition de nos jeux de données simulés.\ninstallation\nPour l’installation du module, c’est vite fait :\n\nCréation du service worker\nLa création du service worker, c’est tout aussi rapide :\n\nÇa vient préciser l’emplacement du fichier généré dans le package.json :\n\nNote : le répertoire publique utilisé dépend de votre architecture projet. Dans notre cas, on utilise ./dist.\nPréparation des données simulées\nNous préparons les mocks dans un fichier src/mocks/handlers.js. L’objet retourné est un tableau qui décrit pour chaque entrée une réponse de test à apporter à une URL donnée.\n\nChaque entrée du tableau fait appel à la fonction rest de MSW et emploie la structure rest.httpMethodName(url, responseHandler).\nLa méthode peut prendre une valeur parmi les méthodes de requête HTTP standard, les plus courantes étant : get/post/put/patch/delete.\nLe gestionnaire de réponse est une fonction qui prend trois arguments :\n\nles informations de la requête interceptée (req) ;\nune fonction utilitaire pour créer la réponse mockée (res) ;\nun objet fournissant un ensemble de fonctions permettant de renseigner le statut, les en-têtes et le corps de la réponse (ctx).\n\nSi on prend par exemple la récupération de nos billets de blog, la fonction",
		"description": "Storybook c’est génial pour faire du Behavior Driven Development ou documenter une bibliothèque de composants. En revanche, dès que le code illustré fait appel à des API, on est vite en galère…",
		"date": 1631491200,
		"image": "/assets/images/art-vid/art-js-storybook-msw.jpg",
    "_tags": ["tutoriel","outil","js"],
		"title": "Simulez vos appels réseau dans Storybook avec MSW",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/storybook-msw/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Il arrive régulièrement qu’on ait besoin de mettre du travail de côté le temps de traiter une tâche prioritaire sur notre projet ou de récupérer les nouveautés produites par nos collègues qui sont nécessaires à notre travail courant. Plutôt que de créer un commit dont les contenus seront mal finis, nous préférerons isoler ce travail dans la remise Git, appelée stash en anglais.\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nPrincipes de fonctionnement\nLe scénario d’utilisation classique est le suivant :\n\non met de côté ;\non réalise la tâche prioritaire ;\non reprend ce qu’on avait mis de côté.\n\nLe stash est une zone au même titre que la copie de travail (working directory), le stage et le dépôt local. On y place tout ou partie du travail en cours en appelant la commande git stash ….\nIl est géré sous forme de pile, c’est-à-dire qu’on peut y ajouter plusieurs lots de modifications et que ces lots seront « empilés ». Ça signifie que pour « dépiler », on récupérera par défaut le dernier lot inséré (sauf appel explicite).\n\nNote : si vous n’êtes pas à l’aise avec les zones et états Git, vous pouvez comprendre ces mécanismes dans notre cours gratuit d’introduction aux concepts fondamentaux de Git. Pour un rappel plus succinct, nous vous recommandons cette cheatsheet interactive très complète.\nQue désigne-t-on par « travail en cours » ?\nIl s’agit des fichiers connus de Git (ayant déjà fait l’objet de commits antérieurs) qui ont subi des modifications ou qui ont été supprimés.\nDe base ça exclut les nouveaux fichiers (non suivis par Git), mais l’option -u (ou sa version longue --include-untracked) nous permet de forcer leur mise dans le stash.\n\nComprendre ce qu’on peut mettre dans le stash et comment\nClassiquement on met tout ce qui “traîne” dans le stash sans trop se poser de question. La plupart des gens utilisent alors git stash sans option. Ceci a pour conséquence d’ajouter dans le stash une entrée nommée sur la base du message du commit courant, préfixé par “WIP” (Working In Progress / travail en cours) et le nom de la branche courante.\n\nÇa n’est clairement pas idéal pour déterminer ce que contient l’enregistrement dans le stash. Aussi nous recommandons-vous, comme pour un commit, de bien nommer votre stash : git push -m 'Un message clair concernant le stash'.\nPour résumer, l’usage “classique” que nous vous recommandons pour mettre du travail de côté consiste à prendre tout le travail en cours, nouveaux fichiers compris, et de nommer tout ça correctement :\n\nDoit-on tout mettre dans le stash ?\nGit nous permet de faire du stash chirurgical, en choisissant précisément les fichiers, voire les portions de fichiers qu’on souhaite mettre de côté.\nPour choisir les fichiers, il suffit de les désigner via leur chemin complet ou des globs (exemple : git stash index.txt styles/*.css).\nPour l’ajout de portions de fichiers on utilisera l’option interactive git stash push -p … (ou --patch) qui nous proposera de choisir parmi des segments de modifications (équivalent de git add -p … pour l’ajout au stage).\n\nAnalyser le stash\nOn a parfois besoin de vérifier ou analyser ce qui est contenu dans le stash.\nDe base bon nombres d’interfaces graphiques et terminaux améliorés (via le prompt) sauront vous retransmettre une information globale sur le nombre d’entrées présentes dans le stash. Ensuite vous devrez aller chercher l’info, par exemple avec la ligne de commande.\nOn peut ainsi afficher l’ensemble des entrées du stash avec :\n\nOn comprend alors l’intérêt d’avoir correctement nommé les entrées du stash.\n\nPour obtenir la liste des fichiers modifiés on pourra faire un :\n\nLes fichiers non-suivis ne sont pas affichés par défaut, il faut renseigner l’option -u ou --include-untracked pour les voir :\n\nOn peut aussi demander à afficher les modifications elles-mêmes, au sein des fichiers :\n\n\nAttention : avec git show, en raison du mode stockage du stash, seules les modifications non stagées seront affichées. C’est parce que le commit technique référencé par le stash stocke uniquement ces infos, utilisant des commits techniques parents distincts pour les nouveaux fichiers et les modifications stagées.\nExtraire du stash\nOn peut choisir 2 modes d’extraction du stash :\n\non extrait et on garde une copie dans le stash : git stash apply\non extrait sans garder l’entrée dans le stash : git stash pop (= apply + drop).\n\nDans les deux cas Git ne tentera pas de replacer dans le stage les fichiers stagés lors de la mise dans le stash. Pour tenter de restaurer cet état vous pouvez renseigner l’option --index (valable pour apply comme pop).\nLe plus fréquemment vous souhaiterez sortir l’entrée du stash au moment de son extraction :\n\nEt si le stash ne peut pas être extrait ?\nGit vous indiquera alors la marche à suivre, à savoir qu’il faut commiter vos modifications en cours qui gênent l’application du stash.\n\nUne fois ce commit réalisé, si les modifications extraites de votre stash touchent de",
		"description": "Vous avez du travail en cours non prêt à être commité et vous devez effectuer des opérations sur votre projet ? Git stash est là pour vous aider !",
		"date": 1634515200,
		"image": "/assets/images/art-vid/art-git-stash.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Mettre du travail de côté avec le stash",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-stash/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Peut-être connaissez-vous le stash qui sert à mettre du travail de côté ? Git worktree vous permet en quelque sorte de faire la même chose. La différence est que les worktrees vous permettent de laisser votre espace de travail en l’état et en créent un autre ailleurs sur votre disque. Cet autre espace de travail aura la particularité de pointer sur le même dépôt local que le dépôt initial mais pointera sur une autre branche.\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\n\nQuand est-ce utile ?\nIl y a 2 situations “classiques” pour lesquelles l’usage des worktrees peut s’avérer plus adapté que le stash.\nStaging complexe à préserver\nSi on a déjà bien avancé sur le staging de notre travail, il serait frustrant de voir à terme le stash pop refuser de le restaurer, au prétexte qu’on aura entre-temps modifié certains des fichiers concernés par notre stage.\nOn utilise alors git worktree pour créer un autre répertoire projet pointant sur le même dépôt local que notre projet actuel. On pourra travailler sereinement sur une autre branche puis reprendre, dans notre répertoire initial, notre commit en cours de préparation.\nBascule régulière entre branches impactant l’environnement\nEn soi, basculer régulièrement entre deux branches (par exemple une branche de fonctionnalité et une de correctifs urgents) n’entraîne pas forcément de lourdeur particulière, et le stash reste un mécanisme rapide et agile.\nCependant, il arrive qu’on doive régulièrement basculer entre des branches très différentes les unes des autres, par exemple entre notre développement fonctionnel courant et de la maintenance corrective sur une version déjà ancienne. Même lorsqu’elles ne sont pas si éloignées, nos branches peuvent aussi nécessiter à chaque restitution sur notre working directory un lourd travail de recompilation d’artefacts voire de réinstallation de dépendances.\nAfin d’éviter de perdre un temps considérable à chaque bascule, on peut alors faire co-exister ces branches sur le disque, chacune dans son worktree.\n\nMise en œuvre\nPour initialiser un worktree depuis notre dépôt courant nous devons exécuter la commande :\n\nL’option -b permet d’indiquer le nom de la nouvelle branche à créer. Si cependant on souhaite utiliser une branche déjà exitante, il suffira de ne pas renseigner cette option et de passer le nom de la branche voulue en dernier argument (« point de départ »).\nVoici deux exemples d’utilisation :\n\nUne fois notre worktree créé, il ne nous reste plus qu’à aller dans le répertoire associé pour travailler normalement sur notre branche.\nÉtat de mes worktrees\nLorsqu’on utilise les worktrees on souhaite parfois faire le point pour déterminer, par exemple, si on doit décider d’en supprimer certains (nettoyage).\nImaginez que vous ayez créé un worktree pour effectuer un correctif urgent de production :\n\nVous avez laissé le worktree sans trop vous en préoccuper. Puis un jour vous décidez de faire du nettoyage. Vous pourrez alors lister vos worktrees pour le projet courant en faisant un :\n\n\nSupprimer un worktree\nVient le moment où un worktree n’est plus utile. Vous voudrez alors le supprimer :\n\nEn passant par cette commande vous garantissez que vous ne supprimez pas un worktree ayant du travail en cours, lequel risquerait par conséquent d’ être perdu (nouveaux fichiers, fichiers modifiés).\nSi toutefois le worktree en question avait du travail en cours que vous estimez jetable, l’option -f (ou sa version verbeuse --force) vous permettra de contourner ce garde-fou :\n\n\nOops ! J’ai supprimé le répertoire de mon worktree sans passer par la commande\nSi on part du principe que vous n’avez pas ainsi jeté du travail en cours utile, pas de souci : il faut simplement « synchroniser » notre dépôt local pour qu’il prenne cette suppression en compte :\n\nNote : nous verrons plus loin la notion de verrouillage de worktrees ; si le worktree que vous tentez de supprimer est verrouillé, il faudra le déverrouiller d’abord, avec git worktree unlock &lt;chemin-du-worktree&gt;.\nDéplacer un worktree\nVous pouvez déplacer ou renommer un répertoire de worktree :\n\nLà aussi, vous pourriez avoir renommé ou déplacé le dossier en direct, sans passer par Git. Vous pourrez alors faire appel à la fonction de réparation des worktrees depuis le worktree déplacé :\n\n\nAttention si vous travaillez avec des disques réseaux ou nomades\nSi vous choisissez de placer vos worktrees sur un partage réseau ou un disque pouvant être retiré/déconnecté, vous devrez le signaler à Git pour éviter la purge de la référence quand il ne trouvera plus le worktree lors d’une opération de nettoyage interne (garbage collection).\nPour cela vous devrez verrouiller les worktrees concernés, soit dès la création avec :\n\n…soit après, avec la commande :\n\nCe verrouillage bloquera également la possibilité de supprimer ou déplacer le worktree désigné (via Git s’entend).\nBien évidemment, qui dit verrouillage dit aussi déverrouillage :\n\nRésumons tout ça\n",
		"description": "Vous êtes en plein milieu d’un travail complexe avec des fichiers dans différents état et devez traiter une urgence sur votre proje ? Git stash n’est pas tout à fait approprié ? Utilisez les worktrees !",
		"date": 1634515200,
		"image": "/assets/images/art-vid/art-git-worktree.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Dédoublez-vous avec les worktrees",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-worktree/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Bienvenue dans notre nouvelle série d’articles : JS idiomatique !\nÀ travers une grosse douzaine d’articles au fil des prochaines semaines, nous allons vous permettre de « monter en gamme » dans votre utilisation de JS afin que votre code soit plus idiomatique, c’est-à-dire qu’il embrasse la philosophie et les intentions modernes du langage, avec ses syntaxes récentes, ses motifs modernes, bref, en finir avec le JS « à la papa ».\nVoici ce qui vous attend :\n\nPropriétés et méthodes concises\nNoms de propriétés calculés\nClasses (dont les nouveautés ES2022 !)\nDéstructuration\nRest et Spread (dont ES2018)\nValeurs par défaut\nTemplate literals\nPortée, hoisting et mots-clés déclaratifs\nLe binding et this\nFonctions fléchées\nOptional chaining et Nullish coalescing\nOpérateurs d’affectation logique\nSéparateurs numériques\nESM (modules ES)\n\nNe manquez aucun épisode !\nPour être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de vous abonner à notre newsletter et à notre chaîne YouTube. Vous pouvez aussi nous suivre sur Twitter.\nEt bien entendu, n’hésitez pas à jeter un œil à nos formations ! Si explorer l’intégralité des recoins du langage vous intéresse, la ES Total notamment est faite pour vous !\n",
		"description": "Découvrez notre nouvelle série d’articles à ne pas manquer : JS idiomatique !",
		"date": 1640217600,
		"image": "/assets/images/art-vid/art-js-idioms.jpg",
    "_tags": ["tutoriel","js"],
		"title": "JS idiomatique : notre nouvelle série !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-idiomatique/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Voici le premier article de notre nouvelle série, JS idiomatique. Aujourd’hui, on se penche sur les propriétés et méthodes concises, qui nous permettent de déclarer de façon plus courte, plus claire et plus efficace les membres d’un littéral objet ou d’une classe.\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nLa redondance répétitive\nVoici un petit exemple de littéraux objet JS « à la papa »…\n\nÇa ne vous sort pas par les yeux, ces body: body, method: method, headers: headers et autres name: name ?!\nEt pourtant, bon sang, dans du JS courant ça arrive tout le temps qu’on construise ainsi des littéraux objets ayant, pour tout ou partie de leurs propriétés, une valeur obtenue en référençant un identifiant homonyme, présent dans la portée. En somme, a: a.\nPropriétés concises\nES2015 (l’édition 2015 d’ECMAScript, le standard officiel qui sous-tend JavaScript) a introduit les syntaxes concises dans les littéraux objets (et les corps de classes, mais c’est une autre histoire).\nLe cas qui nous occupe (a: a) est tellement courant qu’il dispose d’une syntaxe rien que pour lui : on ne met l’identifiant qu’une fois. Voyez plutôt :\n\nC’est beaucoup mieux, non ? Remarquez qu’en pratique, on décide de recourir à cette syntaxe propriété par propriété : il est fréquent que nos littéraux objets aient aussi des propriétés qui ne correspondent pas à ce besoin :\n\nMéthodes concises\nDans le même esprit, la façon « traditionnelle » de déclarer des « méthodes », à savoir :\n\n…a du plomb dans l’aile. Il faut avouer qu’elle désarçonne les personnes venant d’autres langages, la syntaxe n’ayant rien à voir. C’est dû au fait qu’en JavaScript, il n’y a pas de « méthode » au sens répandu du terme (en particulier, les fonctions que vous définissez ne sont pas intrinsèquement associées à des objets), juste des propriétés dont les valeurs s’avèrent être des fonctions.\nLa syntaxe ci-dessus a plusieurs inconvénients, petits ou grands :\n\nC’est déroutant quand on vient d’un langage à la POO (programmation orientée objets) classique\nC’est verbeux\nAvant ES2015, ça donnait des fonctions anonymes (faute de nom explicite entre le mot-clé function et le début de la signature)\nSi on commençait à jouer avec le prototype de notre objet et à tenter d’accéder au prototype parent depuis une telle fonction, on pouvait avoir des surprises.\n\nES2015 a donc permis les méthodes concises, qui donneraient ceci :\n\nElle a plusieurs avantages :\n\nÇa ressemble davantage aux langages avec une POO classique\nC’est plus court (on a donc plus de chances que les devs s’en servent, en jouant sur la flemme à la frappe)\nLes fonctions sont forcément nommées (même si en pratique, ES2015 aurait nommé automatiquement les fonctions affectées aux propriétés avec la syntaxe précédente)\nLa chaîne de prototypes fonctionne correctement au sein de ces fonctions\n\nEn somme, on n’a que des raisons de s’en servir !\nUne ligne sur deux\nEn pratique, ce genre de code se rencontre extrêmement souvent dans du code JS idiomatique. Pour les propriétés concises notamment, on pourrait presque parler d’une ligne sur deux. Voici quelques exemples réels issus de nos formations ou de nos projets en production :\n\nÇa vous a plu ? Ne manquez pas la suite !\nPour être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de vous abonner à notre newsletter et à notre chaîne YouTube. Vous pouvez aussi nous suivre sur Twitter.\nEt bien entendu, n’hésitez pas à jeter un œil à nos formations ! Si explorer l’intégralité des recoins du langage vous intéresse, la ES Total notamment est faite pour vous !\n",
		"description": "Simplifiez vos littéraux objets grâce à la syntaxe de propriétés et méthodes concises disponible depuis ES0215.",
		"date": 1640217600,
		"image": "/assets/images/art-vid/art-js-idioms-shorthands.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Propriétés et méthodes concises en JS",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-proprietes-et-methodes-concises/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Bienvenue dans notre deuxième article de la série JS idiomatique.\nLes littéraux objets, c’est bien, mais les propriétés sont « en dur » : si vous avez besoin d’y placer une propriété (ou une méthode) au nom variable suivant le contexte, vous deviez traditionnellement procéder en deux temps.\n\nMais depuis ES2015, c’est fini cet irritant pas de deux !\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nBon, déjà, dans l’exemple précédent, on aurait pu recourir aux propriétés concises pour commencer :\n\nEnsuite, la seule raison pour laquelle on a dû passer par un identifiant local, c’est pour pouvoir utiliser l’opérateur d’indexation indirecte […] de JS afin d’accéder dynamiquement à une propriété de l’objet (puisque cet opérateur accepte une expression quelconque en opérande, pour ensuite aller chercher la propriété dont le nom est l’évaluation de l’expression).\nES2015 a rajouté les noms de propriétés calculés, qui nous permettent de recourir à cette même syntaxe à base de crochets directement au sein des littéraux objets (et des corps de classes, soit dit en passant, on en parlera bientôt). Voyez plutôt :\n\nEst-ce que c’est pas TROBO™ 😍 ça les gens ?!\nPour les méthodes aussi\nEt ça marche aussi pour les méthodes concises, hein. Imaginez que la propriété de marquage doive en fait être une méthode qui renverrait un truc contextuel :\n\nSymboles (notamment symboles connus)\nEn fait c’est même pour ça que ça été rajouté au langage : pour permettre à nos objets d’implémenter des symboles connus\nBon, à ce stade, on a vu la syntaxe et les usages basiques. La suite de cet article entre dans des exploitations plus avancées, si vous aimez aller fouiller tous les recoins du langage. On y évoque d’autres aspects du langage qui sont parfois bien exotiques, alors si vous préférez, vous pouvez vous arrêter là. L’idée est de fournir davantage d’exemples concrets interagissant avec d’autres aspects de JS.\nPour revenir aux symboles, prenons l’exemple de l’itérabilité :\n\nExploitable partout\nComme souvent avec JS, on a essayé de faire quelque chose qui s’entrelace bien avec les autres syntaxes possibles, notamment les méthodes concises, les qualifieurs async ou les méthodes génératives. Ça peut donner des trucs velus :\n\n\n🤒 Celui-là, si tu ne l’as pas bien compris, c’est carrément normal. Il est bourré de syntaxes modernes et de concepts un peu dingues. Mais si tu veux fouiller, on a une super formation.\n\nUn dernier exemple\nNotez que ça peut servir pour des tas d’autres choses. Par exemple, en combinaison notamment avec la syntaxe de « spread d’objets » (dont le nom officiel de spec est les Rest/Spread Properties, introduites avec ES2018 et dont on parlera dans un article très bientôt), ça permet de faire de « l’immutabilité basique » pour dériver des objets de façon dynamique, comme dans un réducteur Redux implémenté à la main.\nImaginons que vous ayez une tranche d’état applicatif qui agit comme un dictionnaire des progressions d’objectifs, dont les clés sont les IDs des objectifs et les valeurs leur niveau de progression ; quelque chose de ce genre-là :\n\nImaginons maintenant que votre réducteur ait une action PROGRESS_ON_GOAL qui contienne un ID d’objectif et un niveau de progression ; elle doit dériver un nouvel état qui ne touche pas aux autres progressions, mais altère celle de l’objectif concerné. C’est une clé de l’objet (un nom de propriété) qu’on ne connaît pas à l’avance, qui peut être un peu n’importe quoi. Merci les noms de propriétés calculés !\n\nEn mode bogoss™… (Mais je ne vous en voudrai pas si vous préférez utiliser Immer, hein.)\nÇa vous a plu ? Ne manquez pas la suite !\nPour être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de vous abonner à notre newsletter et à notre chaîne YouTube. Vous pouvez aussi nous suivre sur Twitter.\nEt bien entendu, n’hésitez pas à jeter un œil à nos formations ! Si explorer l’intégralité des recoins du langage vous intéresse, la ES Total notamment est faite pour vous !\n",
		"description": "Marre de stocker vos objets dans une variable pour pouvoir y injecter une propriété au nom dynamique ? Les noms de propriétés calculés sont là pour vous aider !",
		"date": 1640217600,
		"image": "/assets/images/art-vid/art-js-idioms-computed.jpg",
    "_tags": ["tutoriel","js"],
		"title": "Noms de propriétés calculés en JS",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-noms-de-proprietes-calcules/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Il est fondamental de bien comprendre les zones pour saisir l’essence de Git. Il y a 5 zones :\n\nworking directory (copie de travail)\nstage (connu également sous les noms d’index, staging area, caching area)\nlocal repository (dépôt local, parfois appelé .git directory)\nremote repository (dépôt distant)\nstash (remise)\n\nNote : nous utiliserons dans cet article les terminologies anglaises qu’on retrouve le plus souvent dans les documentations et les options de commandes.\nParmi ces zones, les 3 principales (celles qu’on utilise tout le temps) sont le working directory, le stage et le local repository. On va donc se concentrer dans un premier temps sur celles-ci, puis nous expliquerons les autres.\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\n3 zones principales pour l’usage courant, local !\nL’architecture distribuée de Git favorise avant tout le travail local. Si on travaille seul, on peut même travailler 100% localement, sans dépôt distant.\nLe dépôt distant, comme son nom l’indique, est la seule zone non locale.\nLes avantages principaux de travailler localement sont :\n\nla performance : les opérations sont rapides car sur le disque local ;\nl’aspect « déconnecté » : en l’absence de réseau on peut continuer de travailler avec Git.\n\nGit maintient par ailleurs une copie locale des historiques déjà parcourus/utilisés, qui contourne le problème usuel de criticité d’un serveur centralisé de versions (Single Point of Failure). En d’autres termes, l’intégralité des versions sont disponibles à travers les historiques locaux cumulés des machines participant au projet.\nLa représentation classique qu’on trouve notamment dans la documentation officielle de Git est sous forme de colonnes. La meilleure ressource que nous ayons trouvé à ce jour est cette représentation interactive par Andrew Peterson, dont voici une capture d’écran :\n\nWorking directory\nC’est la première zone qu’on utilise, notre copie de travail. Dès qu’on a initialisé Git sur un projet, tout travail versionné (ajouts, suppressions, modifications) a lieu dans cette zone.\nStage\nGit diffère des systèmes de gestion de versions historiques (Subversion, CVS, et consorts) par l’existence d’une zone dédiée à la préparation des commits : le stage (parfois appelé index). On peut la voir comme une zone tampon dans laquelle on va lister les modifications qu’on souhaite mettre dans notre prochain commit (ajouts, suppressions, tout ou partie des modifications).\nQui dit préparation au commit dit qu’on peut ajouter ou retirer des éléments au stage avant de commiter. On retrouve donc des commandes à cet effet :\n\ngit add … ou son alias git stage pour enregistrer les manipulations qu’on souhaite commiter (ajouts, suppressions, modifications) ;\ngit rm [--cached] … pour enregistrer une suppression ;\ngit restore --staged (anciennement git reset) pour retirer des éléments ajoutés au stage.\n\nLocal repository\nLe dépôt local est un peu comme notre base de données locale Git : il stocke tout ce qui est « validé » (commité).\nEn pratique, il stocke plus que les commits et arborescences de fichiers car il enregistre également nos positions de branches (quel commit est pointé par quelle tête de branche) ainsi qu’une référence essentielle à Git : HEAD (le « vous êtes ici » de votre GPS Git).\nDonc quand on parle de l’historique du projet, c’est essentiellement le dépôt local qui est concerné.\nDes zones, mais surtout des états de fichiers\nBien que la notion de zones soit fondamentale, nous travaillons avec des fichiers. Ceux-ci vont donc changer d’état en fonction de nos actions.\nOn trouve 4 états :\n\nuntracked pour les nouveaux fichiers (sauf ceux ignorés) ;\nmodified pour les fichiers versionnés (présents dans le dernier commit ou le stage) puis modifiés depuis ;\nstaged pour les fichiers ajoutés au stage ;\nunmodified pour les fichiers dont la représentation est identique dans les 3 zones principales.\n\nLe dernier état ne nous est jamais vraiment signalé dans les affichages graphiques ou le terminal. Il sert exclusivement à savoir qu’un fichier est déjà connu de Git (« versionné »).\n\nCas particulier : le fichier de Schrödinger\nLe terme est non officiel, nous l’utilisons surtout comme moyen mémo-technique pour signaler qu’un fichier peut être dans 2 états simultanément (comme le chat de Schrödinger 🐈) : modified et staged.\n\nÀ quel moment peut-on obtenir ce résultat ?\n2 cas de figures principaux peuvent nous mener à ce résultat :\n\nla modification d’un fichier dans le working directory alors que celui-ci a déjà été stagé ;\nl’emploi de l’ajout partiel (git add -p …, expliqué dans le détail dans cet autre article) qui permet de choisir indivudellement les modifications d’un fichier à intégrer au stage.\n\nComment un ajout partiel est-il possible ? Eh bien, lorsque Git enregistre un fichier en vue du prochain commit (via un git add …), il mémorise la version complète du contenu du fichier (snapshot / instantané) dans un fichier techniq",
		"description": "Les zones Git : à quoi servent-elles et pourquoi les apprendre ?",
		"date": 1641513600,
		"image": "/assets/images/art-vid/art-git-zones.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Les zones Git : dans quel état j’ère ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-zones/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Lorsqu’on débute avec Git, une des premières commandes qu’on utilise est git add. Elle est essentielle à une bonne utilisation de Git puisqu’elle nous permet de préparer nos commits. Elle n’est pourtant jamais vraiment apprise, ce qui est regrettable car elle nous offre des options très pratiques !\nPour bien comprendre cet article, il est important d’avoir déjà assimilé la notion de zones Git. Et comme on aime faire les choses bien, on a écrit un article à ce sujet.\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\n\nPrincipe de fonctionnement\nLorsqu’on fait un git add … on demande à Git d’enregistrer dans le stage les fichiers qu’on souhaitera plus tard valider (intégration au commit). En d’autres termes, on ajoute, modifie, supprime des fichiers dans notre copie de travail et on signale à Git que tout ou partie de ces modifications est à mettre dans un statut intermédiaire (staged) avant d’être validé sous la forme d’un commit.\nOn a donc la possibilité de préciser des chemins complets ou partiels (globs) et ne prendre qu’une partie des modifications réalisées dans notre copie de travail (working directory) en vue d’un commit prochain.\n\nSi la technique vous intéresse, voici ce qui se passe sous le capot :\n\nPour chaque fichier, un « instantané » du contenu est capturé :\n\nil ne stocke pas les différences mais bien l’intégralité du fichier dans sa nouvelle version ;\nce fichier est optimisé pour stockage sur le disque et appelé blob (pour Binary Large Object) ;\nle nom de ce fichier est une empreinte basée sur le contenu du fichier (hash de type SHA-1 ou SHA-2) ;\nce fichier est stocké dans le répertoire .git/objects.\n\n\nLes références aux fichiers sont enregistrées dans le stage (fichier .git/index).\n\nUtilisation « classique »\nQue vous soyez dans un terminal ou dans un éditeur muni d’une interface Git, vous aurez accès aux utilisations les plus fréquentes de la commande add, à savoir l’enregistrement des ajouts, modifications et suppressions des fichiers complets. Ceci équivaut en ligne de commande à passer le ou les chemins de fichiers concernés :\n\n\n\nOn peut aller bien plus loin et gagner en temps, en confort, en qualité en s’aidant de quelques options. Remarquez que certaines options ne sont parfois disponibles qu’en ligne de commande. À vous de déterminer si votre éditeur préféré sait gérer celles qui vous intéressent.\nNotre sélection d’options utiles\n\n&lt;chemins&gt; (ou -- &lt;chemins&gt; pour lever l’ambiguïté avec le double tiret POSIX) ;\n-u / --update, pour ne traiter que les fichiers déjà versionnés ;\n-A / --all / --no-ignore-removal, la totale : ajouts, modifications, suppressions ;\n-f / --force pour forcer l’ajout de fichiers normalement ignorés ;\n-p / --patch, pour ne stager qu’une partie des modifications des fichiers ;\n-N / --intent-to-add pour permettre les diffs, le add -p et le commit -a des fichiers non-suivis.\n\nUn petit tour des globs\nLes (nombreuses) commandes Git capables de travailler avec des chemins de fichiers vous offrent la possibilité (en ligne de commande notamment) de passer des chemins exacts (fichiers ou répertoires) voire des globs. Faisons un petit tour d’horizon de ces usages :\n\nCes syntaxes sont utilisables pour la partie fichiers de l’appel, qui suit les options de git add.\nTout sauf les nouveautés\nVous souhaiterez parfois n’intégrer que les modifications et suppressions, donc tout sauf les fichiers nouvellement créés (qui ne sont pas encore versionnés). Pour ça, vous avez l’option -u / --update :\n\nTout, partout !\nVous voudrez souvent prendre l’intégralité du travail en cours : ajouts, suppressions et modifications. On utilise en général git add ., mais si vous avez tendance à vous balader dans vos répertoires, ce . ne désignant que le répertoire courant et ses sous-répertoires, vous pourriez manquer les répertoires parents.\nC’est là tout l’intérêt d’employer plutôt git add --all / -A :\n\nCesse de m’ignorer !\nSi les fichiers que vous souhaitez ajouter font partie des fichiers habituellement ignorés par Git (voir le fonctionnement du .gitignore), vous devrez alors forcer leur ajout avec l’option --force / -f. Une fois ces fichiers versionnés, leurs modifications ultérieures apparaitront au même titre que pour les autres fichiers. Pour cesser de les versionner tout en les conservant sur disque, vous aurez besoin d’un git rm --cached par exemple (notez qu’ils existeront toujours dans les commits qui les contenaient).\nPour illustrer cela, prenons le cas de figure récurrent des logs. Généralement les fichiers de logs sont placés dans un répertoire applicatif dédié, ici log/, et on ne souhaite pas historiser les logs dans Git, ça n’a aucun intérêt. On va alors indiquer dans le fichier .gitignore qu’on ne souhaite pas versionner les fichiers contenus dans ce répertoire :\n\nSi votre stack technique ne crée pas automatiquement son dossier de logs (et refuse de se lancer s’il n’existe pas), vous devrez vous assurer qu’il exi",
		"description": "Git add vous permet de préparer vos commits en ajoutant au stage vos fichiers. Mais connaissez-vous toutes ses subtilités ?",
		"date": 1641945600,
		"image": "/assets/images/art-vid/art-git-add.jpg",
    "_tags": ["tutoriel","git"],
		"title": "Git add hero 🤘",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-add/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Bienvenue dans notre troisième article de la série JS idiomatique.\nSi JS a toujours permis la Programmation Orientée Objets (POO), son recours initial à la POO prototypale a dérouté la majorité des gens. Depuis ES2015 toutefois, et de façon plus ou moins continue depuis, JS s’est doté de syntaxes plus traditionnelles et d’extensions régulières de fonctionnalités pour la définition et la gestion de classes et de leurs instances.\nTu connais déjà class, extends, constructor et super ? C’est ce que tu crois… et en prime, y’a plein de nouveaux trucs depuis. Voici un bon gros tour de piste, plein de détails croustillants.\nVous préférez une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nPOO traditionnelle / classique vs. POO prototypale : un rappel\nJavaScript et Java ont été conçus en même temps, pour sortir en même temps, dans le même produit (Netscape Navigator 2, fin 1995). Je vous racontais déjà les détails il y a… 10 ans #coupdevieux.\nLes commerciaux de Sun ont fait pression pour que JS ne fasse pas d’ombre à Java, qui devait être marketé comme le langage « sérieux », « professionnel », etc. afin de détrôner C++. Du coup, JS n’avait absolument pas le droit de mettre en avant des fonctionnalités POO similaires à Java, et s’est donc vu interdire d’utiliser les mots-clés concernés, qui sont devenus mots réservés, interdits pour tout identifiant ou nom de propriété (ex. class, extends, interface, implements, private, public, final…). C’est la raison pour laquelle le DOM déclare des propriétés className (ce qu’on a retrouvé notamment dans React, au grand dam de beaucoup ; ES5 (2009) a toutefois permis d’utiliser des mots réservés comme noms de propriétés. On peut donc faire const obj = { class: 'Foo' } mais pas const class = 'Foo'.)\nSeulement voilà, il était hors de question pour Brendan Eich, le créateur de JS, de pondre un langage pourri, sans fonctionnalités orientées objets. Il a donc été puiser dans tout le reste de la POO, au-delà de l’approche minimaliste dite « traditionnelle », en allant notamment du côté de la POO prototypale, inspirée de Self par exemple. On la trouve aujourd’hui dans divers langages, dont IO.\nDans cette approche, on n’a pas de classes à proprement parler, uniquement des objets. Et tout objet peut servir de prototype à d’autres. Un objet C peut avoir pour prototype un objet B, qui a lui-même pour prototype un objet A… Ça ressemble à une hiérarchie d’héritage de classes, mais sans les classes, et avec surtout la possibilité de modifier tant les relations de prototype que le contenu de ces objets, ce qui rend tout ça nettement plus dynamique !\nEn pratique, la POO prototypale peut simuler complètement la POO traditionnelle, mais peut aussi aller beaucoup plus loin (comme par exemple Ruby ou le boss originel de la POO : Smalltalk), en permettant un typage hautement dynamique, l’évolution à la volée des relations de prototypage ou l’extension des prototypes, les objets singletons, les eigenclasses, etc.\nÀ quoi ça ressemble, en prototypal ?\nImaginons qu’on veuille faire une classe de base Shape dotée de quelques méthodes, puis une classe Square qui la spécialise. On va volontairement opter pour du code façon ES3 (pré-2009) et sans triturer la propriété alors pseudo-officielle __proto__. (Mais en ES5, on aurait pu passer par des descripteurs de propriétés et Object.create() afin de rendre tout ça plus clean). Ça donnerait ça :\n\nÇa pique les yeux hein ?! Hé oui… Pourtant, ça offre une puissance folle. Mais c’est hyper déroutant quand on vient d’une syntaxe plus classique et répandue.\nSyntaxe de classes ES2015\nES2015 (longtemps appelé ES6) a fait deux constats majeurs :\n\nLa syntaxe liée au mode prototypal est un gros frein pour la plupart des gens, sans parler des concepts sous-jacents, qui semblent exotiques.\nEn prototypal comme en traditionnel, beaucoup de gens tombent dans divers pièges usuels de conception de leurs classes, surtout lorsqu’ils définissent des hiérarchies de classes.\n\nElle a donc sorti une nouvelle syntaxe de classes, qui était tout de suite beaucoup plus familière. Pour reprendre l’exemple précédent :\n\nAaaaah, ben voilà ! Tout de suite, on se sent à la maison !\nLe balèze caché\nSi la syntaxe semble familière, elle offre toutefois beaucoup plus de flexibilité que ce qu’on trouve dans la plupart des autres langages.\nPour commencer, la classe elle-même est une expression, pas une déclaration. On peut donc stocker la référence dans une variable, ou même la renvoyer à la volée. Du coup, elle peut être anonyme. Par exemple :\n\nC’est parce que sous le capot, une classe reste une fonction, la nouvelle syntaxe ne change rien à l’implémentation sous-jacente à base de fonctions et prototypes :\n\nEncore plus fort : la clause extends accepte elle aussi une expression, et pas un simple identifiant fixe. On peut donc étendre une classe fournie dynamiquement, voire construite à la volée par des appels de fonction :\n\nNote au passage qu’une définition d",
		"description": "Tu crois tout savoir sur les classes en ES2015+ ? Parions que tu vas apprendre plein de choses quand même dans cet article…",
		"date": 1642377600,
		"image": "/assets/images/art-vid/art-js-idioms-classes.jpg",
    "_tags": ["js"],
		"title": "Les classes en ES2015+",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-classes/",
		"locale": "fr",
		"readingTime": "13 min"
	},	{
		"content": "Et si on prenait l’élément constituant de base Git, le commit, et qu’on le décortiquait pour découvrir son anatomie ? Je vous propose dans cet article d’autopsier un commit pour comprendre tout un tas d’autres mécanismes qui en découlent ! À vos scalpels !\nAvant cet article vous voudrez peut-être explorer le fonctionnement des zones ou encore apprendre à maîtriser la commande add.\n\nVous préférez une vidéo ?\nSi vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :\n\nRôle d’un commit\nAvant d’attaquer la découpe, il me semble nécessaire de faire un pas de côté et d’analyser les intentions que servent un commit.\nUn commit est une unité de travail participant à un projet, une brique de l’édifice projet. On parle souvent de commit « atomique » pour une unité de travail cohérente, représentant « un tout ». C’est l’usage recommandé, même s’il ne peut être contraint. La meilleure représentation qu’on puisse s’en faire est la réalisation pleine d’une tâche décrite par la gestion de projet (cette tâche étant la plus petite possible).\nLe commit a la charge d’enregistrer les modifications* sur les fichiers et répertoires ainsi que les informations utiles à un suivi, ce qu’on appelle les métadonnées :\n\nL’identité de l’auteur : nom, e-mail ;\nLe message renseigné par l’auteur, censé décrire le contenu des modifications apportées ;\nLa date de création du commit par l’auteur ;\nL’identité du commiteur : nom, e-mail (généralement identiques à l’auteur) ;\nLa date de réalisation du commit par le commiteur ;\nLes éventuelles références des commits parents ;\nUne signature GPG, optionnelle.\n\nOn distingue les rôles d’auteur et commiteur pour assurer un suivi efficace dans des cas comme :\n\nle réemploi d’un commit d’un endroit à un autre (patch, cherry-pick) ;\nla modification d’un commit (amend, rebase) ;\nla réalisation d’une commit en pair-programming.\n\nOn garantit ainsi cette distinction entre la personne qui a réalisé la tâche et celle qui a créé le commit.\n*Techniquement Git ne stocke pas les modifications mais des instantanés complets des fichiers.\nNote : si vous utilisez les notes Git (c’est-à-dire git notes), leurs informations ne sont pas stockées dans le commit, mais dans un objet commitish dédié faisant référence au commit.\nEn résumé, le rôle du commit est d’enregistrer un lot de travail, d’indiquer qui l’a réalisé, à quel moment et à partir de quel état du projet.\nUnchain my heart commits 🎶\nPoussons un peu plus loin que le simple commit et parlons des commits et des liens qu’ils entretiennent. Lorsqu’on construit un historique Git, on crée une série de commits qui se référencent par lien de parentalité. Vous voyez ces schémas qui nous montrent des flèches qu’on peut croire dans le « mauvais » sens ?\n\nEn réalité, chaque flèche exprime la référence parente détenue par le commit dont elle part. C’est un point absolument fondamental à la bonne compréhension de certaines mécaniques de Git : un historique Git est exprimé par le chaînage des commits entre eux. Si on creuse encore plus loin, on s’aperçoit même que tout le fonctionnement de Git est basé sur des références d’objets Git entre eux (branches, HEAD, commitishs, blobs, trees, etc). Mais ça sort du périmètre de cet article.\nAutopsie\nÇa, c’était en surface. Sortons maintenant le scalpel et découvrons la manière dont est composé mon commit, et pourquoi ?\nJe pars de l’exemple d’un projet initialisé avec les répertoires src et log et les fichiers .gitignore et README.md.\n\nLe commit initial est déjà réalisé via la commande git commit -m 'Initial commit' et possède l’identifiant b4cf8aec80f87ac6a1e21e47ffc42dd4ec53ef2a.\nPour analyser un objet de type commit (ou commitish) je peux utiliser la commande show en lui passant la référence de l’objet (ou toute autre référence dont la résolution revient au même) :\n\nNote : mon affichage est enrichi dans le terminal par l’utilitaire diff-so-fancy.\nJ’obtiens les informations générales constituant mon commit : les métadonnées principales (auteur, date, message) et les modifications :\n\najout du fichier .gitignore et détail de son contenu ;\najout du fichier README.md et détail de son contenu ;\najout du fichier vide log/.keep (pour enregistrer la présence du répertoire log) ;\najout du fichier vide src/.keep (pour enregistrer la présence du répertoire src).\n\nJe ne vais cependant pas m’arrêter là, car la commande show ne fournit pas les détails que je souhaite vous montrer. L’ensemble des objets techniques Git qui nous intéressent sont stockés dans le répertoire .git/objects/. Mais je me casserais le nez à essayer d’y accéder directement car ils font l’objet d’optimisations sur le disque et sont illisibles tels quels. Je vais donc utiliser la commande de plomberie* cat-file pour afficher le contenu-même des objets techniques associés qui m’intéressent, à commencer par mon commit.\n* Git offre environ 110 commandes réparties en 2 grandes catégories : la porcelaine (≈ 40) et la plomberie (le reste). Presque tout le mond",
		"description": "Ne vous êtes-vous jamais demandé ce qu’est vraiment un commit ?",
		"date": 1643068800,
		"image": "/assets/images/art-vid/art-git-commit-detail.jpg",
    "_tags": ["git"],
		"title": "Anatomie d’un commit Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-commit-detail/",
		"locale": "fr",
		"readingTime": "9 min"
	},	{
		"content": "Bienvenue dans notre quatrième article de la série JS idiomatique.\nES2015 (longtemps appelé « ES6 ») nous a apporté énormément de choses, dont ce que j’aime appeller la « Sainte Trinité » : la déstructuration, le rest/spread, et les valeurs par défaut. Nous allons les voir chacun dans son propre article.\nLa déstructuration a ceci de particulier qu’elle met le plus de temps à vraiment « percoler » dans nos p’tites cellules grises, de façon à être utilisée à son plein potentiel dans notre code. C’est souvent au fil des mois, voire des ans, à force de repasser sur son code, qu’on finit par en tirer pleinement parti. C’est aussi une syntaxe parfois un peu déroutante. Dans cet article, nous allons l’explorer en profondeur, et essayer de te donner les billes pour exploiter au mieux son potentiel.\nVous préférez une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nDéstructuration ou décomposition ?\nUne fois n’est pas coutume, je ne suis pas fan du choix de traduction dans la version française du MDN : l’équipe a choisi de recourir au terme unique « décomposition » tant pour le destructuring, dont parle cet article, que pour le rest/spread, que nous traiterons dans l’article suivant.\nJe ne vois pas bien l’intérêt de faire l’amalgame entre ces deux notions, même si elles sont en effet étroitement liées. Le MDN jouissant d’une réputation considérable — et méritée — la plupart des articles francophones que je vois dans les résultats des moteurs de recherche parlent de décomposition. Mais du coup, on ne sait jamais s’ils parlent d’un ou l’autre des sujets ainsi désignés.\nDu coup, je m’en tiendrais à « déstructuration » comme équivalent du terme anglais destructuring.\nPourquoi déstructurer ?\nL’objectif premier de la déstructuration consiste à récupérer en une fois (en une instruction, si tu préfères) plusieurs données issues d’une source structurée (donc un objet). On évite ainsi de multiplier les déclarations / affectations, ainsi que les indexations multiples « nombres magiques » sur les tableaux, ou qualifiantes sur les propriétés nommées d’un objet, etc.\nOn va regarder la syntaxe et les cas d’utilisation en détail, mais franchement, tu préfères quoi ? Ce genre de code :\n\n…ou plutôt celui-ci :\n\nPerso, le choix est vite fait.\n(Si tu te demandes où sont passés les deux-points, c’est que tu n’es pas au fait des propriétés concises.)\nOù puis-je déstructurer ?\nUne déstructuration peut survenir partout où il y a affectation, qu’elle soit explicite ou implicite.\nAffectation explicite\nIl y a un affectation explicite en présence d’un opérateur d’affectation =, qu’on soit dans une déclaration ou non.\nLa plupart des gens pensent qu’on est forcément dans une déclaration (avec par exemple const, puisque const is the new var). Quelque chose comme ça :\n\nEt c’est en effet le cas majoritaire. Néanmoins, il est parfaitement possible d’affecter vers des identifiants existants, du moment qu’ils sont réaffectables (donc pas const). Comme par exemple dans l’accesseur écrivain ci-dessous :\n\nIci, on déstructure directement vers des propriétés de l’objet courant (this), qui n’ont pas besoin d’être déclarées à la volée (ou préalablement).\n\nTu es peut-être déstabilisé·e par le point-virgule présent avant la déstructuration ? Il vient du fait que, dans un style de code sans points-virgules (que nous favorisons depuis près de 10 ans), un des deux cas à la marge problématiques vient de la présence en début de ligne d’un crochet ouvrant : JS pourrait croire qu’il s’agit d’une indexation dynamique (opérateur crochet, comme par exemple dans items[2]) de l’expression à la fin de la ligne de code précédente.\nNote qu’ici on est en début de bloc, il n’y a donc pas d’ambiguïté, et ce code marcherait parfaitement sans le point-virgule ; mais nous auto-formattons notre code avec Prettier, et ce dernier essaie de nous éviter des pièges si on devait un jour insérer une ligne avant celle où nous déstructurons ainsi, ce qui pourrait altérer la sémantique. En forçant un point-virgule en début de ligne, on est tranquilles : cette déstructuration ne risque pas d’être un jour comprise différemment par le moteur JS.\n\nAffectation implicite\nL’affectation implicite résulte ici de la sémantique du langage, sans opérateur =. Ça couvre en pratique deux cas de figure :\n\nles paramètres dans la signature d’une fonction (qui se voient implicitement affecter les arguments de l’appel) et…\nle contenu des déstructurations (chaque élément se voyant implicitement affecter une donnée issue de l’objet source).\n\nOn va revenir sur les syntaxes dans un petit moment, mais voici des exemples de chaque cas :\n\nDeux types de déstructuration\nIl existe deux types de déstructuration :\n\nnominative : on s’intéresse aux propriétés de l’objet source par leurs noms, et l’ordre n’a donc aucune importance. La source peut alors être n’importe quel objet.\npositionnelle : l’objet source doit alors être un itérable (les plus connus étant les tableaux), et on s’int",
		"description": "La déstructuration devient vite un incontournable de notre code JS moderne… mais es-tu bien sûr·e de l’avoir comprise pour de vrai ?",
		"date": 1643587200,
		"image": "/assets/images/art-vid/art-js-idioms-destruct.jpg",
    "_tags": ["js"],
		"title": "La déstructuration en ES2015+",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-destructuration/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Git 2.34 (novembre 2021) et Git 2.35 (janvier 2022) nous apportent quelques nouveautés sympathiques, et comme toujours, des améliorations de performance. Je t’ai préparé une petite sélection des trucs que j’ai trouvés cool 🤩.\n\nTu préféres une vidéo ?\nTu as la flemme de lire, pas de soucis, je t’ai préparé un résumé en vidéo :\n\nGit 2.34\nJe commence par la version la plus ancienne, mais surtout celle qui apporte le plus de nouveautés !\nAuto-correction interactive des commandes\nLà je suis fan 🤩 ! Comme moi, tu souffres peut-être du « syndrome des moufles »™ quand tu tapes dans le terminal : tu manques des touches et saisis de travers tes commandes (« git pish » ou le célèbre « git vommit » 🤮).\n\nDepuis un petit moment Git nous conseille la bonne commande via un petit texte juste après notre échec, et pouvait même l’exécuter automatiquement, si tu avais opté pour ce comportement. Mais Git 2.34 va plus loin et nous permet d’activer le prompt interactif :\n\n\nNouvelle stratégie de fusion par défaut\nLa stratégie de fusion par défaut a été changée de « recursive » à « ort », youhou 🙌 !! Bon OK, comme ça, il y a peu de chances que ça te parle. La stratégie ORT (pour “Ostensibly Recursive’s Twin”), comme son nom l’indique, est la stratégie jumelle de Recursive. « À quoi bon remplacer une stratégie par une autre identique ? » me diras-tu. Eh bien, pour deux raisons majeures :\n\nRecursive était devenue quasi impossible à maintenir en raison de son code légataire ;\nles performances méritaient d’être améliorées (les heuristiques restent inchangées, c’est l’implémentation et donc l’exécution qui posaient problème).\n\nPour te donner une idée des gains de performance, cette stratégie est :\n\njusqu’à 500 fois plus rapide pour une fusion contenant des renommages ;\njusqu’à 9 000 fois (tu as bien lu) plus rapide pour une série de fusions similaires, comme dans un rebase par exemple (grâce à la mise en cache et la réutilisation des résultats de fusions précédentes).\n\nSurlignage du log en mode --grep\nÇa a toujours manqué dans Git : le surlignage des termes recherchés dans les messages de commit via l’option --grep est enfin arrivé !\n\n\n🪦 RIP --preserve-merges\nAprès des années de bons et loyaux services, l’option --preserve-merges dépréciée de la commande rebase a définitivement été retirée de Git. Ne sois pas triste 😿, sa remplaçante est là depuis un moment 😹 : --rebase-merges. L’intention finale reste la même puisqu’on reproduit nos fusions locales lors du rebase. Si te ne comprends pas ce que je raconte, tu peux regarder du côté de notre article « Bien utiliser Git merge et rebase » ou de notre cours vidéo « Git merge vs rebase ».\nSigner avec des clés SSH\nPeut-être as-tu déjà travaillé avec des projets dont les contenus (commits/tags) étaient certifiés par signature numérique, via des clés GnuPG. Cette signature est désormais possible avec des clés SSH (seulement à partir d’OpenSSH 8.8).\nVoici une idée de ce que donnent des commits signés dans GitHub :\n\nEn vrac\nComme toujours on bénéficie de différentes optis, principalement concernant la performance, mais aussi concernant les submodules, la doc’…\nCôté perf’, on bénéficie d’une amélioration du sparse-checkout, très utile pour optimiser le travail avec les mono-repo massifs (datant de Git 2.25).\nLa commande rebase nous donne une information plus claire lorsqu’elle ne rejoue pas certains commits dont le contenu est déjà présent (skip).\nSi tu es curieux·se, tu peux aller creuser les release notes.\nGit 2.35\nUne seule nouveauté a retenu mon attention dans cette version : la possibilité de mettre de côté dans le stash uniquement ce qu’on a stagé (ce qu’on a préparé pour notre prochain commit avec un git add).\n\n\nLà aussi tu peux regarder les release notes.\nSi tu veux en apprendre plus sur Git, que dirais-tu de participer à notre formation Git Total ?\n",
		"description": "Auto-correction des commandes, nouvelle stratégie de fusion par défaut… Git 2.34 et 35 nous offrent de belles surprises !",
		"date": 1644451200,
		"image": "/assets/images/art-vid/art-git-2-34-35.jpg",
    "_tags": ["git"],
		"title": "Quoi de neuf dans Git 2.34 et 2.35 ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-2-34-35/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Bienvenue dans notre cinquième article de la série JS idiomatique.\nDans notre article sur la déstructuration, on attaquait ce que j’aime appeler la « Sainte Trinité » : la déstructuration, le rest/spread, et les valeurs par défaut. Dans celui-ci, on va donc traiter du deuxième compère, et notre prochain article de la série s’occupera du dernier larron.\nSi beaucoup de gens ont vite « adopté » le rest/spread tel qu’on le trouve dans ES2015 (c’est-à-dire sur itérables uniquement), il est facile de ne pas en percevoir toutes les subtilités, et puis on fait trop souvent l’impasse sur l’extension apparue avec ES2018, qui permet de les appliquer sur des objets génériques aussi, un vrai bonheur pour faire de l’immutabilité pas cher. Voyons tout ça ensemble.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\n« Décomposition » ?! Je dis non.\nComme je te le disais déjà dans l’article précédent donc, je ne suis pas fan du choix de traduction dans la version française du MDN, qui recourt au terme unique « décomposition » tant pour le destructuring, dont on parlait alors, que pour le rest/spread, que nous traitons ici.\nCet amalgame est source de confusion, voire de frustration (comme tous les amalgames… #sifflote), du coup on utilisera ici les termes anglais, faute d’une traduction qualitative établie : rest et spread.\nLe rest et le spread, pourquoi faire ?\nL’idée, c’est de pouvoir passer d’une série de valeurs (ou paires clé-valeur) individuelles à un conteneur consolidé (Array, nouvel objet), ou réciproquement.\nLes cas d’utilisation sont nombreux, mais pas forcément intuitifs, surtout pour les personnes n’ayant pas déjà une longue expérience de production en JavaScript (et qui ne sont donc pas forcément tombées sur les situations concernées).\nL’opérateur est le même pour les deux usages : le ... préfixe (c’est-à-dire avant l’identifiant), par exemple ...items. C’est l’emplacement dans le code qui détermine le rôle :\n\nDans une déclaration, c’est un rest. Par exemple, au sein d’une signature de fonction ou d’une déstructuration. Un rest apparaît toujours à la fin de la liste.\nDans une expression, c’est un spread. Par exemple, au sein des arguments d’un appel de fonction, d’un littéral tableau ou d’un littéral objet. Un spread peut apparaître n’importe où (pas nécessairement en fin de liste), et on peut avoir plusieurs spreads dans un même contexte.\n\nRest positionnel\nComme son nom l’indique, un rest sert à récupérer… « le reste ».\n\nC’est utilisable dans les signatures de fonctions et… dans les déstructurations positionnelles (puisqu’on te dit qu’ils sont potes !).\nL’idée est de regrouper les éléments de liste restants dans un véritable Array. Ça sert principalement à deux choses :\n\nImplémenter des fonctions variadiques, c’est-à-dire acceptant un nombre variable d’arguments. C’est particulièrement adapté aux fonctions de nature mathématique ou agrégative (ex. concaténation, combinaison en un résultat unique).\nExtraire les premiers éléments d’un itérable (généralement pour leur appliquer un traitement spécifique) et conserver le reliquat d’un seul tenant.\n\nImaginons une fonction qui réalise la moyenne de ses arguments, quel qu’en soit le nombre. On peut évidemment utiliser une simple boucle, auquel cas le bon vieil arguments des fonctions traditionnelles pourrait suffire :\n\nMais ça pourrait être plus sympa de recourir à la méthode reduce() de Array. Sauf que arguments n’est pas un Array1, pas de chance. Qui plus est, la signature de la fonction n’indique en rien qu’on accepte un nombre quelconque d’arguments. Essayons avec le rest au sein de la signature :\n\n(1 : c’est une instance de ~SaloperieInutileDeMerde~Arguments).\nIl faut bien comprendre qu’avant, faire ça en mode tableau, c’était chaud 🔥 :\n\nEn prime, cette syntaxe reste disponible pour les fonctions fléchées, qui ne disposent en revanche pas de arguments (nous y reviendrons dans l’article qui leur sera prochainement dédié #teaser #abonneToi #bonPourTaPeau).\nC’est aussi utilisable dans les déstructurations positionnelles, par exemple ici :\n\nUn rest positionnel produira toujours un tableau, quitte à ce qu’il soit vide. Aucun cas particulier du genre null ou undefined à gérer. Ça, c’est le côté bisou 😘 / cadeau 🎁 de la conception du truc, car les cas particuliers, c’est la plaie.\nSpread positionnel\nAu cas où tu l’ignorerais, en anglais, “to spread” signifie « étaler », ce qui donne une indication sur le rôle de l’opération.\nLe spread positionnel accepte en opérande n’importe quel itérable et le consomme intégralement : il revient à placer, à cet endroit du code, toutes les valeurs de l’itérable séparées par des virgules. On peut l’utiliser dans un appel de fonction ou dans un littéral tableau.\nPour rappel, beaucoup de trucs (#jargon) sont itérables : les tableaux bien entendu, mais aussi les NodeLists (tu sais, ce que renvoie par exemple document.querySelectorAll()), les Maps, les Sets, et même les Strings (ce q",
		"description": "Le rest / spread, cousin de la déstructuration, est vite indispensable en JS moderne… Sur itérables ou sur objets génériques, découvrez toute sa puissance !",
		"date": 1644796800,
		"image": "/assets/images/art-vid/art-js-idioms-rest-spread.jpg",
    "_tags": ["js"],
		"title": "Le rest/spread en ES2015 / ES2018",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-rest-spread/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Bienvenue dans notre sixième article de la série JS idiomatique.\nVoici la fin de la « Sainte Trinité » ! Après la déstructuration et le rest/spread, voici enfin les valeurs par défaut !\nLes valeurs par défaut existent dans la plupart des langages, et souvent bien avant que JavaScript les ajoute en 2015. Mais ça valait le coup d’attendre : les possibilités de la version JavaScript sont parfois plus avancées que dans les autres langages.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nPourquoi des valeurs par défaut ?\nOn s’en sert pour formaliser les valeurs par défaut de données, et en limiter les cas d’application.\nC’est utilisable partout où on a une affectation implicite, donc pour rappel :\n\nles signatures de fonctions (les paramètres sont implicitement affectés par les valeurs des arguments de même position) ;\nles déstructurations (dont les éléments sont implicitement affectés par les données issues de la source déstructurée).\n\nL’opérateur est, on s’en doutait, =, et il n’est déclenché que pour undefined.\nOn faisait comment avant ?\nC’est très différent de ce qui se passait avec la bidouille traditionnelle pour les valeurs par défaut, qui reposait le plus souvent sur le OU logique (||), et donc sur la coercition booléenne 😅 de la valeur d’origine :\n\nDans cette ancienne approche, tout ce qui était falsy était ignoré au profit de la valeur par défaut. C’était un problème si certaines falsy values étaient légitimes, par exemple ci-dessus un times à zéro (0 || 1 vaudra 1, car 0 est falsy) ou un separator vide ('' est falsy).\nAlors c’est vrai que des fois c’est pratique de gérer d’un même coup plusieurs valeurs jugées invalides (genre undefined et null, voire NaN), ce qui ne marchera pas avec la syntaxe des valeurs par défaut, mais le plus souvent, se concentrer sur undefined est approprié.\nLisibilité et complétion\nPar ailleurs, un peu comme pour les rest positionnels en signature, utiliser les valeurs par défaut améliore le degré d’information apporté par la signature sur le comportement de la fonction, tout en allégeant le début de celle-ci :\n\nCette approche a des avantages significatifs :\n\nLa signature est plus informative et explicite.\nLes mécanismes de complétion / popup d’info sur arguments des éditeurs et EDI retranscrivent le plus souvent ces infos.\nLe début de la fonction n’est pas encombré par le “massage des arguments”, ne serait-ce que pour gérer leurs valeurs par défaut.\n\nN’importe quelle expression, et même des backrefs !\nÀ droite du signe égal, on peut avoir n’importe quelle expression JS, y compris avec des appels de fonction, ce qui est rare hors de JS. En attendant l’arrivée des throw expressions, certains s’en servent pour rendre un élément « obligatoire » en lui fournissant une valeur par défaut qui lève une exception :\n\nOn peut même utiliser dans notre expression des termes présents plus à gauche dans la liste. Là aussi, peu de langages ont cette capacité dans leurs valeurs par défaut. Voici un exemple sympa :\n\nIci, le deuxième argument aura une valeur par défaut automatiquement alignée sur la longueur du texte dans le premier argument (bon, si on n’a pas de blagues Unicode, mais ça se corrige facilement). Si j’appelle juste banner('hello'), dans la fonction, l’argument line vaudra '-----' par défaut… Trop classe !\nUn autre petit exemple que j’adore est lié à cette fois où j’avais une fonction qui extrayait les délimiteurs ouvrant et fermant d’un contenu balisé et me renvoyait un tableau ouvrant + fermant, à ceci près que si les délimiteurs n’étaient pas symétriques (comme le sont &lt;&gt;, (), [] et {}), le tableau ne contenait qu’un élément :\n\nMais à l’usage, j’avais parfois besoin de gérer les deux cas de façon unifiée, avec l’ouvrant et le fermant, même lorsqu’ils étaient identiques. La possibilité de recourir aux backrefs dans les valeurs par défaut me permet d’écrire ça de façon concise et très porteuse d’intention :\n\nJ’adore 😍 !\nBien concevoir sa signature\nEn mai 2020, dans notre série 19 pépites JavaScript, j’avais parlé de la bonne définition de paramètres nommés optionnels, et comme ça touche de près à la déstructuration nominative et aux valeurs par défaut, je vous en remets une couche ici.\nPersonne n’aime ce genre d’appels de fonction :\n\nLes signatures avec plusieurs paramètres positionnels, non-intuitifs et utilisant le même type de donnée, sont imbitables à l’usage ; c’est un gros problème de maintenabilité. On préfère largement utiliser des paramètres nommés. JS n’a pas de syntaxe dédiée (contrairement à Ruby, Swift, Kotlin, PHP 8 ou C#, pour ne citer qu’eux), mais on s’en approche fort avec la déstructuration nominative :\n\nDu coup à l’appel c’est nettement plus sympa, ça « s’auto-documente » :\n\nC’est quand même nettement mieux !\nCeci dit… et si tous les arguments sont optionnels ? Soit parce qu’ils ont tous une valeur par défaut définie, soit parce que ceux qui n’en ont pas ne sont pas exigés de toutes façons ? En",
		"description": "Les valeurs par défaut, ça peut sembler basique, mais si JS les a eues après les autres, elles y sont également plus balèzes, ça valait le coup d’attendre !  Découvre ici tous leurs secrets…",
		"date": 1644969600,
		"image": "/assets/images/art-vid/art-js-idioms-default-values.jpg",
    "_tags": ["js"],
		"title": "Les valeurs par défaut en ES2015+",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-valeurs-par-defaut/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Bienvenue dans notre septième article de la série JS idiomatique.\nOn parle aujourd’hui des template literals, anciennement nommés template strings dans la spec de JS, et apparemment traduits par «littéraux de gabarits » en français, ce qui reste assez peu descriptif je trouve…\nJavaScript aura attendu 2015 pour pouvoir enfin interpoler des contenus facilement dans ses chaînes de caractères littérales, mais comme souvent avec JS, ça valait le coup d’attendre ! Car on ne s’est pas contentés de fournir la même fonctionnalité que dans les autres langages qui avaient déjà quelque chose de similaire : on a fait beaucoup plus !\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nPourquoi utiliser des template literals ?\nLes template literals visent à rendre les littéraux chaînes de caractères plus pratiques.\nPour rappel, historiquement, JS autorisait deux délimiteurs pour les littéraux chaînes de caractères : l’apostrophe, ou single quote (') et le guillemet, ou double quote (&quot;).\nContrairement à ce qui se passe dans la plupart des langages, il n’y a aucune différence entre les deux : c’est simplement qu’on doit échapper un caractère ou l’autre à l’intérieur, en fonction du délimiteur. Mais sinon, toutes les mêmes syntaxes y sont disponibles.\nEn revanche, ces littéraux ne permettaient pas, ou en tout cas pas bien…\n\n…d’aller à la ligne dans le littéral : impossible de faire facilement un fragment de HTML sous forme de String, par exemple, ou un bout de code en général.\n…d’interpoler, c’est-à-dire d’injecter des expressions dynamiques au sein de la chaîne.\n\nJS autorisait en fait depuis longtemps le retour à la ligne au sein d’un littéral texte, pourvu que chaque ligne concernée se termine par un backslash (\\). Mais en pratique, ça déconnait à pleins tubes sur divers moteurs JS (chacun déconnant à sa façon, sinon c’est pas fun).\nPour l’interpolation en revanche, on en était réduits à des séries de concaténations mal fichues, dans lesquelles on oubliait souvent une espace (ou on en mettait une en trop), sans parler des ambiguïtés entre l’addition et la concaténation :\n\nJS ne pouvait toutefois pas simplement changer la sémantique existante, sinon On Casse Internet™ : il pourrait très bien y avoir quelque part sur un site internet un littéral texte visant à afficher tel quel ce qui serait devenu une syntaxe interprétée, et on ne peut pas le risquer. JS doit toujours, à tout prix, préserver la compatibilité ascendante !\nOn a dû introduire un nouveau délimiteur ; ça a manifestement été décidé par des !@# d’américains avec leurs claviers QWERTY non internationaux, parce qu’ils ont opté pour un caractère qui saoule tous les autres : le backtick ou backquote (`). Sur la plupart des autres claviers, ce caractère nécessite une combinaison de touches (pas sur Apple FR, ceci dit) mais surtout c’est en général une touche morte : le système attend la touche suivante pour déterminer s’il compose les deux (pour faire un « ò » par exemple) ou s’il retranscrit le backtick tout seul. Ça varie d’un OS et d’un éditeur à l’autre, à toi de voir ce que ça donne chez toi, tu vas vite t’habituer, t’inquiète pas.\nAu sein de ces nouveaux délimiteurs de littéral, donc :\n\nL’intégralité du code source fait partie de la chaîne (retours chariots, indentation, etc.).\nOn peut interpoler sereinement n’importe quelle expression avec ${…}.\nOn dispose par ailleurs d’un mécanisme d’étiquetage qui permet d’étendre les modes d’interprétation du littéral.\n\nVoyons ça en pratique.\nl’interpolation\nVoici un petit exemple :\n\nDe fait, on peut interpoler n’importe quelle expression entre les accolades ; comme toujours, JS ne s’est pas amusé à créer une grammaire dédiée limitant artificiellement les expressions autorisées, mais réutilise la grammaire d’expression générique. On peut donc y coller des trucs compliqués : des appels de fonctions, des map entiers avec des callbacks, etc.\n\nOn peut aussi bien entendu aller à la ligne entre les accolades, pour avoir un code plus lisible produisant le contenu interpolé. Prettier ne se prive pas de s’en servir pour préserver les longueurs de ligne, d’ailleurs.\n\nBon, après, si tu mets un énorme bousin au cœur de ta chaîne, tu flingues sun peu la lisibilité, hein, trouve le bon équilibre.\nGaffe à la coercition String !\nEn revanche, attention à ne pas te laisser piéger par tes attentes usuelles en termes de gabarits : tu pourrais penser que null et undefined sont des « valeurs vides », et que leur interpolation donnera donc un contenu vide, mais pas du tout ! Par défaut, les valeurs interpolées sont converties en String ; or, la conversion officielle de null et undefined est spécifiée depuis toujours : elle donne les textes 'null' et 'undefined', ce qui la foutrait mal :\n\nDu coup si tu souhaites pouvoir interpoler correctement des données potentiellement pas là ou null, prévois le coup dans ton expression avec au choix un || ou un ??, suivant que tu veux une alternative à ",
		"description": "Les template literals en JS, c’est bien plus que de l’interpolation et du multi-lignes… Découvre leurs secrets dans cet article !",
		"date": 1645401600,
		"image": "/assets/images/art-vid/art-js-idioms-template-literals.jpg",
    "_tags": ["js"],
		"title": "Les template literals en ES2015+",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-template-literals/",
		"locale": "fr",
		"readingTime": "9 min"
	},	{
		"content": "Bienvenue dans notre huitième article de la série JS idiomatique.\nTous les langages de programmation ont une notion de portée ; et la plupart des langages impératifs ou orientés objets l’implémentent de façon similaire. Mais JavaScript a — comme souvent — quelques spécificités importantes, sans compter qu’ES2015 a ajouté de nouveaux comportements. Voyons ça en détail, pour comprendre en quoi var est à bannir, pourquoi function est parfois plus pratique que les fonctions fléchées, et d’autres choses encore !\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nLa portée, c’est quoi ?\nRevenons un instant sur les bases. On utilise ce terme de deux façons, qui correspondent à deux perspectives réciproques :\n\nLa portée d’un identifiant, c’est l’ensemble des endroits du code où cet identifiant est « visible », c’est-à-dire référençable.\nLa portée d’un endroit du code, c’est l’ensemble des identifiants référençables depuis cet endroit (c’est le sens retenu dans une phrase comme « à cet endroit, la fonction bidule est dans la portée »).\n\nOn va se concentrer ici principalement sur le premier sens : la portée de nos identifiants, c’est-à-dire de nos déclarations. Mais on reparlera du deuxième sens lorsqu’on abordera les fermetures lexicales (“closures” en anglais).\nPortée en JS et hoisting\nHistoriquement, JavaScript ne fournissait que deux mots-clés déclaratifs : var et function.\nCes deux mots-clés étaient visibles dans leur unité de portée, qui était forcément la fonction englobante (à défaut, la portée globale). En d’autres termes, il n’y avait pas d’unité de portée plus petite que le bloc de fonction. Les autres blocs (les paires d’accolades suivant une structure de contrôle comme un if ou un for par exemple) n’avaient pas leur propre portée, contrairement à ce qui se passe dans de nombreux langages :\n\nC’est déjà un point surprenant pour beaucoup de gens venant à JS depuis des langages à la portée plus traditionnelle, par exemple en C# ou Java (mais pas en PHP, qui n’a pas de portée dédiée aux blocs non plus). Les idiosyncrasies (#TIL) de JS sur les portées ne s’arrêtent toutefois pas là.\nLe hoisting\nLorsqu’un moteur JS met en place une unité de portée, il procède au hoisting des déclarations de fonctions (function) et de variables (var), c’est-à-dire qu’il fait remonter les déclarations en haut de la portée (celles des fonctions d’abord, puis celles des variables). Attention, on parle bien des déclarations, pas des initialisations. Les variables, donc, sont déclarées mais undefined jusqu’à l’exécution de leur ligne d’initialisation.\nAinsi, le code précédent est en fait perçu comme celui-ci :\n\nEt du coup, pour l’interprétation du code d’origine, on a les aspects surprenants suivants :\n\nUne fausse bonne idée ?\nLe hoisting des déclarations de fonctions est plutôt une bonne idée, en nous permettant de commencer notre code par l’algo principal avant de charger le cerveau de la personne qui lit le code avec le détail des fonctions locales. Le déroulé « du principal vers les détails » peut ainsi rester « de haut en bas », ce qui est une bonne chose :\n\nEn revanche, le hoisting des déclarations var, qui entraîne la possibilité de référencer ces variables avant leur ligne déclarative (mais elles y seront undefined), n’a pas seulement aucun intérêt, c’est carrément contre-productif. Ça vient d’une optimisation prématurée de l’allocation des registres dans les toutes premières moutures du moteur JS de Netscape, et ça n’a plus aucune raison d’être depuis plus de 20 ans.\nC’est la raison derrière le fameux problème des boucles numériques sur traitement asynchrone :\n\nLa manière de régler ça, avant ES2015, consistait à utiliser une IIFE, ce qui est garanti imbitable pour la plupart des devs JS :\n\nNon mais sérieux… On verra qu’avec ES2015, ça se règle beaucoup plus simplement, en changeant simplement le mot-clé déclaratif.\nAttention aux expressions de fonctions !\nRemarque aussi que JS ne hoiste pas les expressions de fonctions, c’est-à-dire les endroits où le mot-clé function apparaît à un endroit du code n’autorisant que les expressions et pas les instructions (on ne pourrait pas y mettre un if, par exemple). Ainsi, le code suivant ne marcherait pas :\n\nEn effet, ici c’est la déclaration var qui est hoistée, sans son initialisation. Alors qu’avec une déclaration de fonction, ça marche :\n\nÀ propos, les fonctions fléchées étant des expressions, elles ne sont pas hoistées par leur nature-même.\nUn mot sur les fermetures lexicales (closures)\nJS a également un aspect très particulier (et extrêmement pratique) de gestion des portées : les fermetures lexicales. Ça vient de la nature éminemment asynchrone et événementielle des codes JavaScript, où du code va souvent être exécuté bien après que la fonction englobante (qui a planifié ce code) a fini de s’exécuter. Regarde ce code :\n\nQuand la fonction logOnClicks s’exécute, elle définit message, scheduledAt et announcement, planifie un ges",
		"description": "La portée en JavaScript a parfois des comportements surprenants, mais en comprenant son fonctionnement et le rôle des différents mots-clés déclaratifs, tu peux écrire du code plus propre et pratique.",
		"date": 1646006400,
		"image": "/assets/images/art-vid/art-js-idioms-scope-hoisting.jpg",
    "_tags": ["js"],
		"title": "Portée, hoisting et mots-clés déclaratifs",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-portee-hoisting/",
		"locale": "fr",
		"readingTime": "8 min"
	},	{
		"content": "Bienvenue dans notre neuvième article de la série JS idiomatique.\nAujourd’hui c’est du lourd, puisqu’on va régler la question du this en JavaScript. Enfin presque, parce qu’on parlera des fonctions fléchées la prochaine fois, mais on va traiter disons… 95% du sujet aujourd’hui ! Si on revient à l’essentiel, le comportement fondamental de this en JavaScript se résume à une phrase (courte) ! La prochaine fois que tu verras une personne soi-disant senior en JS se perdre dans des pseudo cas particuliers, tu pourras remettre ça au clair en un rien de temps, tu verras.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nAttends voir, “binding” ?\nMême si c’est légèrement un abus de langage, avec le temps, le terme binding en JS a fini par désigner le mécanisme d’association (ou pas) d’une valeur à this lors de l’exécution d’une fonction. Un temps, on a vu le terme « contexte » pour cette même notion, mais c’est un terme trop générique pour être utile, et aujourd’hui la plupart des API proposant ce type de réglage appellent le paramètre concerné thisArg, ce qui est nettement plus explicite.\nUn petit quiz pour commencer\nPrends le code suivant :\n\nÀ ton avis, le code bob.greet() va…\n\nloguer « Salut moi c’est Bob »\nloguer « Salut moi c’est undefined »\nlever une ReferenceError\nlever une TypeError du genre « pas de propriété firstName sur undefined ?\n\n(Je précise que le comportement serait ici le même en mode laxiste et en mode strict.)\nRéfléchis un peu, réponds, puis défile vers le bas pour lire la réponse. Ne triche pas !\n…\nÇa renverra bien « Salut moi c’est Bob ». Et très franchement, si ça faisait autre chose, on ne serait sans doute pas en train de parler de JavaScript, là. Le langage n’aurait jamais pris.\nBon, soit, mais prenons maintenant d’autres cas de figure. Je vais t’en donner plusieurs, qui vont tous se comporter pareil, car il s’agit en fait de quelques exemples d’un même cas général, déclinable autant qu’on veut :\n\nN’importe lequel de ces exemples ferait quoi, à terme, à ton avis ?\n\nLoguer « Salut moi c’est Bob »\nLoguer « Salut moi c’est undefined »\nLever une ReferenceError\nLever une TypeError du genre « pas de propriété firstName sur undefined ?\n\nTu sais quoi faire…\n…\nÇa dépend du mode d’exécution de ton JS.\nAllons bon, v’là autre chose.\nEn mode laxiste (qui est le mode par défaut des moteurs JS, ça vend la confiance), dans tous ces cas au sein de la fonction exécutée, this vaudrait l’objet global (par exemple, dans le thread JS principal d’une page web classique, ce serait window). Cet objet global existe, on a donc le droit d’en lire les propriétés. Il n’a en revanche pas de propriété firstName (sauf si tu fais des trucs louches), de sorte que this.firstName vaudra undefined, et c’est donc la réponse 2 qui sera juste.\nEn mode strict (qui doit être explicite dans ton code, mais est aussi le mode utilisé par défaut pour le code transpilé par Babel ou TypeScript, notamment), this serait ici undefined, de sorte que this.firstName lèverait une erreur : c’est la réponse 4 qui marche.\nLe comportement strict est nettement plus utile, car il permet du fail-fast : s’assurer que le code va échouer immédiatement, de façon visible (une exception est levée), au plus près du code problématique (notre façon d’appeler bob.greet). Sans ça, on peut très bien avoir du code erroné (qui manipule undefined au lieu de la donnée souhaitée) mais dont on ne repère les effets délétères que longtemps après dans l’exécution du programme. Pas glop.\nC’est défini à l’appel !\nDéjà, je rappelle qu’on ne parle pas ici des fonctions fléchées, mais des autres : celles déclarées avec function ou en méthodes concises dans un littéral objet ou corps de classe.\nDans tous les langages orientés objets, this fait partie du contrat d’appel de la fonction, au même titre que ses arguments. C’est une sorte de paramètre caché, encore que parfois il soit explicitement déclaré — comme le self de Python, premier paramètre de toutes les méthodes.\nSi dans la majorité des langages, this est défini lexicalement (en fonction du type de déclaration de la fonction dans le code), en JavaScript, this est entièrement défini par l’appel. C’est la façon dont on appelle la « méthode » qui définit ce que vaudra this au sein de celle-ci.\nJe mets des guillemets, car en JavaScript il n’y a pas de méthodes au sens classique du terme, uniquement des fonctions. Une fonction n’est intrinsèquement associée à aucun objet en particulier. Notamment, le fait que sa déclaration initiale figure au sein d’un littéral objet ou d’un corps de classe n’a absolument aucune importance en termes de this. C’est là une différence majeure avec la plupart des langages orientés objets, et la source de beaucoup de confusion pour les personnes arrivant à JS depuis un autre langage.\nLà tu vas me dire : « tu déconnes, Christophe, regarde, on arrivait bien à faire bob.greet(), y’avait bien une méthode greet sur bob, là ! »\nHéééééé non.\nEn fait, c",
		"description": "Le comportement de this en JS s’explique en une petite phrase !  Il est temps de lever le voile sur ce faux mystère qui déroute beaucoup trop de monde…",
		"date": 1646611200,
		"image": "/assets/images/art-vid/art-js-idioms-binding-this.jpg",
    "_tags": ["js"],
		"title": "Le binding et this en JavaScript",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-binding-this/",
		"locale": "fr",
		"readingTime": "8 min"
	},	{
		"content": "Bienvenue dans notre dixième article de la série JS idiomatique.\nOn fait suite aujourd’hui à l’article de la semaine dernière sur le binding et this en JavaScript pour parler en détail des fonctions fléchées, apparues en ES2015. Leur syntaxe est bien connue, elles sont assez populaires, pourtant leur comportement réel est souvent mal compris, ce qui peut donner lieu à des soucis opérationnels ou, à tout le moins, à une utilisation inadaptée.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nLes fonctions fléchées ont deux aspects indépendants (ou si ton TJM est d’au moins 500€ HT/j, tu dois dire « orthogonaux » 😉) :\n\nLa concision de leur syntaxe\nLa lexicalité du this (et de trois autres trucs)\n\nConcision de la syntaxe\nC’est une raison majeure pour laquelle les gens recourent aux fonctions fléchées, même quand le this n’entre pas en ligne de compte.\nLa syntaxe est la suivante :\n\nLa signature ; si techniquement les parenthèses sont optionnelles en cas de paramètre unique, la bonne pratique consiste à toujours mettre les parenthèses, qui sont de toutes façons obligatoires en cas de paramètres multiples ou inexistants. C’est d’ailleurs le réglage par défaut de Prettier depuis sa version 2.0.\nLa flèche (=&gt;), parfois appelée fat arrow (mais c’est pas sympa, elle a rien demandé, c’est quoi ce body shaming, en plus y’a pas de thin arrow en JS…)\nEt enfin, deux cas de figure :\n\nSoit des accolades, qui constituent alors un corps de fonction.\nSoit n’importe quoi d’autre, qui est alors une expression JS dont le résultat est automatiquement renvoyé par la fonction.\n\n\n\nDétail amusant : une fonction fléchée est donc a priori anonyme ; en pratique, ce n’est le cas que pour les callbacks, parce qu’ES2015 auto-nomme toute autre fonction anonyme (fléchée ou non) d’après l’identifiant vers lequel elle est affectée. Par exemple :\n\nLorsqu’on utilise un corps de fonction, ça signifie qu’on a eu recours à une fonction fléchée (plutôt qu’une fonction traditionnelle) soit pour conserver le this en vigueur dans la portée parente, soit pour des raisons de concision déclarative. Mais le corps de fonction a les mêmes règles ; notamment, il ne renvoie rien automatiquement : c’est à nous de faire un éventuel return explicite avec la valeur souhaitée.\nDans les autres cas, on bénéficie du retour automatique de l’expression fournie, ce qui est idéal pour les petits one-liners passés comme prédicats ou mappers à de nombreuses fonctions utilitaires, comme filter ou map par exemple.\nCompare la version traditionnelle :\n\nAvec la version fléchée :\n\nC’est quand même plus sympa. On peut aussi déstructurer, tant qu’à faire (ça restait possible dans les fonctions traditionnelles, hein) :\n\nSweet.\nLe piège des littéraux objets\nEn JS, l’accolade ouvrante ({) a deux significations, suivant qu’on est à un emplacement autorisant les blocs ou non. Dans le premier cas, elle ouvre un bloc. Dans le second (on n’autorise que les expressions), elle ouvre un littéral objet.\n\nLorsqu’on prend l’habitude d’utiliser des fonctions fléchées, on devient vite fan de la syntaxe à renvoi automatique, par exemple :\n\nLe souci, c’est lorsqu’on veut renvoyer un littéral objet. On serait tenté·e de juste faire ça :\n\nLe souci c’est qu’ici on a écrit un bloc, et pas de bol, il était syntaxiquement valide. Il contient en fait une étiquette d’instruction (size:), suivie d’une expression à virgules (name.length, name) qui est évaluée (et vaut son terme final, soit name)… et aucun return, alors qu’on est dans un bloc : la fonction de rappel renvoie donc, par défaut, undefined.\n\nC’est notamment fréquent dans, par exemple, les sélecteurs Redux. Imaginons qu’on veuille écrire un sélecteur acceptant l’état applicatif intégral pour n’en récupérer que deux propriétés racines, sans les modifier :\n\nOooooh la belle fonction qui renverra undefined.\nSi on souhaite rester sur de la fonction fléchée, deux solutions. Soit on fait effectivement un bloc, et on met un return explicite :\n\nC’est dommage parce qu’au final c’est plus long qu’une fonction traditionnelle, sans en avoir les avantages (hoisting notamment). Ou alors, on force les accolades à désigner un littéral, en s’assurant qu’elles apparaissent à un endroit du code exigeant une expression. Le moyen le plus simple de faire ça de façon neutre consiste à les enrober par des parenthèses :\n\nC’est parfois bizarre à lire, comme ici, dans la mesure où on retrouve exactement les mêmes caractères de part et d’autre de la flèche. Sauf qu’à gauche, c’est une signature de fonction qui déstructure son unique argument, alors qu’à droite c’est un littéral objet en notation concise.\nÇa sauve quand même bien la vie quand tu déclares ta fonction fléchée à la volée comme callback :\n\nLexicalité\nL’autre raison d’utiliser une fonction fléchée touche généralement à this. On souhaite pouvoir utiliser le this de la portée parente au sein d’un callback, typiquement.\nSi tu as lu l’article précédent, tu sais ",
		"description": "Quasi tout le monde fait des fonctions fléchées, mais parfois à tort, en tout cas sans vraiment comprendre leur comportement.  Découvre leurs subtilités, leurs avantages et leurs limites, et apprends quand les utiliser de façon pertinente.",
		"date": 1647216000,
		"image": "/assets/images/art-vid/art-js-idioms-arrow-functions.jpg",
    "_tags": ["js"],
		"title": "Les fonctions fléchées en JavaScript",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-fonctions-flechees/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Comment apprendre Git sans connaître son vocabulaire ? Dans cette série sur le glossaire Git je t’explique les termes incontournables, pour que tu parles Git et que Git te parle !\n\nVoilà ce qui t’attend :\n\nZones : dépôt local, dépôt distant, index/stage, copie de travail, stash\nPorcelaine et plomberie : typologie et rôles des commandes\nObjets et cascade de références\nHEAD : où ai-je la tête ?\nBranches : de simples étiquettes\nCommit atomique\nFusion et conflits\nRebase : le couper-coller de l’historique\nDépôt distant vs. dépôt local\nÉtiquettes : identifier des points d’historique\nSubmodules : quand t’as pas le choix…\n\nComment ne manquer aucun épisode ?\nSi tu veux être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de t’abonner à notre newsletter et à notre chaîne YouTube. Tu peux aussi nous suivre sur Twitter. Si tu aimes ce que nous faisons, n’oublie pas de liker, de commenter et d’en parler autour de toi 🙂.\nEt bien entendu, n’hésite pas à jeter un œil à nos formations ! Si comprendre Git sur le bout des doigts t’intéresse, la Git Total est faite pour toi 😎 !\n",
		"description": "Dans cette série découvrez les termes essentiels pour bien comprendre Git",
		"date": 1652400000,
		"image": "/assets/images/art-vid/art-git-glossary.jpg",
    "_tags": ["git"],
		"title": "Glossaire des termes utiles Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/glossaire-git/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Sais-tu que Git possède 141 commandes ? Sais-tu aussi que parmi ces commandes on distingue entre les commandes utiles à l’utilisateur·rice (porcelaine) et celles de plus bas niveau, plutôt utiles aux scripts (plomberie) ?\nVoyons tout ça, vite fait bien fait !\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nPourquoi ce vocabulaire ?\nTu l’as sans doute compris, la documentation Git décrit par une métaphore les 2 grands groupes de commandes qui le composent.\nImagine que tu veuilles te laver les mains 🤲. Ça paraît logique d’aller au lavabo, d’actionner le robinet et de laisser s’écouler l’eau par la bonde 🚰 plutôt que de sortir le poste à souder, la colle PVC et de bricoler arrivée et évacuation d’eau 👩‍🔧.\nEn tant qu’utilisateur·rice « classique » Git on va donc interagir davantage avec la porcelaine qu’avec la plomberie.\nQu’est-ce qui les distingue ?\nOn a une distinction technique pour une partie des commandes de porcelaine dans le terminal car celles-ci bénéficient de la complétion (tu sais, quand tu commences à saisir la commande et que tu fais Tab pour l’autocomplétion).\nDe manière générale, les commandes de porcelaine sont construites à partir des commandes de plomberie. Tu peux donc sereinement te concentrer sur la porcelaine tout en gardant à l’esprit que, pour des cas particuliers, comme des scripts techniques, tu devras peut-être recourir aux commandes de plomberie.\nDu coup, on a quoi en porcelaine ?\nOn compte 41 commandes “principales” de porcelaine (mai 2022 / Git 2.36). Mais on utilise généralement au quotidien 10 à 20 de ces commandes. Pourquoi ? Parce que certaines ont un usage occasionnel, lié à un workflow spécifique.\nPar exemple, l’envoi puis l’application automatique des patchs par e-mail via git format-patch, git send-mail et git am est lié au workflow historique du noyau Git. Il y a fort à parier qu’il serait irritant pour toi aujourd’hui.\nVoici la liste des commandes de porcelaine listées par Git (je t’ai mis en gras celles que je considère utiles régulièrement 😉) :\n\n\n\nCommande\nRôle\n\n\n\n\nadd\nAjouter le contenu de fichiers dans l’index\n\n\nam\nAppliquer une série de patchs depuis une boîte mail\n\n\narchive\nCréer une archive des fichiers depuis un arbre nommé\n\n\nbisect\nTrouver par dichotomie la modification qui a introduit un bug\n\n\nbranch\nLister, créer ou supprimer des branches\n\n\nbundle\nDéplacer des objets et références via une archive\n\n\ncheckout\nBasculer de branche ou restaurer la copie de travail (voir switch)\n\n\ncherry-pick\nAppliquer les modifications introduites par des commits existants\n\n\ncitool\nAlternative graphique à commit\n\n\nclean\nSupprimer les fichiers non-suivis de l’arbre de travail\n\n\nclone\nCloner un dépôt dans un nouveau répertoire\n\n\ncommit\nEnregistrer les modifications dans le dépôt\n\n\ndescribe\nBaptiser un objet avec un nom lisible à partir d’une référence disponible\n\n\ndiff\nAfficher les changements entre les commits, entre commit et copie de travail, etc.\n\n\nfetch\nTélécharger les objets et références depuis un autre dépôt / un dépôt distant\n\n\nformat-patch\nPréparer les patchs pour soumission par courriel\n\n\ngc\nEffacer les fichiers non-nécessaires et optimiser le dépôt local\n\n\ngitk\nNaviguer visuellement dans un dépôt Git\n\n\ngrep\nAfficher les lignes de fichiers suivis correspondant à un motif\n\n\ngui\nUne interface graphique portable pour Git\n\n\ninit\nCréer un dépôt Git vide ou réinitialiser un existant\n\n\nlog\nAfficher l’historique des commits\n\n\nmaintenance\nLancer les tâches d’optimisation des données du depôt Git\n\n\nmerge\nFusionner deux ou plusieurs historiques de développement ensemble\n\n\nmv\nDéplacer ou renommer un fichier, un répertoire ou un lien symbolique\n\n\nnotes\nAjouter ou inspecter les notes d’un objet\n\n\npull\nRapatrier et intégrer un autre dépôt ou une branche locale\n\n\npush\nMettre à jour les références distantes ainsi que les objets associés\n\n\nrange-diff\nComparer deux plages de commits (par exemple deux versions d’une branche)\n\n\nrebase\nRéappliquer des commits par-dessus une autre base de travail (en vrai ça fait plus 😉)\n\n\nreset\nRéinitialiser le HEAD courant à l’état spécifié\n\n\nrestore\nRestaurer des fichiers de la copie de travail\n\n\nrevert\nCréer un commit annulant un commit existant\n\n\nrm\nSupprimer des fichiers de la copie de travail et de l’index\n\n\nshortlog\nRésumer la sortie de ‘git log’\n\n\nshow\nAfficher différents types d’objets\n\n\nsparse-checkout\nInitialiser et modifier une extraction partielle\n\n\nstash\nRemiser les modifications en cours d’une copie de travail\n\n\nstatus\nAfficher l’état de la copie de travail et de l’index\n\n\nsubmodule\nInitialiser, mettre à jour et inspecter les sous-modules\n\n\nswitch\nBasculer de branche\n\n\ntag\nCréer, lister, supprimer un objet d’étiquette ou vérifier sa signature\n\n\nworktree\nGérer des copies de travail multiples\n\n\n\nSi tu es curieux·se, tu peux obtenir une liste plus détaillée en faisant un git help --all.\nComme je l’ai décrit plus haut, il s’a",
		"description": "Porcelaine et plomberie : décrouvrir et comprendre les commandes et leur rôle",
		"date": 1652400000,
		"image": "/assets/images/art-vid/art-git-plumbing-porcelain.jpg",
    "_tags": ["git"],
		"title": "Porcelaine et plomberie : typologie et rôles des commandes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/porcelaine-et-plomberie-git/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Git traite des fichiers, des répertoires et leurs évolutions lors de la vie d’un projet. Sa conception est calquée sur ce principe : nos fichiers sont représentés par des fichiers blobs, nos répertoires par des fichiers trees, et un instantané / une version du projet par un fichier commit. Voyons ensemble comment tout ça est structuré.\nCet article fait partie de notre série sur le glossaire Git.\nL’essentiel du contenu de cet article est une redite de l’article décrivant l’anatomie d’un commit. Si tu as déjà bien intégré ces concepts, tu peux le survoler pour te concentrer sur la fin (chaînage et purge). Je prends cependant ici une approche différente, du bas vers le haut (des blobs aux commits), à l’envers de l’autre article.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nC’est bien tout ça, mais ça m’apporte quoi ?\nOn pourrait croire que regarder sous le capot et comprendre les rouages de Git n’a pas d’utilité particulière. Pourtant, après des années à former des gens à Git, je me suis aperçu que ça facilitait énormément la compréhension de tout un tas de mécanismes et commandes, en plus de démystifier cet outil qui paraît parfois très complexe.\nPar exemple, savoir que Git fonctionne avec des références facilite, pour un commit, la perception du « annuler » (pointer sur la référence précédente, « d’avant ») ou « refaire » (repointer vers la référence initiale, « d’après »).\n\nOn commence donc avec l’analyse des objets dans l’ordre de création et avec ce qui représente nos fichiers.\nPour décrire en détail certains points techniques je vais utiliser la commande de plomberie cat-file pour voir le type et le contenu d’un fichier technique Git (ne t’embête pas à la retenir, c’est pour mes démos 🙂).\nNom / identifiant des objets Git\nGit emploie un procédé unique pour nommer et identifier ses objets : leur nom est défini par le contenu qu’ils représentent et que Git passe à un algorithme dit de « hachage » (SHA-1 / SHA-2). J’insiste sur ce dernier point : le nom / l’identifiant d’un fichier technique Git est intrinsèquement lié à SON CONTENU. On obtient ainsi un identifiant sous forme d’une clé hexadécimale de 40 ou 64 caractères. On dit ainsi de Git qu’il est un système de fichiers adressables par contenu.\nJe peux lui demander de m’afficher le contenu d’un de ses objets connus en lui passant son identifiant.\n\nCe procédé s’appliquant aussi bien aux blobs qu’aux trees et commitishs. Voyons ces derniers dans le détail.\nBlob\nLorsqu’on crée un fichier dans un projet et qu’on l’ajoute à Git, il est stocké sous forme d’un blob (Binary Large OBject). Pour le constater il suffit d’observer le répertoire .git/objects/ de notre projet et de faire un ajout (git add …) :\n\nIl s’agit d’un instantané (copie intégrale du contenu du fichier) qui subit des optimisations sur le disque (notamment une compression via zlib). Le fait que le nom du blob soit défini par son contenu implique 2 choses importantes :\n\nsi je modifie mon fichier dans mon espace de travail (son contenu, indépendamment de son nom et son emplacement) et que je l’ajoute à nouveau à Git, j’obtiendrai un autre blob avec un autre identifiant ;\nsi je copie mon fichier ailleurs dans mon projet (ou au même endroit avec un autre nom) et que j’ajoute ce nouveau fichier, aucun nouveau blob ne sera créé, car le contenu sera strictement identique.\n\nPour les « puristes », Git ajoute le type de fichier, sa taille et un séparateur au contenu avant de calculer l’identifiant (checksum SHA-1/SHA-2). Ainsi, pas de risque d’ambiguïté.\n\nEnfin, voyons notre blob pour vous prouver que le contenu stocké est bien celui attendu :\n\nAstuce : Git nous permet de désigner des objets dès les 5 premiers caractères de leur identifiant (sauf en cas d’ambiguïté avec un autre objet démarrant par la même chaîne). Ainsi dans l’exemple précédent j’aurais pu faire git cat-file -p e3cd3. D’ailleurs on peut configurer le log (et par ricochet diverses autres commandes) pour nous présenter seulement les 7 premiers caractères par défaut : git config --global log.abbrevCommit true.\nReprenons notre exemple précédent et voyons ce que donne la copie puis la modification :\n\nOn observe bien qu’ajouter une copie du fichier ne crée pas de nouveau blob. En revanche, ajouter une version modifiée en crée bien un.\nDes fichiers, pas des répertoires\nGit se préoccupe principalement des fichiers. Il ne permet pas de gérer directement des répertoires. En d’autres termes, tu ne peux pas ajouter un répertoire vide à un projet.\nPourtant, représenter la structure d’un projet intégrant des répertoires vides est un besoin fréquent. N’as-tu jamais de répertoire log ou config nécessaire à ton projet mais dont les fichiers ne doivent pas être versionnés ?\nL’astuce commune pour faire face à cette situation est alors de créer un fichier vide dans le répertoire et donc d’ajouter ce fichier pour enregistrer le chemin du répertoire dans Git. Pour le nom du fichier, c’est à ta con",
		"description": "Blob, tree, commitish : quelles sont les pièces détachées de Git ?",
		"date": 1653004800,
		"image": "/assets/images/art-vid/art-git-objects.jpg",
    "_tags": ["git"],
		"title": "Les objets Git : blob, tree, commitish",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/objets-et-references-git/",
		"locale": "fr",
		"readingTime": "7 min"
	},	{
		"content": "Bienvenue dans notre onzième article de la série JS idiomatique. Aujourd’hui on se penche sur une série d’opérateurs arrivés avec ES2020, qui simplifient considérablement notre code : ceux du Optional Chaining et du Nullish Coalescing. Tu vas voir, ça change la vie !\nTout d’abord, on est désolés d’avoir dû laisser passer près de 2 mois depuis le précédent épisode de cette série ; parfois, les priorités du planning sont chamboulées… Mais on est de retour pour la dernière ligne droite ! (Et en parallèle, on a démarré la série du Glossaire Git, ne la rate pas !)\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nIn English?\nEt oui. Si la traduction française « chaînage optionnel » est pas mal, c’est beaucoup plus délicat pour l’autre opérateur, comme en témoigne le choix pataud de nos amis du MDN France avec « coalescence des nuls » : si c’est là ce qu’ils ont trouvé de mieux, c’est qu’on est vraiment mal. Déjà, ça fait un peu « la coalescence par / pour les nuls », ce qui peut faire tiquer, mais en prime ça exclut la nuance du nullish, qui indique qu’on parle aussi de undefined.\nBref, je vais rester sur Nullish Coalescing, mais je n’ai rien contre « Chaînage optionnel », hein.\nL’Optional Chaining\nSi tu fais du JS depuis un petit moment, tu as forcément déjà rencontré ce genre de code :\n\nParfois on travaille avec des données structurées dont certains segments ne sont pas toujours présents (soit qu’ils sont optionnels, soit qu’ils ne sont pas toujours initialisés en amont) ; si ces situations sont nominales, on doit alors se blinder en vérifiant, à chaque étape où c’est pertinent, la présence du segment.\nC’est verbeux. Mais vraiment.\nES2020 a donc sorti une série d’opérateurs pour nous éviter ça. Ils partagent tous le même comportement :\nSi l’opérande gauche est null ou undefined (nullish), ils court-circuitent à undefined ; sinon, ils évaluent l’opérande droite.\nAttention, l’expression finale ne vaudrait pas null mais undefined en cas de court-circuit, hein, même si l’opérande gauche vaut null : l’idée est de normaliser le résultat du court-circuit.\nL’opérateur de base est ?. (interrogation-point), qu’on utilise pour l’indexation directe, là où on aurait recouru à un simple point (.) :\n\nPour l’indexation indirecte (l’opérateur traditionnel []), on a ?.[], comme ceci :\n\nEt pour l’appel de fonction (l’opérateur traditionnel ()), on a logiquement ?.() :\n\nMais pourquoi toujours le point ?!\nPour des raisons d’ambiguïté d’analyse syntaxique. Si on avait opté pour ?., ?[] et ?(), ça aurait causé des conflits potentiels d’interprétation avec les expressions combinant opérateur ternaire (… ? … : …) et littéraux tableaux ou paires de parenthèses. Il est très difficile de produire un parser (analyseur syntaxique) capable de produire efficacement un ternaire tout en autorisant ces syntaxes plus concises, notamment en l’absence d’espacement, par exemple suite à une minification, ou avec un espacement hétérogène :\nobj?[expr].filter(fun):0\n\nfunc?(x - 2) + 3 :1\n\nDu coup, on démarre toujours par ?. ; ne t’inquiète pas, on s’y fait très vite.\nEt encore, il a fallu traiter spécifiquement le cas ?.3 (quand un entier suit immédiatement le point) pour permettre les ternaires sur flottants (cond?.3:0)…\nN’en mets pas à tous les niveaux pour rien !\nCes opérateurs créent ce qu’on appelle un court-circuit long : tout le reste de l’expression (à un détail près qu’on verra dans un instant) est court-circuité en cas d’opérande gauche nullish. Imaginons le cas suivant :\n\nL’objet data peut être nullish.\nS’il ne l’est pas, on a la certitude qu’il contient une propriété identity, qui est un objet.\nL’objet référencé par la propriété identity a toujours une propriété security, qui est un objet.\nL’objet référencé par la propriété security a parfois une méthode sign, mais pas toujours.\n\nIl serait inutile et déroutant, donc une mauvaise pratique d’écrire ceci :\n\nEn effet, en lisant ce code, on déduira logiquement que identity et security ne sont pas toujours là, ce qui n’est pas vrai : dès lors qu’on a data, on est sûrs d’avoir data.identity.security ! On se retrouve donc avec un modèle mental erroné de la donnée, et du code inutilement verbeux.\nAu lieu de ça, on écrira ceci :\n\nPuisqu’on a des court-circuits longs, du moment que data est nullish, toute l’expression vaudra undefined, la partie à droite du premier ?. ne sera même pas évaluée. Et le code nous communique bien la nature optionnelle ou garantie de chaque segment.\nDe ce point de vue, on a l’équivalent dans C# et Swift, notamment. D’autres langages ont l’accès optionnel, mais sans le court-circuit profond (ex. Kotlin, Dart ou Ruby), ce qui explique peut-être ce genre de défaut d’utilisation dans JS, si les personnes ont des réflexes qui viennent de là.\nNote : la portée du court-circuit long se limite toutefois aux parenthèses englobantes immédiates. Du coup, attention à ce genre de code :\n\nIci, si data est nullish, le terme représenté",
		"description": "Fini les ternaires ou && imbriqués pour accéder en profondeur à une chaîne de données optionnelles ! Avec ces opérateurs d’ES2020, tout ça se simplifie drastiquement.",
		"date": 1653436800,
		"image": "/assets/images/art-vid/art-js-idioms-oc-nc.jpg",
    "_tags": ["js"],
		"title": "Optional chaining et Nullish coalescing",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-optional-chaining-nullish-coalescing/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Comment savoir où nous sommes dans notre historique Git ? Sur quelle branche ? Dans quel état de notre projet ? C’est le rôle de HEAD : je ne vais nulle part sans ma tête ! Laisse-moi t’expliquer ce fondamental de Git.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nOù tu iras j’irai 🎶\nOn considère le plus souvent HEAD comme un pointeur sur le dernier commit de la branche courante (ce qu’on appelle aussi la tête de branche). C’est généralement le cas, mais pas tout le temps.\nHEAD est bien un pointeur, une référence vers un emplacement donné de notre historique (un commit si tu préfères). Il a deux fonctions principales :\n\nnous repérer dans notre historique (le « Vous êtes ici » du GPS) ;\ndéfinir l’endroit depuis lequel nous produisons un commit.\n\nSon comportement nominal est de « suivre » une étiquette de branche ou, pour être plus précis, de nous indiquer quelle est la branche active, définissant ainsi l’état de notre espace de travail, l’emplacement (le commit) qui servira de parent à notre prochain commit et la branche qui devra bouger.\nNote : le terme « étiquette de branche » ne te dit rien ? Pas de panique, je t’explique ça dans un prochain article. Si tu as peur de le manquer, n’hésite pas à t’abonner à notre newsletter.\nSous le capot\nUne petite explication technique t’aidera peut-être.\nHEAD est représenté par le fichier .git/HEAD. Si on regarde son contenu, on trouvera toujours une seule ligne dont le format sera le plus souvent celui-ci :\nref: refs/heads/nom-de-branche\n\nEn d’autre termes, il contient généralement une référence à la branche courante. En fait, c’est justement parce qu’il contient la référence d’une branche, que celle-ci est considérée comme la branche courante / active !\nTu peux observer son comportement si tu demandes à Git de basculer sur une autre branche :\ngit switch autre-branche\n\nTu verras alors le fichier .git/HEAD pointer vers cette autre branche :\nref: refs/heads/autre-branche\n\nSi on pousse un peu et qu’on crée un commit depuis cet emplacement, on verra que cette référence n’aura pas changé, HEAD pointera toujours sur autre-branche. C’est la valeur de cette étiquette de branche qui aura bougé (seulement parce qu’elle était désignée active par HEAD).\nUne référence souvent implicite\nDe nombreuses commandes utilisent HEAD comme valeur par défaut pour marquer un emplacement à analyser. C’est le cas de git show qui, sans référence explicite, utilisera HEAD par défaut et affichera le commit « courant ».\nIl en va de même pour git log lorsqu’on ne spécifie pas de syntaxe de révision qui t’affichera tout l’historique des commits jusqu’à HEAD.\nRepérer HEAD dans le log\nDu coup si HEAD est un indicateur précieux de notre emplacement courant, il semble pertinent de le repérer dans notre historique. C’est l’objectif de l’option --decorate de la commande log. Mais tant qu’à faire, autant utiliser un alias sympathique qui gère correctement l’affichage de notre historique (comme je l’expliquais dans cet autre article) :\ngit config --global alias.lg &quot;log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'&quot;\n\n\nOn obtient alors un affichage précisant l’emplacement de HEAD et la branche qu’il référence :\nHEAD -&gt; master\n\nAttention chéri·e, ça va trancher\nTu as probablement noté que j’indiquais plus haut que HEAD référence généralement une branche.\nDisons qu’il s’agit du comportement pour les usages classiques. Restent certains usages à la marge qui nécessitent de ne pas référencer une branche, que ce soit pour se remettre à l’état d’une version antérieure sans risquer de faire régresser le projet (switch ou checkout), ou par le biais du comportement inhérent à certaines commandes (rebase, bisect, submodule…).\nOn se retrouve alors dans une situation dite de « tête détachée » (ou « HEAD détachée » dans le guide officiel, probablement pour le côté moins gore 🔪😱).\nHEAD renseigne alors non plus une référence de branche mais directement un commit :\n\nOn discutera dans un prochain article de ce mécanisme et des moyens d’en sortir ou de s’en prémunir.\nComment ne manquer aucun épisode ?\nComprendre HEAD est essentiel pour bien utiliser Git.\nD’autres éléments de vocabulaire spécifiques à Git permettent d’aller encore plus loin dans cette compréhension. Aussi je t’invite à t’abonner à notre newsletter et à notre chaîne YouTube pour ne rater aucun de nos tutos et articles. Tu peux aussi nous suivre sur Twitter. Si tu aimes ce que nous faisons, n’oublie pas de liker, de commenter et d’en parler autour de toi 🙂.\nEt bien entendu, n’hésite pas à jeter un œil à nos formations ! Si comprendre Git sur le bout des doigts t’intéresse, la Git Total est faite pour toi 😎 !\n",
		"description": "Git HEAD : le « vous êtes ici » du GPS Git",
		"date": 1653609600,
		"image": "/assets/images/art-vid/art-git-head.jpg",
    "_tags": ["git"],
		"title": "Git HEAD : où ai-je la tête ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-head/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "Bienvenue dans notre douzième article de la série JS idiomatique. Aujourd’hui on continue sur les opérateurs récents avec les opérateurs d’affectation logique, qui permettent de simplifier certaines expressions courantes.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nLe monde d’avant\nAlors qu’on dispose depuis toujours (héritage du C) des opérateurs d’affectation combinés pour les opérations mathématiques (+=, %=…) et bit-à-bit (&amp;=, ^=…), on n’avait rien pour les opérations logiques (c’est-à-dire booléennes) :\n\nLa version courte\nES2021 a officialisé trois opérateurs d’affectation logique : &amp;&amp;=, ||= et ??=. On retrouvait déjà les deux premiers en Ruby, et leur absence en JS agaçait donc bien les Rubyistes (dont moi).\n\nÇa court-circuite toujours !\nContrairement aux variantes mathématiques ou bit-à-bit, qui résultent toujours en une affectation (et donc le déclenchement d’un éventuel accesseur écrivain), ces opérateurs préservent la sémantique de court-circuit de l’opération logique associée.\nEn particulier, il n’y aura affectation que si l’opérande droit est évalué. C’est pratique si tu écris quelque part où ça a un effet de bord indésirable, comme une perte de focus (écriture dans innerHTML par exemple) ou d’état local.\nVoici un petit exemple pour bien enfoncer le clou :\n\n(Si la syntaxe #tone te surprend, va donc voir la partie membres réellement privés de notre épisode ultra-complet sur les classes.\nQuels moteurs JS ?\nC’est officiel depuis ES2021, mais comme souvent la prise en charge native n’a pas attendu :\n\nTous les navigateurs modernes depuis mi-2020\nNode 15+ (2020 aussi)\n\nEt pour tout le reste, il y a Babel.\nÇa t’a plu ? Ne manque pas la suite !\nIl y a aussi encore plusieurs sujets merveilleux à venir dans cette série JS idiomatique.\nPour être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de t’abonner à notre newsletter et à notre chaîne YouTube. Tu peux aussi nous suivre sur Twitter.\nEt bien entendu, n’hésite pas à jeter un œil à nos formations ! Si explorer l’intégralité des recoins du langage t’intéresse, la ES Total notamment est faite pour toi !\n",
		"description": "Encore une façon sympathique de raccourcir son code JS tout en améliorant sa lisibilité.",
		"date": 1654041600,
		"image": "/assets/images/art-vid/art-js-idioms-logical-assignment.jpg",
		"title": "Les opérateurs d’affectation logique en JS",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-affectation-logique/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Tu viens de l’univers SVN ou équivalent et tu as peur de faire des branches ? Ou tu découvres seulement la gestion de versions et tu souhaites apprendre comment gérer tes branches avec Git ? Cet article est fait pour toi !\nJe t’explique ici ce que sont les branches, la facilité avec laquelle on peut les manipuler, et pourquoi on peut les créer et les supprimer sans crainte.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nUne simple étiquette\nOn a vu dans l’article sur les objets Git qu’un historique est constitué de commits que se référencent à la chaîne.\nIci, c2 pointe sur son commit parent c1 qui pointe sur son commit parent c0 :\n\nLa notion de branche n’est qu’un complément à cela pour permettre de désigner un emplacement en lui attribuant un nom. On appose alors une étiquette sur le dernier commit (le plus récent) de l’historique censé représenter la branche. En d’autres termes, une branche n’est qu’un pointeur sur un commit.\nIci la branche dev pointe sur le commit c2 et désigne donc implicitement la “chaîne” jusqu’à c0 :\n\nCe qu’on appelle alors la branche est la cascade des références de commits (jusqu’au commit racine, qui n’a plus de commit parent).\nCes étiquettes ont la particularité d’évoluer lorsqu’on produit de nouveaux commits alors qu’elles constituent la branche active, ou lorsqu’on souhaite les déplacer ailleurs (annulation de commits etc.). Elles servent également à indiquer au garbage collector les chaînes de commits à préserver (ça fonctionne aussi avec les tags). Enfin, elles peuvent aussi servir au partage via les dépôts distants.\nDans le diagramme ci-après, le commit c3 a été produit depuis l’état de c2. Il pointe donc sur son parent c2 et l’étiquette de branche dev a évolué pour le référencer :\n\nPerformance et tranquillité\nCe fonctionnement par référence est extrêmement pratique à bien des égards :\n\nla performance est accrue : on ne manipule que des pointeurs ;\non peut garder l’esprit tranquille quand on effectue nos opérations : jamais un commit ou objet Git ne sera supprimé, au pire il sera déréférencé.\n\nLa création d’une branche ne représente rien de plus que la création d’un fichier unique sur le disque. La branche est disponible localement et pourra être partagée plus tard (ou pas, si on veut réaliser un travail « privé »).\nLe renommage d’une branche signifie uniquement le renommage de son fichier descripteur.\nLa suppression d’une branche consiste en la suppression de ce fichier, donc du pointeur, mais en aucun cas des commits qu’elle désignait. Là aussi, c’est du coup très rapide. On a en prime la capacité de récupérer un historique potentiellement perdu (déréférencé / invisible dans le log classique).\nPour donner un contre-exemple, lorsqu’on demande à SVN de créer une branche, il va (sur le serveur SVN) dupliquer l’intégralité de l’historique et des fichiers désignés et les affecter à cette branche. On est donc soumis à la latence réseau en plus d’une duplication encombrante. Il en va de même pour la suppression et les autres manipulations.\nCycle de vie d’une branche : les cernes des branches\nComme dans nos articles sur les objets Git et HEAD je trouve intéressant de regarder sous le capot la manière dont sont traitées nos branches pour mieux les comprendre.\n(En botanique, les cernes sont les cercles / anneaux de croisance d’un arbre 🌳.)\nInitialisation d’un projet\nÀ l’initialisation d’un projet, aucun commit ni branche n’existe. Une branche par défaut sera créée au premier commit. Par convention cette branche s’appelle main (auparavant master, ce renommage ayant eu lieu suite au mouvement Black Lives Matter).\nOn trouve cette référence de branche active / courante via notre HEAD :\n\nLes fichiers des étiquettes de branches sont stockés dans le répertoire .git/refs/heads/ et portent le nom des branches. Pour l’instant ce répertoire est vide car je n’ai rien dans le projet.\nSi je crée un commit, j’observe l’apparition du fichier .git/refs/heads/main. Et si je regarde son contenu je m’aperçois qu’il ne contient qu’une ligne de 40 caractères : un identifiant de commit (SHA-1).\n\nÉvolution d’une branche\nSi je continue et réalise d’autres commits, je constate que ce fichier enregistre la référence du dernier commit produit :\n\nCréer une autre branche\nPuisque les branches ne sont que de simples étiquettes, rien ne m’empêche d’en créer autant que je veux, où je veux. Généralement je crée une branche depuis mon emplacement actuel pour démarrer un travail spécifique :\n\nJ’ai délibérément choisi ce nom avec un séparateur slash / pour te montrer que dans le répertoire .git/refs/heads/ on obtient un sous-répertoire feat/ qui contient un fichier specific-stuff. Ce type de nommage me permet de regrouper mes branches par sous-ensembles thématiques mais me contraint par la même occasion en m’empêchant de créer une branche feat. Je trouve cette approche avantageuse car elle nous évit",
		"description": "Le savais-tu : les branches Git ne sont que de simples étiquettes ? Découvre dans cet article la souplesse que cela nous apporte et apprend à ne plus avoir peur d’utiliser les branches",
		"date": 1654214400,
		"image": "/assets/images/art-vid/art-git-branches.jpg",
    "_tags": ["git"],
		"title": "Les branches : de simples étiquettes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-branches/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "Bienvenue dans notre treizième (et avant-dernier…) article de la série JS idiomatique.\nAujourd’hui on fait le point sur une petite syntaxe fort sympathique, mais dont l’arrivée en JS a connu de nombreux obstacles : les séparateurs numériques. Une évolution du langage chère à mon cœur 😉.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nC’est quoi le souci ?\nOh, tu vas tout de suite comprendre :\n\nMais désormais la vie est belle\nDe nombreux langages ont adopté le séparateur numérique _ (underscore) dans leurs littéraux numériques, parfois depuis des lustres. C’est notamment le cas de Java, Python, Perl, Ruby, Rust ou C#, pour ne citer qu’eux.\nNote bien que le séparateur ne change strictement rien à la valeur finale, il est juste là pour plus de lisibilité du code source, avec peu ou prou les mêmes contraintes de bon sens que dans les autres langages le proposant :\n\nPas en début ou en fin de littéral (let n = _10_ : non, deux fois non !)\nPas en fin de partie entière ni en début de partie flottante ou exposant dans un littéral flottant (let n = 5_._0e_10 : non, non et non !)\nPas de séparateurs adjacents (const FEE = 15__00 : non !)\n\n\nJ’ajoute que ça marche aussi pour les littéraux BigInt (type introduit en ES2020), pour lesquels c’est particulièrement utile.\n\nÇa marche donc pour les littéraux décimaux (entiers et flottants, y compris en notation scientifique), hexadécimaux, binaires et même octaux (déjà moins utile).\nAttention quand même…\nAfin de Ne Pas Casser Internet™, les fonctions Number (y compris en tant que constructeur), parseInt et parseFloat ne reconnaissent pas ces séparateurs, préservant ainsi la compatibilité ascendante, sacro-sainte en JavaScript.\nPourquoi ça a pris des années, au fait ?\nLa proposition initiale remonte à mi-2017, pourquoi diable a-t-il fallu attendre quatre ans pour une évolution qui, somme toute, a un impact très mineur sur la syntaxe comme sur la sémantique de la bibliothèque standard ?!\nEssentiellement parce qu’à peu près au même moment, une autre proposition, Numeric Literal Suffixes, a vu le jour, qui s’est retrouvée en conflit frontal avec les séparateurs numériques en termes de syntaxe.\nIl aura fallu trois ans (jusqu’en septembre 2020) pour que cette dernière finisse par prévaloir, simplement parce qu’elle avait avancé plus vite tout en collaborant au mieux avec l’autre, qui reste au stade 1 du processus de standardisation à l’heure où j’écris ces lignes (et franchement, je doute qu’elle passe un jour au stade 2, le besoin me paraît trop niche).\nEnfin, en tout cas, ayé, c’est disponible !\nQuels moteurs JS ?\nC’est officiel depuis ES2021, mais comme souvent la prise en charge native n’a pas attendu, surtout que la sémantique est bien connue et très facile à intégrer :\n\nTous les navigateurs modernes depuis mi-2020\nNode 12+\n\nEt pour tout le reste, il y a Babel.\nÇa t’a plu ? Ne manque pas la suite !\nIl y a plein de sujets merveilleux dans cette série JS idiomatique, et le prochain, c’est du lourd !\nPour être sûr·e de ne rater aucun de nos tutos et articles, le mieux est encore de t’abonner à notre newsletter et à notre chaîne YouTube. Tu peux aussi nous suivre sur Twitter.\nEt bien entendu, n’hésite pas à jeter un œil à nos formations ! Si explorer l’intégralité des recoins du langage t’intéresse, la ES Total notamment est faite pour toi !\n",
		"description": "Marre de devoir compter à la main les chiffres d’un nombre pour en connaître l’échelle ? Marre de devoir les découper à la main pour isoler les composants ? Voici enfin les séparateurs numériques !",
		"date": 1654646400,
		"image": "/assets/images/art-vid/art-js-idioms-numeric-separators.jpg",
    "_tags": ["js"],
		"title": "Les séparateurs numériques en JS",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-separateurs-numeriques/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "La qualité des commits est souvent prise à la légère, voire négligée. Pourtant la création de commits dits « atomiques » ⚛️ bénéficie grandement aux projets et à leurs participants. Je t’explique ici ce qu’on entend par « atomique » et quels sont les bénéfices ?\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nC’est d’la bombe bébé !\nLe terme atomique est utilisé ici non pas pour décrire des commits qui feraient exploser notre historique 🤯 mais plutôt l’inverse, à savoir faciliter sa cohérence.\nSi on s’en réfère à sa définition Wikipedia, un commit atomique est une opération qui applique un ensemble de changements distincts en une seule opération.\nAvec mes mots ça donnerait : un commit atomique représente un ensemble de travail cohérent s’intéressant à un aspect particulier du projet découpé le plus finement possible. Autrement dit, si ta méthode de gestion de projet t’encourage à définir en amont les tâches les plus petites possibles, tu peux considérer que chacune des tâches doit être représentée par un commit.\nLes solutions comme GitHub, GitLab, BitBucket et bien d’autres encouragent d’ailleurs ce principe en permettant certaines automatisations entre leur gestion de tickets/issues et nos commits (principalement l’insertion des références des commits et la fermeture automatique de tickets).\nBénéfices\nComme je l’ai énoncé plus haut, les bénéfices sont multiples :\n\nl’historique (log) du projet gagne en lisiblité (couplé au bon nommage des commits) ;\nle réemploi d’un aspect du projet d’un endroit à un autre est facilité (exemple du report de correctif via le cherry-picking, sorte de copier/coller de commit) ;\nl’analyse du contenu du commit est plus simple et efficace (contrairement à des commits « fourre-tout ») ;\nla fréquence des commits est plus importante, donnant le sentiment d’un accomplissement plus régulier (il ne faut pas négliger l’aspect psychologique) et permettant un suivi projet efficace.\n\nParfois « l’effort » fourni pour la bonne mise en œuvre des commits atomiques aura un effet bénéfique sur la méthodologie projet et le management : la mécanique mentale de découpe des aspect au plus près du code sera exploitée en amont, lors de la découpe des tâches à réaliser en réunion d’équipe.\nUn exemple simple\nPrenons l’exemple d’un projet où je dois afficher un texte à l’utilisateur qui aura plusieurs déclinaisons selon un nombre count passé en paramètre :\n\nsi count = 0, j’affiche Aucune tâche réalisée\nsi count = 1, j’affiche Une tâche réalisée\nsi count &gt; 0, j’affiche ${count} tâches réalisées\n\nMon travail va se décliner sous la forme de sous-tâches, chacune représentée par un commit identifiable :\n\ncréation d’une fonction utilitaire de pluralisation et de ses tests ;\ncréation et affichage du texte faisant l’appel à cette fonction utilitaire.\n\nAinsi même sur un sujet en apparence simple, on voit qu’on peut découper en sous-aspects. Le premier commit, celui intégrant la fonction utilitaire, pourra facilement être extrait et exploité ailleurs, sans embarquer la gestion de l’affichage du texte.\nPour ne rien rater de la suite…\nSi tu veux être sûr·e de ne rater aucun de nos tutos et articles, tu peux t’abonner à notre newsletter et à notre chaîne YouTube. Tu peux aussi nous suivre sur Twitter. Si tu aimes ce que nous faisons, n’oublie pas de liker, commenter et d’en parler autour de toi 🙂.\nEt bien entendu, n’hésite pas à jeter un œil à nos formations ! Si comprendre Git sur le bout des doigts t’intéresse, la Git Total est faite pour toi 😎 !\n",
		"description": "De l’importance de créer des commits avec des contenus cohérents, traitant d’un sujet spécifique à la fois.",
		"date": 1654819200,
		"image": "/assets/images/art-vid/art-git-atomic-commit.jpg",
    "_tags": ["git"],
		"title": "Des commits atomiques ⚛️",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/commit-atomique/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "La notion de fusion et de conflit n’est pas propre à Git. Il s’agit cependant bien d’éléments clés de son vocabulaire avec quelques spécificités. Revoyons ensemble rapidement ces bases et découvrons ce que Git nous apporte en complément.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nFusion : quoi et pourquoi ?\nLe principe de fusion vient de la capacité que l’on a à produire du travail isolé, notamment avec les branches, pour ensuite l’intégrer à un tronc commun (une autre branche). Pour les psycho-rigides mordus de botanique je vous le concède, on aurait pu appeler ça une anastomose, mais je doute sérieusement que ce terme soit favorable à la compréhension de Git.\nGénéralement on crée une sous-branche depuis une branche « parente » pour plus tard y intégrer le travail de cette sous-branche. Cette intégration finale fait donc évoluer la branche « parente », autrement appelée la branche récipiendaire (celle qui reçoit la fusion).\n\nEn pratique Git nous laisse la capacité de fusionner ce qu’on veut vers n’importe quel emplacement. Il ne pose aucune contrainte. On voit ainsi des personnes opérant des fusions « dans le mauvais sens » pour effectuer des mises à jour. Imagine un peu ta branche dev créée depuis main, et que main ait reçu une évolution nécessaire à la finalisation de dev. Voilà la manière dont certaines personnes intégreraient la mise à jour :\n\nPersonnellement j’évite autant que possible cette approche car elle dégrade notre graphe d’historique. Pour comprendre mieux pourquoi, je te recommande notre article bien utiliser Git merge et rebase.\nLe « pourquoi fusionner » est donc fondamental. Pour ma part je m’en tiens à la réponse suivante : j’ai fini un travail isolé, ce travail est prêt à être intégré au tronc commun.\nMême pas peur\nLorsque je donne notre formation Git je me trouve souvent confronté à des personnes qui ont peur de fusionner. J’avais les mêmes sueurs froides lorsque je travaillais avec d’autres systèmes de gestion de versions. Heureusement Git exploite des heuristiques qu’on peut considérer comme l’état de l’art de la gestion de fusion, notamment avec sa stratégie de fusion par défaut (ORT). Et si cela ne nous convient pas, on peut préciser d’autres stratégies (plutôt dans des cas ultra-particuliers et je doute que cela te concerne un jour).\nPour le dire simplement : on peut avoir confiance en Git pour nous assister au mieux dans nos fusions. Et si malgré ça tu as toujours peur, garde à l’esprit qu’on peut défaire une fusion (merci la gestion par références 😁).\nOui, mais j’ai quand même des conflits\n\nBah oui, Git sait arbitrer beaucoup de choses, mais lorsque les mêmes lignes d’un fichier ont été modifiées sur 2 branches différentes et qu’on les fusionne, il ne va pas choisir au hasard un résultat pour nous.\nSi je simplifie les choses, admettons que notre fichier possède un en-tête, un corps et un pied de page. Sur la première branche on aura modifié l’en-tête et le corps, sur la seconde le corps et le pied de page. Suite à la fusion Git va automatiquement renseigner l’en-tête depuis la première branche, et le pied de page depuis la seconde. Il nous laissera uniquement le corps a arbitrer manuellement, donc en conflit.\nPour ça il va utiliser une syntaxe standard à base de chevrons gauches, droits et de signes « égal »:\n\nLa partie entre les chevrons gauches et les signes « égal » désigne la version provenant de la branche courante (on a l’indication HEAD ici). La partie basse renseigne la version provenant la branche qu’on essaye de fusionner.\nNotre travail consiste donc à choisir entre ces versions ou recréer la version qui nous convient et retirer ces lignes de marqueurs avant de demander à Git de continuer cette opération.\nPour être plus précis, les conflits peuvent apparaître dans de nombreux contextes de fusion de fichiers. Autrement dit : la fusion de branches n’est pas la seule opération pouvant amener des conflits, mais la procédure de résolution reste toujours la même, ouf 😮‍💨 !\nFusion en « fast-forward »\nQuand il s’agit d’évolutions de notre historique projet, Git s’évertue à lisser au mieux nos contenus en évitant autant que possible les contenus inutiles (commits vides par exemple). Il apporte ce même soin pour les fusions, lorsque la branche qu’on souhaite fusionner n’est qu’une évolution depuis sa branche initiale. En d’autres termes, il n’y a pas de divergence entre ces branches, c’est-à-dire qu’aucune évolution / aucun commit n’a été produit sur la branche récipiendaire depuis le point de départ de la seconde branche. Dans notre graphe d’historique, ça donne généralement lieu à une série de commits en ligne droite depuis l’étiquette de branche initiale.\nSi on analyse bien ça, on se rend vite compte que pour intégrer le contenu de la seconde branche il suffit d’avancer notre étiquette de branche initiale. Et tu sais quoi, le « fast-forward » c’est e",
		"description": "Qu’est-ce qu’une fusion ? Que signifie le fast-forward ? Comment gérer les conflits ?",
		"date": 1655424000,
		"image": "/assets/images/art-vid/art-git-merges.jpg",
    "_tags": ["git"],
		"title": "Fusion et conflits",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/fusions-et-conflits/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "Et si vous profitiez de l’accalmie de l’été pour monter en compétence ?\n\nPendant juillet et août on vous propose nos formations pour votre entreprise (en intra) à moitié prix 🎁 !\nQue ce soit dans vos locaux ou à distance, vous pourrez :\n\noptimiser votre gestion de sources et de projet avec Git,\napprendre à développer des applications web riches avec JavaScript, React et Redux,\ntout savoir sur l’état de l’art du développement d’API avec Node.js,\nou encore devenir un expert en JavaScript pur.\n\nCette offre concerne nos formations Git Total, Web Apps Modernes, Node.js et ES Total.\nVous êtes une toute petite structure et n’avez que très peu de monde à former, rendant nos tarifs forfaitaires inadaptés ? D’une part, vous pouvez grouper votre demande avec d’autres petites structures de vos amies, on vous appliquera le tarif au global (une sorte de session inter-entreprises maison, quoi) ; d’autre part, si vous êtes au moins 4, faites-nous signe quand même, on trouvera des solutions !\nAlors, vous en dites quoi ? 😊\n\n\nJe demande un devis pour une intra Git Total ;\nJe demande un devis pour une intra Web Apps Modernes ;\nJe demande un devis pour une intra Node.js ;\nJe demande un devis pour une intra ES Total.\n\n",
		"description": "Dans cette série découvrez les termes essentiels pour bien comprendre Git",
		"date": 1656028800,
		"image": "/assets/images/art-vid/art-promo-ete-2022.png",
		"title": "Profitez de l’été pour vous former à prix cassé",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/promo-ete-2022/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "La notion de rebase en Git est incontournable. Que tu décides ou non d’utiliser cette fonctionnalité (et je peux t’assurer que tu voudras l’utiliser), il te faut savoir les actions qu’elle te permet de réaliser pour décider en pleine conscience.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nChanger de base\nComme son nom le suggère, le rebase décrit un changement de base. Mais un changement de base de quoi ? Et bien, il s’agit de « déplacer » une partie de l’historique, donc un ensemble de commits, en changeant le commit de départ (la base). Si tu as quelques notions de géométrie, tu peux voir ça comme une translation.\n\nEn réalité c’est un chouilla plus complexe. Ça s’apparente plus à une série de couper/coller des commits du segment initial sur la nouvelle base. Et si on précise l’étiquette de branche qui termine ce segment, elle sera au final déplacée pour pointer sur le dernier commit ainsi rejoué.\n\nCe qui est top, c’est qu’on peut en faire autant qu’on veut :\n\nVictor, nettoyeur\nEn plus de permettre de déplacer des segments d’historique, rebase nous permet, grâce à son mode interactif, de remanier tout ou partie des commits du segment. On peut tout faire :\n\nsupprimer des commits (ne pas les couper/coller) ;\nré-écrire des messages de commits ;\nréordonner des commits ;\nfusionner des commits ;\nmodifier des commits (pour les découper par exemple).\n\nRien ne t’empêche d’ailleurs de prendre comme base le commit servant déjà, actuellement, de base. De cette manière tu peux nettoyer le segment « sur place ». C’est probablement un des usages les plus courants, par exemple quand tu t’aperçois que tu as oublié quelque chose dans un commit antérieur, ou simplement que tu as mal décrit un commit.\nQuels rôles alors ?\nPeut-être que ça te paraît déjà évident, mais tant qu’à faire, je préfère être explicite.\nLes fonctions courantes que remplit rebase sont assez variées, mais fondamentalement ça va nous servir à mettre à jour notre historique.\nMettre à jour une branche\nImagine un instant que tu aies un tronc commun désigné par la branche main. Tu as entamé le développement d’écrans pour une fonctionnalité donnée sur une branche dev. Entre temps main a intégré des évolutions avec un nouveau thème graphique. Pour pouvoir terminer ta fonctionnalité tu aimerais, idéalement, te mettre à jour sur ce nouvel état de main.\nÇa revient au tout premier diagramme animé de cet article.\nTu peux même choisir de ne mettre à jour qu’un intervalle de commits donné (qui court généralement jusqu’à la fin de la branche, mais démarre plus tard que le point de divergence) :\n\nCorriger un ou plusieurs commits passés\nC’est probablement la raison pour laquelle j’utilise le plus rebase, quand je remarque soit un message mal rédigé (de temps en temps j’oublie la référence d’un ticket pour lier à mon outil de gestion de projet), ou encore que j’ai oublié un fichier dans un commit précédent, que je crée un commit complémentaire et que je veux faire de ces 2 commits éloignés un seul commit atomique.\n\nNettoyer une branche avant publication\nDernier cas d’usage, moins courant (mais ça c’est parce que je travaille très bien 😉), c’est lorsque je veux mettre mon historique au propre avant de publier. Je retire les commits qui s’annulent (commit + revert), je regroupe les commits qui traitent d’un même sujet, je normalise mes messages…\nPull + rebase = ❤️\nSi, comme moi, tu as compris que tes synchronisations (récupérations) avec le dépôt distant méritent (que dis-je : se doivent) d’utiliser le rebase, alors ton historique est propre, lisse, dénué de pollution visuelle liée à de la fusion des branches distantes dans leur équivalent local.\nÀ mon grand désarroi, Git ne définit pas ce comportement par défaut, il est suggéré mais on doit encore le configurer manuellement.\n\nÇa mérite un peu plus d’explication, non ? Git gère la synchro entre local et distant en gardant sur notre projet, localement, une référence à part pour chaque branche distante. Par exemple, j’ai ma branche main et son équivalent distant origin/main. Chacune est donc gérée comme une branche séparée. Et pour les synchroniser, Git a pendant longtemps réalisé par défaut la fusion de la branche distante dans la branche locale. Ça donnait des trucs sacrément moches dans l’historique. On a donc carrément intérêt à opérer plutôt le rebase de notre branche locale sur la branche distante à jour. On part alors du principe que la branche distante a (presque) toujours raison et doit servir de base aux commits qu’on a produit localement.\nHeureusement, une fois qu’on a mis en place la configuration qui va bien, ça roule tout seul sans qu’on s’en préoccupe 😮‍💨.\n\nMerge ≠ Rebase\nPar pitié, ne tombe pas dans le panneau d’opposer merge et rebase. Crois-tu qu’à un seul instant les responsables de Git se sont dit qu’ils allaient produire des commandes qui se superposent ou s’opposent. Quel en sera",
		"description": "Qu’est-ce qu’un rebase ? À quoi cela peut-il bien servir ?",
		"date": 1656028800,
		"image": "/assets/images/art-vid/art-git-rebase.jpg",
    "_tags": ["git"],
		"title": "Rebase : le couper-coller de l’historique",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-rebase-c-est-quoi/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Git utilise une architecture dite distribuée. L’idée étant de permettre en premier lieu de travailler localement, sans dépendance réseau (contrairement aux architectures centralisées), et en second lieu de favoriser la redondance de l’historique sur chaque machine locale.\nOn a donc à cet effet un dépôt local qui gère l’historique avec lequel nous travaillons et, lorsqu’on a besoin de partager ou sauvegarder notre projet, un dépôt distant avec lequel nous synchronisons notre dépôt local.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\n99% du travail se fait localement\nIl s’agit bien évidemment d’une statistique inventée™ même si la réalité nous montre qu’on s’en rapproche sensiblement.\n\nSi je le souhaite, je peux même travailler 100% localement, c’est-à-dire uniquement avec mon dépôt local (et les autres zones locales bien entendu). Je ne suis pas contraint de créer un dépôt distant et de me synchroniser. En pratique on choisira néanmoins de passer par un dépôt distant « central » pour travailler en équipe ou simplement garantir la réplication de notre historique ailleurs que sur notre machine.\nFini le Single Point of Failure (SPF)\nChaque poste qui se synchronise avec le dépôt distant contient l’historique parcouru et enrichi localement. Grâce à ça, si notre dépôt central devait faire « Pouf c’est tout ! », on pourrait reconstruire l’intégralité de l’historique du projet en prenant les historiques combinés des dépôts locaux : de quoi en tranquiliser plus d’un·e.\n\nComment fonctionnent les synchronisations ?\nGit ne réalise aucune opération en sous-marin pour que notre dépôt local soit synchronisé avec le distant (et inversement). Il s’agit d’opérations que nous devons effectuer manuellement :\n\nl’envoi / le partage du local vers le distant (push) ;\nla récupération des nouveautés distantes vers le local (pull / fetch).\n\nOn gagne ainsi en performances car la connexion réseau n’est sollicitée qu’au moment de ces opérations. Le reste des opérations sont locales et ne dépendent donc que de la performance de notre machine.\n\nPartage branche par branche\nMême si on a défini un dépôt distant sur un projet, aucun partage n’est pour autant réalisé. Nous devons explicitement dire quelles sont les branches que nous souhaitons partager (généralement en faisant un premier envoi/push depuis la branche concernée, en prenant soin d’activer son suivi par défaut). De ce fait, on peut considérer nos branches locales comme « privées » jusqu’à nouvel ordre.\nDu partage plutôt que de la sauvegarde\nJ’en profite pour te faire une petite recommandation. Je vois bon nombre de personnes utiliser à tort Git comme un système de sauvegarde plutôt que comme un système de gestion de projet et de partage. Ça se manifeste par des synchronisations systématiques généralement inutiles (commit + push) et un historique dégradé (on oublie de considérer la valeur sémantique des commits et de leur message). Sans parler qu’il y a fort à parier que tu as plein d’autres choses à sauvegarder sur ta machine. Tu as alors tout intérêt à utiliser un système dédié à la sauvegarde (exemples : OneDrive pour Windows, Backblaze en multi-plateformes).\nImagine le cumul de perte de temps à l’échelle d’une équipe à force de synchronisations intempestives pouvant entraîner des conflits plus fréquents. Pense donc à partager seulement quand c’est utile, et si tu as peur de perdre tes données si ta machine crashe (chose qui arrive heureusement très rarement de nos jours), contente-toi d’un partage par demi-journée ou par journée.\nPlusieurs dépôts distants ?\nLà encore Git peut surprendre car il ouvre une fois de plus l’étendue des possibles en nous permettant l’emploi de dépôts distants multiples. La seule « contrainte » est que lors de la synchronisation de nos branches locales avec leurs équivalences distantes, nous ne pouvons définir qu’un dépôt distant par défaut (pour faire du git push et git pull sans paramètre de dépôt explicite comme par exemple git pull upstream dev).\nCe détail d’architecture a donné lieu à des workflows tels que le GitHub Flow et sa notion de fork :\n\nOn part d’un projet noyau P sur lequel nous n’avons que les droits en lecture ;\nOn copie/colle (fork) sur le serveur distant ce projet en P’ qui nous appartient (droits en lecture/écriture) ;\nOn travaille localement avec P’ (dépôt distant généralement nommé origin) ;\nQuand le projet noyau à reçu une mise à jour et qu’on souhaite la récupérer dans P’, on configure sur notre machine un dépôt distant vers P en lecture seule (qu’on nommera pour l’exemple upstream).\n\nBilan, notre projet local possède 2 références vers des dépôts distants séparés.\n\n\nGestion des droits\nLa responsabilité des droits et comptes utilisateurs autorisant ou non les synchronisations entre dépôts n’appartient pas à Git. Ce sont les surcouches serveurs (GitHub, GitLab, Bitbucket, etc.) qui gèrent cette fonctionnalité.\n",
		"description": "L’architecture de Git est dite distribuée. Il gère à cet effet une copie locale de l’historique et nous permet de nous synchroniser avec un ou plusieurs dépôts distants.",
		"date": 1656892800,
		"image": "/assets/images/art-vid/art-git-repositories.jpg",
    "_tags": ["git"],
		"title": "Dépôt distant vs. dépôt local",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-depot-distant-et-local/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "Il arrive parfois qu’on ait besoin de nommer un endroit fixe de notre historique. Le cas le plus fréquent sert à renseigner une version logicielle : la suite d’évolutions / commits nous amène de la version 2.0.0 à la version 2.1.0.\nGit nous fournit un mécanisme pour apposer ces libellés : les tags.\nCet article fait partie de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nQuels rôles ?\nComme je l’ai dit précédemment, on utilise généralement les tags pour marquer une version logicielle, mais on peut très bien les utiliser pour d’autres raisons. On peut avoir besoin de marquer temporairement un endroit dans l’historique, ou on peut vouloir conserver une partie d’historique sans pour autant garder la branche associée.\n\nCertaines personnes utilisent les tags comme évènements déclencheurs pour des automatisations, comme un déploiement en environnement de production par exemple. Cette pratique est généralement faite du côté des interfaces des serveurs Git, comme GitHub et GitLab.\nÀ toi donc de choisir le ou les rôles qui te conviendront le mieux.\n2 types de tags\nLes tags peuvent être simples ou annotés. La différence réside dans le fait qu’un tag simple représente une simple étiquette nommée quand le tag annoté renseigne en plus des métadonnées (auteur·e du tag, horodatage, message).\n\nLa documentation officielle recommande l’emploi des tags annotés pour les versions logicielles afin de renseigner en message une description de la version marquée. Personnellement je me contente de tags simples car je préfère décrire les évolutions dans un fichier intégré au projet, généralement appelé release notes ou changelog. D’autant plus qu’il existe des technologies qui nous permettent d’automatiser tout ça.\nQuel format de nom ?\nGit émet les mêmes contraintes pour le nom des tags que pour les autres formats de références comme les branches (voir git help check-ref-format pour plus de détail). On utilisera généralement des libellés alphanumériques, éventuellement contenant des slash / ou des tirets, sans espace.\nPour gérer tes versions logicielles, je te recommande de suivre la convention Semantic Versioning (qui n’est pas propre à Git).\n\nManipulation des tags\nOutre la création des tags, on peut aussi les déplacer, les supprimer, les renommer.\nAttention toutefois aux manipulations des tags partagés. Dès lors que tu partages un tag et qu’une partie de ton équipe le récupèrent, toute modification de ce tag ne sera pas transmise. Git considère qu’il ne doit pas changer un tag dans le dos de l’utilisateur. Tu peux alors choisir entre :\n\nutiliser un autre tag, admettant ainsi que tu as merdé ;\nprévenir tes collègues de ton erreur et leur demander de se synchroniser (suppression du tag localement et récupération explicite).\n\nÀ toi donc de choisir la meilleure solution selon le contexte de ton projet.\nIl y a encore tant à savoir !\nPour ne pas manquer le dernier épisode sur les submodules ni nos prochaines séries et articles, tu peux te tenir informé·e en t’abonnant à notre newsletter, à notre chaîne YouTube, en nous suivant sur Twitter ou encore mieux, en suivant notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Nommer un endroit fixe d’historique, par exemple pour indiquer un numéro de version logiciel.",
		"date": 1657497600,
		"image": "/assets/images/art-vid/art-git-tags.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Les tags : identifier des points d’historique",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-tags/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Bienvenue dans notre quatorzième et dernier article de la série JS idiomatique.\nOn termine en beauté avec un vaste sujet : les ESM, pour ES Modules, c’est-à-dire les modules natifs à ECMAScript, qui constituent aujourd’hui le standard de la modularité en JavaScript, dans Node.js comme dans le navigateur, au moins en termes de syntaxe, mais de plus en plus souvent en termes de sémantique et de chargement.\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nDès ES2015\nLe TC39, le comité à l’ECMA qui standardise ECMAScript (le standard officiel pour “JavaScript”), a senti dès le début des années 2000 (après la version ES3, en 1999) que les usages sans cesse plus complexes de JS nécessitaient un système de modules avancé, intégré directement au langage.\nHélas, les ambitions d’ES4 étaient telles qu’il s’est écroulé sous son propre poids, pour être finalement oblitéré par un ES5 beaucoup plus resserré en 2009, et il aura fallu attendre ES2015 (longtemps appelé “ES6”, mais il a inauguré le passage à des versions annuelles) pour voir apparaître une bonne partie des chantiers entamés au début du millénaire. (D’ailleurs, on trouve aux stades 1 à 3 du processus de standardisation des idées qui ont émergé pour ES4, c’est dire comme le périmètre était foisonnant…)\nConcepts\nQuelques mots importants avant d’entrer dans le détail de la syntaxe et de la sémantique associée.\nLes ESM reprennent la correspondance 1:1 entre fichiers et modules (qu’on trouve dans CommonJS notamment) : dans un contexte ESM, le fichier est le module, et réciproquement, sans avoir à utiliser une déclaration explicite au sein du fichier. Un fichier ne constitue qu’un module, un module n’est constitué que d’un fichier.\nUn ESM constitue une sorte de portée qui lui est propre (son environment record), et tout ce qui y est déclaré (par un des mots-clés déclaratifs : var, function, let, const ou class) est par défaut invisible de l’extérieur.\nLes ESM sont par ailleurs automatiquement en mode strict, dans la mesure où ils constituent un nouveau contexte d’évaluation du code, comme par exemple les corps de classes ES2015. Il est donc impossible d’y déclarer par inadvertance une globale en « oubliant » le mot-clé déclaratif lors de l’initialisation.\nUn ESM déclare des bindings d’import (ses propres dépendances à des modules tiers) et d’export (ce que lui met à disposition des autres modules). Il utilise pour ce faire les deux mots-clés — plutôt explicites — import et export.\nLes imports entraînent, à la première résolution du module importé, son initialisation et, à terme, la mise en cache du module ainsi obtenu, sur base de son chemin résolu (son “chemin canonique”, en quelque sorte). C’est le même principe que pour le require(…) de CommonJS ou le require_once de PHP, par exemple.\nExports\nLes exports sont forcément à la racine lexicale du module (“top-level”), c’est-à-dire qu’ils ne peuvent pas figurer au sein d’un bloc (structure de contrôle ou fonction) ou d’une expression ; par conséquent, ils ne peuvent pas être conditionnels ou dynamiques, ce qui entraîne une propriété fondamentale des ESM : leur structure d’export est statique.\nC’est très pratique pour les analyser statiquement et ouvrir la voie à tout un outillage de type tree-shaking, élimination de code mort (DCE), etc. qu’on va retrouver notamment dans les bundlers pour du code front (Webpack, Rollup et consorts).\nLa seule syntaxe incontournable, celle qui suffirait, est l’export nommé a posteriori :\n\nToutefois, le TC39 avait à cœur de nous fournir des syntaxes de confort pour tout un tas de cas. On trouve donc diverses autres options.\nL’export nommé à la volée, devant le mot-clé déclaratif :\n\nL’export renommé a posteriori, notamment pour se conformer à une exigence d’API exposée (si on est un plugin, par exemple) tout en gardant des noms internes spécifiques, plus explicites :\n\nL’export par défaut, qui est forcément unique au sein du module et peut être a posteriori :\n\n…ou à la volée :\n\nLorsqu’il exporte une déclaration, un export par défaut n’est possible que pour les fonctions et les classes (après tout, une classe ES2015 est une fonction sous le capot), mais pas les constantes (const) et variables (let, var).\nUn export par défaut peut également publier une valeur littérale :\n\nL’export par défaut, un export nommé comme les autres\nContrairement à ce qui se passe en CommonJS (on y reviendra), l’export par défaut reste un export nommé, en l’occurrence nommé default, on a simplement une syntaxe concise qui nous évite de faire un truc du genre :\n\nUn ESM n’a que des exports nommés, contrairement à CommonJS ; c’est d’ailleurs pour ça que lorsqu’une interopérabilité permet à du CJS de charger un module ESM (transpilé ou non), il doit pour récupérer l’export par défaut faire require('./transpiled/esm.js').default au lieu de s’arrêter au require seul, comme il le ferait pour un « export par défaut » CJS (module.exports = …).\nOù placer les exports ?\n",
		"description": "Tout savoir sur les modules natifs à ECMAScript, les \"ES Modules\" ou ESM, apparus avec ES2015 et qui constituent aujourd’hui le standard de la modularité en JavaScript, dans Node.js comme dans les navigateurs.",
		"date": 1658361600,
		"image": "/assets/images/art-vid/art-js-idioms-esm.jpg",
    "_tags": ["js","tutoriel"],
		"title": "Les ESM (modules ES)",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-es-modules/",
		"locale": "fr",
		"readingTime": "12 min"
	},	{
		"content": "Git a été créé initialement pour répondre aux besoins spécifiques en gestion de versions du noyau Linux. Parmi ces besoins on trouve la performance et le besoin de gérer des projet volumineux.\nLes submodules répondent à cela et vont encore plus loin car ils permettent d’assembler différents projets au sein d’un projet conteneur. On peut voir ça à l’inverse comme la capacité de séparer les briques d’un projet monolithique pour permettre leur réemploi par ailleurs (principe du plugin).\nIls apparaissent parfois comme la seule solution disponible avec Git pour traiter ces problématiques. Pourtant il existe des alternatives.\nCet article est le dernier de notre série sur le glossaire Git.\n\nTu préfères une vidéo ?\nSi tu es du genre à préférer regarder que lire pour apprendre, on a pensé à toi :\n\nÀ quoi ça sert exactement ?\nImagine un instant que tu participes à ce projet extrêmement volumineux qu’est le noyau Linux, qui intègre de très nombreuses briques applicatives. Lorsque tu récupères le projet localement ou que tu te synchronises avec, si tu dois récupérer l’ensemble des briques/modules, tes synchronisations vont durer une éternité, et l’occupation d’espace disque va être très conséquente.\nImagine maintenant que tu travailles pour un constructeur d’imprimantes. Si tu dois développer un nouveau pilote pour le noyau linux, tu n’auras probablement aucun intérêt à récupérer tous les pilotes graphiques, les pilotes réseaux et mêmes les pilotes des autres constructeurs d’imprimantes.\nPour optimiser ton travail localement tu préfèreras te synchroniser uniquement avec les modules qui t’intéressent. C’est précisément l’intention des submodules !\nComment est-ce architecturé ?\nLes submodules te permettent de créer un assemblage de différents projets Git au sein d’un projet conteneur. Git va fonctionner un peu comme un système de gestion de dépendances en listant les modules qui sont nécessaires au projet conteneur dans un fichier spécifique, le .gitmodules.\nConfiguration/installation submodules\nLa mise en place initiale est probablement l’étape la plus facile : depuis le projet conteneur, on désigne les sous-projets à ajouter. Ils sont alors initialisés et le code est récupéré. Reste seulement à partager/commiter la configuration qui renseigne les modules disponibles pour le projet (à savoir le fichier .gitmodules).\n\nInitialisation des modules par les autres participants\nLà, ça commence à se compliquer. Une personne participant au projet conteneur récupère celui-ci avec des sous-répertoires vides représentant les différents modules ainsi que le fichier de configuration les décrivant. Elle choisit ensuite les modules avec lesquels elle souhaite travailler localement et demande à Git de récupérer le code depuis chaque dépôt associé.\nOn a donc une décomposition en 2 à 3 étapes :\n\nrécupération des infos du projets conteneur ;\ninitialisation des modules choisis ;\nrécupération du contenu des modules localement (cette étape peut être groupée avec la précédente).\n\n\nCe système apporte beaucoup de souplesse mais requiert une bonne connaissance des submodules par l’ensemble des participants au projet.\nSynchronisation des mises à jour\nLà, ça se complique encore plus. C’est probablement la raison principale qui mène les utilisateurs des submodules à les fuir ou à les détester. Voyons pourquoi :\nChaque sous-répertoire correspond à un projet Git. Le conteneur et les sous-projets ont donc des cycles de vie distincts. Par conséquent lorsqu’on se place à l’intérieur de l’un d’eux on accède à son historique (au lieu de celui du conteneur).\nSi on fait une mise à jour d’un sous-module depuis le projet conteneur, on doit alors effectuer plusieurs étapes pour la partager :\n\nOn se place dans le sous-module, au sein du projet conteneur, pour commiter la mise à jour ;\nOn envoie cette mise à jour vers le dépôt distant du sous-module ;\nOn remonte dans notre projet conteneur, on ajoute la nouvelle référence du sous-module et on commite;\nPour finir, on envoie cette mise à jour de référence vers le dépôt distant du projet conteneur.\n\n\nLorsqu’on récupère des nouveautés depuis le conteneur qui touchent aux submodules, on ne récupère par défaut que le fichier décrivant les modules au sein du projet conteneur (le .gitmodules) à jour. La mise à jour des submodules concernés ne sera pas réalisée. C’est à nous de le faire explicitement, sans quoi nous risquons d’introduire une regression en faisant à nouveau pointer le projet conteneur sur la version précédemment utilisée d’un submodule. On doit donc :\n\nRécupérer la mise à jour de référence dans le projet conteneur (fichier .gitmodules) ;\nRécupérer explicitement la mise à jour du ou des submodules qui nous intéressent.\n\n\nAutre piège courant : lorsqu’on publie une mise à jour d’un sous-module qu’on a modifié depuis le projet conteneur, si on oublie d’envoyer les modifications depuis le sous-projet vers son dépôt distant, on va alors bloquer nos collègues car Git ne sera pas en mesure de récupérer l’historiqu",
		"description": "Assembler de projets Git à la manière d’un système de gestion de dépendances, c’est l’intention des submodules, mais attention aux pièges…",
		"date": 1659916800,
		"image": "/assets/images/art-vid/art-git-glossary-submodules.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Submodules : assemblez vos projets Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-glossary-submodules/",
		"locale": "fr",
		"readingTime": "6 min"
	},	{
		"content": "\nLe diff classique fourni par Git nous donne tout un tas d’informations dont une partie n’est pas essentielle et a tendance à polluer l’affichage dans le terminal. Les points gênants sont principalement l’absence de démarcation claire entre fichiers et les modifications sur une ligne dont la différence est affichée sous forme de deux lignes (suppression/ajout), on peine alors à distinguer les éléments modifiés sur la ligne concernée (rappelle-toi le jeu des 7 différences).\n\nOn a regardé du côté des options de la commande diff et de la configuration, mais rien n’était pleinement satisfaisant. On a alors cherché un outil tiers qui nous facilite la vie dans le terminal, qui soit facile à installer et utiliser. C’est là qu’on a découvert diff-so-fancy.\nL’installation se fait rapidement en une fois sur chaque machine. Différents procédés d’installation sont possibles :\n\nnpm ;\nHomebrew ;\nNix ;\nDépôt communautaire Arch ;\nppa:aos for Debian/Ubuntu Linux ;\nou à défaut en clonant le dépôt Git et en renseignant le script dans le $PATH.\n\nMa méthode préférée — car c’est la plus portable — utilise npm :\n\nUne fois l’installation faite, il faut demander à Git d’utiliser cet outil :\n\nOn peut ensuite personnaliser les couleurs et certains comportements, mais le comportement par défaut est très largement suffisant.\nQuand on a tout ça, voilà le type d’affichage qu’on obtient :\n\nMaintenant, à toi de jouer 😉 !\nNe t’arrête pas là !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Que dirais-tu de voir de manière claire les différences par fichier et par ligne, sans pollution visuelle ?",
		"date": 1661126400,
		"image": "/assets/images/art-vid/art-protip-git-diff-so-fancy.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : un diff sympa et efficace dans le terminal",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-diff-so-fancy/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nLe log, c’est cet outil Git qui nous affiche l’historique des commits. On en a généralement besoin pour :\n\nafficher les derniers commits créés, histoire de savoir où on en est dans notre travail ;\nvisualiser les branches en cours et leurs évolutions respectives.\n\nLe souci, c’est que le log « classique », ça ressemble à ça :\n\nÇa affiche les commits du plus récent (en haut) au plus ancien (en bas), sans indication de branche, avec tout le détail du commit :\n\nidentifiant complet sur 40 caractères,\nmessage complet (potentiellement sur plusieurs lignes),\ndate et nom du responsable du commit,\net des sauts de lignes histoire d’aérer tout ça.\n\nAutant dire que ça n’est pas ultra efficace. Résultat, bien des gens se tournent par dépit vers des interfaces graphiques (on multiplie les outils). Git propose pourtant tout un tas d’options pour personnaliser l’affichage. Je te passe le détail de ces options ici pour m’intéresser à notre alias magique 🧙‍♂️ !\nAvant ça, posons les informations et le format qu’on aimerait avoir pour faciliter notre lecture :\n\nConcision : première ligne du message du commit, qui l’a produit et quand, identifiant abrégé (pour faciliter son ré-emploi avec d’autres commandes) ;\nVisuel : enchaînement graphique clair des commits, visualisation des branches, des tags, de notre position actuelle (HEAD).\n\nOn peut obtenir cet affichage du log avec les options suivantes :\n\nBon, clairement, tu ne voudras pas taper ça à chaque fois, donc autant en faire un alias. Chez Delicious Insights, on l’a nommé lg, facile à taper et proche de log. Pour l’enregistrer tu n’as qu’à copier/coller la ligne qui suit dans ton terminal :\n\nLe rendu est nettement plus agréable et efficace. Les options restent disponibles. On peut ainsi étendre la visualisation aux branches par exemple en faisant un git lg --branches (en prenant le même historique que pour l’exemple en début d’article).\n\n\n  Astuce\n  Pour obtenir systématiquement les identifiants abbrégés on peut renseigner la configuration globale suivante :\n  git config --global log.abbrevCommit true\n\nSi tu veux tout savoir sur le log, regarde cet autre article 👀.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Le log classique Git (pour l’affichage de l’historique des commits) ne répond pas au cas d’usage standard. Plutôt que d’utiliser une interface graphique, utilisons un alias et un log personnalisé.",
		"date": 1661731200,
		"image": "/assets/images/art-vid/art-protip-git-lg.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : un log graphique qui déboîte",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-lg/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nLorsqu’on déplace HEAD ou des têtes de branches (donc lorsqu’on crée des commits, change de branche, fusionne des branches, rebase une branche, annule des commits (reset ou commit --amend)…), Git enregistre la position précédente de HEAD et de la tête de branche active éventuelle. Ces positions sont enregistrées dans les reflogs.\nJ’aime à dire que le reflog est notre parcours réel, alors que le log est le tracé GPS « idéal ». Tu peux aussi voir ça comme le Petit Poucet qui marque son chemin avec des cailloux 🪨🪨🪨.\nGrâce au reflog et à des notations particulières (ce qu’on appelle les syntaxes de révisions), on peut accéder à la position de la branche précédente en appelant @{-1} ou sa version raccourcie -.\nSi je suis sur une branche main et que je souhaite retourner sur la branche dev sur laquelle j’étais juste avant, je peux faire un git switch -. Si je relance cette commande, je retournerai sur la branche main.\n\n\n  Astuce\n  Cette notation trouve son équivalence dans les terminaux shell avec la commande cd - qui permet de revenir au répertoire précédent.\n\nLe truc sympa c’est qu’on est pas cantonné à la commande switch. On peut aussi utiliser cette notation pour d’autres choses comme rebase ou merge :\n\ngit merge - : fusionne la branche précédente dans la branche courante ;\ngit rebase - : rebase la branche courante sur la branche précédente.\ngit cherry-pick - : réplique dans la branche courante le dernier commit (par exemple un bugfix) de la branche précédente.\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Sais-tu qu’on peut facilement accéder à la dernière branche active avec la notation \"-\" ?",
		"date": 1662940800,
		"image": "/assets/images/art-vid/art-protip-git-last-active-branch.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : dernière branche active avec “-”",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-last-active-branch/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nQu’on écrive du code ou de la documentation, on rencontre très souvent le besoin de dupliquer des lignes (généralement pour les modifier) ou de les déplacer (seules ou par bloc).\nOn adore pour ça les raccourcis de VSCode qui nous permettent de faire ça à la vitesse de l’éclair ⚡ !\nDéplacer des lignes\nPour déplacer une ligne, tu places ton curseur dessus, maintiens la touche Alt enfoncée, et déplace avec la flèche du haut ⬆️ ou du bas ⬇️ selon ton besoin.\nTu veux faire pareil avec un bloc de plusieurs lignes ? Il te suffit de sélectionner les lignes voulues avec la souris ou ton curseur en gardant la touche Maj enfoncée ou encore avec le multi-curseur (dont on parlera dans un prochain épisode).\nDupliquer des lignes\nPour dupliquer une ligne, tu places ton curseur dessus, tu maintiens les touches Alt + Maj (shift/majuscule) enfoncées, puis ton appuies sur flèche du haut ⬆️ ou du bas ⬇️ selon si tu veux dupliquer vers au-dessus ou en dessous.\nLà encore ça fonctionne avec plusieurs lignes à la fois ! Ça claque ou pas 😎 ?\nOui mais ces combinaisons ne me plaisent pas !\nBien évidemment tu peux configurer ça et choisir d’autres combinaisons de touches. Perso, je trouve qu’elles sont très bien pensées de base.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre nos formations du feu de dieu 🔥 : Git Total !\n",
		"description": "Découvre ces raccourcis claviers qui te permettent de déplacer et dupliquer rapidement des lignes",
		"date": 1663545600,
		"image": "/assets/images/art-vid/art-vscode-protip-copy-move-lines.jpg",
    "_tags": ["vscode","tutoriel"],
		"title": "VSCode protip : déplacer, dupliquer des lignes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/vscode-protip-copy-move-lines/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "\nAh, les fautes d’inattention, les oublis et autres messages mal rédigés… Toutes ces situations où on a créé un commit pour s’apercevoir dans la foulée qu’on a foiré !\nHeureusement l’option --amend de la commande commit est là pour nous sauver 😮‍💨 !\nConceptuellement, Git fera pour nous un pas en arrière puis un pas en avant. Il va revenir à l’état d’avant validation, donc avec nos fichiers stagés (équivalent de git reset --soft HEAD~1), et revalidera automatiquement avec tous les fichiers stagés (dont les nouveaux, si on avait ajouté au stage avant de lancer le --amend). En gros, il va annuler notre commit et en créer un nouveau à la place, nous permettant des modifications intermédiaires :\n\najout / retrait de fichiers ;\nmise à jour des méta-données (généralement le message de commit).\n\n\nLa commande est simple :\n\nVoyons les cas de figure classiques.\nAjout d’un fichier oublié\nLe cas le plus courant est l’oubli d’un fichier, très souvent non suivi et non ajouté à la volée lors d’un git commit -am '…'.\nLa procédure est alors la suivante :\n\non ajoute le ou les fichiers au stage : git add &lt;les-chemins&gt; ;\non annule et remplace le commit : git commit --amend\n\n\nAstuce\nVoici un alias qui te permet après ajout du fichier au stage de corriger le commit en place :\ngit config --global alias.oops 'commit --amend --no-edit --no-verify'\nL’option --no-edit permet de conserver le message tel quel sans repasser par l’éditeur. L’option --no-verify permet de ne pas relancer le hook de pre-commit ni de commit-msg.\n\nMise à jour du message\nQui n’a jamais fait de faute de frappe ni oublié une référence importante comme un numéro de ticket dans un message de commit ? Personnalement je suis assez champion de ça.\nDans cette situation on va devoir :\n\nvérifier que notre stage est vide (on ne veut pas embarquer des choses dans le commit revisité) ;\nlancer la commande git commit --amend, éventuellement avec le message « à la volée » si on souhaite le réécrire entièrement (git commit --amend -m 'Nouveau message').\n\n\nAstuce\nPourquoi ne pas utiliser un alias dont le nom marquerait plus clairement l’intention de renommage ?\ngit config --global alias.reword 'commit --amend'\n\nTu veux en savoir plus sur la manière dont est construit un commit ? On a un article qui parle de ça !.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Tu as foiré ton dernier commit et tu souhaites le corriger ? La commande \"git commit --amend\" est ton amie !",
		"date": 1664150400,
		"image": "/assets/images/art-vid/art-protip-git-amend.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : réparer le dernier commit avec \"--amend\"",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-amend/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nMettre à jour nos dépendances…\nOn va dire qu’on se soucie de notre dette technique, et donc de ne pas laisser nos dépendances de code tomber en désuetude… Sécurité, performances, nouvelles fonctionnalités : les raisons de les tenir à jour sont nombreuses. Il est donc bon de budgeter un peu de temps à intervalle régulier pour auditer le “retard” de nos dépendances installées afin de les tenir à jour.\nLe souci avec npm outdated et npm update\nDe base, npm propose une commande outdated, qui va nous lister, pour toutes nos dépendances présentes dans le package.json, celles qui ont une mise à jour possible. On y trouvera la version actuellement installée, celle qu’on peut vouloir installer en respectant la contrainte de version sémantique en place, et la dernière version actuellement disponible sur le référentiel (qui peut être sur une majeure ultérieure).\nIl est généralement conseillé d’ajouter l’option --long pour distinguer entre dépendances de production et de développement, ainsi qu’avoir les URLs des projets pour pouvoir explorer leurs historiques.\n\nLes modules qui peuvent bénéficier d’une mise à jour tout en respectant leur contrainte actuelle de version sémantique (c’est-à-dire qu’une nouvelle version existe sur la même majeure que l’actuelle) sont listés en rouge (car il est très souhaitable de mettre à jour, et ça ne comporte normalement aucun risque).\nCeux qui sont “à jour de leur majeure” mais disposent d’une nouvelle version majeure sont listés en jaune (il reste souhaitable de les mettre à jour, mais c’est peut-être incompatible avec nos contraintes d’environnement). Il est alors fortement conseillé d’aller voir le lien associé, d’y chercher le Changelog (généralement présent dans un fichier CHANGELOG.md ou au sein de la page Releases de GitHub) pour vérifier si on peut y aller, s’il faut juste mettre à jour quelques points dans notre code, ou si c’est encore trop tôt pour nous.\nYarn et pnpm proposent la même commande, avec un affichage quasi identique.\nJusqu’ici ça va, mais ça ne nous permet pas de faire la mise à jour. On a donc une autre commande, npm update, qui s’occupe de ça.\nMAIS !\nAppelée sans rien, elle va mettre à jour tous les modules “rouges” vers la dernière version. On ne souhaite pas forcément ça, on peut vouloir y aller granulairement. Il faut alors passer en arguments chaque module voulu, avec la nouvelle version voulue, ce qui est hyper fastidieux. Par ailleurs, par défaut, elle ne retranscrira pas ces nouvelles versions comme “exigence minimum” dans notre package.json, ce qui est un peu dommage : il faut préciser --save.\nEnfin, elle ne permet pas de mettre à jour automatiquement les modules “jaunes”, qui changent de majeure. Il faut les spécifier individuellement en arguments. J’aurais alors plutôt tendance à utiliser npm install.\nBref, pas top en termes d’ergonomie.\nMais voici npm-check ! 🥳\nC’est une petite commande tierce-partie qui va (si j’active son mode “update”):\n\nAnalyser les mises à jour possibles\nLes regrouper par niveau de mise à jour (patch, mineure, majeure, non-semver c’est-à-dire inférieure à 1.0.0)\nFournir une interface interactive pour sélectionner les mises à jour voulues\nExécuter une commande globale de mise à jour par type de dépendance (production, développement, pairs, etc.)\nMettre à jour les exigences minimum de version dans le package.json\n\nOn peut l’installer en global, mais j’ai tendance à faire une installation temporaire à la volée avec npx :\n\n\nNote qu’il existe un autre outil tiers assez connu, npm-check-updates, mais je trouve son ergonomie nettement moins agréable.\nÀ propos de Yarn et pnpm…\nLes deux proposent la même commande outdated, mais proposent aussi de base une version interactive de leur mise à jour, dont l’interface est quasi identique à celle de npm-check :\n\nyarn upgrade-interactive --latest (il faut toutefois avoir installé le plugin Yarn interactive-tools)\npnpm update --interactive --latest\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Mets facilement à jour tes dépendances avec npm-check ! Tellement plus agréable que outdated + update…",
		"date": 1664323200,
		"image": "/assets/images/art-vid/art-js-protip-npm-check.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : npm-check",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-npm-check/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nSi comme moi tu utilises Git essentiellement dans le terminal, alors tu utilises très souvent la commande git status. Ce qui me gêne dans l’affichage proposé par défaut, c’est que le choix des couleurs est identique pour les fichiers modifiés, les fichiers créés et les fichiers conflictuels. De base on trouve une différence entre les fichiers indexés/stagés en vert, et les fichiers non indexés en rouge (qu’ils soient modifiés ou non suivis).\n\nC’est là qu’intervient ma configuration personnalisée. Je précise la couleur du texte et du fond selon le statut des fichiers. J’ai opté pour :\n\nNoir sur fond jaune pour les fichiers non suivis (notamment ceux fraîchement créés) ;\nMagenta pour les fichiers ayant des conflits.\n\nJe pousse même avec une mise en forme italique pour les fichiers en conflit.\n\n\nCouleurs et mises en forme\nLes mises en formes peuvent être cumulées (mais n’en abuse pas trop non plus). Leur ordre n’a pas d’importance. Les valeurs possibles sont :\n\nbold pour mettre en gras ;\ndim pour atténuer la couleur du texte (pas celle du fond) ;\nul pour souligner le texte ;\nblink pour faire clignoter le texte (je déconseille) ;\nreverse pour inverser les couleurs ;\nitalic pour mettre en italique ;\nstrike pour barrer le texte.\n\nPour les couleurs on peut choisir de ne renseigner qu’une couleur — auquel cas ça changera uniquement la couleur du texte — ou préciser deux valeurs, la première pour le texte, la seconde pour le fond. Les valeurs possibles sont nombreuses, certains formats dépendent de ce que ton terminal prend en charge :\n\nles valeurs « classiques », textuelles sont normal, black, red, green, yellow, blue, magenta, cyan, white et default ;\nune valeur numérique entre 0 et 255 (si le terminal supporte le mode ANSI 256) ;\nune valeur hexadécimale, comme #ff0ab3 (là aussi si le terminal supporte les valeurs RGB 24 bits).\n\n\n  normal ou default ?\n  La valeur normal permet de reprendre la valeur déjà renseignée par une autre configuration quand la valeur default réinitialise à la valeur par défaut du terminal.\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "\"git status\" est probablement la commande qu’on utilise le plus dans le terminal. Mais sais-tu qu’on peut choisir la couleur de certains affichages ?",
		"date": 1664755200,
		"image": "/assets/images/art-vid/art-protip-git-colored-status.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : personnaliser la couleur des statuts",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-colored-status/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nPar pitié 🙏, ne me dis pas que tu utilises git blame ! Cette commande, outre l’intention que souligne son nom, ne t’apportera pas l’information utile attendue, pire, elle risque de t’amener sur des faux-positifs et tu risques alors d’aller chahuter un·e collègue à tort (ce qui est doublement mal 😡).\nConcrètement qu’apporte cette commande ? Elle te fournit l’aperçu du fichier analysé dans sa version actuelle en te mettant en parallèle pour chaque ligne le dernier commit associé et son auteur·e, sans information sur la modification réalisée !\nÇa veut dire que, là où tu penses que ton ou ta collègue a introduit une erreur, cette personne n’a peut-être en réalité que retiré un espace en fin de ligne, ou réindenté.\nCe qui nous ramène à la bonne méthode : l’analyse par le log des évolutions, soit par le log -L vu ici, soit par des options comme -S ou -G dont tu trouveras le détail dans cet autre article.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Si tu utilises \"git blame\" et que tu crois que c’est une bonne idée, tu te trompes !",
		"date": 1665360000,
		"image": "/assets/images/art-vid/art-protip-git-blame.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : blame, oui mais non !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-blame/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "\nN’as-tu jamais souhaité lister seulement les évolutions au sein d’une fonction ? Ça serait génial, on pourrait alors mieux déterminer l’origine d’un bug ou avoir une vision fine du travail réalisé au fil de l’eau.\nPeut-être savais-tu déjà que tu peux obtenir la liste des commits qui modifient un fichier donné :\n\n\nJe te présente sa version évoluée avec l’option -L !\n\n\nCette option a la particularité de ne permettre l’analyse que d’un fichier à la fois, mais surtout, d’une portion choisie, ici à l’aide du nom de la méthode/fonction recherchée. On obtient alors le détail, commit après commit, des évolutions de ce bloc (et rien d’autre, ni dans ce fichier, ni ailleurs).\nEn réalité, ça ne fonctionnera pas toujours parfaitement et il est possible dans certains cas de figures que tu aies plus que ta fonction (en gros, ça peut déborder par le bas).\nJe te recommande alors de passer plutôt par cette autre syntaxe d’appel, surtout si tu as le fichier sous les yeux pour obtenir rapidement les numéros de lignes de début et de fin de la fonction.\n\nElle identifie la portion actuellement entre ces lignes, et ajuste l’intervalle associé pour chaque commit historique analysé, en fonction des changements pertinents. L’avantage, qu’écris-je, la puissance de cette syntaxe est qu’elle fonctionne avec n’importe quoi, tu n’es pas cantonné·e à la seule analyse de fonctions/de méthodes 🌈🦄 !\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Analyser les évolutions d’un bloc de code, déterminer l’introduction d’une erreur, d’un bug : “git log -L” vient te sauver 🦸‍♀️",
		"date": 1665360000,
		"image": "/assets/images/art-vid/art-protip-git-log-l.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : suivre les évolutions d’une fonction avec log -L",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-log-function/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nCombien de fois as-tu oublié d’ajouter un fichier pour découvrir ton erreur plus tard, après quelques commits ?\nPerso, je suis un fervent défenseur des commits atomiques qui sont, je pense, une des clés de la qualité et de l’automatisation des projets (regarde par exemple Conventional Commit et Semantic Release). Du coup, je fais de mon mieux pour corriger ces commits en utilisant le rebase interactif, et je ne peux que t’encourager à faire de même (et si tu as peur du rebase, c’est que tu n’as pas suivi notre formation Git Total 😁) !\nMon objectif est de te permettre de faire ça le plus rapidement possible, que ça devienne un reflexe !\nTu connais peut-être déjà l’option git commit --fixup (ou --squash) qui crée un commit dont l’intitulé signale qu’il corrige un autre commit ? Grâce à ça, si tu lances un rebase interactif, il viendra automatiquement placer l’application du commit en fixup sous la ligne du commit à corriger 😎 !\nLa procédure complète\nTu ajoutes tes fichiers oubliés au stage.\nTu fais un git commit --fixup=&lt;ref-du-commit-à-corriger&gt;.\nTu lances ton rebase interactif en partant du commit précédent celui à corriger : git rebase --autosquash -i -r &lt;ref-du-commit-à-corriger&gt;~1.\nTon éditeur s’ouvre, te propose la liste des actions à réaliser avec le fixup au bon endroit. Tu n’as plus qu’à enregistrer et fermer ce fichier, et le tour est joué ! Pense à vérifier ton log pour être sûr que tout est bon, éventuellement en faisant un git show --name-only &lt;ref-du-nouveau-commit&gt; pour vérifier la liste des fichiers impactés par le commit corrigé.\n\nComme ça m’arrive de temps en temps, je me suis fait un alias “magique” 🧙‍♂️ qui consiste à appeler ces deux commandes en une fois (pour corriger un seul commit) :\n\nEt voilà !\n\n  Une config aux petits oignons\n  Il y a plus d’un alias utile parmi les nombreux éléments de configuration possibles. Tu peux t’inspirer de la nôtre pour en apprendre d’avantage.\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Que dirais-tu d’un alias qui te permette d’ajouter rapidement des fichiers à un commit précédent ?",
		"date": 1665964800,
		"image": "/assets/images/art-vid/art-protip-git-autofixup.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : ajouter en un clin d’œil des modifs oubliées à un vieux commit",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-autofixup/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nTout comme il m’arrive d’oublier des fichiers dans un commit, il m’arrive également de mal rédiger des messages de commit et de m’en apercevoir plus tard (avec quelques commits effectués entre temps). Ce que j’oublie probablement le plus souvent, c’est lier le ticket traité par le commit.\nPLUS tard, pas TROP tard !\nNe me dis pas que tu penses « Tant pis, j’irai dans l’interface le renseigner à la main ! » ou que tu laisses tomber ! C’est peut-être parce que tu ne connais pas le rebase interactif, ou que tu en as peur 😨. Franchement, tu ne devrais pas, avec un peu d’apprentissage cette commande s’avère être une alliée plus que précieuse !\nMis à part cette histoire de rebase, sais-tu qu’on a la possibilité de créer un commit qui exprime cette intention de changer le message ? Je parie que non ! Heureusement, je suis là 😁. Je te présente la commande git commit --fixup reword:&lt;ref-du-commit-à-corriger&gt;. Alors oui, cette syntaxe n’est pas facile à retenir. Mais on s’en moque, on va se faire un bel alias aux airs d’incantation magique 🔮. Introducing autoreword :\n\nQue va-t-il se passer si tu lances cette commande ?\n🌀 Un vortex maléfique s’ouvrira, libérant les flammes de l’enfer qui réduiront ce monde en cendres 🔥 !! (En fait non, pas besoin de magie pour ça 😭)\nPlus sérieusement, Git va ouvrir ton éditeur avec un message démarrant par amend! … suivi de la première ligne du message du commit à corriger, puis un saut de ligne et à nouveau le message du commit à corriger (complet cette fois, donc potentiellement sur plusieurs lignes).\n\nTu peux alors changer tout le message, sauf la première ligne.\n\nReste à enregistrer puis fermer.\nGit finalise alors la création du commit signalant la correction, puis notre alias lance automatiquement le rebase interactif en partant du commit précédent le commit à corriger. Et comme on a précisé juste avant dans l’alias GIT_EDITOR=true, il n’ouvre pas l’éditeur et auto-valide le rebase interactif.\nLà on est carrément dans de la magie noire ! Soyons donc un peu curieux et regardons ce qu’il effectue si on retire ce GIT_EDITOR=true de l’alias : il ouvre à nouveau ton éditeur avec la liste des actions qu’il s’apprête à mener. Et là, surprise : ton commit signalant la correction est automatiquement placé sous le commit à corriger avec le préfixe fixup -C.\n\nTu n’aurais rien d’autre à faire qu’à vérifier, enregistrer et fermer le fichier. Ton rebase entre ensuite en action (sans conflit).\nDans tous les cas tu vérifieras ton log pour voir que tout est bon !\nSi tu vois dans le fichier décrivant les actions du rebase les clés label onto et reset onto c’est normal, c’est lié à l’option --rebase-merges qui garantit la préservation de tes fusions locales lors du rebase. Tu n’as pas à t’en préoccuper 😌.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Que dirais-tu d’un alias qui te permette de modifier rapidement le message d’un commit précédent ?",
		"date": 1665964800,
		"image": "/assets/images/art-vid/art-protip-git-autoreword.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : renommer un vieux commit",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-autoreword/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nIl est très fréquent qu’on aie besoin d’aller récupérer un ou plusieurs éléments à la fin d’un tableau ou d’une String. Historiquement, c’était un peu la lose, mais les choses ont changé !\nÀ l’ancienne…\nCommençons par les recettes de grand-mère. Mais pour le coup, ce n’est pas forcément dans les vieux pots qu’on fait les meilleures soupes !\nTu le sais peut-être, les méthodes slice() (sur Array et String) et splice() (sur Array) autorisent les indices négatifs : ils se comportent comme s’ils étaient préfixés par length, de sorte que −1 désigne le dernier élément, −2 l’avant-dernier, etc. :\n\nHélas ! Outre que Array#slice() enverra un tableau (alors qu’on veut souvent un seul élément), ce qui nous obligerait à faire un items.slice(-1)[0] un peu gore, ça ne fonctionnera de toutes façons pas pour l’opérateur d’indexation indirecte, [], qu’on utilise le plus souvent pour aller chercher un élément dans un tableau (voire une String) :\n\nLa raison est simple : la sémantique de [] n’a rien à voir avec des positions. Cet opérateur prend un nom de propriété, et soit la propriété est là (et on récupère sa valeur), soit elle ne l’est pas (et on récupère undefined).\nC’est pourquoi on en était réduit à cette sempiternelle saleté :\n\nPas glop™.\nDes indices négatifs avec un enrobage proxy ?\nDepuis ES2015, nous avons les proxies ES (voir mon talk en anglais à Fronteers 2019 ou la doc MDN en français, en attendant mon talk en français à BDX I/O 2022).\nSi nous pouvons accéder à un objet enrobé par le proxy idoine, on a tout-à-coup la possibilité d’utiliser une indexation négative ! À toi de voir si ça te botte lorsque tu renvoies des tableaux par exemple, pour autoriser ce type d’accès au code qui t’appelle.\n\nVoyons ce que ça donne :\n\nat() sur les itérables de la bibiothèque standard\nBon, on n’a pas toujours le luxe, ou simplement l’envie, d’enrober nos tableaux avec un proxy sur-mesure. Alors on fait quoi ?\nEh bien, depuis ES2022, nous disposons de la méthode at(index) sur tous les itérables positionnels définis par la bibliothèque standard : Array, tableaux typés et String.\n\nfindLast() et findLastIndex()\nES2023 va officialiser deux nouvelles méthodes utilitaires sur Array et les tableaux typés, qui facilitent la recherche depuis la fin du tableau, plutôt que depuis le début.\nAprès tout, on avait bien lastIndexOf() et reduceRight() depuis ES5, mais ES2015 n’avait pas fourni de versions « depuis la fin » de ses ajouts find() et findIndex(). Il était donc temps, parce qu’autrement on en était réduit à faire des boucles à la main 🤮 ou à faire un reverse() coûteux (et mutatif) en premier lieu !\n\nfindLast() et findLastIndex() ne seront certes officiels qu’en juin 2023, mais sont déjà pris en charge nativement partout (Safari 15.4, Firefox 104, Chrome/Edge 97, Node 18, Deno 1.24), et pour le reste, c’est polyfillable trivialement avec core-js (via Babel / TS ou non).\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Découvre les multiples façons, certaines toutes récentes, d’aller chercher facilement sur la fin d’un tableau en JavaScript.",
		"date": 1666137600,
		"image": "/assets/images/art-vid/art-js-protip-last-items.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Récupérer les derniers éléments d’un tableau",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-last-items/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nAh, les joies du formatage de dates (et d’heures)… Bien sûr, on peut faire un format unique, numérique, et dire qu’on a fini. Ça peut passer (surtout pour des formats techniques), mais ce n’est pas idéal, et même franchement pas propre lorsqu’on s’adresse à des humains, avec leurs cultures et les usages de formatage de celles-ci.\nAprès tout, si un site américain t’affiche 08/12/2022, s’agit-il du 12 août ou du 8 décembre ? Sans savoir quelle approche il retient pour la prise en compte de ta locale, on n’a aucune certitude !\nVoyons ensemble quelles options on a pour faire ça bien sans surcharger le JS de notre appli.\n\nLes méthodes historiques de Date\nAu commencement était la méthode toString() de Date. Celle-ci nous sort un format américain abrégé de la date, de l’heure et du fuseau horaire, pour le fuseau local par défaut. La forme n’est pas sans rappeler celle des champs d’horodatage des protocoles Internet, tels que définis en dernier lieu par la RFC 5322 :\n\nRemarque comme le nom du fuseau horaire (timezone) est, lui, localisé selon tes préférences navigateur, alors que le reste utilise en dur les abréviations anglaises. #CaptainConsistency\nCe format est en fait la concaténation, entre autres, des méthodes toDateString() et toTimeString(), qui sont là pratiquement depuis le début aussi, au même titre que toGMTString(), qui a été dépréciée au profit de toUTCString() (l’UTC ayant remplacé le GMT depuis bien longtemps). ES5 a aussi rajouté le très utile toISOString(), qui suit le standard ISO8601, utilisé par exemple dans JSON et tout plein de standards comme mécanisme de sérialisation par défaut des dates/heures :\n\nEt oui, toUTCString() utilise un code de fuseau… GMT 🤦🏻 soupir Bref, tout ça ne vaut pas grand chose quand on affiche des horodatages à destination des humains.\nOn utilise des bibliothèques alors ?\nHistoriquement, pour pouvoir formater intelligemment des dates et heures, on avait recours à des bibliothèques tierces.\nLa plus célèbre dans ce domaine, encore très utilisée même si ça fait des années que son équipe nous encourage à utiliser autre chose, est Moment.js. C’est une super manière d’embarquer 300Ko minifiés de JS dans nos bundles pour rien (et même si tu configures ton bundler pour n’inclure que les locales qui t’intéressent, tu en as pour 70Ko minimum).\nDepuis quelques années, Luxon (successeur officiel de Moment) et date-fns ont pris le relais, même si leur cœur de métier n’est pas tant le formatage que les manipulations (distances, avancement / recul, etc.). Ces deux dernières sont d’ailleurs entièrement basées sur l’API Intl (standard ECMA-402), qui fait partie de la bibliothèque standard de JavaScript.\nDu coup, la valeur ajoutée de ces bibliothèques, pour les cas qui nous occupent, est à peu près nulle.\nIntl.DateTimeFormat\nVoilà des années que nous disposons de l’API Intl (standardisée par le même comité qui s’occupe de JavaScript et JSON), dont la raison d’être consiste à nous donner un accès JavaScript le plus complet possible aux formatages usuels de données, pour tous les locales standardisés.\nDates et heures, montants numériques, listes, pluralisation, collation / tri… Chaque locale a ses conventions, habitudes, usages… Et tout ça est activement maintenu au sein du Common Locale Data Repository, ou CLDR, qui fait lui-même partie d’un projet plus vaste appelé les International Components for Unicode (ICU).\nTu t’en doutes, tout ça fait un gros paquet de données, présent dans chaque OS au travers d’une ou plusieurs bibliothèques système. Sur Ubuntu par exemple, la libicu66 totalise plus de 30Mo de données. C’est à peu près le même volume sur les autres OS, mais on n’a évidemment pas envie de trimballer tout ça dans notre JavaScript.\nL’API Intl nous offre un accès direct à la plupart des infos de la CLDR de notre OS d’exécution, ce qui est trop cool 😀\nPour ce qui est des dates et heures, on a deux classes, la plus connue étant Intl.DateTimeFormat. Le constructeur a la signature suivante :\n\nOn peut lui préciser un ou plusieurs locales souhaités, par ordre décroissant de priorité. Il s’agit de chaînes BCP47 plus ou moins raffinées (allant du simple code de langue générique, comme 'fr', pour le français en général au code détaillé de variante type de-DE-u-co-phonebk, qui est la variante annuaire de l’ordre de tri allemand). Je te conseille de toujours préciser la déclinaison pays (ex. fr-FR pour le français de France), mais au-delà c’est rarement pertinent.\nLe système utilisera le premier locale qu’il est à même de prendre en charge vu sa base CLDR sous-jacente.\nOn peut aussi ajouter à l’info de locales des options, et là y’en a beaucoup. On ne va pas toutes les couvrir, en particulier nous allons ignorer celles qui permettent de choisir explicitement les segments d’information (jour de la semaine, jour du mois, mois, année, heures, minutes, secondes, etc.) ou d’altérer les comportements par défaut du locale (cycles horaires, etc.).\nCependant, nous allons nous intéresser ici à des op",
		"description": "Découvre comment formater en JavaScript des dates et heures nickel, au cordeau, quelle que soit la langue, et sans aucune bibliothèque !",
		"date": 1666742400,
		"image": "/assets/images/art-vid/art-js-protip-date-formatting.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Formatter une date/heure selon les usages locaux",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-formater-dates/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "\nHier, nous parlions du formatage de dates et d’heures, aujourd’hui nous allons voir comment formater des intervalles de dates et d’heures de façon élégante !\nformatRange(), la classe mondiale\nPeu de gens ont remarqué que DateTimeFormat s’est doté un peu plus tard d’une gestion des intervalles, extrêmement utile pour formater des réunions, évènements, etc. qui ont un horodatage de début et de fin.\nJ’ai moi-même eu à implémenter ce genre de trucs (en Ruby par exemple) et pour que ce soit joli, c’est la plaie : suivant qu’on est sur le même jour, ou le même mois, ou la même année, etc. on ne veut pas forcément répéter la totale pour le début et la fin. Sans parler des formats courts (à base de tiret semi-cadratin par exemple en français) et longs (« du… au… » ou « de… à… », par exemple). C’est vite l’enfer !\nMais plus maintenant :\n\nRemarque notamment la forte variation de format côté allemand, selon que les heures sont dans la même journée ou pas. Franchement c’est trop fort, ça me fait des papillons dans le ventre 🤩\nEnvie d’aller plus loin ?\nTu as de la veine, outre le protip d’hier sur le formatage de dates et d’heures, on en a un troisième demain sur les distances temporelles !\nC’est dispo où ?\nBin écoute, partout. Si on prend tout ce que je t’ai montré ici, tu es tranquille sur tout navigateur qui a, disons, moins de 3 ans, ainsi que depuis Node 13 et Deno 1.8. Donc vas-y !\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Découvre comment formater en JavaScript des intervalles temporels nickel, au cordeau, quelle que soit la langue, et sans aucune bibliothèque !",
		"date": 1666828800,
		"image": "/assets/images/art-vid/art-js-protip-date-ranges.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Formatter un intervalle de dates",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-intervalles-dates/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nAprès le protip d’avant-hier sur le formatage de dates et d’heures et celui d’hier sur le formatage d’intervalles temporels, nous bouclons le trio aujourd’hui en formatant des distances temporelles !\nIntl.RelativeTimeFormat\nMoins connu que DateTimeFormat, RelativeTimeFormat est là depuis un bon moment aussi pour exprimer des moments relativement à maintenant, donc sous forme de distance temporelle dans le passé ou l’avenir.\nHélas, ça ne prend pas comme argument un horodatage (ou deux), mais une quantité et une unité formelle, ce qui est déjà pas mal.\nLe constructeur accepte le même argument de locales que DateTimeFormat (et toutes les API Intl, en fait), et les options éventuelles sont au nombre de deux :\n\nstyle, qui peut valoir 'long' (valeur par défaut, utilisant l’unité de distance principale en toutes lettres), 'short' (abrège l’unité) et 'narrow' (abrège encore davantage si le locale le permet)\nnumeric, qui peut valoir 'always' (valeur par défaut, qui exprime la distance numériquement quelle qu’elle soit) ou 'auto' (qui retranscrira différemment certaines distances proches, généralement sous forme textuelle).\n\nRegarde un peu :\n\nLa. Classe. 😎\nC’est dispo où ?\nBin écoute, partout. Si on prend tout ce que je t’ai montré ici, tu es tranquille sur tout navigateur qui a, disons, moins de 3 ans, ainsi que depuis Node 13 et Deno 1.8. Donc vas-y !\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Découvre comment formater en JavaScript des distances temporelles nickel, au cordeau, quelle que soit la langue, et sans aucune bibliothèque !",
		"date": 1666915200,
		"image": "/assets/images/art-vid/art-js-protip-relative-dates.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Formatter une distance temporelle",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-distances-temporelles/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "Ce lundi 3 octobre 2022 est sortie la version 2.38 de Git avec deux nouveautés notables, la première étant une nouvelle option de rebase, --update-refs, l’autre étant l’intégration d’un nouvel outil pour faciliter la gestion de dépôts massifs, j’ai nommé Scalar !\nJe te fais un résumé !\n\n\nL’option update-refs : une presque excellente nouvelle\nAvec Christophe, on a cru un instant qu’on avait enfin notre deep rebase 😃. Fausse joie 😞, mais joie quand même car cette nouvelle option satisfera tout de même quelques cas d’usages.\nDéjà, à quoi sert cette nouvelle option ? Elle nous permet de mettre à jour les références des branches qui sont dans l’historique direct de la branche qu’on rebase. Bon, dit comme ça, il y a peu de chance que tu aies compris. Voyons donc tout ça plutôt avec un schéma animé :\n\nOn trouve quand même sympa le fait de pouvoir rebaser des branches par-dessus une autre, même si ça ne marche qu’avec des branches “en ligne droite”. Ça signifie que pour une branche dev qui aurait une sous-branche feature, les 2 ayant divergé (évolué chacune de son côté), si on rebase dev, la branche feature restera à ses état et emplacement actuels.\n\nMême chose si je rebase feature, la branche dev restera où elle est :\n\nOn continue d’espérer le rebase des branches en profondeur un de ces jours.\nScalar : comme un aboutissement pour la performance\nMicrosoft fournit là une contribution très importante pour la gestion des dépôts massifs avec l’introduction dans la distribution de Git d’un utilitaire, surcouche à Git qui s’appuie sur les évolutions déjà intégrées comme l’amélioration de la maintenance, le sparse-checkout ou encore les commit graphs.\nL’intention est donc d’améliorer la performance pour les contributeurs·rices mais aussi de faciliter la maintenance de ces dépôts.\nHistoire de bien beta-tester le bousin, ils ont pris un projet à peine sensible : Office 365 !\nPour la petite histoire, ça fait un petit moment qu’il bossent sur le sujet de la perf pour répondre aux contraintes de leurs projets. Scalar était d’ailleurs initialement codé en .NET Core.\nJe passe mon tour pour une démo ici, ça mérite un article qu’on produira peut-être plus tard.\nTout savoir sur Git 2.38\nIl y a toujours plus à dire sur une nouvelle version. Aussi n’hésite pas à consulter directement l’article GitHub résumant tout ça, ou, si tu es courageux·se, va regarder les les notes de versions.\nNe manque pas les prochaines nouveautés !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Git 2.38 est sortie ce lundi 3 octobre avec deux nouveautés remarquables",
		"date": 1667174400,
		"image": "/assets/images/art-vid/art-git-2.38.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Quoi de neuf dans Git 2.38 ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-2-38/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nTu fais peut-être partie de celles et ceux qui aiment n’avoir que le contenu qu’ils éditent à l’écran, que ça soit parce que ton écran est assez petit ou pour éviter le parasitage graphique de la nav latérale. Sauf que c’est franchement pénible de passer par le menu pour afficher / masquer cette barre latérale, tu utilises alors le raccourci fourni de base par VSCode, le fameux Ctrl+B.\nEt puis un jour tu dois bosser sur un fichier Markdown et là, c’est le drame (enfin pas vraiment) : ton Ctrl+B met le texte sélectionné en emphase / gras, tu ne peux plus masquer ton menu facilement, tu es triste 😭 !\nEn tout cas, nous, ça nous a gênés ! On a donc opté pour une astuce extraordinaire, à laquelle seulement quelques personnes dans l’univers on probablement pensé : on a redéfini l’alias ! (truc de ouf malade 😲)\nPour ne pas nous éloigner de notre habitude, on est parti sur un Ctrl+Shift+B. Pour ça, on a ouvert nos raccourcis claviers VSCode (Ctrl+K Ctrl+S) et on a cherché dans la liste « bascule latérale » (ou si tu es en anglais, cherche par le raccourci ctrl+b, tu trouveras la commande idoine parmi les résultats proposés). On peut alors ajouter un raccourci complémentaire pour la commande, soit en cliquant bouton droit et en choisissant Ajouter une combinaison de touches, soit en sélectionnant la ligne et en tapant Ctrl+K Ctrl+A. Une fois le champ de saisie ouvert, on presse le raccourci voulu (ex. Ctrl+Shift+B), on valide, et on est de nouveau maître de la barre latérale 💪 !\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre nos formations du feu de dieu 🔥 : Git Total !\n",
		"description": "Masque / affiche la barre latérale dans VSCode comme un·e pro",
		"date": 1668988800,
		"image": "/assets/images/art-vid/art-vscode-sidebar-toggle.jpg",
    "_tags": ["vscode","tutoriel"],
		"title": "VSCode protip : basculer la sidebar même depuis du Markdown",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/vscode-protip-toggle-sidebar/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nAh, les branches dans Git… Combien de fois ai-je vu des branches « traîner » chez mes clients, jamais supprimées car simplement mal analysées… Et cette « astuce » plus que douteuse qui consiste, quand le nom de la branche qu’on souhaite créer existe déjà, à ajouter un suffixe numérique 🤦.\nIl est donc temps de faire les choses bien ! En plus, ça ne demande pas franchement beaucoup d’efforts. Il faut surtout savoir déterminer les branches existantes, leur rapport éventuel avec une branche distante (tracking), et leur état vis-à-vis de cette dernière (nouveaux commits locaux ou distants, branche distante supprimée).\nVoici la commande tant attendue, tellement attendue que tu en as marre de lire mes phrases à rallonge qui tardent dans la transmission de cette information essentielle, que dis-je quasi vitale à ton existence aujourd’hui malheureuse mais très bientôt heureuse d’utilisateur·rice Git… Le suspense est à son comble, la voici… La voilà… Tu trépignes d’impatience (je le sais), mais ne doute pas de mon souhait profond de te fournir la raison même pour laquelle tu lis en ce moment ces lignes, car si tu n’étais pas là pour ça, tu serais très certainement incapable de lire ce paragraphe qui n’en finit plus, résultat d’un craquage immense en cette fin de semaine pluvieuse de novembre 2022, année riche en articles et protips comme tu l’as peut-être déjà constaté :\n\nTant qu’à partir dans des délires psychédéliques, j’en profite pour te donner le moyen mnémotechnique ultime pour retenir ce combo d’options : « AVV Jules César ».\nConcrètement, ça donne quoi ?\nÇa t’affiche les branches locales, les branches distantes (ça c’est l’option -a), l’information du dernier commit désigné par la branche (identifiant / SHA-1 et première ligne du message, ça c’est l’option -v) et enfin, le rapport entre nos branches locales et les branches distantes (l’autre option -v). Vois ce que ça donne :\n\n\nNote les indications après le nom des branches distantes associées aux branches locales : on observe les infos gone, behind X et ahead X. Respectivement cela signifie que la branche distante a été supprimé sur le serveur (gone), que la branche locale n’a pas appliqué/récupéré X commits (behind) ou qu’au contraire elle a avancé de X nouveaux commits qui ne sont pas encore partagés/pushés (ahead). On peut trouver des situations de désynchronisation dans les 2 sens en même temps lorsqu’on a travaillé sur une branche localement et qu’on récupère les infos de la branche distante (git fetch) après qu’un·e collègue ait bossé dessus et pushé.\nAvec ça, plus d’excuse pour ne pas effectuer un suivi précis de tes branches, et le cas échéant un peu de nettoyage 😉!\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Découvre ce combo d’options pour lister de manière optimale tes branches dans le terminal",
		"date": 1669593600,
		"image": "/assets/images/art-vid/art-git-branch-avv.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : lister efficacement les branches",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-branch-avv/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nUtiliser Git dans le terminal sans avoir une invite de commande / un prompt adaptés, c’est un peu comme mettre des chaussettes avec des tongues en hiver, c’est moche et c’est sous-optimal !\nLe souci avec les terminaux, c’est qu’il en existe plein ! Comment alors trouver une solution adaptée à chacun ? On avait écrit il y a un bail un article décrivant comment configurer un prompt Git à la mano. Cette méthode est toujours efficace et offre le bénéfice du minimalisme. Par contre pour le design, c’est pas ouf !\n\nIl y a quelques temps nous étions passés à Powerline, plus sympa, (un peu) portable, et qui propose quelques infos liées à quelques technos (Git, Python, Ruby). Par contre il pour le configurer on pouvait se brosser.\n\nEt puis Oh My Posh est apparu dans nos radars ! Bien plus évoluée, plus facile à installer et à configurer, traitant d’un très large spectre de technos (voir la partie “Segments” de la doc).\n\nOn est donc vite tombé sous le charme 😍. À certains égards on peut trouver cette invite de commande trop verbeuse, mais puisqu’on peut la configurer aisément, ça devient vite facile d’en faire une version “light”.\nPour ce qui est de l’installation et de la configuration, je te renvoie directement à sa documentation qui est très bien faite !\nExemple : le mode concis\nJe prends ici l’exemple de mon terminal Linux (sous-système sur Windows / WSL2) auquel je passe la configuration au chargement de Oh My Posh dans mon fichier racine .bashrc :\n\nLe thème se contente de lister le répertoire courant et les statuts Git :\n\nEn définitive on ne gagne pas beaucoup d’espace, on supprime seulement les compléments d’analyse des technos détectées dans le répertoire du projet courant.\n\nExemple : le mode minimaliste Git\nUn dernier exemple de configuration pour ne nous concentrer que sur Git :\n\n\nIl ne s’agit ici que d’exemples simples. Tu peux en trouver pléthore d’autres dans la section “Themes” de la doc.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Ce petit outil te facilitera l’emploi de Git dans le terminal",
		"date": 1670198400,
		"image": "/assets/images/art-vid/art-git-oh-my-posh.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : Oh My Posh, prompt esthétique et configurable",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-oh-my-posh/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "\nParfois, on se retrouve avec des tableaux… dans des tableaux. Un .map() qui a mal tourné, un traitement récursif, des données sources imbriquées : les causes sont nombreuses, et souvent cette représentation en profondeur nous va très bien.\nMais lorsqu’on veut traiter toutes ces données d’un seul tenant, sans parcours profond, on fait comment ?\nHistoriquement, on se tournait vers des bibliothèques, par exemple Lodash et ses fonctions .flattenDeep() ou .flatMapDepth(). Mais depuis ES2019, c’est dans la bibliothèque standard de JavaScript !\nAplanir, plus ou moins\nLes tableaux (Array) proposent la méthode .flat(), qui prend une profondeur optionnelle. Par défaut, celle-ci vaut 1 (un), on n’aplanit donc que d’un niveau :\n\nÉvidemment, pour aplanir un grand coup, il suffit de passer une profondeur maximum suffisante ; un aplanissement « garanti » peut parfaitement limiter à… l’infini avec +Infinity ou Number.POSITIVE_INFINITY, d’ailleurs.\n\nMais… c’est pas un verbe, ça !\nEn effet. Le verbe correct serait .flatten(). Seulement voilà, comme trop souvent, on a buté sur tous ces sites existants qui utilisent encore MooTools, le coupable habituel. Ce dernier définissait déjà .flatten() sur Array, avec naturellement une sémantique différente (aplanissement intégral systématique), et a donc privé le TC39 de ce joli nom. (Si tu te demandais aussi pourquoi on a .includes() au lieu de .contains() sur les chaînes et les tableaux, maintenant tu sais.)\nÀ propos des tableaux clairsemés (sparse arrays)\nPetit point de détail qui mérite d’être mentionné : les cellules inexistantes au sein du tableau sont ignorées par l’aplanissement, qui ne produira donc jamais de tableau clairsemé. C’est un bon moyen de « retirer les trous ».\n\nAplanir tout en transformant\nIl arrive fréquemment qu’on souhaite appliquer une transformation aux éléments du tableau avant de l’aplanir ; on pourrait donc faire d’abord un .map(), puis un .flat(). Ce qui est dommage, c’est que ça parcourt deux fois les données. C’est notamment le cas lorsque notre mapper renvoie un tableau, mais qu’on souhaite avoir le résultat à plat.\nIl est possible d’optimiser ça avec .flatMap(). Celle-ci a la même signature que .map() (fonction de rappel acceptant jusqu’à 3 arguments et, s’il ne s’agit pas d’une fonction fléchée, this optionnel à définir au sein du rappel).\n\nAttention ! Il ne s’agit pas de l’équivalent d’un .flat() suivi d’un .map(), mais de l’inverse ! Notre mapper se prend donc les éléments d’origine en direct ; notamment, les tableaux imbriqués lui sont passés en tant que tableaux, pas en tant qu’appels individuels fournissant un seul élément. Ça correspond bien au cas d’usage dominant, où les mappers renvoient des tableaux qu’il faut accumuler à plat.\nC’est aussi pour ça qu’on n’a pas d’argument optionnel de profondeur max : puisque notre fonction de rappel reçoit les tableaux imbriqués tels quels, libre à elle de décider de faire un .flatMap() récursif dessus si elle le souhaite.\nTableaux ou itérables ?\nCe serait super d’avoir ça sur tous les itérables (et même tous les itérateurs), mais il faudra pour ça attendre que la proposition Iterator helpers, qui vient d’atteindre le stade 3 du processus de standardisation, passe au stade 4. On récupèrera alors bien d’autres méthodes utiles sur tous les itérateurs.\nPour le moment, ce n’est que sur les tableaux (le type Array).\nC’est dispo où ?\nBin écoute, partout. Dans tous les navigateurs modernes, ainsi que depuis Node 11 et Deno 1.0. Donc vas-y !\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Pas besoin de bibliothèques tierces pour aplanir des tableaux en JavaScript, y compris lors d’opérations `.map()` renvoyant des tableaux !",
		"date": 1670371200,
		"image": "/assets/images/art-vid/art-js-protip-array-flat.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Aplatir des tableaux imbriqués",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-array-flat-flatmap/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nSi comme moi tu souffres du syndrome des doigts en mousse™ ou que tu tapes au clavier avec des moufles 🥊 (restrictions énergétiques obligent 😅), alors tu ne pourras qu’apprécier cette option de configuration qui te propose de corriger des commandes à la volée.\nQuel comportement peut-on obtenir ?\nÀ la base on bénéficiait d’une suggestion automatique, mais simplement par un texte dans le terminal.\n\nOn avait également la possibilité d’appliquer automatiquement la suggestion, sans validation. Le souci avec cette approche est que l’interprétation n’est pas toujours ce qu’on souhaite :\n\nEn novembre 2021, une nouvelle option est arrivée dans Git 2.34 : le prompt, ou la validation par l’utilisateur de la suggestion :\n\nNous voilà donc rassurés de pouvoir éviter tout mauvaise interprétation 😌 !\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Toi aussi tu tapes parfois mal tes commandes ? Et si Git te rectifiait le tir à la volée ?",
		"date": 1670803200,
		"image": "/assets/images/art-vid/art-git-protip-autocorrect.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : corriger tes commandes",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-autocorrect/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nOn a vu dans nos articles précédents qu’on pouvait produire des commits atomiques en ajoutant parfois de manière chirurgicale les contenus (parties de fichiers modifiés par exemple).\nNous avions également évoqué comment visualiser les fichiers et leurs états, notamment les fichiers ajoutés / prêts à être commités, dans le protip sur la coloration du git status. Mais nous n’avons pas vu comment visualiser les contenus des modifications qu’on s’apprête à commiter.\nL’important ici n’est pas tant la commande que la mise en place d’une (bonne) habitude : vérifier avant de valider. La commande est très simple, on veut voir les différences des fichiers qui ont été stagées (staged en anglais) :\n\nOn peut ensuite filtrer en ajoutant des options supplémentaires (également disponibles sans l’option --staged). Par exemple lors de l’ajout de nouveaux fichiers, obtenir leur diff peut gêner l’affichage si on souhaite visualiser les modifications des autres fichiers. Même chose avec les fichiers supprimés. On peut alors soit passer uniquement les chemins des fichiers ou motifs à cibler :\n\n…soit utiliser l’option de filtrage permettant de cibler les types de modifications qui nous intéressent :\n\nAvec ça tu ne devrais plus commiter des choses inattendues 😉. Et si l’affichage classique dans le terminal ne te convient pas, va voir notre article sur diff-so-fancy.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Au-delà des noms des fichiers listés par `git status`, sais-tu comment vérifier les contenus que tu t’apprêtes à commiter",
		"date": 1671408000,
		"image": "/assets/images/art-vid/art-protip-git-diff-staged.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : vérifier avant de commiter",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-diff-staged/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": " -->\n2023 sonne l’heure du changement ! Nous rebrandons notre formation phare et on lui ajoute diverses évolutions pour toujours suivre l’état de l’art des technologies. Web Apps Modernes devient React PWA (qui a en outre l’intérêt de fonctionner en français comme en anglais), ce qui retranscrit nettement mieux ses piliers fondamentaux.\nPlus qu’un simple renommage\nOn en a profité pour faire aboutir des évolutions importantes :\n\nLes quelque 5 heures de remise à niveau sur le JS moderne du premier jour sont parties, comme depuis déjà un an pour notre formation Node.js. Début 2022, on a pris le temps d’en consigner tout le contenu (et bien plus encore) dans notre série JS idiomatique d’articles et de vidéos gratuites, qu’on recommande à tou·te·s !\nLe temps ainsi libéré permet non seulement encore plus d’exercices en autonomie, mais aussi d’explorer plus avant la partie PWA.\n\nJusqu’ici nous mettions en œuvre les notifications, un offlining complet via Service Worker, le manifeste applicatif pour l’installabilité et les shortcuts pour une intégration plus fine dans l’OS hôte d’actions applicatives courantes.\nNous y ajoutons désormais Web Share (comme émetteur standardisé de contenus à partager), et explorons les opportunités d’ajouter de façon pertinente d’autres API sympathiques de l’univers PWA, en particulier Badging.\n\n\nUne version TypeScript soignée est aussi disponible, à la demande, en format intra-entreprise (et il n’est pas exclu qu’elle devienne la version de référence en inter-entreprises d’ici fin 2023).\nNous formalisons aussi les « devoirs à la maison », optionnels et 100% autonomes, pour celleux qui aiment repartir de zéro et explorer dans leur coin les compétences acquises chaque jour, en-dehors du fil rouge applicatif de la formation elle-même.\n\n👉🏻 Voir le programme de la formation React PWA 👈🏻\nTrès prochainement, nous y intègrerons aussi davantage d’appels API (et plus seulement de l’authentification) afin d’illustrer notamment les diverses orchestrations possibles du chargement incrémental de données, tout particulièrement la voie proposée par la dernière génération de React Router, très inspirée de Remix.\nLes origines\nFin 2011 et début 2012, nous lancions des formations très courtes (1 journée chacune) autour de JS pur et sa bibliothèque standard (« JS Puissant ») d’une part, et du développement front-end moderne d’autre part (« JS Guru »). Dès fin 2012, il devenait apparent que beaucoup de clients avaient en fait besoin des deux volets et étaient désireux de pousser les choses plus loin : « JS Total » était née.\nÀ l’époque, cette approche moderne reposait sur Brunch, Backbone.js (donc jQuery et Undescore.js), Jade (désormais Pug), Stylus, Web Storage (via Lawnchair), Application Cache et une gestion assez directe du DOM.\nÇa nous emmenait déjà bien loin : des applis 100% client, persistées, accessibles et utilisables hors-ligne… il y a plus de 10 ans !\nL’importance des noms\nEn 2015, la formation était intégralement réécrite pour s’aligner sur l’état de l’art de la construction d’applications front-end riches et performantes. Au revoir Brunch, Backbone.js, jQuery, Underscore.js, Lawnchair, Jade, Stylus et Application Cache ; bonjour Webpack, React, Redux, Material UI, Jest, SCSS et ServiceWorker ! Une sacrée réécriture.\nDans le même temps, on nous demandait de plus en plus souvent une formation complète sur JavaScript et sa bibliothèque standard. Quelque chose pour aller explorer tous les recoins, toutes les syntaxes, toutes les fonctionnalités intégrées. D’ailleurs, vu son nom de « JS Total », celleux qui ne faisaient pas l’effort de lire le programme pensaient que c’était ce que proposait la formation.\nOn savait que ce nom convenait en fait mieux à une formation langage, mais on ne voulait pas juste transférer le nom existant, ce qui aurait entraîné pas mal de confusion. On a donc décidé de nommer la nouvelle « ES Total », et de renommer la formation front-end « Web Apps Modernes ». Ce nouveau nom avait en outre l’avantage d’un acronyme pratique, monosyllabique et facile à prononcer : WAM, terme que nous allions utiliser quasi tous les jours en interne.\nEt en attendant ta formation…\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou sur Mastodon\n",
		"description": "Notre formation phare évolue et change de nom pour mieux refléter son contenu !",
		"date": 1671667200,
		"image": "/assets/images/art-vid/art-react-pwa.jpg",
    "_tags": ["formations","annonce"],
		"title": "Web Apps Modernes évolue et devient React PWA !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/react-pwa/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nAh, le forçage de push ou l’écrasement de l’historique distant par notre historique local, voilà un sujet qui crée beaucoup d’agitation !\nLe tumulte qu’il génère est souvent lié à une compréhension partielle du potentiel de la commande push. Cette même compréhension partielle est imputable à une mauvaise approche de conception / nommage des options. Il se trouve en effet que l’option de forçage la plus dangereuse se trouve être aussi la plus facile à saisir 🤦‍♂️ : la fameuse option --force.\nHistoire d’enfoncer le couteau, la plupart des éditeurs, probablement en raison du fait que leurs devs n’ont pas été fichus de lire la doc’ en entier, proposent une option unique de forçage qui est le --force ! 🤦‍♂️🤦‍♂️\nPourtant, il existe une option dont le but est de garantir qu’on n’écrase pas un historique qui n’aurait pas été récupéré au préalable depuis le distant : --force-with-lease.\nCette option a tout intérêt à être combinée avec une seconde option --force-if-includes pour vérifier non seulement que l’état du dépôt distant a été récupéré mais aussi qu’il a été appliqué à notre historique local.\nPlus simplement, ne fais plus de git push --force, sauf si c’est pour volontairement effacer un historique produit par un·e de tes collègues !\nPréfère un git push --force-with-lease --force-if-includes. Et si c’est trop long à taper, fais-toi un alias :\n\n\n  Note que tu peux activer l’option --force-if-includes par défaut dans la configuration\n  git config --global push.useForceIfIncludes true\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Sais-tu que tu peux forcer le push sans risquer d’écraser le travail de tes collègues ?",
		"date": 1674432000,
		"image": "/assets/images/art-vid/art-git-protip-push-with-lease.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : forcer gentiment le push",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-push-with-lease/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nSi tu utilises la ligne de commande, tu as forcément remarqué qu’à la première tentative de push d’une branche locale Git ne fait rien (mais le fait bien) et t’affiche un message te suggérant de faire explicitement un git push --set-upstream origin &lt;nom-de-branche&gt;. C’est pour que tu indiques vers quel dépôt distant tu veux envoyer le travail de ta branche (oui, tu peux avoir plusieurs remotes), et au passage pour que Git mette en place un suivi (tracking) automatique (ce qui te permettra par la suite de ne faire que du git pull et git push sans option depuis ta branche).\nC’est contraignant, surtout que 99% du temps on n’a qu’un dépôt distant où envoyer notre travail.\nQue dirais-tu de pouvoir gérer automatiquement la création de ta branche sur le remote avec un simple git push ?\nC’est ce que propose l’option de configuration push.autoSetupRemote sortie dans Git 2.38 (fin 2022). Tu peux la renseigner au global dans ta configuration :\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Fini la contrainte de tracking explicite de nos branches !",
		"date": 1675036800,
		"image": "/assets/images/art-vid/art-git-protip-auto-setup-remote.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : renseigner automatiquement la synchro au push",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-push-auto-setup-remote/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "\nQue tu sois dans le terminal ou dans ton éditeur, lorsque tu dois gérer de nombreux fichiers conflictuels suite à une fusion qui a mal tourné, c’est parfois pénible ! Tu dois ouvrir les fichiers les uns après les autres, puis tu dois valider tes arbitrages en ajoutant les fichiers au stage. Autant dire que, outre le fait que tu n’y prends pas plaisir, c’est long et tu risques d’oublier d’ajouter certains fichiers au stage si tu n’es pas vigilant·e.\nIdéalement on aimerait que ces fichiers soient ouverts à la chaîne par Git, et qu’une fois notre arbitrage terminé (fichier modifié, enregistré et fermé), il soit automatiquement validé / ajouté au stage.\nDevine quoi ? Git propose cette fonctionnalité ! Il s’agit de la commande mergetool. En gros, au lieu d’ouvrir toi-même les fichiers conflictuels, tu lances cette commande et Git les ouvrira pour toi ! 🪄\n\nAvant de foncer tête baissée et de lancer cette commande dans ton terminal, prends le temps de lire la suite, car il y a quelques astuces et subtilités.\nPour commencer, tu dois définir l’outil par défaut que tu souhaites utiliser. Il existe déjà une liste d’outils disponibles sur ta machine ainsi qu’une liste de suggestions d’outils à installer. Pour voir tout ça, tu peux renseigner la commande avec l’option :\n\nPar défaut, Git regardera les outils déjà présents et ouvrira le premier qu’il trouvera. Ces outils font généralement bien le job, mais il faut savoir les utiliser (ou en sortir quand il s’agit de vim 😅 : ZZ ou :q!). Si tu souhaites occasionnellement utiliser un outil disponible dans la liste, tu peux alors passer l’option --tool à la commande :\n\nMais pour être peinard·e, tu voudras surtout définir ton outil par défaut. Pour ça, il faut passer par la configuration :\n\nAttention, si tu souhaites utiliser un éditeur non présent dans la liste, tu dois le signaler à Git comme mergetool personnalisé (ce que tu vois plus haut dans la liste user-defined). Là encore ça passe par la configuration :\n\nEt voilà, le tour est joué ! Aux prochains conflits, plus besoin d’aller ouvrir tes fichiers à la mano, tu n’auras plus qu’à lancer git mergetool.\n\nSeulement après un git merge ?\nEt non, ça fonctionne avec toute situation de conflit ! Ça peut faire suite à un merge, un rebase, à l’application d’un stash, ou encore un switch --merge.\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, à nous suivre sur Twitter ou sur Mastodon ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "La résolution des fichiers conflictuels suite à une fusion est parfois longue à traiter. Heureusement Git nous fournit un outil pour accélérer tout ça !",
		"date": 1675641600,
		"image": "/assets/images/art-vid/art-git-protip-mergetool.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Git protip : gérer les conflits à la chaîne avec mergetool",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-mergetool/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nOn est en 2023, et les promesses comme async / await sont désormais bien ancrées (même si je vois toujours plein de gens faire n’importe quoi).\nEt pourtant, on utilise toujours ces bons vieux setTimeout() et setInterval()… Basés callbacks. Un reliquat du passé, bien sûr, alors on n’a pas le choix… Ou alors si ?!\nTout vient à point à qui sait attendre\nCommençons par le côté back. Node.js propose depuis sa toute première version les API setTimeout() et setInterval() issues du navigateur ; sans ça (et console), personne ne serait venu ! 😅\nCes API sont bien entendues basés callbacks, mais depuis Node 15 une version basée promesses est également disponible :\n\nLa classe ! 🤩\nPerso, quand je l’utilise comme ça, j’ai même tendance à la renommer :\n\nÉvidemment, contrairement au bon vieux sleep des univers bloquants, ça ne bloque pas le thread : ça reste des promesses, après tout ! C’est suspensif, pas bloquant.\nPas que setTimeout()…\nTout ce qui vient de timers propose la même chose, notamment setInterval() et setImmediate().\nPour les intervalles, tu te demandes peut-être comment ça se passe, vu que c’est récurrent ? Eh bien ça nous renvoie un itérable asynchrone (qui renvoie toujours la même valeur, que tu peux d’ailleurs choisir de fournir en 2e argument), consommable par exemple avec une boucle for…await :\n\nEn pratique, le clearInterval() revient simplement à quitter la boucle (comme ici avec break), mais si tu veux pouvoir annuler l’intervalle depuis un autre point du code, il y a le même mécanisme d’annulation découplée que pour tout le reste des travaux à base de promesses : AbortController et AbortSignal.\n\nOn trouve le même type de variations pour les écouteurs d’événements (ex. await once(stream, 'close') avec node:events), l’accès au système de fichiers (ex. await readdir(path) avec node:fs/promises), ou même les flux en lecture (flux Node classiques ou ReadableStream compatibles Web), qui sont aussi des itérables asynchrones sujets aux signaux.\nBref, await c’est la vie ! 😎\nC’est dispo où ?\nPour les timers, depuis Node 15. Pour le système de fichiers, les flux en lecture et les événements, depuis Node 10 (mais il aura fallu attendre Node 14 pour le chemin de module noyau fs/promises, et Node 15 pour les signaux).\nEt côté navigateur ?\nSeules les nouvelles API sont basées promesses, mais tu peux très facilement enrober setTimeout :\n\nSi tu veux vraiment aller au bout et gérer les signaux, c’est jouable (c’est dispo sur tous les navigateurs modernes depuis des lustres) :\n\n(Et pour setInterval, ce n’est pas très difficile, je te laisse essayer 😉).\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Le `setTimeout()` à callback est mort, vive celui basé promesse qu’on peut `await` !",
		"date": 1675814400,
		"image": "/assets/images/art-vid/art-js-protip-timers-promises.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : faire une pause avec setTimeout(), oui, mais en mode await !",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-timers-promises/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nJe vois régulièrement ces temps-ci des gens copier/coller ce petit bout de code pour produire un tableau de N copies d’une même valeur :\n\nC’est inutilement verbeux pour le coup, mais ça ne veut pas dire que from() est inutile, loin de là ! Comment bien choisir‚ alors ?\nToujours la même valeur : faisons court avec juste fill()\nJavaScript a toujours permis d’initialiser un tableau à une longueur donnée avec Array(n). C’est hyper concis, mais les cellules du tableau n’existent pas, c’est un peu le tableau clairsemé ultime : il n’a aucune cellule définie !\nDu coup les opérations type map() et consorts ne feraient rien, ou renverraient leur résultat par défaut, « à vide » :\n\nLa façon classique de « remplir » le tableau consiste à utiliser fill() sur celui-ci :\n\nC’est super quand la valeur est toujours la même (par exemple false, 0 ou la chaîne vide ''), ce qui arrive tout de même régulièrement en pratique, au début d’un traitement le plus souvent.\nMais quand la valeur change d’une cellule à l’autre ?\nValeurs distinctes : utilisons intelligement from()\nÀ la base, Array.from() sert principalement à convertir un itérable en véritable Array. Par exemple à partir d’une Map, d’un Set, des codepoints d’une String ou encore d’une NodeList, pour citer les cas les plus courants.\nEn pratique, si l’argument n’est pas itérable, il doit au moins être “array-like”, c’est-à-dire exploitable par les méthodes standard de Array, et donc disposer d’une propriété length qui soit un entier positif (ou nul).\nPour l’anecdote d’ailleurs, Array.from({ length: 5 }) n’est pas tout-à-fait la même chose que Array(5) : le second ne définit pas les cellules, alors que le premier les cale à undefined :\n\nC’est cool, mais le vrai bonus est son deuxième argument, optionnel : le mapper, la fonction de transformation à la volée.\nOn peut s’en servir pour générer des valeurs quelconques, ou les baser sur la position par exemple, puisque comme la plupart des méthodes itératives (par exemple map() ou filter()), elle reçoit non seulement la valeur de base, mais aussi son index.\n\nPourquoi pas une fonction range(), façon Lodash (la borne end est exclusive / ouverte) ?\n\nSympa 😎\nTL;PL\n\nfrom() part d’une source et peut calculer les valeurs à la volée\nfill() est plus pratique pour une valeur unique, et plus concise avec Array(size)\nLes deux datent de ES2015 (donc dispo partout sauf IE, mais désormais on s’en fiche complètement)\n\nRéférences\nLes docs interactives en français du MDN sont comme toujours super utiles :\n\nArray.from()\nArray#fill()\nArray()\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter ou encore mieux, à suivre une de nos formations du feu de dieu 🔥 !\n",
		"description": "Array.fill() ou Array#from() ?!  Tout dépend du besoin, comme toujours, alors voici comment bien choisir au cas par cas.",
		"date": 1679443200,
		"image": "/assets/images/art-vid/art-js-protip-array-from-fill.jpg",
    "_tags": ["js","tutoriel"],
		"title": "JS protip : Array.from() ou Array#fill() ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/js-protip-array-from-fill/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\n\nCet article vient compléter notre article de 2013 dont le contenu est toujours valable et qui décrit certains éléments mis en place dans notre configuration.\nL’article actuel décrit plus la mise en place de la configuration, les avantages et inconvénients.\n\nSavoir configurer Git, c’est super ! Ça permet de préciser des comportements, des aliases, de renseigner nos outils préférés pour travailler avec Git, de personnaliser jusqu’aux couleurs d’affichage des commandes dans le terminal… Mais la configuration, c’est aussi un truc contraignant, parce que le comportement de base n’est pas forcément optimal, parce que ça implique de créer les fichiers de configuration, de répliquer la même configuration sur chaque machine, et parce qu’on n’est pas forcément au courant des choses qu’on peut optimiser !\nÀ la base, ça pourrait être mieux…\nC’est un fait plutôt regrettable : Git n’est pas au top d’emblée ! Certains comportements demandent à être optimisés, comme par exemple le pull en mode rebase (rebase = merges pour être exact). Tu ne devrais même pas te poser la question de l’utilité de cette configuration, et pourtant, te voilà à devoir expliciter tout ça.\nLa raison est simple : les évolutions ne doivent pas changer les comportements nominaux. Dit autrement : tu ne devrais pas voir de différence de comportement suite à une mise à jour de Git. J’admets que cette approche est plutôt discutable, mais sauf en prenant la main sur l’organisation du projet (c’est possible, vu que c’est de l’open-source), ça ne risque pas de changer dans l’immédiat.\nComment alors remédier à ce problème ? C’est très simple, il te suffit de suivre notre formation Git Total 😁 ! Mais si tu n’as pas cette chance, alors tu devras te contenter de lire la doc suivre nos recommandations. Comme on n’est pas trop vaches 🐮, on t’a commenté chaque élément de configuration, histoire que tu aies au moins des pistes pour comprendre à quoi tout ça peut servir.\nCôté syntaxe, ça ressemble à un fichier .ini ou à du TOML. En gros on a un bloc dont l’en-tête est définie avec des crochets, suivi de lignes sur le format clé = valeur.\n\nTu auras parfois besoin d’agir sur des blocs nommés qui permettent de spécifier certains aspects (parfois appelés drivers) d’une fonctionnalité ou commande. Voici un exemple avec la gestion de la coloration de la commande status :\n\nC’est mignon tout ça, mais je mets ça où ?\nOn a plusieurs options, mais la plus simple et efficace consiste à renseigner la configuration au global pour ton compte utilisateur·rice. Ça servira ainsi à tous tes projets sur la machine. Tu y trouveras généralement un fichier .gitconfig (et sinon, tu peux le créer). Si tu as un doute, tu peux y accéder depuis ton terminal en faisant un git config --global --edit (attention, ça risque de l’ouvrir par défaut dans vim). Certains éditeurs graphiques permettent aussi d’éditer cette configuration, souvent au sein de leur propre interface.\nSi tu es sur Windows, prends garde si les comptes sont stockés sur un serveur : si le réseau tombe, ta configuration Git ne sera alors plus chargée (elle est lue à chaque commande / action Git). Tu ne t’en apercevras pas forcément car Git ne remontera pas d’erreur. Une solution est alors de changer son emplacement en modifiant la variable d’environnement XDG_CONFIG_HOME.\nOn peut aussi préciser la configuration “locale”, au plus proche du projet. Il s’agit alors du fichier .git/config de ton projet (oui oui, ça n’est pas le même nom 🤦). C’est utile pour préciser ou surcharger certaines infos. Par exemple quand je bosse sur des projets open-source je renseigne mon adresse e-mail perso plutôt que la pro (l’exemple est donné juste après). Et puis on y trouve les définitions des dépôts distants, branches, etc. qui sont évidemment distincts d’un projet à l’autre.\n\nAussi disponible au niveau système\nCe n’est clairement pas l’approche que nous recommandons, mais Git va également chercher à charger la configuration depuis un niveau système (mingw32\\etc\\gitconfig ou mingw64\\etc\\gitconfig sur Windows, etc/gitconfig sur Linux et MacOS).\n\nComment dois-je renseigner ma configuration ?\nAu-delà du bon gros copier/coller de notre gabarit de configuration, tu voudras parfois changer certains éléments. Tu peux soit modifier le fichier à la main, soit faire ça via la ligne de commande.\nSi tu édites un fichier de configuration à la main et que tu as peur de tout casser, sache que le parser de Git saura te dire à quelle ligne tu as une erreur. Va donc sans crainte.\nPour la méthode “safe”, tu peux appeler la commande selon le gabarit suivant :\n\nSi tu retires l’option --global ça travaillera sur la configuration locale.\n\nComment Git charge-t-il ma configuration ?\nLes fichiers de configuration sont lus à chaque commande Git. D’abord au niveau global, puis au niveau local / projet. La configuration globale est alors enrichie, voire surchargée par les définitions locales.\nEnfin, selon ce que tu cherches à réaliser comme manipulation, tu pourras général",
		"description": "Impossible d’utiliser Git de façon optimale sans toucher à sa configuration !",
		"date": 1679875200,
		"image": "/assets/images/art-vid/art-git-config-part-2.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Comment configurer Git ?",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-config-part-2/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "\nLorsqu’on travaille avec Git, on souhaite rarement versionner tous les fichiers d’un projet. Qu’il s’agisse de fichiers liés au système d’exploitation, de fichiers techniques liés à un éditeur / EDI, de fichiers sensibles (clés de sécurités, configuration, etc) ou simplement de fichiers générés localement (logs, fichiers temporaires, etc.), on veut éviter de les partager.\nGit dispose d’un mécanisme pour les ignorer. Un fichier ignoré ne pourra pas être ajouté au projet et n’apparaîtra pas parmi les fichiers listés par Git (voir la commande git status).\n\nPlusieurs manières de procéder\nLa meilleure manière de faire consiste à créer un fichier .gitignore à la racine du projet.\nCe fichier doit être versionné / ajouté au projet pour que ses règles soient appliquées chez tou·te·s les participant-e·s au projet.\nIl existe certes des alternatives, mais chez Delicious Insights on les classe parmi les FBI™ (Fausses Bonnes Idées) :\n\nplusieurs fichiers .gitignore dans le projet (un par répertoire, par exemple) ;\nun fichier global au compte, via la configuration, et donc non versionné ;\nle fichier .git/info/exclude, non versionné / partagé.\n\nPour ne pas te laisser sur ta faim, je vais argumenter un peu :\n1. Plusieurs fichiers .gitignore\nPourquoi créer plusieurs fichiers là où tu peux en avoir un seul, plus facile à maintenir ?\n2. Un fichier global\nL’idée peut paraître intéressante pour définir des règles globales à notre compte et applicables sur l’ensemble des projets sur notre poste (en plus des règles locales à chaque projet), sauf que…\n\nces règles ne seront pas partagées ;\nnos collègues risquent d’intégrer des fichiers que nous aurions ignorés de notre côté.\n\nSi vraiment tu souhaites tenter ça, tu peux regarder la commande :\n\nTu ne pourras pas dire que je ne t’ai pas prévenu·e 😉.\n3. Le fichier .git/info/exclude\nMêmes arguments que précédemment : pas de partage, donc quel intérêt ?\nSyntaxe\nCôté syntaxe, on utilise une syntaxe existante et robuste : les globs. On peut renseigner des noms / chemins de fichiers ou répertoires précis, ainsi que des motifs. On peut même spécifier des négations (ce qu’on ne veut pas ignorer), ce qui est utile lorsqu’on souhaite renseigner des exceptions à un motif plus global.\n\nMes fichiers étaient déjà versionnés\nTu risques d’être confronté·e un jour à un cas de figure un peu particulier où tu souhaites ignorer des fichiers qui sont déjà versionnés. L’ajout de la règle au .gitignore n’est pas suffisante, tes modifications apparaissent toujours, disponibles à l’ajout 😨. Tu dois en plus “sortir” le fichier de la gestion de versions. Forcément, Git propose une commande pour ça :\n\nLa suppression du fichier est enregistrée dans Git, mais pas sur le disque (c’est tout l’intérêt de l’option --cached). Tu gardes donc ton fichier, mais désormais il est considéré comme exclu (si tu as renseigné la règle dans le .gitignore, hein !).\nAttention cependant, tout l’historique du fichier reste présent dans Git. Tu ne fais que cesser de le versionner à partir de maintenant. Si tu veux le retirer ainsi que toutes ses traces, je te recommande…\n\nde te poser la question : est-ce vraiment utile ?\nsi oui, d’utiliser alors un outil pour retravailler tout l’historique projet : filter-repo.\n\n\nMa recommandation\nSi tu souhaites purger un fichier critique qui n’aurait jamais dû être versionné (comme une clé privée, par exemple), garde à l’esprit qu’il a déjà pu être récupéré.\nDonc il ne suffira pas de le purger de l’historique, assure-toi de regénérer les clés et d’ignorer les fichiers concernés désormais (toujours avec .gitignore).\n\nJe veux ajouter un fichier ignoré\nTu as deux solutions :\n\nSoit tu changes les motifs ignorés, donc le fichier .gitignore, en utilisant éventuellement une négation (ce qu’on a vu en exemple avec la syntaxe) ;\nSoit tu forces l’ajout avec un git add --force.\n\nComme je l’ai expliqué avant, si un fichier est versionné, le .gitignore n’agit plus dessus. Donc en forçant l’ajout une première fois, tu es tranquille pour la suite.\nGabarits pour le .gitignore\nTu te doutes bien qu’on utilise généralement les mêmes socles, éditeurs, systèmes d’exploitation. Il est donc naturel qu’on retrouve les mêmes motifs à ignorer d’un projet à l’autre.\nIl existe des solutions pour récupérer facilement ces gabarits. On t’explique tout ça dans ce protip complémentaire.\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter et Mastodon ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Quelles sont les techniques pour ignorer des fichiers avec Git pour ne pas risquer d’ajouter des fichiers non désirés ? Et à l’inverse, comment peut-on ajouter des fichiers qui sont ignorés ?",
		"date": 1681084800,
		"image": "/assets/images/art-vid/art-git-ignore.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Ignorer des fichiers avec Git",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-ignore/",
		"locale": "fr",
		"readingTime": "3 min"
	},	{
		"content": "\nTu as peut-être suivi notre tutoriel qui t’explique comment ignorer (ou pas) des fichiers dans Git. Du coup, tu as commencé à rédiger ton fichier .gitignore à la racine de ton projet, et tu t’es probablement rendu compte qu’il y avait plein de choses à y ajouter :\n\nfichiers liés au système d’exploitation (fichiers .DS_Store sur Mac, Thumbs.db sur Windows, .swp sur linux…) ;\nfichiers techniques liés à un EDI ou au contexte projet (.settings/ pour Eclipse, .idea_modules/ pour WebStorm/PhpStorm…).\n\nQue dirais-tu de t’épargner ça en profitant de gabarits existants ?\nTu as peut-être déjà vu, voire utilisé les gabarits proposés sur certaines plateformes comme GitLab (à l’initialisation du projet).\n\nMais il y a encore mieux ! Laisse-moi te présenter l’ultime moteur de génération de fichier .gitignore, j’ai nommé gitignore.io !\n\nOn peut difficilement faire plus simple et efficace : tu renseignes les technos avec lesquelles les gens vont bosser sur ton projet, tu appuies sur le bouton “Créer”, et tu obtiens un contenu textuel que tu peux copier-coller dans le fichier .gitignore de ton projet.\nElle est pas belle la vie ?\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter et Mastodon ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Le .gitignore c’est super ! Mais ça peut être long et fastidieux à renseigner. Et si on pouvait faire ça nickel en une fois ?",
		"date": 1681084800,
		"image": "/assets/images/art-vid/art-git-protip-gitignore-io.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Protip Git : des gabarits faciles pour le `.gitignore`",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-protip-gitignore-io/",
		"locale": "fr",
		"readingTime": "1 min"
	},	{
		"content": "Triturer des URL, c’est fréquent. On y cherche une info, on veut modifier une URL existante, on veut en construire une de toutes pièces : tout ça arrive régulièrement, mais y’a pas mal de pièges et d’aspects techniques parfois déroutants. Ça marche en dev, mais plus en prod, confronté à des vraies données, des vrais cas de figure.\nOn a pourtant tout ce qu’il faut pour faire ça plus vite, en plus court, et de façon robuste !\n\n -->\nPetits rappels sur la structure d’une URL\nUne URL contient en fait un paquet de composantes potentielles. Le diagramme ci-dessous illustre les principaux :\n\n\nOn commence par le protocole (parfois appelé scheme), qui va jusqu’au deux-points inclus ; ici c’est https:.\nEnsuite vient l’authentification éventuelle (voir plus bas).\nPuis c’est le tour du nom d’hôte (hostname), qui est un FQDN (Fully-Qualified Domain Name) ; ici c’est my.project.test.\nIl est potentiellement suivi d’un deux-point et d’un port réseau, surtout si celui-ci n’est pas le port par défaut du protocole (par exemple, le port HTTP par défaut est 80, celui de HTTPS est 443). Ici c’est 4443.\nSuit alors le chemin (pathname, parfois path), qui n’est jamais vide (il est par défaut à /) ; ici c’est /api/v1/batch.\nOn a ensuite la recherche (search, souvent appelée query ou query string), qui peut être vide. Elle court du point d’interrogation jusqu’au hash éventuel. Ici, c’est ?locale=en&amp;mode=editorial.\nEnfin, on peut avoir un hash (parfois appelé anchor), qui indique le plus souvent un fragment de page web à cibler, ou une instruction de routage côté client. Il peut être vide, et vaut ici #key=a2bc043.\n\nEnsemble, le nom d’hôte et le port contituent l’hôte (host), ici my.project.test:443. Dans le même esprit, le protocole et l’hôte constituent l’origine (origin), ici https://my.project.test:4443, qui sert de base aux politiques CORS et CSP, et à pas mal d’autres contraintes de sécurité.\nIl est par ailleurs possible de transmettre une authentification HTTP Basic en insérant un segment entre le protocole et le nom d’hôte :\n\nTout ça est difficile à manipuler manuellement, notamment car :\n\nIl faut échapper tous les caractères problématiques (genre un slash dans un segment de chemin)\nIl faut encoder la recherche en conformité avec le dernier standard applicable, et ça resserre les vis au fil du temps (actuellement c’est la RFC 3986 qui fait foi (et les mises à jour de la RFC 8820), et tous les systèmes ne sont pas toujours à jour sur les dernières contraintes). Bref, c’est relou.\n\nManipuler tout ça avec URL\nLe constructeur global URL est notre ami :\n\n\nC’est un peu open bar !\nSi l’argument n’est pas une String, il est converti en tant que tel via un appel à sa méthode toString() (tous les objets en ont une).\nÇa nous permet d’utiliser justement un objet URL, mais aussi window.location ou encore un HTMLAnchorElement, c’est-à-dire un nœud du DOM pour une balise &lt;a&gt;, car leur conversion en chaîne de caractères donne leur URL associée.\n\nIl n’exige qu’un argument, mais dans un contexte front-end on prendra soin de toujours lui fournir le 2e, qui indique une base de résolution, afin de gérer les URL relatives aussi :\n\nOn voit ici que comme le 1er argument, le 2e n’a pas besoin d’être une String.\nUne fois qu’on a un objet URL sous la main, on peut lire et écrire tous les segments, y compris les agrégats :\n\nprotocol (inclut le :)\nusername et password\nhostname, port, host (hostname:port) et origin (protocol//host)\npathname (jamais vide)\nsearch (mais on a mieux, on va y venir)\nhash\n\nIl existe aussi la propriété href, renvoyée implicitement par son toString, qui représente l’URL dans sa totalité.\nQuelques exemples :\n\nOn peut bien sûr se galérer à analyser / modifier search à la main, mais on a mieux : la propriété en lecture seule searchParams est une instance dynamiquement liée de URLSearchParams, qu’on va voir maintenant.\nManipuler la query string avec URLSearchParams\nLes segments de recherche (query strings) ont un format pas si simple que ça. Tu en as déjà vu, c’est sûr :\n?given=%C3%89lodie&amp;family=Jaubert+Porteneuve\n\nIl y a la question des espaces, de l’encodage en hexadécimal de chaque octet des codets et surrogate pairs UTF-8, etc. Pas glop !\nCe format est utilisé plus largement : c’est par exemple lui qui encode les contenus de formulaires web en mode POST (sauf s’ils envoient des fichiers). La requête HTTP porte alors le type MIME application/x-www-form-urlencoded, qui suit les mêmes règles.\nC’est sans doute pourquoi le constructeur URLSearchParams existe indépendamment de URL.\nOn peut construire un tel objet de plein de façons, c’est très flexible :\n\nUn dictionnaire clés / valeurs sous forme d’un objet nu\nUn dictionnaire clés / valeurs sous forme d’un itérateur de paires, tel qu’une Map ou un simple tableau de paires\nUne String représentant un segment de recherche (avec ou sans le ? au début), ou à défaut un objet dont le toString() produira ça :\n\n\nÇa se comporte presque comme une Map, au sens où on retrouve la plupart",
		"description": "Construire ou découper à la main une URL (ou un de ses segments) est bourré de pièges et de cas à la marge.  Mais dans un browser comme dans Node.js, on a en fait déjà les outils pour faire ça bien !",
		"date": 1681084800,
		"image": "/assets/images/art-vid/art-url-search-params-fr.jpg",
		"title": "Manipulation robuste des URL avec `URL` et `URLSearchParams`",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/url-search-params/",
		"locale": "fr",
		"readingTime": "5 min"
	},	{
		"content": "\nLe cherry-pick ça n’est pas quand ton amour a oublié de se raser (#BlagueÀ2Balle) mais la possibilité que nous offre Git d’effectuer du report de commit d’un endroit à un autre dans l’historique d’un même projet. Il s’agit donc de copier-coller un ou plusieurs commits.\nQuand l’utiliser ?\nTout dépend des workflows en place sur tes projets. On trouve généralement deux grands cas de figure :\n\nle report de correctif d’une branche à une autre ;\nla reprise de fonctionnalité d’une branche à une autre.\n\nIl est donc très rare qu’on vienne dupliquer un commit sur une même branche. On est plus souvent confrontés à une logique du « tiens, ce truc là, j’en ai besoin là aussi ! ».\nProcédure\nLa procédure est simple et se fait en deux étapes :\n\nComme pour une fusion, on se place sur la branche qui va évoluer / recevoir le commit : git swith &lt;la-branche&gt;\nOn réplique le commit : git cherry-pick -x &lt;commit-1&gt;\n\nOn peut en repliquer plusieurs à la fois, auquel cas Git nous les appliquera à la chaîne, mais on préférera généralement une application unitaire.\n\nChaque commit répliqué produira donc un nouveau commit avec une nouvelle identité.\n\nPetit rappel sur l’identifiant d’un commit\nL’identifiant d’un commit est basé sur le contenu du commit. Dans ce contenu on trouve l’identité du ou des commits parents.\nAinsi, appliquer un commit sur un autre parent produira un nouvel identifiant.\nSi tu veux en savoir plus à ce sujet, regarde notre article sur l’anatomie d’un commit.\n\nL’option -x\nContrairement aux fusions, le cherry-picking n’offre pas la possibilité de visualiser dans l’historique la provenance du contenu intégré/reporté. Ça n’est pas franchement grave puisqu’on garde toutes le infos réellement utiles (contenu + méta-données, dont l’auteur du commit). On peut néanmoins demander l’intégration dans le message du commit de la référence au commit copié grâce à l’option -x. On obtiendra alors une ligne supplémentaire en fin de message de commit qui ressemblera à ceci :\n\nVisuellement, ça donne quoi ?\nSi on devait visualiser l’opération dans notre historique, on verrait ça :\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter et Mastodon ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Reporter un correctif d’une branche à une autre ne demande qu’une toute petite commande",
		"date": 1683504000,
		"image": "/assets/images/art-vid/art-git-cherry-pick.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Copier-coller des commits avec cherry-pick",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-cherry-pick/",
		"locale": "fr",
		"readingTime": "2 min"
	},	{
		"content": "\nOn a vu dans notre article sur le cherry-picking comment reporter des commits d’un endroit à un autre sans effort au sein d’un même projet ! Voyons ici comment effectuer le même type d’opération d’un projet vers un autre.\nQuand est-ce utile ?\nIl s’agit ici d’un besoin très particulier. Généralement avec une architecture comprenant un projet socle ou noyau et des projets déclinés depuis ce socle (des clones).\n\nCertaines évolutions ou correctifs réalisés sur l’un des projets doivent parfois être reportés sur les autres projets du groupe.\nDocteur patch\nLes patches Git servent à ça et sont réalisés en 2 étapes :\n\nextraire les commits souhaités sous forme de fichiers (les patches) ;\nappliquer ces patches sur un autre projet.\n\n\nExtraire\nPour créer les patches, on utilise la commande format-patch :\n\nJe conseille vivement l’emploi de l’option -o / --output-directory afin d’éviter tout risque d’ajout des fichiers de patches dans le projet actuel.\nL’option -k / --keep-subject sert à conserver le message du commit extrait. Sans ça, le message serait préfixé par [PATCH].\nEnfin, l’option numérique -3 permet d’indiquer le nombre de commits qu’on veut extraire jusqu’au commit désigné inclus.\nIl existe différentes syntaxes, même si personnellement je préfère la syntaxe explicite utilisée ci-dessus. En voici d’autres que je trouve parfois utiles :\n\nEn pratique, on n’a pas besoin de regarder le contenu d’un patch. Mais pour satisfaire ta curiosité voici à quoi ça ressemble :\n\nOn trouve une en-tête et les modifications (équivalent d’un git diff -p --stat). Le format servait originellement (et sert peut-être encore) à l’envoi des patches automatiquement par e-mail au format mbox (UNIX mailbox). Je vais éviter de rentrer dans les détails, mais si ça t’intéresse n’hésite pas à nous le dire en commentaire ! 👇\nAppliquer les patches\nUne fois extraits, on va appliquer ces patches dans les projets voulus. On a alors 2 façons de faire :\n\nsoit on applique les modifs dans la copie de travail, sans committer (on doit finaliser nous-même) : git apply --3way ../patches/* ;\nsoit on demande à appliquer les commits en mode “copier-coller” : git am --3way ../patches/*.\n\nJ’ai tendance à préférer la seconde méthode car elle s’apparente au cherry-picking, ce qui me va bien. À toi de voir ce qui te convient le mieux.\nL’option --3way sert en cas de conflit, je t’explique ça un peu plus bas.\nDes conflits ?\nComme pour le cherry-picking, on peut être confrontés à des conflits. La procédure est toujours la même : on arbitre et on continue / redonne la main.\n\nDans ces moments-là, git status est ton meilleur ami et va te guider !\n\nPour faire simple :\n\ntu corriges ;\ntu ajoutes au stage / à l’index ;\ntu fais un git am --continue\n\n\n\nAstuce\nTu peux t’épargner l’ouverture de l’éditeur et du message de commit en renseignant à la volée GIT_EDITOR=true. Par exemple, dans un shell Unix/Linux/macOS :\n\n\nL’option --3way permet de laisser les fichiers en situation de conflit dans la copie de travail pour que tu puisses faire ton arbitrage. Sans ça, il t’affichera le message d’erreur mais n’appliquera pas le patch problématique. Tu peux configurer Git pour qu’il l’effectue systématiquement :\n\nNote que ce comportement s’applique également à la commande apply.\nUtiliser le cherry-picking d’un projet vers un autre ?\nÀ coup d’astuces, on peut utiliser le cherry-picking plutôt que les patches. Pour ça, il faut aller dans chaque projet concerné par le report, y charger la branche du projet noyau (oui je sais, ça peut sembler étrange, mais c’est possible !), et enfin effectuer le cherry-picking. Voilà comment faire :\n\nOn définit un nouveau remote sur le projet enfant :\n\n\n2. On récupère le contenu de la branche qui nous intéresse :\n\n\nOn affiche l’historique de la branche si on n’a pas déjà les identifiants de commits à récupérer :\n\n\n\nOn se place sur la branche sur laquelle on souhaite appliquer les commits, ou on en crée une :\n\n\n\nOn peut faire notre report via le cherry-picking :\n\n\n\n\nDes astuces en veux-tu en voilà !\nOn a tout plein d’articles et de vidéos existants et encore beaucoup à venir. Pour ne rien manquer, tu devrais penser à t’abonner à notre newsletter, à notre chaîne YouTube, nous suivre sur Twitter et Mastodon ou encore mieux, à suivre notre formation du feu de dieu 🔥 : Git Total !\n",
		"description": "Le cherry-picking n’est valable que d’un projet sur lui-même. Comment faire alors pour reporter des commits sur un autre projet ?",
		"date": 1685318400,
		"image": "/assets/images/art-vid/art-git-patch.jpg",
    "_tags": ["git","tutoriel"],
		"title": "Reporter des commits vers un autre projet",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/git-patch/",
		"locale": "fr",
		"readingTime": "4 min"
	},	{
		"content": "\nChez Delicious Insights, nous avons toujours eu à cœur de faire que nos formations soient accessibles au plus grand nombre.\nÇa commence par des tarifs ajustés. Avec au maximum 500€ HT / jour / personne, on est en bas de la fourchette du marché pour des formations live (synchrones), en particulier vu leur niveau d’expertise.\nDes cerceaux en flamme 🔥\nOn est évidemment certifiés Qualiopi pour être éligibles aux financements mutualisés et publics (malheureusement hors CPF, qui a des exigences complémentaires ardues liées aux certifications reconnues par l’État).\nOn se contorsionne pour figurer dans les catalogues de Pôle Emploi (même si la prise en charge, elle, est aléatoire…) ; on fait une croix sur nos automatisations et on réplique nos catalogues et sessions chez les intermédiaires utilisés par de nombreux grands groupes, pour que leurs effectifs puissent venir.\nOn fait régulièrement des offres spéciales ; à l’époque de NodeSchool Paris, on faisait gagner des places de formation ; etc.\nTout ça est déjà super, mais hélas pour beaucoup d’entre vous, ça ne suffit pas.\nEncore trop de monde sur le carreau 🥹\nEn dépit de tous ces efforts, plusieurs catégories de personnes ne peuvent pas venir à nos formations faute d’un financement adéquat :\n\nLes demandeur·se·s d’emploi qui se voient refuser une prise en charge 😡\nLes particuliers, y compris les étudiant·e·s qui aimeraient compléter leur cursus\nLes indépendant·e·s, dont l’OPCO (ex. FIFPL) propose en général une prise en charge très partielle\nLes TPE et PME de la tranche 11–49 personnes, qui ont généralement les critères de financement les plus limitatifs auprès de leur OPCO (alors que c’est précisément à ce stade de croissance qu’on devrait leur mettre les watts en formation, pfff…). Résultat, faute souvent de pouvoir abonder le tarif avec leur tréso déjà tendue, ils cotisent à perte et ne vont pas se former…\n\nPour toutes ces personnes, qui ont pourtant un besoin vital de montée en compétences, même nos tarifs ajustés sont trop élevés.\nUn jour, nous serons éligibles au CPF. Mais même en carburant sur le sujet, outre que ça ne financera pas forcément tout et que ce n’est pas le rôle du CPF (pour des salarié·e·s en tout cas), ça ne sera pas avant mi-2024 vu les délais d’instruction des dossiers de certification, et puis ça n’aiderait pas les personnes qui n’ont pas encore travaillé suffisamment longtemps en salariat.\nAlors que faire ?\nLes workshops : nos Best Of à prix tout doux ! 😍\nNous avons décidé de proposer un format pour aider cette (large) cible, celles et ceux qui n’ont hélas pas accès à nos formations « classiques ».\nNous appelons ça les Workshops.\nLe concept est simple :\n\n🎖️ Focus sur le cœur de valeur de nos formations phares. On commence avec la JS Masterclass, qui pioche la quintessence du programme de ES Total et la Git Masterclass, qui fait pareil pour la Git Total.\n🎁 Un tarif le plus abordable possible, avec une grille simple :\n\n249€ TTC en tarif normal\n199€ TTC en tarif lancement les 10 jours suivant l’annonce\nDes tarifs TTC parce que quand les gens paient eux-mêmes, ils ne réfléchissent pas en HT. Et à ce prix-là, pour les employé·e·s ça peut souvent passer en note de frais, comme certaines licences logicielles, équipements, cours pré-enregistrés en ligne, etc.\n\n\n\nLes modalités sont aussi soigneusement étudiées :\n\n⚡ Résolument live / synchrone : un cours pré-enregistré, même avec plein d’éléments interactifs, ce n’est pas une formation. Là, vous avez un formateur en face, voire deux !\n📅 Sur une seule journée de 7 heures. C’est plus facile à incruster dans vos emplois du temps.\n💻 100% en ligne : ce n’est pas parce qu’il y a autant d’IT en Région Parisienne qu’on doit imposer transport et hébergement à tous les autres !\n🔄️ Replay illimité : si vous loupez un bout, ou voulez revoir une explication, pas de souci.\n🕹️ Multi-modal : juste regarder et écouter, 7 heures durant, c’est épuisant et on ne retient que quelques bouts. Pour garder la pêche et mieux ancrer les savoirs, on multiplie les segments : slides, démos, exercices interactifs, quizzes ludiques et compétitifs, tours de table, etc.\n📈 Plus grande capacité : nos formations classiques plafonnent à 10 participant·e·s. Pour aider plus de gens, nos Workshops montent à 40. Mais pour ne laisser tomber personne, on est deux sur le pont : un qui présente, l’autre qui surveille le chat et s’assure que toute question est traitée, qu’elle soit vocalisée ou non.\n💬 Une communauté autour de chaque Workshop, avec la mise à disposition d’un serveur Discord pour chacun, auquel les personnes inscrites ont accès à partir de quelques jours en amont, et sans limite de temps. Pour discuter avant, pendant, et surtout échanger après la formation, poser des questions, affiner sa compréhension, se faire de nouvelles relations, aller plus loin !\n🥰 Venez comme vous êtes : vous préférez ne pas garder votre webcam allumée ? Ne pas prendre la parole ? Sentez-vous libre. Interagissez via le chat et les nombreux se",
		"description": "Une journée de formation live, 100% en ligne, tarifée pour être accessible à tou·te·s, à très forte valeur ajoutée : ce sont les Workshops par Delicious Insights !",
		"date": 1686009600,
		"image": "/assets/images/art-vid/art-workshops.jpg",
    "_tags": ["workshops","git","js"],
		"title": "Le bon plan formation ultime : découvre nos Workshops",
		"url": "https://delicious-insights.com/fr/articles-et-tutos/workshops/",
		"locale": "fr",
		"readingTime": "4 min"
	}]
