<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[Code-Garage]]></title>
        <description><![CDATA[Code-Garage]]></description>
        <link>https://code-garage.com</link>
        <generator>RSS for Node</generator>
        <lastBuildDate>Sun, 05 Apr 2026 13:04:55 GMT</lastBuildDate>
        <atom:link href="https://code-garage.com/blog/rss" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[La différence entre RUN et CMD avec Docker]]></title>
            <description><![CDATA[Découvrez la différence entre RUN et CMD dans Docker, leur rôle dans un Dockerfile et comment éviter les erreurs courantes.]]></description>
            <link>https://code-garage.com/blog/la-difference-entre-run-et-cmd-avec-docker</link>
            <guid isPermaLink="true">https://code-garage.com/blog/la-difference-entre-run-et-cmd-avec-docker</guid>
            <category><![CDATA[Docker]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Tue, 31 Mar 2026 14:43:51 GMT</pubDate>
            <content:encoded><![CDATA[<p>Quand vous écrivez votre premier Dockerfile, les instructions <code>RUN</code> et <code>CMD</code> qui prêtent souvent à confusion.</p>
<blockquote>
<p>Elles peuvent sembler similaires… mais elles n’ont <strong>absolument pas le même rôle</strong>.</p>
</blockquote>
<p>À noter que <strong>si vous ne connaissez pas Docker</strong>, cet article ne vous sera pas très utile, mais vous pouvez toujours aller écouter notre introduction à Docker dans <a href="https://code-garage.com/podcast/classic/episode-145">un épisode dédié du podcast</a> !</p>
<h2>La commande RUN</h2>
<p><code>RUN</code> est utilisé <strong>lors de la construction de l’image Docker</strong>.</p>
<p>Par exemple :</p>
<pre><code class="language-docker">RUN apt-get update &amp;&amp; apt-get install -y curl
</code></pre>
<p>Cette commande est exécutée :</p>
<ul>
<li>pendant le <code>docker build</code></li>
<li>pour modifier l’image</li>
</ul>
<blockquote>
<p><code>RUN</code> sert à <strong>préparer l’image.</strong></p>
</blockquote>
<p>Chaque instruction <code>RUN</code> crée une nouvelle couche dans l’image Docker.</p>
<p>Typiquement, vous utilisez <code>RUN</code> pour :</p>
<ul>
<li>installer des dépendances</li>
<li>copier ou générer des fichiers</li>
<li>configurer l’environnement</li>
</ul>
<h2>La commande CMD</h2>
<p><code>CMD</code> est utilisée <strong>lors du lancement du conteneur</strong>.</p>
<p>Par exemple :</p>
<pre><code class="language-docker">CMD [&quot;node&quot;, &quot;server.js&quot;]
</code></pre>
<p>Cette commande est exécutée :</p>
<ul>
<li>quand vous faites <code>docker run</code></li>
<li>au démarrage du conteneur</li>
</ul>
<blockquote>
<p><code>CMD</code> sert à dire : “voilà ce que fait ce conteneur quand il démarre”.</p>
</blockquote>
<h2>La différence clé</h2>
<p>La différence principale tient en une phrase :  <code>RUN</code> s’exécute <strong>pendant le build</strong> tandis que <code>CMD</code> s’exécute <strong>au runtime</strong>.</p>
<p>Autrement dit :</p>
<ul>
<li><code>RUN</code> modifie l’image</li>
<li><code>CMD</code> définit le comportement du conteneur</li>
</ul>
<h3>Un exemple concret</h3>
<p>Prenons un Dockerfile simple :</p>
<pre><code class="language-docker">FROM node:18
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .

CMD [&quot;node&quot;, &quot;index.js&quot;]
</code></pre>
<p>Ce qu’il se passe :</p>
<ol>
<li><code>RUN npm install</code> installe les dépendances <strong>dans l’image</strong></li>
<li><code>CMD [&quot;node&quot;, &quot;index.js&quot;]</code> lance l’application <strong>au démarrage</strong></li>
</ol>
<blockquote>
<p>Sans <code>CMD</code>, le conteneur ne ferait rien.</p>
</blockquote>
<h2>Pour aller plus loin</h2>
<h3>CMD peut être remplacé</h3>
<p>Par exemple :</p>
<pre><code class="language-bash">docker run mon-image echo &quot;Hello&quot;
</code></pre>
<p>Ici :</p>
<ul>
<li><code>CMD</code> est ignoré</li>
<li>la commande <code>echo &quot;Hello&quot;</code> est exécutée</li>
</ul>
<blockquote>
<p><code>CMD</code> est une valeur par défaut.</p>
</blockquote>
<h3>Le système de couches (layers)</h3>
<p>Chaque <code>RUN</code> ajoute une couche à votre image.</p>
<p>Par exemple :</p>
<pre><code class="language-docker">RUN apt-get update
RUN apt-get install -y curl
</code></pre>
<blockquote>
<p>Crée deux couches.</p>
</blockquote>
<p>Les différentes couches sont utilisées par Docker pour optimiser la mémoire utilisée par les images, car <strong>les couches similaires sont partagées entre les différents conteneurs !</strong></p>
<h2>Résumé de l'article</h2>
<p><code>RUN</code> et <code>CMD</code> sont complémentaires.</p>
<ul>
<li>utilisez <code>RUN</code> pour construire votre environnement (exécuté pendant le build)</li>
<li>utilisez <code>CMD</code> pour lancer votre application (exécuté au runtime)</li>
</ul>
<blockquote>
<p>Si vous les confondez, votre conteneur ne fera probablement pas ce que vous attendez.</p>
</blockquote>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_pixel_art_scene_of_a_bakery_kitchen_where_3880f6c2_e944_4407_b1c9_8894f91a32c5_9435666357.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Git : comment supprimer tous les fichiers en dehors de l’historique]]></title>
            <description><![CDATA[Découvrez comment supprimer les fichiers non suivis par Git après un git reset, avec git clean, les bonnes options et les précautions à connaître.]]></description>
            <link>https://code-garage.com/blog/git-comment-supprimer-tous-les-fichiers-en-dehors-de-l-historique</link>
            <guid isPermaLink="true">https://code-garage.com/blog/git-comment-supprimer-tous-les-fichiers-en-dehors-de-l-historique</guid>
            <category><![CDATA[Git]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Thu, 26 Mar 2026 09:57:15 GMT</pubDate>
            <content:encoded><![CDATA[<p>Quand on utilise Git, il y a une situation assez classique qui finit toujours par arriver.</p>
<blockquote>
<p>un <code>git reset</code>.</p>
</blockquote>
<p>Vous revenez en arrière, vous changez d’état, vous annulez un commit ou vous bougez votre branche… et là, en regardant votre projet, <strong>vous vous retrouvez avec plein de fichiers qui traînent.</strong></p>
<p>Parfois ce sont :</p>
<ul>
<li>des fichiers générés</li>
<li>des dossiers de build</li>
<li>des fichiers temporaires</li>
<li>des morceaux d’un ancien état du projet</li>
</ul>
<blockquote>
<p>Et dans <code>git status</code>, vous voyez apparaître <strong>une longue liste de fichiers “nouveaux”</strong>.</p>
</blockquote>
<p>Git ne les a pas supprimés, parce qu’ils ne font pas partie des fichiers suivis à cet instant. <strong>Mais si vous souhaitez vous en débarasser</strong> (autrement qu’en supprimant tout à la main), voilà comment faire !</p>
<h2>La bonne commande : git clean</h2>
<p>Pour supprimer les fichiers non suivis, Git propose cette commande :</p>
<pre><code class="language-bash">git clean -f
</code></pre>
<p>Cette commande supprime les fichiers non suivis du dossier courant.</p>
<p>Mais attention :</p>
<blockquote>
<p><code>git clean</code> est une commande destructive.</p>
<p>Une fois les fichiers supprimés, Git ne pourra pas les restaurer.</p>
</blockquote>
<h2>Le mode simulation</h2>
<p>Avant de lancer une suppression, le bon réflexe est d’utiliser :</p>
<pre><code class="language-bash">git clean -n
</code></pre>
<blockquote>
<p>Le <code>-n</code> signifie <em><strong>dry run</strong></em>. C’est probablement l’option la plus importante de toute la commande.</p>
</blockquote>
<p>Git affiche ce qu’il supprimerait, sans réellement le faire. Si vous avez beaucoup de fichiers apparus après un <code>git reset</code>, <strong>commencez toujours par là.</strong></p>
<h2>Supprimer les dossiers</h2>
<p>Par défaut, <code>git clean</code> ne supprime pas les dossiers non suivis.</p>
<p>Or après un reset, ce sont souvent justement des dossiers entiers qui traînent :</p>
<ul>
<li><code>dist/</code></li>
<li><code>build/</code></li>
<li><code>.cache/</code></li>
<li>anciens dossiers générés</li>
</ul>
<p>Pour inclure les dossiers, utilisez :</p>
<pre><code class="language-bash">git clean -fd
</code></pre>
<ul>
<li><code>f</code> pour forcer</li>
<li><code>d</code> pour inclure les répertoires</li>
</ul>
<blockquote>
<p>Dans beaucoup de cas, après un <code>git reset</code>, c’est cette commande qu’on cherche vraiment.</p>
</blockquote>
<h2>Inclure les fichiers ignorés par .gitignore</h2>
<p>Il y a un autre cas fréquent.</p>
<p>Vous faites un reset, puis vous voulez repartir d’un projet vraiment propre.</p>
<p>Mais certains fichiers sont ignorés par Git via <code>.gitignore</code> :</p>
<ul>
<li>dossiers de build</li>
<li>fichiers d’environnement</li>
<li>caches</li>
<li>dépendances générées</li>
</ul>
<p>Par défaut, <code>git clean</code> ne les supprime pas.</p>
<p>Si vous voulez aussi supprimer ces fichiers ignorés, il faut utiliser :</p>
<pre><code class="language-bash">git clean -fdx
</code></pre>
<p>Cette commande supprime :</p>
<ul>
<li>les fichiers non suivis</li>
<li>les dossiers non suivis</li>
<li>les fichiers ignorés par <code>.gitignore</code></li>
</ul>
<blockquote>
<p>Elle est très utile pour remettre un projet dans <strong>un état vraiment propre.</strong></p>
</blockquote>
<p>Mais elle doit être utilisée <strong>avec une grande prudence.</strong></p>
<h3>Supprimer UNIQUEMENT les fichiers ignorés</h3>
<p>Pour ne supprimer que les fichiers présents dans <code>.gitignore</code> ,on utilise le paramètre <code>-X</code> (à ne pas confondre avec <code>-x</code>) :</p>
<pre><code class="language-bash">git clean -fdX
</code></pre>
<blockquote>
<p>Supprime <strong>uniquement les fichiers ignorés</strong></p>
</blockquote>
<h2>Conclusion</h2>
<p>Retenez surtout ceci :</p>
<ul>
<li><code>git clean -n</code> permet de vérifier avant</li>
<li><code>git clean -fd</code> supprime fichiers + dossiers</li>
<li><code>git clean -fdx</code> fait le ménage complet</li>
</ul>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_pixel_art_scene_of_a_cluttered_room_being_30f18ffc_8d51_4962_85d1_b4d864a4e024_351ab3051d.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Comment ne pas exécuter les scripts tiers avec npm, pnpm et yarn]]></title>
            <description><![CDATA[Découvrez comment utiliser npm install --ignore-scripts pour empêcher l’exécution de scripts dangereux ou inutiles lors de l’installation des dépendances npm.]]></description>
            <link>https://code-garage.com/blog/comment-ne-pas-executer-les-scripts-tiers-avec-npm-pnpm-et-yarn</link>
            <guid isPermaLink="true">https://code-garage.com/blog/comment-ne-pas-executer-les-scripts-tiers-avec-npm-pnpm-et-yarn</guid>
            <category><![CDATA[NodeJS]]></category>
            <category><![CDATA[NPM]]></category>
            <category><![CDATA[PNPM]]></category>
            <category><![CDATA[Yarn]]></category>
            <category><![CDATA[Sécurité]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Tue, 17 Mar 2026 08:50:43 GMT</pubDate>
            <content:encoded><![CDATA[<p>Quand vous installez un projet Node.js, il y a un réflexe très courant :</p>
<pre><code class="language-bash">npm install
</code></pre>
<p>Cette commande semble anodine. Elle télécharge simplement les dépendances listées dans le <code>package.json</code>.</p>
<p>Mais en réalité, <strong>npm peut aussi exécuter du code</strong> pendant l’installation.</p>
<p>Beaucoup de développeurs l’ignorent, mais certains packages contiennent des scripts qui s’exécutent automatiquement lors de l’installation. Et dans certains cas, ces scripts peuvent poser problème : comportements inattendus, téléchargements lourds… ou pire, <strong>scripts malveillants</strong>.</p>
<p>Heureusement, npm propose une option simple pour éviter cela :</p>
<pre><code class="language-bash">npm install --ignore-scripts
</code></pre>
<blockquote>
<p>Cette option empêche npm d’exécuter les scripts définis dans les dépendances.</p>
</blockquote>
<h2>Les scripts exécutés automatiquement par npm</h2>
<p>Dans un <code>package.json</code>, un package peut définir plusieurs scripts.</p>
<p>Par exemple :</p>
<pre><code class="language-json">{
  &quot;scripts&quot;: {
    &quot;postinstall&quot;: &quot;node build.js&quot;
  }
}
</code></pre>
<blockquote>
<p>npm peut exécuter automatiquement certains scripts pendant l’installation.</p>
</blockquote>
<p>Les plus courants sont :</p>
<ul>
<li><code>preinstall</code></li>
<li><code>install</code></li>
<li><code>postinstall</code></li>
<li><code>prepare</code></li>
</ul>
<p>Ces scripts sont souvent utilisés pour compiler du code natif, télécharger des binaires, générer des fichiers nécessaires au package, préparer des assets, etc…</p>
<blockquote>
<p>Le problème, c’est que <strong>npm exécute ces scripts automatiquement</strong>, sans vous demander votre avis.</p>
</blockquote>
<h2>Le risque : exécuter du code sans le savoir</h2>
<p>L’écosystème npm est immense. On compte aujourd’hui <strong>plus de deux millions de packages</strong>.</p>
<blockquote>
<p>Et comme dans tout écosystème ouvert, il arrive que certains packages soient malveillants ou compromis.</p>
</blockquote>
<p>Plusieurs incidents ont déjà eu lieu :</p>
<ul>
<li>des packages abandonnés repris par des acteurs malveillants</li>
<li>des dépendances injectant du code espion</li>
<li>des scripts envoyant des informations système</li>
</ul>
<p>Les scripts <code>postinstall</code> sont particulièrement sensibles, car ils s’exécutent <strong>directement sur votre machine</strong> au moment de l’installation.</p>
<p>Concrètement, un script npm peut :</p>
<ul>
<li>accéder à votre système de fichiers</li>
<li>lire des variables d’environnement</li>
<li>envoyer des données vers Internet</li>
<li>modifier votre configuration</li>
</ul>
<blockquote>
<p>En d’autres termes : <strong>un simple <code>npm install</code> peut exécuter du code arbitraire</strong>.</p>
</blockquote>
<h2>Utiliser ignore-scripts pour garder le contrôle</h2>
<p>Pour éviter cela, npm propose une option très simple :</p>
<pre><code class="language-bash">npm install --ignore-scripts
</code></pre>
<p>Avec cette commande :</p>
<ul>
<li>npm télécharge les dépendances</li>
<li>npm les installe dans <code>node_modules</code></li>
<li><strong>mais aucun script n’est exécuté</strong></li>
</ul>
<p>Cela bloque :</p>
<ul>
<li><code>preinstall</code></li>
<li><code>install</code></li>
<li><code>postinstall</code></li>
<li><code>prepare</code></li>
</ul>
<p>Les packages sont installés <strong>sans exécution de code externe</strong>.</p>
<blockquote>
<p>⚠️ <strong>Attention : <code>--ignore-scripts</code> bloque absolument tous les scripts.</strong></p>
</blockquote>
<p>Il n’est pas possible de désactiver uniquement <code>postinstall</code> ou un script spécifique.</p>
<p>Si vous utilisez cette option, <strong>aucun script lifecycle ne sera exécuté</strong>, quel que soit le package.</p>
<p>Cette option est particulièrement utile dans plusieurs situations :</p>
<ul>
<li>audit de dépendances</li>
<li>analyse d’un projet inconnu</li>
<li>environnement sécurisé</li>
<li>pipeline CI/CD</li>
<li>installation de dépendances non fiables</li>
</ul>
<h2>Équivalent avec pnpm et yarn</h2>
<p>Si vous utilisez un autre gestionnaire de paquets, sachez que <strong>des options similaires existent</strong>.</p>
<h3>pnpm</h3>
<p>pnpm propose exactement la même option :</p>
<pre><code class="language-bash">pnpm install --ignore-scripts
</code></pre>
<blockquote>
<p>Le comportement est identique à npm : les dépendances sont installées mais <strong>aucun script lifecycle n’est exécuté</strong>.</p>
</blockquote>
<h3>Yarn</h3>
<p>Avec Yarn (v1 ou v3), l’option est également disponible :</p>
<pre><code class="language-bash">yarn install --ignore-scripts
</code></pre>
<blockquote>
<p>Comme pour npm et pnpm, cela bloque l’exécution des scripts <code>preinstall</code>, <code>install</code> et <code>postinstall</code>.</p>
</blockquote>
<p>Autrement dit, <strong>les trois principaux gestionnaires de paquets Node.js offrent ce mécanisme de sécurité</strong>.</p>
<h2>Réactiver les scripts si nécessaire</h2>
<p>Si un package a réellement besoin de ses scripts pour fonctionner, vous pouvez les relancer plus tard.</p>
<p>Par exemple :</p>
<pre><code class="language-bash">npm rebuild
</code></pre>
<p>Ou simplement relancer l’installation normalement :</p>
<pre><code class="language-bash">npm install
</code></pre>
<blockquote>
<p>L’avantage est que <strong>vous gardez le contrôle sur ce qui s’exécute sur votre machine</strong>.</p>
</blockquote>
<p>Dans un écosystème aussi vaste que npm, cette petite option peut éviter de nombreux problèmes.</p>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Chat_GPT_Image_Mar_13_2026_10_48_35_AM_copy_a7e3964495.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Découvrez BullMQ, une MessageQueue simple avec NodeJS]]></title>
            <description><![CDATA[Dans une application moderne, certaines opérations peuvent être longues et bloquer l’application principale, on utilise alors souvent des files de tâches. BullMQ est une solution simple pour gérer ce type de traitement en arrière-plan.]]></description>
            <link>https://code-garage.com/blog/decouvrez-bullmq-une-message-queue-simple-avec-nodejs</link>
            <guid isPermaLink="true">https://code-garage.com/blog/decouvrez-bullmq-une-message-queue-simple-avec-nodejs</guid>
            <category><![CDATA[Asynchrone]]></category>
            <category><![CDATA[Redis]]></category>
            <category><![CDATA[NodeJS]]></category>
            <category><![CDATA[Python]]></category>
            <category><![CDATA[PHP]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Mon, 09 Mar 2026 09:20:06 GMT</pubDate>
            <content:encoded><![CDATA[<p>Imaginez une application web qui doit un exporter un zip, puis l’envoyer par e-mail, <strong>pour qu’un utilisateur puisse télécharger des données.</strong></p>
<p>Si votre serveur attend que <strong>le zip soit compressé puis envoyé</strong> avant de répondre à l’utilisateur :</p>
<ul>
<li>la requête devient lente</li>
<li>votre serveur peut bloquer</li>
<li>la requête peut échouer à cause d’un timeout</li>
</ul>
<blockquote>
<p>La solution consiste à <strong>déléguer ce travail à un système de tâches asynchrones</strong>.</p>
</blockquote>
<p>Au lieu de créer le zip directement, l’application ajoute une tâche dans une file :</p>
<pre><code class="language-plaintext">(1) Exporter données (user@example.com) -- En cours...
(2) Exporter données (user2@test.com)   -- En attente
(3) Exporter données (user3@fake.com)   -- Tâche ajoutée
</code></pre>
<p>L’utilisateur, lui, va recevoir une confirmation immédiate du traitement de sa demande, et un autre processus (parfois un autre serveur, conteneur,…) <strong>se chargera de traiter la demande et d’envoyer l’email.</strong></p>
<p>Comme ceci :</p>
<pre><code class="language-plaintext">Lire la tâche en cours
|
Récupérer les données
|
Créer l'archive zip
|
Envoyer l'email (user@example.com)
|
Valider la tâche
</code></pre>
<blockquote>
<p>Tant qu’il y a des tâches en cours, le processus les traitera les unes à la suite des autres, <strong>dans l’ordre d’arrivée (First In - First Out ou FIFO)</strong></p>
</blockquote>
<p>De cette manière, <strong>notre serveur web n’est pas bloqué par des tâches longues ou coûteuses</strong>, il peut continuer à traiter le reste de ses requêtes facilement !</p>
<h2>Qu’est-ce que BullMQ ?</h2>
<p><a href="https://bullmq.io/"><strong>BullMQ</strong></a> est une bibliothèque permettant de gérer ce type de file de tâches.</p>
<p>Elle repose sur <a href="https://code-garage.com/tags/redis"><strong>Redis</strong></a>, <strong>une base de données en mémoire très rapide</strong> qui sert à stocker et coordonner les tâches.</p>
<blockquote>
<p>Si vous ne connaissez pas Redis, on vous a préparé <a href="https://code-garage.com/blog/redis-une-base-de-donnees-rapide-comme-l-eclair">un article dédié !</a></p>
</blockquote>
<p>Le fonctionnement repose sur trois éléments :</p>
<ul>
<li><strong>La queue (file)</strong> : l’endroit où les tâches sont ajoutées</li>
<li><strong>Les workers</strong> : des processus qui exécutent les tâches</li>
<li><strong>Redis</strong> : le moteur qui stocke les jobs et leur état</li>
</ul>
<p>Le flux ressemble généralement à ceci :</p>
<ol>
<li>L’application ajoute une tâche dans la queue</li>
<li>Redis stocke cette tâche</li>
<li>Un worker récupère la tâche</li>
<li>Le worker exécute l’action (ex : envoyer un email)</li>
</ol>
<blockquote>
<p>Ce modèle permet de <strong>séparer la logique métier principale des traitements lourds</strong>.</p>
</blockquote>
<p>Attention, BullMQ n’est pas un MessageBroker, c’est simplement une file d’attente ! On va voir la différence un peu plus loin avec RabbitMQ par exemple.</p>
<h3>Un exemple simple</h3>
<p>Voici un exemple minimal avec Node.js pour <strong>ajouter une tâche dans une queue</strong> :</p>
<pre><code class="language-js">import { Queue } from &quot;bullmq&quot;;

const emailQueue = new Queue(&quot;email-queue&quot;, {
  connection: {
    host: &quot;localhost&quot;,
    port: 6379
  }
});

await emailQueue.add(&quot;send-welcome-email&quot;, {
  email: &quot;user@example.com&quot;,
  name: &quot;Alice&quot;
});
</code></pre>
<blockquote>
<p>Ce code ajoute une tâche appelée <code>send-welcome-email</code> dans Redis.</p>
</blockquote>
<p>Et voici un exemple d’un Worker qui traite les tâches :</p>
<pre><code class="language-js">import { Worker } from &quot;bullmq&quot;;

const worker = new Worker(
  &quot;email-queue&quot;,
  async job =&gt; {
    const { email, name } = job.data;

    console.log(`Envoi de l'email de bienvenue à ${name} (${email})`);

    // Ici on pourrait appeler un service SMTP
    // sendEmail(email, ...)
  },
  {
    connection: {
      host: &quot;localhost&quot;,
      port: 6379
    }
  }
);
</code></pre>
<blockquote>
<p>Dès qu’une tâche est ajoutée, le worker la récupère et exécute le traitement.</p>
</blockquote>
<h3>Cas d’usage typiques</h3>
<p>Les files de tâches comme BullMQ sont utilisées pour :</p>
<ul>
<li>envoyer des emails</li>
<li>générer des rapports ou documents</li>
<li>traiter des images ou vidéos</li>
<li>importer de grandes quantités de données</li>
<li>exécuter des tâches planifiées</li>
<li>lancer des traitements lourds en arrière-plan</li>
</ul>
<blockquote>
<p>Dès qu’une opération peut prendre du temps ou échouer temporairement, une queue devient utile.</p>
</blockquote>
<h2>Les forces et faiblesses de BullMQ</h2>
<p>BullMQ présente <strong>plusieurs avantages importants</strong> : il est performant, gèrent les “retries” en cas d’échecs, mais possède surtout une très bonne DX et <strong>n’a besoin que d’une dépendance d’infrastructure (Une base Redis).</strong></p>
<p>Mais cela reste néanmoins une solution relativement simple, avec ses limites : <strong>limité à NodeJS, Python et PHP</strong>, il est également mois adapté aux architectures très distribuées.</p>
<h2>Et RabbitMQ alors ?</h2>
<p>La différence principale entre BullMQ et RabbitMQ est leur rôle :</p>
<ul>
<li>BullMQ est une <strong>bibliothèque de gestion de tâches</strong>.</li>
<li>RabbitMQ est un <strong>message broker</strong>, conçu pour faire communiquer plusieurs services entre eux.</li>
</ul>
<p>Avec RabbitMQ, chaque service peut envoyer des messages sur la Queue, et chaque service est libre de traiter un message comme il l’entend. <strong>BullMQ permet simplement d’envoyer une tâche de manière unilatérale</strong>, et avec une seule source de vérité (même si autant de Worker peuvent écouter les tâches).</p>
<blockquote>
<p><strong>RabbitMQ est aussi plus lourd à mettre en place</strong>, avec une infrastructure dédiée, et son protocol basé sur AMQP.</p>
</blockquote>
<h2>Note supplémentaire</h2>
<p>Il est important de rappeler que BullMQ est capable de garder les tâches en mémoire à long terme, <strong>uniquement si la persistence est activée sur votre base de données Redis !</strong></p>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_A_game_of_Jenga_with_a_bull_running_towar_73661975_0c7a_463e_8028_8743ca2870b5_6d0f824c54.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Comment récupérer les variables d’environnement en COBOL ?]]></title>
            <description><![CDATA[Même si COBOL est un langage ancien, il reste encore utilisé dans de nombreux systèmes critiques. Mais comment faire pour adapter son comportement selon l’environnement, par exemple, passer du mode développement au mode production ? La réponse passe par les variables d’environnement.]]></description>
            <link>https://code-garage.com/blog/comment-recuperer-les-variables-environnement-en-cobol</link>
            <guid isPermaLink="true">https://code-garage.com/blog/comment-recuperer-les-variables-environnement-en-cobol</guid>
            <category><![CDATA[Cobol]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Mon, 02 Mar 2026 16:42:26 GMT</pubDate>
            <content:encoded><![CDATA[<h2>Les variables d’environnement, c’est quoi ?</h2>
<p>Une <strong>variable d’environnement</strong> est une valeur stockée par le système d’exploitation et accessible par les programmes.</p>
<p>Elles servent à définir le <strong>contexte d’exécution</strong> d’une application :</p>
<ul>
<li>nom du serveur</li>
<li>chemin vers une base de données</li>
<li>mode de fonctionnement (DEV / PROD)</li>
<li>etc...</li>
</ul>
<blockquote>
<p>En COBOL, on peut y accéder grâce à l’instruction <code>ACCEPT</code>.</p>
</blockquote>
<h2>Lire une variable d’environnement en COBOL</h2>
<p>Voici un exemple simple pour <strong>récupérer la variable d’environnement</strong> <code>APP_MODE</code> :</p>
<pre><code class="language-plaintext">       IDENTIFICATION DIVISION.
       PROGRAM-ID. EnvExample.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  APP-MODE       PIC X(10).

       PROCEDURE DIVISION.
           ACCEPT APP-MODE FROM ENVIRONMENT &quot;APP_MODE&quot;
           DISPLAY &quot;Mode d'exécution : &quot; APP-MODE
           STOP RUN.

</code></pre>
<ul>
<li><code>ACCEPT</code> permet de <strong>lire une entrée externe</strong>.</li>
<li>En précisant <code>FROM ENVIRONMENT &quot;APP_MODE&quot;</code>, on demande à COBOL de lire la variable d’environnement correspondante.</li>
<li>La valeur est stockée dans la variable <code>APP-MODE</code>.</li>
</ul>
<h3>Exemple pratique</h3>
<p>Imaginons que vous vouliez exécuter certaines instructions selon l’environnement :</p>
<pre><code class="language-plaintext">       IF APP-MODE = &quot;DEV&quot;
           DISPLAY &quot;Connexion à la base de test...&quot;
       ELSE
           DISPLAY &quot;Connexion à la base de production...&quot;
       END-IF.
</code></pre>
<blockquote>
<p>Mais avant d’exécuter votreprogramme, tu peux définir la variable selon le contexte :</p>
</blockquote>
<pre><code>Mode d'exécution : DEV
Connexion à la base de test...
</code></pre>
<h2>Gérer les cas particuliers</h2>
<h3>Les valeurs numériques</h3>
<p>Une chose à retenir, c’est qu’une variable d’environnement est toujours passée à un programme sous forme de <code>string</code>. Il est possible de la convertir automatiquement en COBOL, en la déclarant comme une valeur valeur numérique, comme ceci avec <code>port</code> qui serait égal à <code>3000</code> :</p>
<pre><code class="language-plaintext">01 PORT PIC 9(4).
ACCEPT PORT FROM ENVIRONMENT &quot;PORT&quot;
</code></pre>
<blockquote>
<p>Mais ce n’est pas conseillé.</p>
</blockquote>
<p>Si votre votre variable contient par erreur une valeur qui ne peut pas être parsée, alors il y a de fortes chances que votre programme crash (en fonction de votre environnement).</p>
<p>Il vaut mieux lire une valeur alpha-numérique, pour ensuite vérifier et convertir, comme ceci :</p>
<pre><code class="language-plaintext">01 PORT-STR PIC X(10).
01 PORT     PIC 9(4).

ACCEPT PORT-STR FROM ENVIRONMENT &quot;PORT&quot;

IF PORT-STR IS NUMERIC
    MOVE PORT-STR TO PORT
ELSE
    DISPLAY &quot;PORT invalide&quot;
END-IF
</code></pre>
<h3>Les valeurs vides</h3>
<p>Si une variable d’environnement est lue, mais quelle est vide (ou simplement non définie), alors votre programme ne recevras qu’un ensemble d’espaces équivalent à la longueur de votre variables.</p>
<p>Pour vérifier si votre variable est définie ou non, et lui assigner une valeur par défaut, il vous suffira de faire ceci :</p>
<pre><code class="language-plaintext">ACCEPT APP-MODE FROM ENVIRONMENT &quot;APP_MODE&quot;
IF APP-MODE = SPACES
    MOVE &quot;DEV&quot; TO APP-MODE
DISPLAY &quot;Mode d'exécution : &quot; APP-MODE
STOP RUN.
</code></pre>
<blockquote>
<p>La constante SPACES est une constante “figurative”, qui s’adapte au contexte, et elle correspond au nombre d’espaces nécessaires pour remplir votre variable.</p>
</blockquote>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_COBOL_environment_a487796549.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Diplôme, Titre RNCP, Bachelor, Mastère… quelles différences ?]]></title>
            <description><![CDATA[Vous cherchez votre future école et vous êtes perdu dans toute l'offre de diplômes, titres et certifications en tout genre ?]]></description>
            <link>https://code-garage.com/blog/differences-diplome-titre-rncp-bachelor-mastere</link>
            <guid isPermaLink="true">https://code-garage.com/blog/differences-diplome-titre-rncp-bachelor-mastere</guid>
            <category><![CDATA[Education]]></category>
            <category><![CDATA[Etudes & Ecoles]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Mon, 23 Feb 2026 13:16:04 GMT</pubDate>
            <content:encoded><![CDATA[<p>Lorsque vous cherchez une formation en informatique, en initial ou en reconversion, on vous parle de diplômes, de titres RNCP, de Bachelors, Mastères, certifications…</p>
<blockquote>
<p>Tout semble équivalent. En réalité, derrière ces termes se cachent des significations bien différentes.</p>
</blockquote>
<p>Alors on vous a préparé un guide pour éclaircir tout ça !</p>
<h2>Les diplôme d’Etat</h2>
<p>Un diplôme d’État est délivré par une université ou un établissement habilité par l’État (comme une école d’ingénieur). Il s’inscrit dans le système LMD (Licence - Master - Doctorat) et donne <strong>des crédits ECTS reconnus en Europe.</strong></p>
<p>Exemples :</p>
<ul>
<li>BUT Informatique (anciennement DUT)</li>
<li>Licence Informatique</li>
<li>Master Informatique</li>
<li>Diplôme d’ingénieur (Bac +5 réservé aux écoles d’ingénieurs)</li>
</ul>
<p>Ces formations offrent généralement <strong>une base théorique solide</strong> : algorithmique, systèmes, structures de données, parfois mathématiques avancées.</p>
<p>Elles sont particulièrement adaptées si vous souhaitez :</p>
<ul>
<li>Continuer vers un Bac+5 ou un doctorat</li>
<li>Garder une reconnaissance académique forte</li>
<li>Travailler à l’international</li>
</ul>
<blockquote>
<p>En revanche, elles peuvent être plus longues et parfois moins professionalisantes.</p>
</blockquote>
<h2>Les titres professionnels (RNCP)</h2>
<p>Un titre RNCP (Répertoire National des Certifications Professionnelles) est <strong>une certification professionnelle reconnue par l’État.</strong></p>
<p>Il ne s’agit pas d’un diplôme universitaire, mais d’<strong>une validation de compétences</strong> liées à un métier précis.</p>
<p>Chaque titre possède un niveau (5 = Bac+2, 6 = Bac+3/4, 7 = Bac+5) et un référentiel de compétences.</p>
<p>Pour un développeur, vous verrez souvent des titres comme :</p>
<ul>
<li>Développeur web et web mobile (niveau 5)</li>
<li>Concepteur développeur d’applications (niveau 6)</li>
<li>Expert en ingénierie logicielle (niveau 7)</li>
</ul>
<blockquote>
<p>Il en existe d’autres, et elles peuvent changer en fonction des années mais celles-ci sont les plus courantes</p>
</blockquote>
<p>Ces formations reconnues par l’état sont généralement plus professionnalisantes, <strong>avec beaucoup de projets concrets et souvent de l’alternance.</strong></p>
<p>Mais elles vous forment également à <strong>la réalité d’un métier à un instant T</strong>, sans toujours apporter les bases les plus solides pour s’adapter à de futurs changement, contrairement à la voie universitaire.</p>
<h2>Bachelor et Mastère : des termes marketing</h2>
<p>En France, les mots “Bachelor” et “Mastère” ne sont pas protégés.</p>
<p>Cela signifie qu’une école peut appeler sa formation “Bachelor Développeur Web” <strong>sans que cela corresponde à un diplôme d’État.</strong></p>
<p>Ce qui compte réellement, ce n’est pas le nom, mais :</p>
<ul>
<li>Existe-t-il un titre RNCP associé ?</li>
<li>À quel niveau est-il enregistré ?</li>
</ul>
<blockquote>
<p>Un Bachelor ou un Mastère peut être très sérieux… ou simplement marketing. <strong>Il faut toujours faire attention.</strong></p>
</blockquote>
<p>Vous aurez noté la différence entre un “Master” (universitaire) et un “Mastère” (non-reconnu par l’état), beaucoup de personnes confondent les deux chaque année.</p>
<h2>Les certifications</h2>
<p>Une certification n’est ni un diplôme ni un titre RNCP.</p>
<p>Il s’agit d’une validation ciblée de compétences, par exemple :</p>
<ul>
<li>Certification React</li>
<li>Certification AWS</li>
<li>Certification Scrum</li>
</ul>
<blockquote>
<p>Ces certifications peuvent valoriser un profil, mais elles <strong>ne remplacent pas une formation complète.</strong></p>
</blockquote>
<h2>Trouvez votre future école</h2>
<p>La réalité du marché d'aujourd'hui fait que <strong>ce n'est pas simplement le diplôme qui fera de vous un.e professionnel.le</strong>, mais surtout la qualité des apprentissages, des cours et des projets dispensés à l'école qui pourront vous donner une longueur d'avance.</p>
<p>C'est pour cela qu'on a lancé <strong>notre référentiel national des écoles d'informatique en France</strong>, pour que chaque étudiant.e puisse laisser un ou plusieurs avis pour guider les futurs étudiants !</p>
<blockquote>
<p>Découvrez <a href="https://code-garage.com/schools/search">notre référentiel complet</a></p>
</blockquote>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_The_main_building_of_Harvard_Campus_in_a_907113a1_9ab3_47a0_82c8_6b33bc6b28ba_copy_7e864ab1e2.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Générer des PDFs à partir de HTML avec SecretPDF]]></title>
            <description><![CDATA[Apprenez à générer des PDF depuis du HTML avec un seul call d'API !]]></description>
            <link>https://code-garage.com/blog/generer-des-pdfs-a-partir-de-html-avec-secretpdf</link>
            <guid isPermaLink="true">https://code-garage.com/blog/generer-des-pdfs-a-partir-de-html-avec-secretpdf</guid>
            <category><![CDATA[Outils]]></category>
            <category><![CDATA[SaaS]]></category>
            <category><![CDATA[API]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Tue, 17 Feb 2026 13:46:21 GMT</pubDate>
            <content:encoded><![CDATA[<p>Générer un PDF en 2026, c’est censé ne plus être un problème technique. Mais le faire <strong>simplement, proprement, de manière maintenable, scalable et prête pour la production…</strong> ça, c’est une autre histoire.</p>
<blockquote>
<p>Dans cet article, nous allons voir comment générer des PDFs à partir d’un template HTML de la manière la plus simple possible avec <strong><a href="https://www.secretpdf.io">SecretPDF</a>.</strong></p>
</blockquote>
<h2>Pourquoi générer des PDFs est souvent complexe ?</h2>
<p>Le format PDF est à la fois simple et complexe. Il est simple d’utilisation, car portable (il inclut toutes les ressources nécessaire pour le rendu), mais il est complexe à produire.</p>
<blockquote>
<p>Un PDF peut contenir du texte, des polices d’écriture, des images, du vectoriel, etc…</p>
</blockquote>
<p>Il est possible de générer un fichier PDF directement depuis le navigateur, <strong>mais dès que l’on a besoin d’un rendu légèrement complexe (autrement dit “joli”)</strong>, c’est un casse-tête, surtout sur mobile.</p>
<p>Si votre objectif est de :</p>
<ul>
<li>Générer un vrai document</li>
<li>Avec un design intéressant</li>
<li>Du contenu texte sélectionnable (pas seulement une image)</li>
<li>Sans hack CSS obscur</li>
</ul>
<p><strong>Alors vous devez générer des PDF côté serveur</strong>, ce qui implique de trouver la solution qui convient à vos contrainte, monter une architecture, la dimensionner, faire en sorte que cela n’impacte pas les performances de vos autres applications.</p>
<blockquote>
<p>C’est là qu’arrive SecretPDF !</p>
</blockquote>
<p>::: image
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Capture_d_ecran_2026_02_17_a_11_12_20_6fa0af2297.png" alt="">
:::</p>
<h2>SecretPDF, c’est quoi ?</h2>
<p><strong>SecretPDF</strong> est un SaaS facile d’utilisation, avec <strong>une API moderne pour générer des documents PDF à partir de HTML.</strong></p>
<p>Vous lui envoyez :</p>
<ul>
<li>du HTML/CSS (même des classes Tailwind pour le design si vous voulez)</li>
<li>des données dynamiques</li>
<li>un format de page</li>
</ul>
<p>Il vous renvoie :</p>
<ul>
<li>un PDF prêt à télécharger</li>
</ul>
<blockquote>
<p>Et en plus l’outil est RGPD-compliant et neutre en carbone. Que demander de plus ?</p>
</blockquote>
<h3>Le tarif</h3>
<p>SecretPDF fonctionne <strong>avec un système de crédits</strong> (1 pdf = 1 crédit pour les PDF &lt;2Mo)</p>
<p>Vous avez :</p>
<ul>
<li>10 crédits gratuits tous les mois</li>
<li>Puis 0.01$ par crédit</li>
</ul>
<blockquote>
<p>C’est idéal pour les startups et les SaaS : Pas de document généré, pas de paiement.</p>
</blockquote>
<p>D’ailleurs vous n’êtes même <strong>pas obligé de rentrer votre carte bancaire</strong> pour commencer.</p>
<p>À noter également que vous pouvez <strong>générer autant de documents de test que vous désirez</strong>, grâce à une option “sandbox” qui vous permet de tester vos templates gratuitement !</p>
<h2>Etape 1 : Créer un compte</h2>
<p><strong>Pour créer un compte</strong>, il suffit de connecter son compte Github, <a href="https://app.secretpdf.io/sign-in">en un seul clic !</a></p>
<p>Ensuite, vous serez guidé vers la création <strong>de votre premier template et de votre première clé d’API</strong>. L’un des gros avantages de SecretPDF est qu’il vous permet de créer vos templates directement de puis l’interface (avec une preview) ou bien depuis l’API :</p>
<p>::: image
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Capture_d_ecran_2026_02_17_a_13_30_54_55010d1bf7.png" alt="">
:::</p>
<h2>Étape 2 :  Installer le client</h2>
<p>Vous pouvez utiliser l’API avec n’importe quel langage ou framework en suivant <a href="https://www.secretpdf.io/docs/">la documentation officielle</a>, mais vous pouvez également utiliser le client NodeJS dédié pour vous faciliter la vie.</p>
<p>Dans votre projet Node.js <strong>exécutez la commande suivante :</strong></p>
<pre><code class="language-bash">npm install @secretpdf/sdk
</code></pre>
<p>Puis dans votre code, initialisez-le :</p>
<pre><code class="language-jsx">import SecretPDF from &quot;@secretpdf/sdk&quot;;

const client = new SecretPDF({
  apiKey: &quot;&lt;secret&gt;&quot;,
});
</code></pre>
<blockquote>
<p>Il est évidemment conseillé de définir votre clé API dans vos variables d’environnement</p>
</blockquote>
<h2>Etape 3 (optionnelle) : Créer un template depuis l’API</h2>
<p>Si vous préférez créer votre premier template directement depuis l’API, c’est possible, comme ceci :</p>
<pre><code class="language-jsx">const response = await client.createTemplate({
  name: &quot;Facture&quot;,
  size: &quot;A4&quot;,
  content: `
    &lt;main class=&quot;p-10&quot;&gt;
      &lt;h1 class=&quot;text-3xl font-bold text-blue-600&quot;&gt;
        Facture
      &lt;/h1&gt;
      &lt;p&gt;Prestataire : {{name}} (SIRET {{siret}})&lt;/p&gt;
      &lt;p&gt;Montant: {{amount}}€&lt;/p&gt;
      &lt;p class=&quot;mt-4 text-gray-700&quot;&gt;
        Merci pour votre confiance.
      &lt;/p&gt;
    &lt;/main&gt;
  `,
});

const templateId = response.data.id;
</code></pre>
<blockquote>
<p>Je vous conseille quand même d’utiliser l’interface, cela vous facilitera la vie.</p>
</blockquote>
<h2>Étape 4 : Générer votre premier PDF</h2>
<p>Voici l’exemple le plus simple possible pour <strong>générer un PDF à partir de votre template</strong> :</p>
<pre><code class="language-jsx">const response = await client.generate({
  sandbox: true,
  templateId: &quot;&lt;template_id&gt;&quot;,
  data: {
    name: &quot;Nicolas Brondin-Bernard&quot;,
    siret: &quot;784 671 695 00103&quot;,
    amount: 139.99,
    date: new Date()
  }
});
</code></pre>
<blockquote>
<p><code>sandbox</code> permet de générer un document de test avec un watermark par dessus, <strong>ce qui ne consommera aucun crédit.</strong></p>
</blockquote>
<p>La réponse contient une simple propriété <code>data</code> avec le contenu du fichier généré (encodé en Base64), c’est aussi simple que ça !</p>
<h2>Étape 5 (optionnelle) : Sauvegarder le fichier sur disque</h2>
<p><strong>Rien en vous oblige à stocker le fichier généré</strong>, vous pouvez par exemple l’envoyer en réponse HTTP à votre utilisateur, mais si vous souhaitez le faire, rien de plus simple :</p>
<pre><code class="language-jsx">import fs from &quot;fs&quot;;

const response = await client.generate({
  //...
});

const pdfBuffer = Buffer.from(result.content, 'base64');
fs.writeFileSync('output.pdf', pdfBuffer);
</code></pre>
<blockquote>
<p>Et voilà, le tour est joué !</p>
</blockquote>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_A_factory_that_produces_sheets_of_paper_de2ace28db.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Ces 10 femmes qui ont révolutionné l’informatique]]></title>
            <description><![CDATA[Découvrez dix femmes extraordinaires qui ont révolutionné l’informatique et dont les inventions ont façonné la programmation, les réseaux, la cryptographie et l’exploration spatiale.]]></description>
            <link>https://code-garage.com/blog/ces-femmes-qui-ont-revolutionne-l-informatique</link>
            <guid isPermaLink="true">https://code-garage.com/blog/ces-femmes-qui-ont-revolutionne-l-informatique</guid>
            <category><![CDATA[Women in Tech]]></category>
            <category><![CDATA[Inclusion]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Tue, 09 Dec 2025 21:06:57 GMT</pubDate>
            <content:encoded><![CDATA[<p>L’informatique moderne n’est pas seulement le résultat de grandes avancées technologiques : <strong>elle est aussi l’œuvre de femmes extraordinaires.</strong></p>
<p>Leur héritage est partout : dans nos ordinateurs, dans nos communications, dans nos systèmes de navigation, dans nos langages de programmation et <strong>même dans les technologies cryptographiques les plus récentes.</strong></p>
<blockquote>
<p>Pourtant, certains de ces noms vous <strong>sont sûrement encore inconnus.</strong></p>
</blockquote>
<p>À elles seules, ces scientifiques, ingénieures et programmeuses de génie ont :</p>
<ul>
<li>écrit les premiers langages</li>
<li>créé les fondations du réseau moderne</li>
<li>rendu l’informatique plus accessible</li>
<li>sécurisé Internet</li>
<li>participé à des avancées scientifiques majeures</li>
<li>ouvert la voie à de nouvelles disciplines entières</li>
</ul>
<blockquote>
<p>Cet article rend hommage à dix d’entre elles, <strong>dont le travail continue d’influencer notre quotidien numérique.</strong></p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_477_230b1aabce.png" alt="">
:::</p>
<h2>Shafi Goldwasser (1958 - aujourd’hui)</h2>
<h3>Cryptographie</h3>
<p>Mathématicienne et spécialiste de la cryptographie moderne, Shafi Goldwasser reçoit le prix Turing pour ses travaux sur les <strong>preuves à divulgation nulle de connaissance (ZKP)</strong>.</p>
<p>Ces techniques permettent de prouver une information sans jamais la révéler, <strong>un concept au cœur des blockchains, de l’authentification sécurisée</strong> et de la confidentialité des données.</p>
<blockquote>
<p>Elle est l’<strong>une des chercheuses les plus influentes</strong> dans la sécurité informatique contemporaine.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_478_75d7992c09.png" alt="">
:::</p>
<h2>Radia Perlman (1951 - aujourd’hui)</h2>
<h3>Réseau et télécommunications</h3>
<p>Surnommée la <strong>“mère d’Internet”</strong>, Radia Perlman invente le <strong>Spanning Tree Protocol (STP)</strong>, un mécanisme indispensable pour éviter les boucles dans les réseaux Ethernet.</p>
<p><strong>Son invention permet à Internet de s’étendre massivement</strong> et de rester stable malgré des millions d’interconnexions.</p>
<blockquote>
<p>Elle contribue également à de nombreux <strong>protocoles de sécurité et d’optimisation des réseaux</strong> informatiques.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_476_cb16300500.png" alt="">
:::</p>
<h2>Margaret Hamilton (1936 - aujourd’hui)</h2>
<h3>Ingénierie logicielle</h3>
<p>Ingénieure en chef du logiciel embarqué des missions Apollo, <strong>Margaret Hamilton conçoit les programmes qui ont permis à Neil Armstrong et Buzz Aldrin d’alunir en 1969.</strong></p>
<p>Son équipe invente des techniques inédites de gestion d’erreur en temps réel, essentielles lorsque l’ordinateur du module lunaire sature juste avant l’alunissage.</p>
<blockquote>
<p>Son approche rigoureuse est à l’origine du terme <strong>“ingénierie logicielle”</strong>.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_479_a00625a8a1.png" alt="">
:::</p>
<h2>Barbara Liskov (1939 - aujourd’hui)</h2>
<h3>Ingénierie logicielle</h3>
<p>Informaticienne et professeure au MIT, Barbara Liskov reçoit <strong>le prix Turing en 2008 pour ses contributions à la programmation orientée objet.</strong></p>
<p>Elle formule le <strong>principe de substitution de Liskov</strong>, essentiel à la conception de logiciels fiables et modulaires.</p>
<blockquote>
<p>Ses travaux influencent profondément les langages modernes, de Java à C#, mais aussi les systèmes distribués et les bases de données.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_480_174a5fd443.png" alt="">
:::</p>
<h2>Kathleen Booth (1922 - 2022)</h2>
<h3>Ingénierie logicielle</h3>
<p>Kathleen Booth écrit <strong>le premier langage assembleur</strong> et participe à la conception de plusieurs ordinateurs britanniques, notamment l’Automatic Relay Calculator.</p>
<p>Son travail sur <strong>la traduction symbolique des instructions machine</strong> a été déterminant pour rendre la programmation plus intuitive.</p>
<blockquote>
<p>Elle fait partie de ces pionnières dont l’apport est fondamental, mais encore trop peu connu du grand public.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_481_5e530e0e80.png" alt="">
:::</p>
<h2>Betty Holberton (1917 - 2001)</h2>
<h3>Ingénierie logicielle</h3>
<p>Membre de l’équipe des programmeuses de l’ENIAC, l’un des premiers ordinateurs électroniques, Betty Holberton contribue à <strong>la conception des premiers compilateurs, ainsi qu’aux premiers standards de données.</strong></p>
<blockquote>
<p>Elle influence fortement la création du langage <strong>COBOL</strong> et participe à de nombreux projets fondateurs de l’ère informatique.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_482_6993cfa6a1.png" alt="">
:::</p>
<h2>Joan Clarke (1917 - 1996)</h2>
<h3>Cryptographie</h3>
<p>Cryptanalyste exceptionnelle, Joan Clarke rejoint l’équipe d’Alan Turing à Bletchley Park pendant la Seconde Guerre mondiale.</p>
<p>Elle contribue aux efforts de déchiffrement d’Enigma, la machine utilisée par l’armée allemande.</p>
<blockquote>
<p>Son travail, longtemps resté secret, a permis <strong>d’accélérer la fin de la guerre en interceptant des communications cruciales.</strong></p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_483_ef73bcba7e.png" alt="">
:::</p>
<h2>Hedy Lamarr (1914 - 2000)</h2>
<h3>Physique et télécommunications</h3>
<p>Actrice hollywoodienne et inventrice brillante, Hedy Lamarr développe avec George Antheil un système de <strong>saut de fréquences</strong> destiné à <strong>brouiller les communications radio</strong> pendant la Seconde Guerre mondiale.</p>
<p>L’objectif : empêcher les torpilles radioguidées d’être interceptées.</p>
<blockquote>
<p>Cette idée, déposée sous brevet, restera longtemps sous-utilisée… avant de devenir la base des technologies <strong>Wi-Fi</strong>, <strong>Bluetooth</strong> et <strong>GPS</strong>.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_484_827f2ef26a.png" alt="">
:::</p>
<h2>Grace Hopper (1906 - 1992)</h2>
<h3>Ingénierie logicielle</h3>
<p>Pionnière du logiciel et officier de la Navy, Grace Hopper révolutionne la programmation en développant le <strong>premier compilateur</strong>, capable de transformer du texte lisible en instructions machine.</p>
<p>Elle participe ensuite à <strong>la création du langage COBOL</strong>, encore utilisé aujourd’hui dans les banques et administrations.</p>
<blockquote>
<p>On lui attribue également le terme “bug informatique”, après avoir trouvé un insecte bloqué dans un relais d’ordinateur.</p>
</blockquote>
<p>::: illustration
<img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/Group_485_19a18dc7ac.png" alt="">
:::</p>
<h2>Ada Lovelace (1815 - 1852)</h2>
<h3>Pionnière</h3>
<p>Ada Lovelace est souvent considérée comme <strong>la première programmeuse de l’histoire</strong>.</p>
<p>En 1843, en travaillant sur la machine analytique de Charles Babbage (un ancêtre conceptuel de l’ordinateur), <strong>elle imagine un algorithme permettant de calculer les nombres de Bernoulli.</strong></p>
<p>Elle comprend déjà que les machines pourraient un jour manipuler autre chose que des nombres : sons, images, symboles…</p>
<blockquote>
<p>Cette intuition visionnaire dépasse de loin les connaissances de son époque. Ada ne s’est pas contentée d’écrire un programme : <strong>elle a imaginé ce que deviendrait l’informatique moderne.</strong></p>
</blockquote>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_httpss_mj_ec44e0828e.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Pourquoi apprendre NodeJS en 2026 en 4 points clés]]></title>
            <description><![CDATA[Découvrez pourquoi il est essentiel d’apprendre Node.js aujourd’hui, débloquez toute la puissance de JavaScript côté serveur pour des dizaines d’utilisations différentes !]]></description>
            <link>https://code-garage.com/blog/pourquoi-apprendre-nodejs</link>
            <guid isPermaLink="true">https://code-garage.com/blog/pourquoi-apprendre-nodejs</guid>
            <category><![CDATA[NodeJS]]></category>
            <category><![CDATA[Javascript]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Sat, 15 Nov 2025 20:22:53 GMT</pubDate>
            <content:encoded><![CDATA[<p>Si vous débutez en développement web, <strong>vous avez sûrement entendu parler de Node.js</strong>. Peut-être même que vous l’associez simplement à <strong>la création d’API en JavaScript. Et c’est vrai.</strong></p>
<blockquote>
<p>Mais <strong>réduire Node.js à ça, c’est passer à côté de son véritable intérêt</strong> : utiliser JavaScript en dehors du navigateur, pour débloquer son plein potentiel !</p>
</blockquote>
<h2>1. Parce que c’est recherché</h2>
<p>Node.js a commencé comme une mode, mais il est devenu un standard de l’industrie et une <strong>compétence durable, qui va vous ouvrir des opportunités !</strong></p>
<p>Les géants américains comme <strong>Netflix, Paypal, LinkedIn, Uber et même la NASA utilisent NodeJS</strong> en production.</p>
<p>Et même en France, les plus grandes ESN comme Capgemini, Sopra Steria, Atos et Thales déploient des applications Node chez leurs clients.</p>
<blockquote>
<p>C’est d’ailleurs LA technologie web la plus populaire chez les devs selon le <a href="https://survey.stackoverflow.co/2025/technology#most-popular-technologies-webframe">StackOverflow Survey</a> de 2025</p>
</blockquote>
<h2>2. C’est JavaScript, sous stéroïdes</h2>
<p>Apprendre Node.js, c’est <strong>maîtriser un seul langage pour tout faire</strong> :</p>
<ul>
<li>le front-end</li>
<li>le back-end</li>
<li>des outils en ligne de commande</li>
<li>des scripts d’automatisation</li>
<li>et même des applications desktop ou mobiles…</li>
</ul>
<blockquote>
<p>Avec JavaScript dans le navigateur, vous créez des interfaces utilisateur dynamiques, avec <strong>NodeJS vous créez tout ce que vous pouvez imaginer</strong>.</p>
</blockquote>
<p>::: course-ad
:::</p>
<h2>3. Parce que l’écosystème est gigantesque</h2>
<p>Beaucoup de technologies que vous utilisez déjà, ou que vous devez absolument découvrir, reposent sur Node.js :</p>
<ul>
<li>Les frameworks comme <strong>Next.js</strong>, <strong>Nuxt</strong> ou <strong>Astro</strong></li>
<li>Les outils de build comme <strong>Vite,</strong> <strong>Webpack</strong>, <strong>Parcel</strong>, ou <strong>esbuild</strong></li>
<li>Les gestionnaires de paquets comme <strong>npm, yarn</strong> ou <strong>pnpm</strong></li>
<li>Les outils d’automatisation comme <strong>n8n, Puppeteer ou Playwright</strong></li>
</ul>
<blockquote>
<p>En apprenant Node.js, vous ouvrez la porte à <strong>un écosystème infini qui évolue en permanence !</strong></p>
</blockquote>
<h2>4. Parce que c’est performant</h2>
<p>Node.js a été créé par Ryan Dahl <strong>pour résoudre des problèmes de performances</strong> rencontrés avec d’autres serveurs web comme Apache.</p>
<p>Son fonctionnement asynchrone (non bloquant) et <em>event-driven</em> permet de gérer <strong>des dizaines de milliers de connexions simultanées</strong> sans créer des centaines de threads.</p>
<p>Cette architecture, c’est ce qui en fait une solution privilégiée pour les applications en temps réel : messageries, jeux en ligne, dashboards interactifs, etc.</p>
<blockquote>
<p>Pour des cas d’utilisations <strong>avec beaucoup d’I/O</strong>, NodeJS est <a href="https://dev.to/tuananhpham/popular-backend-frameworks-performance-benchmark-1bkh">en général plus performant que du Python, du PHP ou du Ruby</a> (<a href="https://dev.to/aaricevans/nodejs-vs-python-java-and-php-io-speed-comparison-47c6">source alternative</a>)</p>
</blockquote>
<h2>En résumé</h2>
<p>Aujourd'hui, <strong>NodeJS est l'environnement d'exécution</strong> qui fait tourner une grosse partie des applications web modernes et innovantes.</p>
<blockquote>
<p>C'est un environnement simple à maitriser et qui offre des performances impressionnantes !</p>
</blockquote>
<p>Découvrir Node, c'est aussi ouvrir la porte à <strong>la création d'API Web</strong>, de logiciels, de webhooks, d’applications, etc... <strong>C'est un nouveau monde d’opportunités qui s'offre à vous !</strong></p>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_A_rocket_leaving_the_atmosphere_with_dark_8bc3c7ca_5721_4bc8_8a27_73bbeafaffb4_2a000eed54.jpg" medium="image"/>
        </item>
        <item>
            <title><![CDATA[Ajouter une destination au PATH dans Windows]]></title>
            <description><![CDATA[Apprenez à ajouter un dossier au PATH sous Windows et à comprendre son utilité. Découvrez à quoi sert la variable PATH et comment rendre vos outils accessibles depuis n’importe quel terminal.]]></description>
            <link>https://code-garage.com/blog/ajouter-une-destination-au-path-dans-windows</link>
            <guid isPermaLink="true">https://code-garage.com/blog/ajouter-une-destination-au-path-dans-windows</guid>
            <category><![CDATA[Windows]]></category>
            <category><![CDATA[Administration système]]></category>
            <dc:creator><![CDATA[NicolasBrondinBernard]]></dc:creator>
            <pubDate>Mon, 03 Nov 2025 20:13:39 GMT</pubDate>
            <content:encoded><![CDATA[<p>Quand on installe un outil en ligne de commande, comme Node.js, Git ou Python, il arrive souvent qu’on <strong>nous demande “d’ajouter le chemin au PATH”.</strong></p>
<blockquote>
<p><strong>Mais qu’est-ce que cela signifie exactement ?</strong> Et pourquoi est-ce important ?</p>
</blockquote>
<h2>Qu’est-ce que le PATH ?</h2>
<p>Le <strong>PATH</strong> est une <strong>variable d’environnement</strong> de Windows.</p>
<p>Elle contient une liste d’emplacements (ou “chemins”) que le système va parcourir lorsqu’on tape une commande dans le terminal.</p>
<blockquote>
<p>Quand vous tapez <code>node</code> ou <code>git</code> dans le terminal, Windows regarde dans chaque dossier listé dans votre PATH pour y trouver le programme correspondant.</p>
</blockquote>
<p>Si le dossier où <strong>votre programme est installé n’est pas dans le PATH</strong>, Windows ne saura pas où chercher, et vous verrez apparaître une erreur du type :</p>
<pre><code class="language-plaintext">'node' n’est pas reconnu en tant que commande interne ou externe
</code></pre>
<h2>Pourquoi modifier le PATH ?</h2>
<p>Ajouter un dossier au PATH permet d’exécuter un programme <strong>depuis n’importe quel dossier</strong>, sans avoir à taper son chemin complet.</p>
<p>Exemple : Si Node.js est installé dans <code>C:\Program Files\nodejs</code>, vous pouvez l’ajouter à ton PATH pour simplement écrire :</p>
<pre><code class="language-plaintext">node app.js
</code></pre>
<p>au lieu de :</p>
<pre><code class="language-plaintext">&quot;C:\Program Files\nodejs\node.exe&quot; app.js
</code></pre>
<h2>Comment ajouter un dossier au PATH</h2>
<h3><strong>Ouvrez les paramètres système</strong></h3>
<p>Ouvrez <strong>Paramètres &gt; Système &gt; Paramètres système avancé</strong>…</p>
<blockquote>
<p>Ou appuyez sur <code>Win + R</code>, tapez <code>sysdm.cpl</code> et validez</p>
</blockquote>
<p>Puis cliquez sur <strong>Avancé</strong> → <strong>Variables d’environnement</strong>.</p>
<p><img src="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/windows_variable_0e714034c2.png" alt=""></p>
<h3>Modifiez la variable PATH</h3>
<p>Dans la section “Variables système”, sélectionnez la variable nommée <code>Path</code>, puis cliquez sur <strong>Modifier</strong>.</p>
<h3>Ajoutez votre nouveau chemin</h3>
<p>Cliquez sur <strong>Nouveau</strong>, et collez le chemin complet du dossier où se trouve votre exécutable</p>
<blockquote>
<p>(ex : <code>C:\Program Files\nodejs</code>).</p>
</blockquote>
<h3>Validez et redémarrez votre terminal</h3>
<p>Fermez toutes les fenêtres en cliquant sur <strong>OK</strong>.
Ouvrez à nouveau votre terminal, puis testez ta commande (<code>node -v</code> par exemple).</p>
<blockquote>
<p>Bravo, vous avez réussi !</p>
</blockquote>
<p>À noter que parfois vous devrez redémarrer votre machine pour que le changement soit pris en compte partout sur le système…</p>
]]></content:encoded>
            <media:content url="https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/nicolasbrondinbernard_A_dirt_road_in_the_country_side_on_a_sunn_964993ae_7561_49d5_811a_18411e93daf1_b6a131a707.jpg" medium="image"/>
        </item>
    </channel>
</rss>