<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>environnement de dev - Tag - Jordan Chapuy - Blog d'un développeur passionné ❤️</title><link>https://jordanchapuy.com/tags/environnement-de-dev/</link><description>environnement de dev - Tag - Jordan Chapuy - Blog d'un développeur passionné ❤️</description><generator>Hugo -- gohugo.io</generator><language>fr</language><lastBuildDate>Sat, 11 Jul 2026 10:46:00 +0200</lastBuildDate><atom:link href="https://jordanchapuy.com/tags/environnement-de-dev/" rel="self" type="application/rss+xml"/><item><title>Mise : un outil pour les gouverner tous</title><link>https://jordanchapuy.com/posts/2026/07/mise-un-outil-pour-les-gouverner-tous/</link><pubDate>Sat, 11 Jul 2026 10:46:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2026/07/mise-un-outil-pour-les-gouverner-tous/</guid><description><![CDATA[<p>Il y a trois ans (wow, c&rsquo;est loin, je ne m&rsquo;y attendais pas), j&rsquo;écrivais sur les version managers comme <a href="https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/" rel="">un moyen de faire cohabiter plusieurs versions d&rsquo;un langage, SDK et framework</a>. C&rsquo;est encore d&rsquo;actualité, et je le recommande toujours. Là aujourd&rsquo;hui, j&rsquo;ai envie de m&rsquo;étendre un peu plus sur une possibilité que j&rsquo;avais discrètement glissée dans mon post sans aller plus loin : et s&rsquo;il existait <strong>un seul outil pour gérer tous les autres</strong> ?</p>
<p>La réponse est oui, et j&rsquo;en utilise un depuis bientôt deux ans maintenant. Il s&rsquo;appelle <a href="https://mise.jdx.dev/" target="_blank" rel="noopener noreffer"><strong>mise-en-place</strong></a>, ou <code>mise</code> pour les intimes. Au départ, je l&rsquo;ai adopté pour une raison très simple : j&rsquo;en avais marre de chercher un nouveau version manager pour chaque écosystème.</p>
<p><code>nvm</code> pour Node.js. <code>pyenv</code> pour Python. <code>fvm</code> pour Flutter. <code>rustup</code> pour Rust. <code>chruby</code> pour Ruby. Un autre pour je ne sais quel SDK qui arrive sur un projet. Vous avez la musique. Chaque outil est souvent très bien dans son coin, mais l&rsquo;ensemble finit par créer une petite fatigue. Rien de dramatique, on va s&rsquo;en remettre, mais le genre de friction qui revient souvent.</p>
<p>Installer. Mettre à jour. Changer de version. Expliquer à un collègue quoi installer. Retrouver où la version est déclarée. Se souvenir si cette commande s&rsquo;applique globalement ou seulement dans le projet. La promesse de <code>mise</code> est assez agréable : <strong>apprendre une seule façon de faire, puis l&rsquo;appliquer aux autres d&rsquo;outils</strong>.</p>
<h2 id="un-version-manager-généraliste">Un version manager généraliste</h2>
<p><code>mise</code> se place dans la famille des gestionnaires de versions généralistes, comme <code>asdf</code> ou <code>vfox</code>. L&rsquo;idée n&rsquo;est donc pas de gérer uniquement Node.js, Ruby ou Python, mais de fournir <strong>une interface commune pour tout un ensemble de langages, runtimes, SDK et outils de développement</strong>.</p>
<p>Dans un projet, je peux vouloir Python 3.12, Node.js 22, Flutter 3.32, Terraform, Bun, ou encore un outil CLI dont l&rsquo;équipe a besoin. Plutôt que d&rsquo;empiler les gestionnaires spécialisés, je peux demander à <code>mise</code> de s&rsquo;en occuper. Derrière, il sait s&rsquo;appuyer sur plusieurs sources et backends selon les outils. Honnêtement, au quotidien, je n&rsquo;ai pas besoin d&rsquo;y penser. Et c&rsquo;est plutôt bon signe.</p>
<p>Ce n&rsquo;est pas le seul outil capable de faire ça. J&rsquo;avais déjà repéré <code>asdf</code> dans <a href="%28/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/%29" rel="">mon ancien article sur les version manager</a>, et <code>vfox</code> existe aussi dans le même esprit. Pourquoi j&rsquo;ai choisi <code>mise</code> ? Parce qu&rsquo;il m&rsquo;a semblé rapide, actif côté communauté, très fourni en outils supportés, et parce qu&rsquo;il ne s&rsquo;arrête pas au simple rôle de version manager. Je reviendrais dessus juste après.</p>
<p>Mais avant, commençons par le commencement. Installer mise. (Vérifiez tout de même le <a href="https://mise.jdx.dev/" target="_blank" rel="noopener noreffer">site officiel</a> si la méthode a changé entre temps) :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl https://mise.run <span class="p">|</span> sh
</span></span></code></pre></div><p>Si je veux installer Node.js globalement (tout mon PC), la commande ressemble à ça :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mise use -g node@26
</span></span></code></pre></div><p>Si je veux installer Python pour un projet (un dossier et ses enfants) :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mise use python@3.13
</span></span></code></pre></div><p>À partir de là, quand j&rsquo;entre dans le dossier du projet, <code>python</code> pointe vers la bonne version. Je tape <code>python</code>, pas <code>mise python</code>, pas <code>pyenv exec python</code>, pas une commande enveloppée avec un préfixe qui me sort du geste naturel. C&rsquo;est un détail, mais je trouve que ça compte. Quand je lance <code>flutter test</code>, j&rsquo;ai envie d&rsquo;écrire <code>flutter test</code>, pas de me rappeler que sur ce projet précis je dois écrire <code>fvm flutter test</code>.</p>
<h2 id="le-fichier-misetoml">Le fichier <code>mise.toml</code></h2>
<p>Là où <code>mise</code> devient vraiment intéressant, c&rsquo;est avec le fichier <code>mise.toml</code>.</p>
<p>Au début, on peut le voir comme un simple équivalent plus généraliste des fichiers <code>.ruby-version</code>, <code>.node-version</code>, <code>.tool-versions</code>, etc. On déclare les outils et les versions attendues par le projet, puis on versionne ce fichier avec le code. Comme ça, <strong>toute l&rsquo;équipe partage la même configuration</strong>.</p>
<p>Un exemple très simple pourrait ressembler à ça :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tools</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">node</span> <span class="p">=</span> <span class="s2">&#34;26&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">python</span> <span class="p">=</span> <span class="s2">&#34;3.13&#34;</span>
</span></span></code></pre></div><p>Ce n&rsquo;est pas spectaculaire, mais c&rsquo;est très pratique. Le projet dit explicitement &ldquo;pour travailler ici, voici les outils et versions attendues&rdquo;. Le nouveau collègue qui arrive, la machine fraîchement réinstallée, le runner de CI, le moi du futur qui aura tout oublié&hellip; tout le monde lit la même chose.</p>
<p>C&rsquo;est la fin des discussions du style :</p>
<blockquote>
<ul>
<li>Tu es sur quelle version de Node ?</li>
<li>Attends, je croyais qu&rsquo;on était passé en 26 ?</li>
<li>Ah non, sur cette branche il faut encore la version 25.</li>
<li>Pourquoi ça marche chez toi et pas chez moi ?</li>
</ul>
</blockquote>
<p>Bon, je m&rsquo;emballe, cette dernière question ne disparaît jamais totalement malheureusement. Ce serait trop beau. Mais on passe tout de même <strong>d&rsquo;un réglage individuel en un élément de projet versionnée</strong>.</p>
<h2 id="bien-plus-quun-version-manager">Bien plus qu&rsquo;un version manager</h2>
<p>La surprise, pour moi, c&rsquo;est que le fichier <code>mise.toml</code> ne s&rsquo;arrête pas aux outils. On peut aussi y déclarer des variables d&rsquo;environnement, et même des tâches. C&rsquo;est là que <code>mise</code> a commencé à dépasser, chez moi, le rôle du &ldquo;truc qui gère les versions&rdquo; et où je me suis dis que j&rsquo;allais le garder.</p>
<p>Les <strong>variables d&rsquo;environnement</strong>, c&rsquo;est le genre de chose qui finit souvent dans un <code>.env</code>, parfois un fichier différent par outils, ou pire dans une note. Avec <code>mise</code>, on peut les ajouter dans la configuration du projet. Pas les secrets, évidemment. Mais les valeurs non sensibles, les chemins, les réglages utiles au développement, oui.</p>
<p>Et puis il y a les <strong>tâches</strong>. On peut définir des commandes nommées, un peu comme on le ferait avec un <code>Makefile</code> ou des scripts maison. Sauf qu&rsquo;elles vivent dans le même fichier que la déclaration des outils.</p>
<p>Par exemple :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">setup</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">run</span> <span class="p">=</span> <span class="s2">&#34;mise install &amp;&amp; npm install&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">test</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">run</span> <span class="p">=</span> <span class="s2">&#34;npm test&#34;</span>
</span></span></code></pre></div><p>Je simplifie volontairement, mais l&rsquo;idée est là. Sur un projet, il suffit de taper <code>mise setup</code> et cette commande prépare ce qu&rsquo;il faut. Elle installe les outils attendus et prépare le terrain. C&rsquo;est le genre de petite attention qui rend un projet plus accueillant. (et encore une fois, plus &ldquo;future-proof&rdquo; avec notre mémoire)</p>
<p>J&rsquo;ai commencé à le faire sur tout mes nouveaux projets. Je crée un <code>mise.toml</code>, je le source, et petit à petit j&rsquo;y mets les commandes que je rejoue souvent. Pas besoin de se demander si c&rsquo;est <code>make init</code>, <code>npm run setup</code>, <code>./scripts/bootstrap.sh</code> ou autre chose. Pour moi, de plus en plus, c&rsquo;est <code>mise run setup</code>.</p>
<p>Même pour ce blog, j&rsquo;ai une tâche <code>new</code> pour préparer un nouveau post. Créer le dossier, créer un fichier avec un template de post, mettre la date, puis l&rsquo;ouvrir dans VS Code. Rien de révolutionnaire, mais j&rsquo;aime beaucoup écrire de petits scripts pour éviter de répéter les mêmes opérations - <a href="https://jordanchapuy.com/posts/2020/10/soyez-flemmard-ecrivez-des-scripts/" rel="">je suis un flemmard</a>.</p>
<p>Je vous ai parlé des <strong>alias</strong> ? Je peux faire encore plus court en tapant seulement <code>setup</code> ou <code>new</code>. Et ça marche pour tout, pas seulement pour les tâches - ce sont simplement des alias après tout.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">shell_alias</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">new</span> <span class="p">=</span> <span class="s2">&#34;mise run new&#34;</span>
</span></span></code></pre></div><p>Attendez, ce n&rsquo;est pas fini. On peut aller plus loin avec des <strong>hooks</strong> : des commandes qui se lanceront à chaque fois qu&rsquo;on entre/sort du projet, avant ou après une installation, ou même faire du <em>watch</em> ! Quand je vous disais que cet outil allait les gouverner tous. <em>Mon précieux, mon mise</em>.</p>
<h2 id="ce-qui-se-passe-derrière">Ce qui se passe derrière</h2>
<p>Sans rentrer dans un tutoriel complet, ça vaut le coup de comprendre grossièrement comment <code>mise</code> s&rsquo;intègre au terminal.</p>
<p>Le principe de base est assez classique : <code>mise</code> installe les outils dans un de ses dossiers, puis modifie dynamiquement le contenu du <code>PATH</code>. Quand je suis dans un dossier avec un <code>mise.toml</code>, l&rsquo;environnement actif change, et la commande <code>node</code>, <code>python</code> ou <code>flutter</code> pointe vers la version déclarée.</p>
<p>C&rsquo;est aussi pour ça que l&rsquo;expérience reste <strong>très rapide</strong>. En fait, elle est même inchangée. On ne lance pas un gros proxy à chaque commande. Le shell sait directement où chercher les exécutables.</p>
<p>Il existe aussi un mode avec des <em>shims</em> si on en a besoin, c&rsquo;est-à-dire des petits exécutables intermédiaires qui redirigent vers la bonne version. Selon les environnements ou IDE, ça peut être utile. J&rsquo;ai dû passer par les <em>shims</em> pour l&rsquo;extension Flutter de VS Code par exemple.</p>
<p>Je trouve cette partie intéressante parce qu&rsquo;elle répond à une inquiétude que j&rsquo;avais avec certains version managers : est-ce que je vais ralentir mon terminal ? C&rsquo;était par exemple le cas avec <a href="https://jordanchapuy.com/posts/2023/12/mon-terminal-et-zsh-sont-long-a-demarrer-blame-nvm/" rel="">nvm qui est long à démarrer</a>, même si on ne l&rsquo;utilise pas.</p>
<h2 id="bref">Bref</h2>
<p>Au départ, je cherchais surtout un version manager généraliste. Je voulais arrêter d&rsquo;accumuler un outil par langage. <code>mise</code> m&rsquo;a donné ça : une manière commune d&rsquo;installer, mettre à jour et changer de version. Et il est même allé là où je ne l&rsquo;attendais pas avec les variables d&rsquo;environnement et les tâches.</p>
<p>Aujourd&rsquo;hui, je n&rsquo;installe quasiment plus de langage ou de SDK à la main. Flutter ? Via <code>mise</code>. Python ? Via <code>mise</code>. Les outils autour d&rsquo;<a href="https://jordanchapuy.com/posts/2026/06/maintenir-et-reinstaller-son-homelab-proxmox-avec-ansible-sans-tout-refaire-a-la-main/" rel="">Ansible</a> dont je parlais récemment ? Via <code>mise</code> aussi.</p>
<p>Quand je démarre un projet, mon premier réflexe est de créer et compléter le <code>mise.toml</code> au fur et à mesure pour réduire les frictions. À force, ça devient moins un outil de gestion de versions qu&rsquo;un petit <strong>chef d&rsquo;orchestre</strong> pour mon environnement de développement.</p>
]]></description></item><item><title>Mon terminal et zsh sont long à démarrer (blame nvm)</title><link>https://jordanchapuy.com/posts/2023/12/mon-terminal-et-zsh-sont-long-a-demarrer-blame-nvm/</link><pubDate>Fri, 29 Dec 2023 15:44:00 +0100</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2023/12/mon-terminal-et-zsh-sont-long-a-demarrer-blame-nvm/</guid><description><![CDATA[<p>Le terminal, c&rsquo;est une sorte de couteau suisse pour les développeurs. Il permet de faire énormément de choses - presque tout d&rsquo;ailleurs - et on s&rsquo;en sert très souvent. Alors quand le temps de lancement du terminal s&rsquo;allonge, je ne vous cache pas que c&rsquo;est très embêtant.</p>
<p>C&rsquo;était mon cas avec iTerm2 + oh-my-zsh, et on va voir comment trouver les problèmes à la source.</p>
<h1 id="identifier-les-causes">Identifier les causes</h1>
<p>Je n&rsquo;ai pas forcément fait attention au moment exact où mon terminal a commencé à être capricieux pour se lancer. J&rsquo;ai l&rsquo;impression que ça a commencé la semaine marquée par l&rsquo;arrivée d&rsquo;un nouveau super pouvoir du MDM sur nos machines pro. Il analysait toutes les commandes exécutées pour vérifier les bons privilèges à appliquer.</p>
<p>Une belle coïncidence, c&rsquo;était le suspect parfait. Je l&rsquo;ai un peu blâmé sans trop chercher plus loin. Et puis un jour, il est arrivé ce fameux imprévu qui permet au héros de se lancer dans l&rsquo;aventure.</p>
<p>J&rsquo;étais en pair avec un collègue pour l&rsquo;aider sur une erreur autour de cocoapods et iOS. Je lui fais installer un <a href="https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/" rel="">version manager</a> pour Ruby, on modifie son <code>.zshrc</code>, et on veut supprimer le <code>Podfile.lock</code> pour réinstaller proprement les packages. Mais dans la rapidité de l&rsquo;action, il tape <code>rm .zshrc</code>. Aïe. Coup dur.</p>
<p>À ce moment-là, mon collègue est un peu dégoûté - je l&rsquo;aurais été aussi. Avec <code>rm</code>, ça ne part pas à la corbeille, on ne récupère pas facilement ce que l&rsquo;on a supprimé. Ça l&rsquo;embête parce qu&rsquo;il avait effectué plusieurs configurations dedans, et qu&rsquo;il avait passé une heure avec la DSI pour optimiser le temps de chargement. Hop hop hop, attends. Quoi ?!</p>
<p>Lui aussi avait son terminal qui était long au lancement, et de mémoire, ça venait en partie de l&rsquo;initialisation de <code>nvm</code>. Me voilà avec une piste intéressante. Je l&rsquo;ai gardée dans un coin de tête, jusqu&rsquo;à hier soir où j&rsquo;ai fouillé les internets avec une idée de direction plus précise.</p>
<h2 id="mesurer-le-temps">Mesurer le temps</h2>
<p>À l&rsquo;aide de deux instructions, on peut obtenir un rapport avec les différentes étapes exécutées au lancement de <code>zsh</code> et le temps associé.</p>
<p>Il suffit de modifier le fichier <code>.zshrc</code> pour y ajouter <code>zmodload zsh/zprof</code> au tout début, à la première ligne. On quitte le terminal, on le relance et on tape la commande <code>zprof</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">num  calls                <span class="nb">time</span>                       self            name
</span></span><span class="line"><span class="cl">-----------------------------------------------------------------------------------
</span></span><span class="line"><span class="cl"> 1<span class="o">)</span>    <span class="m">2</span>        3047,39  1523,69   43,08%   2046,60  1023,30   28,93%  nvm
</span></span><span class="line"><span class="cl"> 2<span class="o">)</span>    <span class="m">1</span>        4998,69  4998,69   70,66%   1951,31  1951,31   27,58%  nvm_auto
</span></span><span class="line"><span class="cl"> 3<span class="o">)</span>    <span class="m">1</span>         821,18   821,18   11,61%    665,29   665,29    9,40%  nvm_ensure_version_installed
</span></span><span class="line"><span class="cl"> 4<span class="o">)</span>    <span class="m">1</span>         563,64   563,64    7,97%    563,64   563,64    7,97%  is_update_available
</span></span><span class="line"><span class="cl"> 5<span class="o">)</span>    <span class="m">1</span>         743,74   743,74   10,51%    180,11   180,11    2,55%  /.oh-my-zsh/tools/check_for_upgrade.sh
</span></span><span class="line"><span class="cl"> 6<span class="o">)</span>    <span class="m">1</span>         176,44   176,44    2,49%    174,59   174,59    2,47%  nvm_die_on_prefix
</span></span><span class="line"><span class="cl"> 7<span class="o">)</span>    <span class="m">1</span>         155,88   155,88    2,20%    155,88   155,88    2,20%  nvm_is_version_installed
</span></span><span class="line"><span class="cl"> 8<span class="o">)</span>    <span class="m">1</span>          93,04    93,04    1,32%     51,05    51,05    0,72%  compinit
</span></span></code></pre></div><p>Dans ce tableau, on retrouve le nom des étapes, le temps, le pourcentage du temps par rapport à l&rsquo;ensemble, et c&rsquo;est même classé dans l&rsquo;ordre du plus long au plus rapide.</p>
<p>Sur ma machine, je vois clairement que <code>nvm</code> est dans le haut du panier. Plusieurs noms d&rsquo;étapes semblent liées à <code>nvm</code> et elles prennent énormément de temps. Je vais donc optimiser le lancement de <code>nvm</code>, le reste me semble anecdotique. Je le ferais ou pas un jour. Sûrement jamais. :)</p>
<h1 id="améliorer-linitialisation-de-nvm">Améliorer l&rsquo;initialisation de nvm</h1>
<p>J&rsquo;ai trouvé plusieurs moyens pour pallier la lenteur de <code>nvm</code>.</p>
<h2 id="supprimer-nvm-du-zshrc">Supprimer nvm du .zshrc</h2>
<p>Quand on installe <code>nvm</code>, il y a des instructions à ajouter dans notre configuration <code>.zshrc</code>. Leurs rôles sont de charger <code>nvm</code>, de s&rsquo;assurer qu&rsquo;il est à jour, de préparer l&rsquo;auto-complétion, etc. C&rsquo;est ce qui ralentit le lancement de notre terminal. Ces instructions ressemblent à ça :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">NVM_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nvm&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">[</span> -s <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="se">\.</span> <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh&#34;</span>  <span class="c1"># This loads nvm</span>
</span></span><span class="line"><span class="cl">    <span class="o">[</span> -s <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/bash_completion&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="se">\.</span> <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/bash_completion&#34;</span>  <span class="c1"># This loads nvm bash_completion</span>
</span></span></code></pre></div><p>Bon. Eh bien de manière pragmatique, on peut supprimer ces instructions de notre configuration <code>.zshrc</code> et le temps de lancement sera grandement amélioré. Si on n&rsquo;utilise plus <code>nvm</code>, <code>node</code> et compagnie, ou très peu souvent, on n&rsquo;a pas envie de pourrir l&rsquo;expérience nominale de notre terminal.</p>
<h2 id="lazy-loading-de-nvm">Lazy loading de nvm</h2>
<p>Une autre solution serait d&rsquo;initialiser <code>nvm</code> uniquement lorsque l&rsquo;on en a besoin. Quand on tapera une commande avec <code>nvm</code>, <code>node</code> ou <code>npm</code> par exemple. C&rsquo;est du lazy loading. Ce serait l&rsquo;idéal si on veut conserver <code>nvm</code> et que l&rsquo;on veut éviter de ralentir le lancement du terminal.</p>
<p>Il est possible de le faire soi-même en créant quelques fonctions bash comme l&rsquo;explique <a href="https://broken-by.me/lazy-load-nvm/" target="_blank" rel="noopener noreffer">cet article</a>. On peut aussi utiliser le système de plugin de <code>zsh</code>. Luke en a créé un pour nvm : <a href="https://github.com/lukechilds/zsh-nvm" target="_blank" rel="noopener noreffer">zsh-nvm</a>. J&rsquo;ai opté pour cette solution.</p>
<ul>
<li>La première étape est de supprimer les éventuelles instructions <code>nvm</code> de notre fichier <code>.zshrc</code> (cf. partie précédente).</li>
<li>On installe ensuite le plugin <a href="https://github.com/lukechilds/zsh-nvm?tab=readme-ov-file#installation" target="_blank" rel="noopener noreffer">zsh-nvm</a>.</li>
<li>On modifie le fichier <code>.zshrc</code> pour ajouter <code>zsh-nvm</code> dans la liste des plugins.
<ul>
<li>La ligne ressemble à <code>plugins=(.......)</code>.</li>
</ul>
</li>
<li>On indique au plugin que l&rsquo;on veut du lazy loading.
<ul>
<li>On ajoute <code>export NVM_LAZY_LOAD=true</code> juste avant la liste des plugins.</li>
</ul>
</li>
<li>On peut ajouter l&rsquo;auto-complétion si nécessaire.
<ul>
<li>En ajoutant également <code>export NVM_COMPLETION=true</code> avant la liste des plugins.</li>
</ul>
</li>
</ul>
<h2 id="changer-de-version-manager-pour-node">Changer de version manager pour node</h2>
<p>Vu que <code>nvm</code> est le fautif et qu&rsquo;il existe d&rsquo;autres version manager pour node, on peut se demander s&rsquo;il en existe qui sont plus rapides.</p>
<p>Ça semble être le cas pour <a href="https://github.com/Schniz/fnm" target="_blank" rel="noopener noreffer">fnm (Fast Node Manager)</a>. Son nom est revenu plusieurs fois pendant mes recherches et dans les commentaires de personnes qui proposaient des alternatives au lazy loading de <code>nvm</code>. Je ne l&rsquo;ai pas essayé.</p>
<p>Il y a également <a href="https://asdf-vm.com/" target="_blank" rel="noopener noreffer">asdf</a>, un outil unique qui propose de gérer les versions de multiples autres outils (node, Ruby, python, &hellip;). J&rsquo;en parlais dans mon article sur <a href="https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/" rel="">les version manager</a>. Il serait plus rapide que <code>nvm</code> d&rsquo;après ce que j&rsquo;ai lu. À tester. Je pense que je finirais par me passer de mes autres version manager pour tout regrouper avec <code>asdf</code>.</p>
<hr>
<p>Quelques références de contenu que j&rsquo;ai parcouru :</p>
<ul>
<li><a href="https://dev.to/thraizz/fix-slow-zsh-startup-due-to-nvm-408k" target="_blank" rel="noopener noreffer">https://dev.to/thraizz/fix-slow-zsh-startup-due-to-nvm-408k</a></li>
<li><a href="https://blog.mattclemente.com/2020/06/26/oh-my-zsh-slow-to-load/" target="_blank" rel="noopener noreffer">https://blog.mattclemente.com/2020/06/26/oh-my-zsh-slow-to-load/</a></li>
<li><a href="https://broken-by.me/lazy-load-nvm/" target="_blank" rel="noopener noreffer">https://broken-by.me/lazy-load-nvm/</a></li>
<li><a href="https://stackoverflow.com/questions/47009776/how-to-run-nvm-in-oh-my-zsh" target="_blank" rel="noopener noreffer">https://stackoverflow.com/questions/47009776/how-to-run-nvm-in-oh-my-zsh</a></li>
</ul>
]]></description></item><item><title>Des Version Manager pour faire cohabiter plusieurs versions d’un langage, SDK et framework</title><link>https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/</link><pubDate>Mon, 29 May 2023 19:10:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/</guid><description><![CDATA[<p>Ruby, Python, Rust, Node.js, Flutter, &hellip; Comme tout objet dans le monde, les langages, frameworks et outils sont amenés à changer avec le temps. Version mineur par-ci, version majeure par-là. Comment jongler facilement entre les versions ?</p>
<p>Quand on est développeur, on utilise tout un tas d’outils et de SDK. Parfois sur plusieurs projets, qui utilisent des versions différentes bien évidemment. Je peux avoir besoin de Node.js 19 pour le front web et de Node.js 16 pour le backend. Je peux travailler à la fois sur une app Flutter en Dart 2 et une autre en Dart 3. J&rsquo;ai peut-être besoin d&rsquo;une version différente de Python sur mon poste et sur la CI.</p>
<p>Ou parfois sur le même projet avec des branches différentes. Je commence à migrer vers Dart 3 sur une branche, j’ai un bug de prod à corriger il faut que je retourne sur la branche principale qui elle est sous Dart 2.</p>
<p>Si on installe des versions spécifiques à la main, à quoi ressemble notre acrobatie ?</p>
<p>On désinstalle la version X. On télécharge et installe la version Y. On joue avec. On désinstalle la version Y. On télécharge et réinstalle la version X. À chaque étape, c’est un peu de temps perdu. Certains outils sont en plus lourds à télécharger et installer, on se retrouve vite à ouvrir son navigateur ou téléphone et sortir de notre flow :)</p>
<p>C’est là qu’interviennent les outils de gestion de versions.</p>
<h2 id="principe-général">Principe général</h2>
<p>L&rsquo;idée est simple. Plutôt que d’installer directement la toolchain d’un langage par exemple, on va installer l’outil de gestion de version dédié à tel ou tel langage. Chaque langage a son propre gestionnaire, et ce sont souvent des projets open-source. Ils se reconnaissent facilement à leur nom :  ils sont souvent suffixés par <code>Version Manager</code> ou <code>Version Management</code>.</p>
<p>C’est ensuite via le Version Manager que l’on va installer la ou les versions du langage dont on a besoin. Les différentes versions seront installées dans un sous-dossier de l’outil et ne vont pas venir directement s’écraser entre elles dans le dossier <code>/bin</code> (comme ce pourrait être le cas avec une installation classique). On peut ainsi en avoir <strong>plusieurs téléchargées et installées</strong> sur un poste, directement <strong>prêtes à l’emploi</strong>.</p>
<p>Une fois qu’on a installé les versions qui nous intéressent, il n’y a plus qu’à indiquer la version par défaut via <strong>une simple commande</strong>. Et quand on veut changer ? Une commande et c’est opérationnel dans la même seconde. On jongle très facilement avec de multiples versions, branches, projets.</p>
<h2 id="switch-automatique">Switch automatique</h2>
<p>Mieux encore. On peut aller un cran plus loin avec certains Version Manager : <strong>la version utilisée change automatiquement en fonction du projet que l’on ouvre</strong>. C’est le cas avec Ruby par exemple. Il suffit de créer un fichier <code>.ruby-version</code>, d’y écrire le numéro de la version (<code>3.2.2</code>), et de le placer dans le dossier racine du projet. Simple, basique.</p>
<p>L’outil de Version Manager détectera ce fichier et changera la version de Ruby utilisée de manière transparente et automatique. On jongle entre des projets et des branches sans aucune adhérence. On voit encore plus la puissance de ces outils ici.</p>
<p>L&rsquo;intérêt de tels fichiers se retrouve aussi dans le travail en équipe. Le fichier est versionné au sein du projet, ce qui permet à <strong>tous les développeurs d&rsquo;utiliser systématiquement les mêmes versions</strong>.</p>
<h2 id="quelques-exemples">Quelques exemples</h2>
<p>Vous en connaissez probablement déjà quelques uns, voire les utilisez. En voici quelques-uns que j&rsquo;utilise :</p>
<ul>
<li>Si vous travaillez sur des projets web, vous jouez peut-être avec Node.js. Et si vous avez envie de jongler, allez voir du côté de <a href="https://github.com/nvm-sh/nvm" target="_blank" rel="noopener noreffer">nvm (Node Version Manager)</a>.</li>
<li>Des applications mobiles avec Flutter ? <a href="https://github.com/fluttertools/fvm" target="_blank" rel="noopener noreffer">fvm (Flutter Version Management)</a> est là pour nous aider. Il gère aussi le langage Dart.</li>
<li><a href="https://github.com/postmodern/chruby" target="_blank" rel="noopener noreffer">chruby</a>. Il en existe d&rsquo;autres pour Ruby (rvm et rbenv), mais j&rsquo;ai préféré celui-ci car il est léger et il bidouille moins le système (rvm et rbenv surchargent la commande <code>cd</code> par exemple).</li>
<li><a href="https://github.com/pyenv/pyenv" target="_blank" rel="noopener noreffer">pyenv (Python Version Management)</a>.</li>
<li><a href="https://github.com/rust-lang/rustup" target="_blank" rel="noopener noreffer">Rustup (Rust toolchain installer)</a>.</li>
</ul>
<p>La question que vous vous posez peut-être maintenant, c&rsquo;est <em>est-ce qu&rsquo;il en existe un seul pour les gouverner tous</em> ? Jusqu&rsquo;à maintenant, je n&rsquo;avais pas connaissance d&rsquo;un Version Manager qui gérait de multiples runtimes. Mais pendant l&rsquo;écriture de cet article, j&rsquo;ai effectué de rapides recherches et j&rsquo;ai découvert des outils. C&rsquo;est aussi pour ça que j&rsquo;aime écrire, ça me permet de prendre du recul, de chercher davantage, de trouver de nouvelles choses.</p>
<p>En voici deux : <a href="https://github.com/asdf-vm/asdf" target="_blank" rel="noopener noreffer">asdf</a> et <a href="https://github.com/jdxcode/rtx" target="_blank" rel="noopener noreffer">rtx</a>. Je n&rsquo;ai fait aucun test pour le moment, mais je compte bien essayer et vous en parler à l&rsquo;occasion. Si vous avez des retours d&rsquo;expérience avec ces outils, ou d&rsquo;autres, je suis preneur.</p>
<h2 id="contre-parties">Contre-parties</h2>
<p>Il peut y avoir un peu plus de configs et d’étapes à la première installation d&rsquo;un Version Manager, versus installer directement le langage/SDK. Pour autant, cela reste relativement court et facile.</p>
<p>Autre effet de bord pour certains Version Manager, il faut parfois exécuter le langage/SDK via l’outil - ils agissent comme un proxy. Par exemple, on tapera la commande <code>fvm flutter test</code> au lieu de <code>flutter test</code>.</p>
<p>De mon point de vue, j&rsquo;accepte pleinement ces deux points. Je trouve ces inconvénients largement acceptables et plus faibles que les avantages qu’ils apportent - <strong>je peux facilement jongler entre des versions, voire le rendre automatique entre mes projets et mes collègues</strong>.</p>
<p>Mais, il reste une question en suspens. Qui manage les versions des gestionnaires de versions ? 🙃</p>
<p>Une ouverture parfaite pour vous quitter. J&rsquo;y réponds quand même avant de ranger ma plume. A priori, le besoin de jongler à ce niveau n’existe pas. Je les ai installés via <a href="https://brew.sh/" target="_blank" rel="noopener noreffer">Homebrew</a>, le gestionnaire de paquet pour macOS, et c&rsquo;est très bien ainsi.</p>
]]></description></item></channel></rss>