{"id":3391,"date":"2020-06-02T11:36:00","date_gmt":"2020-06-02T09:36:00","guid":{"rendered":"https:\/\/blog.alwaysdata.com\/?p=3391"},"modified":"2020-05-20T07:44:59","modified_gmt":"2020-05-20T05:44:59","slug":"les-sept-cercles-de-lenfer-des-dependances-le-guide-ultime-pour-passer-au-developpement-distant","status":"publish","type":"post","link":"https:\/\/blog.alwaysdata.com\/fr\/2020\/06\/02\/les-sept-cercles-de-lenfer-des-dependances-le-guide-ultime-pour-passer-au-developpement-distant\/","title":{"rendered":"Les sept cercles de l\u2019enfer des d\u00e9pendances&nbsp;: le guide ultime pour passer au d\u00e9veloppement distant"},"content":{"rendered":"<p>Avez-vous d\u00e9j\u00e0 eu affaire \u00e0&nbsp;un projet \u00e0&nbsp;long terme, impliquant l\u2019int\u00e9gration de nombreuses d\u00e9pendances (souvent circulaires), qui finit par prendre une journ\u00e9e enti\u00e8re \u00e0&nbsp;installer localement, seulement pour d\u00e9boguer une petite fonctionnalit\u00e9&nbsp;? Sans aucun doute&nbsp;! Nous connaissons tou\u00b7te\u00b7s le moment o\u00f9 vous procrastinez une session de d\u00e9bogage simplement parce que vous ne voulez pas avoir \u00e0&nbsp;faire tourner l\u2019environnement localement.<\/p>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (200 + 12) \/ (245 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/9PTaAhwri56V2\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/9PTaAhwri56V2\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<p>Bonne nouvelle&nbsp;: il existe une autre solution. Gr\u00e2ce au <em>d\u00e9bogage \u00e0&nbsp;distance<\/em>, vous pouvez ex\u00e9cuter votre environnement sur vos serveurs de <em>staging<\/em> <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_1');\" onkeypress=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_1');\"><sup id=\"footnote_plugin_tooltip_3391_1_1\" class=\"footnote_plugin_tooltip_text\">1)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3391_1_1\" class=\"footnote_tooltip\"><\/span><\/span> et travailler dessus depuis votre&nbsp;IDE&nbsp;!<\/p>\n<p>Les \u00e9cosyst\u00e8mes de d\u00e9veloppement Web ont beaucoup \u00e9volu\u00e9 ces derni\u00e8res ann\u00e9es. Pas seulement les <em>frameworks<\/em> et les outils, mais souvent des environnements entiers. Le changement le plus visible de ces derniers mois a&nbsp;\u00e9t\u00e9 l\u2019adoption massive par la plupart des d\u00e9veloppeurs Web de <a href=\"https:\/\/code.visualstudio.com\/\">VSCode<\/a> comme IDE principal. Bas\u00e9 sur JavaScript, soutenu par <a href=\"https:\/\/github.com\/Microsoft\/vscode\">les \u00e9quipes Open Source de Microsoft<\/a>, avec une stabilit\u00e9 am\u00e9lior\u00e9e et un r\u00e9el gain de performance, et soutenu par une large communaut\u00e9 fournissant <em>beaucoup<\/em> d\u2019extensions&nbsp;: c\u2019est probablement le meilleur choix pour votre outil quotidien.<\/p>\n<p>L\u2019\u00e9quipe de d\u00e9veloppement de Microsoft fournit un <a href=\"https:\/\/code.visualstudio.com\/docs\/remote\/remote-overview\">ensemble d\u2019extensions vous permettant de travailler sur des machines distantes<\/a> utilisant diff\u00e9rents protocoles, comme le v\u00e9n\u00e9rable SSH&nbsp;! Gr\u00e2ce \u00e0&nbsp;notre plateforme, qui vous offre un <a href=\"https:\/\/www.alwaysdata.com\/fr\/services\/ssh-sftp\/\">acc\u00e8s SSH par d\u00e9faut<\/a>, vous pouvez exploiter ces extensions facilement.<\/p>\n<p>Attachez vos ceintures, voici le guide complet&nbsp;!<\/p>\n<h2 id=\"pr\u00e9-requis\">Pr\u00e9-requis<\/h2>\n<p>Tout d\u2019abord, vous aurez besoin de <a href=\"https:\/\/code.visualstudio.com\/\">VSCode<\/a> (\u00e9videmment). Veuillez noter que les <em>Remote Extensions<\/em> ne peuvent fonctionner qu\u2019avec la <a href=\"https:\/\/code.visualstudio.com\/Download\">version officielle<\/a>, et non avec l\u2019\u00e9dition <em>OSS<\/em>, car celles-ci utilisent des composants non-libres. Installez-le en utilisant votre gestionnaire de paquets habituel (sous Linux), ou t\u00e9l\u00e9chargez la version correspondant \u00e0&nbsp;votre syst\u00e8me d\u2019exploitation.<\/p>\n<p>Vous devrez \u00e9galement activer l\u2019acc\u00e8s SSH par clef sur votre compte alwaysdata. Vous pouvez vous r\u00e9f\u00e9rer \u00e0&nbsp;la <a href=\"https:\/\/help.alwaysdata.com\/fr\/acc%C3%A8s-distant\/ssh\/utiliser-des-cl%C3%A9s-ssh\/\">documentation officielle sur l\u2019utilisation des cl\u00e9s SSH<\/a> si vous n\u2019\u00eates pas \u00e0&nbsp;l\u2019aise avec le processus.<\/p>\n<p>Nous vous recommandons d\u2019avoir un fichier de configuration SSH pour d\u00e9clarer vos h\u00f4tes, ce qui sera plus facile \u00e0&nbsp;utiliser dans VSCode. Sur votre machine locale, cr\u00e9ez un fichier <code>$HOME\/.ssh\/config<\/code> avec le contenu suivant&nbsp;:<\/p>\n<pre class=\"txt\"><code>Host alwaysdata\n    User [ad-account]\n    HostName ssh-[ad-account].alwaysdata.net\n    IdentityFile ~\/.ssh\/id_ed25519<\/code><\/pre>\n<p>Remplacez <code>[ad-account]<\/code> par le nom de votre compte alwaysdata, et d\u00e9finissez le chemin d\u2019acc\u00e8s \u00e0&nbsp;votre cl\u00e9 priv\u00e9e SSH en fonction de votre configuration locale.<\/p>\n<p>Sous Windows, vous devrez peut-\u00eatre <a href=\"https:\/\/code.visualstudio.com\/docs\/remote\/ssh#_remember-hosts-and-advanced-settings\">vous r\u00e9f\u00e9rer \u00e0&nbsp;ce fichier de configuration<\/a> dans la configuration de l\u2019extension.<\/p>\n<p>Assurez-vous que votre connexion SSH est pr\u00eate en ex\u00e9cutant <code>$ ssh alwaysdata<\/code> dans votre terminal. Si vous \u00eates connect\u00e9 aux serveurs d\u2019alwaysdata, vous \u00eates&nbsp;pr\u00eat&nbsp;!<\/p>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (239 + 12) \/ (480 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/LcfBYS8BKhCvK\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/LcfBYS8BKhCvK\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<h2 id=\"sur-le-serveur-depuis-votre-canap\u00e9\">Sur le serveur, depuis votre canap\u00e9<\/h2>\n<p>Lancez VSCode et allez dans le <em>gestionnaire d\u2019extensions<\/em> (<kbd>Ctrl<\/kbd>+<kbd>Shift<\/kbd>+<kbd>X<\/kbd>) et installez les extensions <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-vscode-remote.remote-ssh\">Remote \u2013 SSH<\/a> et <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-vscode-remote.remote-ssh-edit\">Remote \u2013 SSH&nbsp;: Editing Configuration Files<\/a>.<\/p>\n<p>\u00c0 pr\u00e9sent, en utilisant le <em>gestionnaire \u00e0&nbsp;distance<\/em>, ou la <em>Palette de commande &gt; Remote-SSH&nbsp;: Connect to Host\u2026<\/em> (<kbd>F1<\/kbd>), activez la connexion \u00e0&nbsp;l\u2019h\u00f4te <code>alwaysdata<\/code>. Apr\u00e8s un certain temps <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_2');\" onkeypress=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_2');\"><sup id=\"footnote_plugin_tooltip_3391_1_2\" class=\"footnote_plugin_tooltip_text\">2)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3391_1_2\" class=\"footnote_tooltip\"><\/span><\/span>, vous serez connect\u00e9 au serveur d\u2019alwaysdata. Une notification verte <code>SSH : alwaysdata<\/code> dans la <em>Barre d\u2019\u00e9tat<\/em> vous le signale. Faisons un test et essayons la commande <em>Fichier &gt; Ouvrir\u2026<\/em> sur un fichier ou un dossier&nbsp;: votre explorateur devrait maintenant afficher votre environnement distant&nbsp;! Vous pouvez \u00e9galement voir que la console (<kbd>Ctrl<\/kbd>+<kbd>`<\/kbd>) s\u2019ouvre sur votre environnement distant.<\/p>\n<p>F\u00e9licitations&nbsp;! Vous travaillez maintenant depuis votre IDE local sur votre compte distant alwaysdata, sans aucune diff\u00e9rence&nbsp;! Vous pouvez maintenant commencer votre session de <em>d\u00e9bogage \u00e0&nbsp;distance de votre application<\/em>.<\/p>\n<hr>\n<p>Un petit mot avant de vous lancer&nbsp;: lorsque vous travaillez \u00e0&nbsp;distance sur nos serveurs avec l\u2019extension <em>Remote \u2013 SSH<\/em>, VSCode consid\u00e8re le dossier <em>distant<\/em> que vous avez ouvert comme l\u2019espace de travail actuel (comme il le fait pour les projets locaux). Pour ce faire, il enregistre ses fichiers de configuration dans le r\u00e9pertoire cach\u00e9 habituel <code>.vscode<\/code> \u00e0&nbsp;la racine de votre projet. Nous vous recommandons vivement d\u2019ignorer ce dossier dans votre outil de versionnement (comme <code>.gitignore<\/code>) et de ne pas le supprimer de votre environnement distant.<\/p>\n<p>Dans ce guide, lorsque nous faisons r\u00e9f\u00e9rence \u00e0&nbsp;certains param\u00e8tres, ils sont li\u00e9s \u00e0&nbsp;l\u2019espace de travail et sont donc enregistr\u00e9s dans ce dossier sur le serveur. Le <em>gestionnaire \u00e0&nbsp;distance<\/em> m\u00e9morise vos espaces de travail distants, ce qui vous permet de les rouvrir rapidement lorsque vous souhaitez d\u00e9marrer une nouvelle session de d\u00e9bogage.<\/p>\n<hr>\n<h2 id=\"javascript-un-langage-pour-les-gouverner-tous\">JavaScript&nbsp;: un langage pour les gouverner tous<\/h2>\n<p>Pour illustrer ce guide, nous avons choisi de nous concentrer sur un seul langage pour le <em>back-end<\/em> et le <em>front-end<\/em>. C\u2019est ici uniquement \u00e0&nbsp;titre d\u2019exemple, et vous pouvez travailler sur n\u2019importe quel type d\u2019architecture. Il vous suffit d\u2019installer le bon <em>plugin<\/em> de d\u00e9bogueur dans VSCode, et tout ira bien. Gardez \u00e0&nbsp;l\u2019esprit qu\u2019alwaysdata supporte <a href=\"https:\/\/www.alwaysdata.com\/fr\/landings\/langages\/\">tous les langages que vous souhaitez<\/a>, n\u2019h\u00e9sitez pas \u00e0&nbsp;choisir celui qui correspondra le mieux \u00e0&nbsp;vos besoins&nbsp;!<\/p>\n<p>Gr\u00e2ce \u00e0&nbsp;notre <a href=\"https:\/\/www.alwaysdata.com\/fr\/services\/installations-rapides\/\">applith\u00e8que<\/a>, vous pouvez d\u00e9ployer un large \u00e9ventail de <em>frameworks<\/em> Web directement \u00e0&nbsp;partir de votre compte. Dans votre interface d\u2019administration, allez \u00e0&nbsp;la section <em>Web &gt; Sites<\/em>, cliquez sur le bouton <em>Installer une application<\/em>, choisissez <em>Express.js<\/em> en cliquant sur la roue crant\u00e9e, et suivez les instructions de l\u2019installateur.<\/p>\n<p>Vous avez maintenant une application <a href=\"https:\/\/expressjs.com\/\">Express.js<\/a> disponible&nbsp;! Cliquez sur son URL pour ouvrir une nouvelle fen\u00eatre pointant vers votre tout nouveau site, vous devriez voir le fameux message de bienvenue <code>Hello&nbsp;World!<\/code>. Utilisons maintenant notre IDE local pour \u00e9diter ce projet.<\/p>\n<p>Il est \u00e0&nbsp;noter la fa\u00e7on dont la m\u00eame base de code sera utilis\u00e9e dans diff\u00e9rents contextes&nbsp;: <em>d\u00e9veloppement<\/em> et <em>production<\/em>. Le site auquel vous venez d\u2019acc\u00e9der tourne en version de <em>production<\/em>. Nous travaillerons sur la m\u00eame base de code mais nous l\u2019utiliserons \u00e0&nbsp;partir de l\u2019acc\u00e8s SSH, en mode <em>d\u00e9veloppement<\/em>. Cela signifie que chaque modification que nous apporterons ne sera pas r\u00e9percut\u00e9e sur la version <em>production<\/em> tant que vous n\u2019aurez pas red\u00e9marr\u00e9 votre site depuis votre panneau d\u2019administration.<\/p>\n<p>Cette distinction <em>production<\/em> vs <em>d\u00e9veloppement<\/em> est valable uniquement pour les langages en processus persistants, comme Node.js, Python, Ruby\u2026 Les langages \u00e0&nbsp;\u00e9tat transitoires, comme PHP, sont syst\u00e9matiquement relanc\u00e9s \u00e0&nbsp;chaque requ\u00eates, et vos changements seront donc imm\u00e9diatement appliqu\u00e9s, sans qu\u2019il soit n\u00e9cessaire de relancer votre&nbsp;site.<\/p>\n<p>Dans VSCode, ouvrez votre espace de travail distant en activant la connexion <code>alwaysdata<\/code> et ouvrez le dossier qui vient d\u2019\u00eatre cr\u00e9\u00e9 par l\u2019installateur de l\u2019applith\u00e9que. Vous \u00eates pr\u00eat \u00e0&nbsp;d\u00e9velopper&nbsp;!<\/p>\n<p>Lan\u00e7ons notre application en mode d\u00e9veloppement&nbsp;: ouvrez le fichier <code>package.json<\/code> et ajoutez un script de <code>debug<\/code>&nbsp;:<\/p>\n<pre class=\"json\"><code>{\n  \/* ... *\/\n  \"scripts\" : {\n    \"debug\": \"NODE_ENV=development node app.js\"\n  }\n  \/* ... *\/\n}<\/code><\/pre>\n<p>Notre application <a href=\"https:\/\/help.alwaysdata.com\/fr\/langages\/nodejs\/configuration\/#environnement\">s\u2019attend \u00e0&nbsp;trouver la variable d\u2019environnement PORT<\/a>, ex\u00e9cutons-l\u00e0 \u00e0&nbsp;partir du terminal int\u00e9gr\u00e9 VSCode&nbsp;: <code>PORT=3000 npm run debug<\/code>. Vous devriez voir un message indiquant que votre application est pr\u00eate. Mais vous ne pouvez pas acc\u00e9der au port distant depuis votre machine locale&nbsp;!<\/p>\n<p>Heureusement, VSCode <em>Remote Extension<\/em> vous permet de d\u00e9clarer un port local \u00e0&nbsp;rattacher <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_3');\" onkeypress=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_3');\"><sup id=\"footnote_plugin_tooltip_3391_1_3\" class=\"footnote_plugin_tooltip_text\">3)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3391_1_3\" class=\"footnote_tooltip\"><\/span><\/span> \u00e0&nbsp;votre environnement distant. Dans le <em>gestionnaire \u00e0&nbsp;distance<\/em>, ajoutez un nouveau port \u00e0&nbsp;la section <em>Forwarded Ports<\/em>. Entrez <code>3000<\/code>. Maintenant, vous devriez pouvoir faire pointer votre navigateur sur http:\/\/localhost:3000, et acc\u00e9der \u00e0&nbsp;votre application distante en mode d\u00e9bogage&nbsp;!<\/p>\n<p>Pour \u00e9viter d\u2019entrer les ports transf\u00e9r\u00e9s \u00e0&nbsp;chaque fois que vous d\u00e9marrez une session, dans les <strong>pr\u00e9f\u00e9rences locales des utilisateurs<\/strong>, cochez la case <em>Remote&nbsp;: Restore Forwarded Ports<\/em> (ou ajoutez <code>\"remote.restoreForwardedPorts\": true<\/code> dans votre fichier local <code>User\/settings.json<\/code>).<\/p>\n<p>Nous sommes maintenant en mesure d\u2019ex\u00e9cuter notre application \u00e0&nbsp;partir de VSCode et d\u2019y acc\u00e9der localement. Voyons maintenant comment la d\u00e9boguer&nbsp;!<\/p>\n<h2 id=\"ex\u00e9cuter-\u00e9chouer-puis-ex\u00e9cuter-\u00e0-nouveau\">Ex\u00e9cuter, \u00e9chouer, puis ex\u00e9cuter \u00e0&nbsp;nouveau<\/h2>\n<h3 id=\"aller-au-del\u00e0-du-code\">Aller au-del\u00e0 du&nbsp;code<\/h3>\n<p>Lan\u00e7ons notre application attach\u00e9e au d\u00e9bogueur VSCode. Elle vous permet de d\u00e9finir des points d\u2019arr\u00eat et d\u2019inspecter <em>callstack<\/em>, m\u00eame \u00e0&nbsp;distance&nbsp;! Installez l\u2019extension <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=msjsdiag.debugger-for-chrome\">Debugger for Chrome<\/a>. Nous allons \u00e9galement \u00e9diter notre script <code>debug<\/code> pour l\u2019ex\u00e9cuter avec le mode d\u2019inspection activ\u00e9&nbsp;:<\/p>\n<pre class=\"json\"><code>\"debug\": \"NODE_ENV=development node --inspect=9321 app.js\"<\/code><\/pre>\n<p>Nous attachons l\u2019inspecteur dans un port non-standard pour \u00e9viter tout conflit, surtout avec la derni\u00e8re partie de ce guide. Ne vous pr\u00e9occupez pas pour le moment.<\/p>\n<p>Nous avons maintenant besoin d\u2019une t\u00e2che de d\u00e9bogage qui fera tourner notre application et y&nbsp;attachera le d\u00e9bogueur. Allez dans le <em>gestionnaire d\u2019ex\u00e9cution et de d\u00e9bogage<\/em> (<kbd>Ctrl<\/kbd>+<kbd>Shift<\/kbd>+<kbd>D<\/kbd>), actuellement vide. Cliquez sur le lien <em>create a&nbsp;launch.json<\/em>, et s\u00e9lectionnez <em>Node.js<\/em> dans le panneau de choix. VSCode cr\u00e9era un nouveau fichier <code>.vscode\/launch.json<\/code> dans votre environnement distant (vous pouvez le voir depuis votre <em>explorateur<\/em>). Remplissez-le avec la configuration suivante&nbsp;:<\/p>\n<pre class=\"json\"><code>{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"type\": \"node\",\n            \"request\": \"launch\",\n            \"name\": \"Server Debug Mode\",\n            \"runtimeExecutable\": \"npm\",\n            \"runtimeArgs\": [\n                \"--scripts-prepend-node-path=true\",\n                \"run-script\",\n                \"debug\"\n            ],\n            \"port\": 9321,\n            \"env\": {\n                \"PORT\": \"3000\"\n            },\n            \"skipFiles\": [\n                \"&lt;node_internals&gt;\/**\"\n            ]\n        }\n    ]\n}<\/code><\/pre>\n<p>Nous y&nbsp;trouvons&nbsp;:<\/p>\n<ul>\n<li><code>runtimeExecutable<\/code>&nbsp;: nous ex\u00e9cutons l\u2019application par le biais de <code>npm<\/code>&nbsp;;<\/li>\n<li><code>runtimeArgs<\/code>&nbsp;: voici notre script <code>debug<\/code>&nbsp;; nous ajoutons \u00e9galement <code>script-prepend-node-path<\/code> pour \u00e9viter les avertissements dus au chemin vers l\u2019ex\u00e9cutable <code>node<\/code> dans le syst\u00e8me de fichiers, qui est sp\u00e9cifique \u00e0&nbsp;l\u2019architecture alwaysdata&nbsp;;<\/li>\n<li><code>port<\/code>&nbsp;: le port auquel nous avons choisi d\u2019attacher l\u2019inspecteur node&nbsp;;<\/li>\n<li><code>env<\/code>&nbsp;: les variables d\u2019environnement pass\u00e9es, ici le port sur lequel l\u2019application Express.js va s\u2019attacher.<\/li>\n<\/ul>\n<p>Nous sommes maintenant pr\u00eats \u00e0&nbsp;faire fonctionner notre application avec le d\u00e9bogueur. Lancez le d\u00e9bogueur avec la fl\u00e8che verte dans le <em>panneau d\u2019ex\u00e9cution<\/em> (ou appuyez sur <kbd>F5<\/kbd>). Votre script de d\u00e9bogage <em>npm<\/em> est ex\u00e9cut\u00e9 par VSCode, et vous pouvez toujours acc\u00e9der \u00e0&nbsp;votre application dans votre navigateur.<\/p>\n<p>Maintenant, ouvrez le fichier <code>app.js<\/code>, et mettez un point d\u2019arr\u00eat sur la ligne <code>res.send<\/code> (6) en cliquant dans la goutti\u00e8re (ou appuyez sur <kbd>F9<\/kbd> avec votre curseur sur la ligne). Rechargez votre navigateur. Votre application devrait faire une pause juste avant d\u2019ex\u00e9cuter l\u2019instruction <code>res.send<\/code> et vous pouvez analyser et d\u00e9boguer votre application depuis le <em>Panneau d\u2019ex\u00e9cution et de d\u00e9bogage<\/em>&nbsp;!<\/p>\n<h3 id=\"outils-pratiques-pour-d\u00e9veloppeurs-surbook\u00e9s\">Outils pratiques pour d\u00e9veloppeurs surbook\u00e9s<\/h3>\n<p>Malheureusement, devoir relancer votre application \u00e0&nbsp;chaque fois que vous modifiez les fichiers est plut\u00f4t fastidieux. Configurons le rechargement \u00e0&nbsp;chaud c\u00f4t\u00e9 serveur&nbsp;!<\/p>\n<ol type=\"1\">\n<li>Installez <a href=\"https:\/\/www.npmjs.com\/package\/nodemon\">Nodemon<\/a> sur votre projet depuis le terminal int\u00e9gr\u00e9&nbsp;: <code>npm install --save-dev nodemon<\/code>.<\/li>\n<li>Editez le script <code>debug<\/code> dans le fichier <code>package.json<\/code> pour lancer l\u2019application avec <code>nodemon<\/code>&nbsp;: <code>NODE_ENV=development nodemon --inspect=9321 --exitcrash app.js<\/code>.<\/li>\n<li>Modifiez la configuration du d\u00e9bogueur dans le fichier <code>launch.json<\/code> en ajoutant l\u2019option <code>\"restart\" : true<\/code>, permettant au d\u00e9bogueur de se r\u00e9attacher \u00e0&nbsp;chaque fois que nodemon red\u00e9marre l\u2019application.\n<pre class=\"json\"><code>\"name\": \"Server Debug Mode\",\n\"restart\": true<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>Ex\u00e9cutez \u00e0&nbsp;nouveau la configuration du d\u00e9bogueur et rechargez votre navigateur&nbsp;: vous devriez \u00eatre en mesure d\u2019acc\u00e9der \u00e0&nbsp;l\u2019application. Modifiez la cha\u00eene <code>Hello World!<\/code> et sauvegardez le fichier. Votre application est automatiquement recharg\u00e9e et le d\u00e9bogueur r\u00e9-attach\u00e9. Rechargez votre navigateur&nbsp;: vous avez le nouveau message&nbsp;!<\/p>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (272 + 12) \/ (360 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/l41lUJ1YoZB1lHVPG\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/l41lUJ1YoZB1lHVPG\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<p>En tant que d\u00e9veloppeurs, nous sommes souvent paresseux&nbsp;: configurons le navigateur pour qu\u2019il se recharge de lui-m\u00eame lorsque l\u2019application serveur est \u00e9galement recharg\u00e9e&nbsp;:<\/p>\n<ol type=\"1\">\n<li>Installez <a href=\"https:\/\/www.npmjs.com\/package\/livereload\">livereload<\/a> dans votre projet&nbsp;: <code>npm install --save-dev livereload connect-livereload<\/code>.<\/li>\n<li>Votre application doit servir une page HTML valide pour pouvoir injecter le script livereload c\u00f4t\u00e9 serveur. Ajoutons <a href=\"https:\/\/www.npmjs.com\/package\/pug\">Pug<\/a> comme moteur de <em>templates<\/em>, et <a href=\"https:\/\/www.npmjs.com\/package\/helmet\">Helmet<\/a> pour g\u00e9rer les en-t\u00eates de s\u00e9curit\u00e9 CORS des pages que nous servons&nbsp;: <code>npm install --save pug helmet<\/code><\/li>\n<li>Configurez votre application pour utiliser le moteur de <em>templates<\/em>, et activez LiveReload lorsque l\u2019app est en mode <em>d\u00e9veloppement<\/em>&nbsp;:\n<pre class=\"js\"><code>const path = require('path')\nconst livereload = require('livereload')\nconst connectLivereload = require('connect-livereload')\nconst helmet = require('helmet')\n\nconst LIVERELOAD_PORT=35729\nconst app = express()\n\napp.use(helmet.contentSecurityPolicy({\n  directives: {\n    defaultSrc: [\"'self'\"],\n    scriptSrc: [\"'self'\", `localhost:${LIVERELOAD_PORT}`, \"'unsafe-inline'\", \"'unsafe-eval'\"],\n    connectSrc: [\"'self'\", `ws:\/\/localhost:${LIVERELOAD_PORT}`]\n  }\n}))\n\nif (process.env.NODE_ENV\n&amp;&amp;  process.env.NODE_ENV === \"development\") {\n  var livereloadServer = livereload.createServer()\n  app.use(connectLivereload({\n    port: LIVERELOAD_PORT\n  }))\n  livereloadServer.server.once('connection', () =&gt; {\n    setTimeout<span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_4');\" onkeypress=\"footnote_moveToReference_3391_1('footnote_plugin_reference_3391_1_4');\"><sup id=\"footnote_plugin_tooltip_3391_1_4\" class=\"footnote_plugin_tooltip_text\">4)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3391_1_4\" class=\"footnote_tooltip\"><\/span><\/span>.\n<h3 id=\"go-go-gadget\">Go Go, Gadget !<\/h3>\n<p>Nous avons un panneau de pr\u00e9visualisation du navigateur, attach\u00e9 au d\u00e9bogueur interne. Voyons ce que nous pouvons en faire !<\/p>\n<ol type=\"1\">\n<li>Cr\u00e9ez un fichier <code>static\/js\/main.js<\/code> au niveau de la racine de votre projet, avec le contenu suivant :\n<pre class=\"js\"><code>window.addEventListener('DOMContentLoaded', () =&gt; {\n  document.querySelector('h1')\n    .addEventListener('click', () =&gt; {\n      alert(\"You didn't say the magic word!\")\n    })\n})<\/code><\/pre>\n<\/li>\n<li>Mettez \u00e0 jour notre <code>index.pug<\/code>, chargez un script <code>main.js<\/code> dans la page :\n<pre class=\"pug\"><code>html\n    head\n        script(src=\"\/js\/main.js\" defer)<\/code><\/pre>\n<\/li>\n<li>Maintenant, \u00e9ditez notre <code>app.js<\/code> pour servir les fichiers statiques :\n<pre class=\"js\"><code>app.use(express.static(path.join(__dirname, 'static')))<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>Si vous lancez l\u2019application maintenant, vous devriez pouvoir cliquer sur le titre et voir la bo\u00eete d\u2019alerte appara\u00eetre dans les notifications VSCode. Mais vous ne pouvez pas acc\u00e9der aux fichiers dans le d\u00e9bogueur, car il doit rattacher ces <em>assets<\/em> aux sources sur le serveur.<\/p>\n<p>Modifiez l\u2019entr\u00e9e <code>Browser Preview: Launch<\/code> dans le fichier <code>launch.json<\/code> et ajoutez le <em>mapping<\/em> vers les fichiers :<\/p>\n<pre class=\"json\"><code>{\n    \"type\": \"browser-preview\",\n    \"request\": \"launch\",\n    \"name\": \"Browser Preview: Launch\",\n    \"url\": \"http:\/\/localhost:3000\",\n    \"pathMapping\": {\n        \"\/js\/\": \"${workspaceRoot}\/static\/js\/\"\n    }\n}<\/code><\/pre>\n<p>Ex\u00e9cutez \u00e0 nouveau la t\u00e2che de d\u00e9bogage. Ajoutez un point d\u2019arr\u00eat dans le fichier <code>main.js<\/code>. Cliquez sur le titre. Votre script est mis en pause et vous pouvez inspecter la <em>callstack<\/em> \u00e0 partir de l\u2019inspecteur de d\u00e9bogage int\u00e9gr\u00e9 !<\/p>\n<p>Terminons en activant \u00e9galement le rechargement en direct des ressources du <em>frontend<\/em>. Mettez \u00e0 jour le fichier <code>app.js<\/code> en ajoutant l\u2019instruction LiveReload <code>watch<\/code> apr\u00e8s avoir cr\u00e9\u00e9 le <code>livereloadServer<\/code> :<\/p>\n<pre class=\"js\"><code>var livereloadServer = livereload.createServer()\nlivereloadServer.watch(path.join(__dirname, 'static'))<\/code><\/pre>\n<p>Vous pouvez maintenant \u00e9diter le fichier <code>main.js<\/code> voir votre navigateur se recharger automatiquement !<\/p>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (384 + 12) \/ (700 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/8IPKZHrNpSTO8\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/8IPKZHrNpSTO8\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<hr>\n<p>C\u2019\u00e9tait un long voyage et un long article juste pour vous donner seulement quelques bases du <strong>D\u00e9bogage \u00e0 distance back et front<\/strong>. Il vous offre la possibilit\u00e9 de conserver votre d\u00e9p\u00f4t de code dans votre compte alwaysdata, lib\u00e9rant votre environnement local strate technique complexe \u00e0 maintenir.<\/p>\n<p>Vous pouvez ex\u00e9cuter votre code \u00e0 distance en <em>mode de d\u00e9veloppement<\/em>, attacher le <em>backend<\/em> au d\u00e9bogueur local, ex\u00e9cuter votre application Web dans un conteneur de navigateur, et ex\u00e9cuter un second d\u00e9bogueur en parall\u00e8le, attach\u00e9 \u00e0 ce navigateur int\u00e9gr\u00e9 !<\/p>\n<p>Cela vous donne la possibilit\u00e9 de tester et de d\u00e9boguer dans un environnement de type production avec tout l\u2019outillage moderne que vous pouvez attendre. Encore plus amusant : lorsque votre session de d\u00e9bogage est termin\u00e9e, il vous suffit de red\u00e9marrer votre <em>Site<\/em> depuis votre panneau d\u2019administration alwaysdata et vos modifications sont en ligne !<\/p>\n<p>Comme mentionn\u00e9 pr\u00e9c\u00e9demment, gr\u00e2ce \u00e0 l\u2019\u00e9cosyst\u00e8me VSCode, des d\u00e9bogueurs sont disponibles pour de nombreux langages modernes comme Python, Ruby, PHP et bien d\u2019autres encore. Pas besoin de s\u2019en tenir \u00e0 JS, vous pouvez utiliser ce guide avec n\u2019importe quel type de langage que vous h\u00e9bergez sur votre compte.<\/p>\n<p>Nous esp\u00e9rons que cela vous aidera \u00e0 am\u00e9liorer votre flux de travail quotidien. Vous voulez en savoir plus sur les cas d\u2019utilisation avanc\u00e9s de votre compte alwaysdata ? Faites-nous part en commentaires de la fa\u00e7on dont nous pouvons vous aider \u00e0 d\u00e9bloquer de nouveaux niveaux dans vos t\u00e2ches quotidiennes !<\/p>\n<div class=\"speaker-mute footnotes_reference_container\"> <div class=\"footnote_container_prepare\"><p><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_label pointer\" onclick=\"footnote_expand_collapse_reference_container_3391_1();\">Notes<\/span><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_collapse_button\" style=\"display: none;\" onclick=\"footnote_expand_collapse_reference_container_3391_1();\">[<a id=\"footnote_reference_container_collapse_button_3391_1\">+<\/a>]<\/span><\/p><\/div> <div id=\"footnote_references_container_3391_1\" style><table class=\"footnotes_table footnote-reference-container\"><caption class=\"accessibility\">Notes<\/caption> <tbody> \n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_3391_1('footnote_plugin_tooltip_3391_1_1');\"><a id=\"footnote_plugin_reference_3391_1_1\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>1<\/a><\/th> <td class=\"footnote_plugin_text\">Peut-\u00eatre fourni par vos co\u00e9quipiers DevOps.<\/td><\/tr>\n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_3391_1('footnote_plugin_tooltip_3391_1_2');\"><a id=\"footnote_plugin_reference_3391_1_2\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>2<\/a><\/th> <td class=\"footnote_plugin_text\">Au cours de laquelle VSCode installe les composants n\u00e9cessaires \u00e0 distance et d\u00e9marre un serveur de d\u00e9veloppement \u00e0 distance en arri\u00e8re-plan.<\/td><\/tr>\n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_3391_1('footnote_plugin_tooltip_3391_1_3');\"><a id=\"footnote_plugin_reference_3391_1_3\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>3<\/a><\/th> <td class=\"footnote_plugin_text\">VSCode s\u2019appuie sur <em>SSH Port Forwarding<\/em> et a besoin que le serveur SSH ait la directive <a href=\"https:\/\/github.com\/microsoft\/vscode-remote-release\/issues\/92\"><code>AllowTCPForwarding<\/code> activ\u00e9e<\/a>. Chez alwaysdata, nous d\u00e9sactivons cette fonction pour des raisons de s\u00e9curit\u00e9, mais nous avons heureusement trouv\u00e9 un moyen de faire fonctionner le <em>Port Forwarding<\/em> pour VSCode sans compromettre la s\u00e9curit\u00e9 !<\/td><\/tr>\n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_3391_1('footnote_plugin_tooltip_3391_1_4');\"><a id=\"footnote_plugin_reference_3391_1_4\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>4<\/a><\/th> <td class=\"footnote_plugin_text\">) =&gt; livereloadServer.refresh('\/'), 100)\n  })\n}\napp.set('view engine', 'pug')\napp.get('\/', (req, res) =&gt; {\n  res.render('index', {\n    title: \"Hello World!\",\n    message: \"Hello World \ud83d\ude3a !\"\n  })\n})<\/td><\/tr><\/tbody><\/table><\/div><\/div><\/code><\/pre>\n<\/li>\n<li>Cr\u00e9ez un fichier <code>views\/index.pug<\/code> \u00e0&nbsp;la racine de votre projet&nbsp;:\n<pre class=\"pug\"><code>html\nhead\n    title= title\n\nbody\n    h1= message<\/code><\/pre>\n<\/li>\n<li>Dans la section <em>Forwarded Ports Section<\/em>, ajoutez un nouveau port \u00e0&nbsp;transf\u00e9rer&nbsp;: <code>35729<\/code>, permettant \u00e0&nbsp;votre navigateur d\u2019acc\u00e9der au serveur livereload.<\/li>\n<\/ol>\n<p>Maintenant, ex\u00e9cutez \u00e0&nbsp;nouveau la configuration du d\u00e9bogueur. Rechargez votre navigateur, il devrait activer le mode LiveReload (vous verrez une requ\u00eate <em>WebSocket<\/em> dans le <em>Panneau R\u00e9seau<\/em>). Modifiez le message envoy\u00e9 au mod\u00e8le. Lors de la sauvegarde, l\u2019application sera red\u00e9marr\u00e9e, le d\u00e9bogueur y&nbsp;sera rattach\u00e9, et votre navigateur sera recharg\u00e9 sans aucune action de votre&nbsp;part&nbsp;!<\/p>\n<h2 id=\"d\u00e9bogueur-\u00e0-tous-les-\u00e9tages\">D\u00e9bogueur \u00e0&nbsp;tous les \u00e9tages<\/h2>\n<h3 id=\"tout-en-un\">Tout en&nbsp;un<\/h3>\n<p>VSCode offre un large choix d\u2019extensions, vous permettant de b\u00e9n\u00e9ficier d\u2019une exp\u00e9rience totalement int\u00e9gr\u00e9e. Alors pourquoi ne pas ex\u00e9cuter et contr\u00f4ler notre navigateur de test directement depuis notre IDE&nbsp;? Il est temps d\u2019installer l\u2019extension <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=auchenberg.vscode-browser-preview\">Browser preview<\/a>.<\/p>\n<p>Cr\u00e9ons une configuration de d\u00e9bogage pr\u00eate \u00e0&nbsp;ex\u00e9cuter le <em>Browser Preview<\/em>. Dans votre fichier <code>launch.json<\/code>, ajoutez une nouvelle configuration apr\u00e8s celle du <em>Server Debug Mode<\/em>&nbsp;:<\/p>\n<pre class=\"json\"><code>{\n    \"type\": \"browser-preview\",\n    \"request\": \"launch\",\n    \"name\": \"Browser Preview: Launch\",\n    \"url\": \"<span class=\"footnote_url_wrap\">http:\/\/localhost:3000\"<\/span>\n}<\/code><\/pre>\n<p>De toute \u00e9vidence, il est parfaitement inutile de lancer l\u2019aper\u00e7u du navigateur sans lancer l\u2019application en arri\u00e8re-plan. C\u2019est pourquoi nous allons cr\u00e9er un <em>Compound<\/em> qui lancera les deux \u00e0&nbsp;partir de notre d\u00e9bogueur. Toujours dans le fichier <code>launch.json<\/code>, ajoutez une entr\u00e9e <code>compounds<\/code> juste apr\u00e8s celle des <code>configurations<\/code>&nbsp;:<\/p>\n<pre class=\"json\"><code>\"compounds\": [\n    {\n        \"name\": \"Client\/Server\",\n        \"configurations\": [\"Server Debug Mode\", \"Browser Preview: Launch\"],\n    }\n]<\/code><\/pre>\n<p>Maintenant, dans votre <em>Panneau d\u2019ex\u00e9cution et de d\u00e9bogage<\/em>, s\u00e9lectionnez la configuration <code>Client\/Server<\/code>, et ex\u00e9cutez-la. Votre application est lanc\u00e9e en mode d\u00e9veloppement avec <em>Nodemon<\/em> et attach\u00e9e au d\u00e9bogueur, et un <em>Panneau de pr\u00e9visualisation du navigateur<\/em> devrait s\u2019ouvrir, pointant sur l\u2019adresse de l\u2019application ((En raison de la fa\u00e7on dont les <em>compounds<\/em> sont ex\u00e9cut\u00e9s, l\u2019aper\u00e7u du navigateur peut pointer sur <code>about:blank<\/code> au lieu de <span class=\"footnote_url_wrap\">http:\/\/localhost:3000.<\/span> Il existe une solution de contournement li\u00e9e \u00e0&nbsp;la possibilit\u00e9 d\u2019ex\u00e9cuter des pr\u00e9-t\u00e2ches (voir <a href=\"https:\/\/github.com\/auchenberg\/vscode-browser-preview\/issues\/114\">le ticket<\/a>). En attendant un correctif, vous pouvez mettre \u00e0&nbsp;jour manuellement l\u2019adresse pour charger votre application dans le panneau de pr\u00e9visualisation.\n\n   <script type=\"text\/javascript\"> function footnote_expand_reference_container_3391_1() { jQuery('#footnote_references_container_3391_1').show(); jQuery('#footnote_reference_container_collapse_button_3391_1').text('\u2212'); } function footnote_collapse_reference_container_3391_1() { jQuery('#footnote_references_container_3391_1').hide(); jQuery('#footnote_reference_container_collapse_button_3391_1').text('+'); } function footnote_expand_collapse_reference_container_3391_1() { if (jQuery('#footnote_references_container_3391_1').is(':hidden')) { footnote_expand_reference_container_3391_1(); } else { footnote_collapse_reference_container_3391_1(); } } function footnote_moveToReference_3391_1(p_str_TargetID) { footnote_expand_reference_container_3391_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } } function footnote_moveToAnchor_3391_1(p_str_TargetID) { footnote_expand_reference_container_3391_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } }<\/script><\/p>","protected":false},"excerpt":{"rendered":"<p>Fatigu\u00e9 de vous battre dans l\u2019enfer des d\u00e9pendances&nbsp;?  Pourquoi ne pas supprimer votre environnement local et essayer les sessions de d\u00e9bogage \u00e0&nbsp;distance&nbsp;?<\/p>\n","protected":false},"author":12,"featured_media":3390,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[230],"tags":[265,142,182],"class_list":["post-3391","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized-fr","tag-debug-fr","tag-langages-fr","tag-node-js-fr"],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/3391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/comments?post=3391"}],"version-history":[{"count":0,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/3391\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media\/3390"}],"wp:attachment":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media?parent=3391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/categories?post=3391"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/tags?post=3391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}