{"id":3416,"date":"2020-06-23T14:08:00","date_gmt":"2020-06-23T12:08:00","guid":{"rendered":"https:\/\/blog.alwaysdata.com\/?p=3416"},"modified":"2020-06-23T11:19:57","modified_gmt":"2020-06-23T09:19:57","slug":"un-nouvel-espoir-pour-le-developpement-frontend-adieu-le-build","status":"publish","type":"post","link":"https:\/\/blog.alwaysdata.com\/fr\/2020\/06\/23\/un-nouvel-espoir-pour-le-developpement-frontend-adieu-le-build\/","title":{"rendered":"Un nouvel espoir pour le d\u00e9veloppement frontend&nbsp;: adieu, le&nbsp;build&nbsp;!"},"content":{"rendered":"<p>Le d\u00e9veloppement Web frontend est devenu un parcours du combattant au fil des ans. Il s\u2019est complexifi\u00e9 aussi bien du point de vue des outils que des frameworks, et vous avez forc\u00e9ment \u00e9t\u00e9 confront\u00e9 au ph\u00e9nom\u00e8ne de <em>JavaScript Fatigue<\/em> d\u00fb \u00e0&nbsp;la croissance rapide de tout l\u2019\u00e9cosyst\u00e8me.<\/p>\n<p>Alors accrochez-vous, en 2020, on repart en arri\u00e8re&nbsp;! L\u2019avenir est d\u00e9j\u00e0 l\u00e0, et il est plus que reluisant&nbsp;\ud83e\udd29&nbsp;!<\/p>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (362 + 12) \/ (480 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/3o6Mbn3J84dYw00DVm\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/3o6Mbn3J84dYw00DVm\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<h2 id=\"au-commencement-\u00e9tait-javascript\">Au commencement \u00e9tait JavaScript\u2026<\/h2>\n<p>\u2026 et puis tout s\u2019est acc\u00e9l\u00e9r\u00e9. Avec l\u2019arriv\u00e9e de Node.js, JS est devenu <em>le<\/em> nouveau challenger. \u00catre capable d\u2019ex\u00e9cuter du JavaScript \u00e0&nbsp;la fois sur le <em>backend<\/em> et le <em>frontend<\/em> a&nbsp;consid\u00e9rablement simplifi\u00e9 le d\u00e9veloppement de nombreux outils, de nouvelles (petites) biblioth\u00e8ques et de nouveaux environnements. Emport\u00e9 par le <em>Registre NPM<\/em>, il s\u2019est rapidement \u00e9tendu et est maintenant le langage <em>de facto<\/em> pour tous les outils de d\u00e9veloppement <em>front<\/em>, ainsi que pour la distribution des d\u00e9pendances.<\/p>\n<p>Puis sont apparus les frameworks <em>front<\/em> r\u00e9actifs, comme <em>React<\/em>, <em>Vue.js<\/em>, ou <em>Svelte<\/em>. Avec leurs architectures intelligentes, ils constituent les biblioth\u00e8ques UI les plus rapides \u00e0&nbsp;l\u2019heure actuelle pour d\u00e9velopper des interfaces complexes dans le navigateur.<\/p>\n<p>Enfin, l\u2019\u00e8re <em>PWA<\/em>. Nous d\u00e9veloppons maintenant des applications Web en utilisant les technologies Web, mais pas n\u00e9cessairement li\u00e9es \u00e0&nbsp;des sites Web. Ce sont des applications, comme toutes les autres. Installables, elles fonctionnent dans des navigateurs <em>chromeless<\/em> comme Electron ou les WebViews, et n\u2019ont rien \u00e0&nbsp;envier aux versions natives.<\/p>\n<p>Nous sommes en 2020, et nous pensons d\u00e9sormais en dehors du navigateur&nbsp;: JavaScript fonctionne partout, nous d\u00e9veloppons des applications en utilisant les technologies du web, et nous appliquons les m\u00eames mod\u00e8les que pour les d\u00e9veloppements natifs. Tout cela avec les m\u00eames mises en garde&nbsp;: \u00e0&nbsp;mesure que l\u2019\u00e9cosyst\u00e8me JS se d\u00e9veloppe, les d\u00e9pendances de nos applications croissent \u00e9galement. Nous sommes maintenant en train de <em>compiler pour le Web<\/em>. Comme pour des d\u00e9veloppements natifs.<\/p>\n<p>Il y&nbsp;a cependant une petite, mais significative, diff\u00e9rence&nbsp;: nous diffusons nos applications en streaming. Lorsque vous servez une application web, vous utilisez toujours les fondamentaux du Web&nbsp;: votre serveur envoie une page HTML qui demande \u00e0&nbsp;son tour ses ressources (images, JS, polices, CSS, etc.). Nous envoyons chaque jour des tonnes de <em>Go<\/em> aux navigateurs de nos utilisateurs, et il est temps d\u2019arr\u00eater l\u2019h\u00e9morragie&nbsp;! En prenant le probl\u00e8me d\u00e8s la conception.<\/p>\n<h2 id=\"le-p\u00e9ch\u00e9-originel-le-packing\">Le p\u00e9ch\u00e9 originel&nbsp;: le <em>packing<\/em><\/h2>\n<p>Aux premiers temps des applications Web, nous avions un nouveau mod\u00e8le pour distribuer des morceaux de JavaScript \u00e0&nbsp;travers les projets sous forme de petites librairies&nbsp;: <em>CommonJS<\/em>. Il \u00e9tait si moderne qu\u2019il est devenu la norme pour la distribution de modules dans l\u2019environnement Node.js. Le principal probl\u00e8me \u00e9tait l\u2019incapacit\u00e9 de la VM de notre navigateur \u00e0&nbsp;comprendre et \u00e0&nbsp;exploiter ce format.<\/p>\n<p>Nous avons donc commenc\u00e9 \u00e0&nbsp;d\u00e9velopper des <em>loaders<\/em>, capables de charger et d\u2019injecter des modules CommonJS dans nos pages principales. Mais cela a&nbsp;rapidement conduit \u00e0&nbsp;un autre probl\u00e8me&nbsp;: nous avons commenc\u00e9 \u00e0&nbsp;servir trop de d\u00e9pendances au navigateur, ce qui a&nbsp;fait gonfler les co\u00fbts de connexion.<\/p>\n<p>Nous avons donc cr\u00e9\u00e9 des <em>bundlers<\/em>, comme <a href=\"https:\/\/webpack.js.org\/\">Webpack<\/a>. Ils sont charg\u00e9s de collecter toutes les d\u00e9pendances et les modules de votre application et de produire un seul fichier JS que votre navigateur peut ex\u00e9cuter. Ils sont rapidement devenus des <em>packers<\/em> en m\u00eame temps, vous permettant d\u2019appliquer des changements et des optimisations \u00e0&nbsp;vos builds, et d\u2019ajouter des m\u00e9canismes pour importer bien plus que des d\u00e9pendances JS&nbsp;!<\/p>\n<p>Nous avons ensuite ajout\u00e9 des pr\u00e9processeurs et des transpilateurs, pour \u00e9crire avec de nouveaux langages vers JavaScript (comme CoffeeScript ou TypeScript), puis de nouveaux outils pour des optimisations suppl\u00e9mentaires, en divisant les ressources en petits morceaux et en les servant uniquement \u00e0&nbsp;la demande. Parce que la performance en prenait un sacr\u00e9&nbsp;coup.<\/p>\n<p>Notre outillage de d\u00e9veloppement est maintenant plus compliqu\u00e9e qu\u2019il ne l\u2019a jamais \u00e9t\u00e9. Nous sommes dans une course sans fin pour ajouter de nouveaux outils qui nous permettent de faire face au probl\u00e8me de la performance. Nous les avons cr\u00e9\u00e9s parce que nous avions besoin de ces outils, mais notre cha\u00eene de production est maintenant un horrible processus bouffi, qui est extr\u00eamement complexe \u00e0&nbsp;comprendre et qui prend une \u00e9ternit\u00e9 \u00e0&nbsp;d\u00e9marrer et \u00e0&nbsp;compiler chaque fois que vous d\u00e9marrez un projet ou enregistrez un fichier.<\/p>\n<p>Cette situation est-elle encore bien l\u00e9gitime&nbsp;?<\/p>\n<h2 id=\"bienvenue-en-2020-zero-build-pipeline\">Bienvenue en 2020&nbsp;: <em>Zero Build Pipeline<\/em><\/h2>\n<p>Alors, passons en revue la liste. Qu\u2019avons-nous aujourd\u2019hui dans notre bo\u00eete \u00e0&nbsp;outils&nbsp;?<\/p>\n<ol type=\"1\">\n<li><em>Modules ES6 natifs<\/em>&nbsp;: navr\u00e9 pour le format CommonJS, mais son descendant, le <em>Module ES6<\/em>, est bien plus efficace. Il est support\u00e9 en natif par <a href=\"https:\/\/nodejs.org\/api\/esm.html\">Node.js<\/a> et <a href=\"https:\/\/caniuse.com\/#feat=es6-module\">les navigateurs<\/a>. Il n\u2019y a&nbsp;plus de raison de l\u2019\u00e9viter.<\/li>\n<li><em>Libres pr\u00e9-compil\u00e9es<\/em>&nbsp;: <a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a> est en de plus en plus couramment utilis\u00e9 <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3416_1('footnote_plugin_reference_3416_1_1');\" onkeypress=\"footnote_moveToReference_3416_1('footnote_plugin_reference_3416_1_1');\"><sup id=\"footnote_plugin_tooltip_3416_1_1\" class=\"footnote_plugin_tooltip_text\">1)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3416_1_1\" class=\"footnote_tooltip\"><\/span><\/span> et nous avons beaucoup de nouvelles biblioth\u00e8ques qui sont d\u00e9velopp\u00e9es avec ce langage. M\u00eame d\u00e9velopp\u00e9s en VanillaJS, ces modules peuvent \u00eatre optimis\u00e9s en dehors de notre cha\u00eene d\u2019outils et distribu\u00e9s dans une version de production. Pas besoin de g\u00e9rer cela de notre c\u00f4t\u00e9 dans <em>notre<\/em> projet.<\/li>\n<li><em>Un grand \u00e9cosyst\u00e8me<\/em>&nbsp;: NPM est l\u2019un des registres de d\u00e9pendances les plus importants au monde. Tout l\u2019univers JavaScript\/TypeScript est rempli d\u2019excellents outils et de librairies utiles, pr\u00eats \u00e0&nbsp;\u00eatre utilis\u00e9s sans devoir les embarquer dans notre build&nbsp;final.<\/li>\n<li><em>HTTP\/2<\/em>&nbsp;: La version 2&nbsp;du protocole est largement disponible et support\u00e9e, et elle r\u00e9duit un grand nombre de requ\u00eates. En effet, il est probablement plus efficace de servir un tas de petits fichiers avec HTTP\/2 plut\u00f4t qu\u2019un gros fichier unique, gr\u00e2ce aux optimisations du protocole. Sans compter le b\u00e9n\u00e9fice associ\u00e9 \u00e0&nbsp;la mise en&nbsp;cache.<\/li>\n<li>Tous nos outils, des commandes Unix aux applications d\u00e9di\u00e9es au <em>frontend<\/em>, offrent une <em>CLI<\/em>, qui permet la construction de pipelines avanc\u00e9s.<\/li>\n<\/ol>\n<p>Cette bo\u00eete \u00e0&nbsp;outils est donc riche en possibilit\u00e9s. Intuitivement, elle nous pousse vers le <strong>Bare Modules Devtools<\/strong>. Voici les id\u00e9es simples qui se cachent derri\u00e8re le concept&nbsp;:<\/p>\n<ol type=\"1\">\n<li>Nous utilisons les modules tels qu\u2019ils sont distribu\u00e9s, dans leur format de module ES6, sans les empaqueter ou les regrouper,<\/li>\n<li>Nous comptons sur HTTP\/2 pour servir efficacement les fichiers de ressources afin de maintenir un taux de performance \u00e9lev\u00e9,<\/li>\n<li>Nous nous en tenons \u00e0&nbsp;0ms pour d\u00e9marrer l\u2019environnement de d\u00e9veloppement, en ne servant que les fichiers bruts et les modules et en ne les modifiant pas dans un contexte de <em>d\u00e9veloppement<\/em>,<\/li>\n<li>Nous pr\u00e9\/post-traitons nos fichiers sources en utilisant directement les CLI (ou avec des outils natifs) pour \u00e9viter de cr\u00e9er de nouvelles cha\u00eenes d\u2019outils complexes.<\/li>\n<\/ol>\n<p>Le 5&nbsp;mai dernier a&nbsp;vu le lancement de la version 2&nbsp;de <a href=\"https:\/\/www.snowpack.dev\/#get-started\">Snowpack<\/a>, et c\u2019est exactement ce dont nous avions besoin pour mettre en \u0153uvre ce concept&nbsp;! Ce nouvel outil est \u00e0&nbsp;la fois un outil de d\u00e9veloppement, qui vous permet d\u2019ex\u00e9cuter vos applications en mode d\u00e9veloppement sans temps de d\u00e9marrage, sans <em>packing<\/em>, avec des mises \u00e0&nbsp;jour rapides, et un outil de construction o\u00f9 vous pouvez d\u00e9finir et associer (<em>pipe<\/em>) des outils pour pr\u00e9parer vos ressources pour les versions de production si n\u00e9cessaire.<\/p>\n<h2 id=\"vous-navez-encore-rien-vu\">Vous n\u2019avez encore rien&nbsp;vu&nbsp;!<\/h2>\n<figure class=\"embed-media__giphy\" style=\"width:65%; padding-bottom:calc(65% * (225 + 12) \/ (400 + 12))\">\n    <video id=\"giphy-${token}\" autoplay loop muted playsinline>\n        <source src=\"https:\/\/media.giphy.com\/media\/3o6ozsTeR2bs1hjBU4\/giphy.mp4\" type=\"video\/mp4\">\n        <img decoding=\"async\" src=\"https:\/\/media.giphy.com\/media\/3o6ozsTeR2bs1hjBU4\/giphy.gif\" alt=\" @Giphy\">\n    <\/video>\n<\/figure>\n<p>Commencez par installer <em>Snowpack<\/em> comme d\u00e9pendance de votre projet&nbsp;:<\/p>\n<pre class=\"sh\"><code>$ cd mon-projet\n$ npm install --save-dev snowpack@next<\/code><\/pre>\n<p>Et c\u2019est tout&nbsp;! Il est maintenant pr\u00eat \u00e0&nbsp;prendre en charge votre processus de d\u00e9veloppement.<\/p>\n<h3 id=\"outils-de-d\u00e9veloppement\">Outils de d\u00e9veloppement<\/h3>\n<p><em>Snowpack<\/em> analysera votre projet, \u00e0&nbsp;la recherche de d\u00e9clarations d\u2019<code>import<\/code>, puis copiera les ressources \u00e0&nbsp;partir du r\u00e9pertoire <code>node_modules<\/code> du projet, ou les installera directement, dans un r\u00e9pertoire <code>web_modules<\/code>.<\/p>\n<p>De l\u00e0, vous pouvez servir vos ressources sous forme de module web et les importer dans votre&nbsp;page&nbsp;:<\/p>\n<pre class=\"html\"><code>&lt;html lang=\"en\"&gt;\n  &lt;body&gt;\n    &lt;canvas id=\"canvas\"&gt;&lt;\/canvas&gt;\n    &lt;script type=\"module\"&gt;\n      import confetti from '\/web_modules\/canvas-confetti.js';\n\n      confetti.create(document.getElementById('canvas'))({\n        particleCount: 200,\n        spread: 200\n      })\n    &lt;\/script&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>Vos scripts doivent \u00eatre d\u00e9clar\u00e9s dans le HTML avec l\u2019attribut <code>type=module<\/code> pour activer le mode Module ES6. Et vos ressources sont import\u00e9es depuis le r\u00e9pertoire <code>web_modules<\/code> \u00e0&nbsp;la racine.<\/p>\n<p>Il suffit de lancer l\u2019installation de snowpack depuis le r\u00e9pertoire de votre projet&nbsp;: le dossier <code>web_modules<\/code> va se peupler avec vos d\u00e9pendances. Vous pouvez \u00e9galement les g\u00e9rer <a href=\"https:\/\/www.snowpack.dev\/#webdependencies\">\u00e0&nbsp;partir de votre fichier package.json<\/a> et avec les <a href=\"https:\/\/www.snowpack.dev\/#config-files\">entr\u00e9es de configuration de snowpack<\/a>.<\/p>\n<p>En <em>mode de d\u00e9veloppement<\/em>, cette configuration vous permet de d\u00e9clarer des fonctionnalit\u00e9s utiles, comme les directives de montage. Elles agissent comme des points de montage Unix, vous permettant de servir tous les \u00e9l\u00e9ments que vous souhaitez \u00e0&nbsp;partir du serveur de d\u00e9veloppement int\u00e9gr\u00e9&nbsp;:<\/p>\n<pre class=\"json\"><code>{\n  \"snowpack\": {\n    \"scripts\": {\n      \"mount:public\": \"mount public --to \/\",\n      \"mount:web_modules\": \"mount web_modules\"\n    }\n  }\n}<\/code><\/pre>\n<p>Ensuite, il suffit de faire tourner <code>snowpack dev<\/code> pour obtenir un serveur de d\u00e9veloppement complet, servant vos ressources avec un <em>LiveReload<\/em> embarqu\u00e9. Avec la commande <code>dev<\/code>, il n\u2019est m\u00eame plus n\u00e9cessaire de mettre \u00e0&nbsp;jour les chemins d\u2019acc\u00e8s vous-m\u00eame&nbsp;: il suffit de suivre la syntaxe habituelle, comme <code>import * as React from 'react'<\/code> dans vos fichiers JS, et Snowpack convertira le chemin d\u2019acc\u00e8s \u00e0&nbsp;la vol\u00e9e.<\/p>\n<p>Au moment du <em>build<\/em>, Snowpack copie simplement vos fichiers, ce qui vous permet de les d\u00e9ployer comme vous le souhaitez. Il ajoute \u00e9galement une option <code>--bundle<\/code>, vous permettant de passer vos fichiers produits \u00e0&nbsp;Parcel, pour optimiser vos versions de production en s\u2019appuyant sur un \u00e9cosyst\u00e8me d\u00e9j\u00e0 existant.<\/p>\n<p>Vous pouvez \u00e9galement d\u00e9finir vos propres scripts <em>snowpack<\/em>, pour personnaliser vos pipelines de construction, comme&nbsp;:<\/p>\n<pre class=\"json\"><code>{\n  \"scripts\": {\n    \/* Build JS and JSX files with Babel *\/\n    \"build:js,jsx\": \"babel --filename $FILE\",\n    \/* Pass CSS to PostCSS *\/\n    \"build:css\": \"postcss\"\n  }\n}<\/code><\/pre>\n<hr>\n<p>L\u2019ancien mod\u00e8le n\u2019est plus adapt\u00e9 \u00e0&nbsp;nos contraintes modernes. Gr\u00e2ce aux technologies actuellement disponibles, nous n\u2019avons plus besoin de conditionner et de regrouper nos applications avec leurs d\u00e9pendances. Au lieu de cela, nous pouvons nous concentrer sur le d\u00e9veloppement plut\u00f4t que sur l\u2019outillage.<\/p>\n<p>Cette approche pr\u00e9sente une bonne philosophie&nbsp;: elle s\u2019appuie sur les outils existants pour maintenir un effort de compatibilit\u00e9 crois\u00e9e (comme le travail avec Parcel, Rollup, Babel\u2026 sous le capot), elle n\u2019impose aucune contrainte et vous pouvez vous rabattre sur n\u2019importe quel autre outil de <em>build<\/em> si vous en avez besoin, et elle est rapide \u00e0&nbsp;ex\u00e9cuter.<\/p>\n<p>Snowpack est le premier concurrent de ce nouvel univers, avec de nombreuses fonctionnalit\u00e9s int\u00e9ressantes, dont <code>import-maps<\/code>, de la proxification de requ\u00eates, du <em>HMR<\/em>, etc. Nul doute que nous verrons rapidement d\u2019autres alternatives <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_3416_1('footnote_plugin_reference_3416_1_2');\" onkeypress=\"footnote_moveToReference_3416_1('footnote_plugin_reference_3416_1_2');\"><sup id=\"footnote_plugin_tooltip_3416_1_2\" class=\"footnote_plugin_tooltip_text\">2)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_3416_1_2\" class=\"footnote_tooltip\"><\/span><\/span>, et c\u2019est le bon moment pour sauter dans le train du <em>bare modules development<\/em>&nbsp;!<\/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_3416_1();\">Notes<\/span><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_collapse_button\" style=\"display: none;\" onclick=\"footnote_expand_collapse_reference_container_3416_1();\">[<a id=\"footnote_reference_container_collapse_button_3416_1\">+<\/a>]<\/span><\/p><\/div> <div id=\"footnote_references_container_3416_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_3416_1('footnote_plugin_tooltip_3416_1_1');\"><a id=\"footnote_plugin_reference_3416_1_1\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>1<\/a><\/th> <td class=\"footnote_plugin_text\">Saviez-vous que vous pouvez <a href=\"https:\/\/help.alwaysdata.com\/en\/languages\/deno\/#signup\">ex\u00e9cuter TypeScript sur les serveurs alwaysdata directement gr\u00e2ce \u00e0&nbsp;Deno<\/a>&nbsp;?<\/td><\/tr>\n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_3416_1('footnote_plugin_tooltip_3416_1_2');\"><a id=\"footnote_plugin_reference_3416_1_2\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>2<\/a><\/th> <td class=\"footnote_plugin_text\">Vue.js a&nbsp;d\u00e9j\u00e0 commenc\u00e9 \u00e0&nbsp;travailler sur son propre outil pour Vue.js&nbsp;: <a href=\"https:\/\/medium.com\/@wearethreebears\/getting-started-with-vite-a-no-bundler-dev-environment-for-vue-js-217a6eb7c9d0\">Vite<\/a>.<\/td><\/tr>\n\n <\/tbody> <\/table> <\/div><\/div><script type=\"text\/javascript\"> function footnote_expand_reference_container_3416_1() { jQuery('#footnote_references_container_3416_1').show(); jQuery('#footnote_reference_container_collapse_button_3416_1').text('\u2212'); } function footnote_collapse_reference_container_3416_1() { jQuery('#footnote_references_container_3416_1').hide(); jQuery('#footnote_reference_container_collapse_button_3416_1').text('+'); } function footnote_expand_collapse_reference_container_3416_1() { if (jQuery('#footnote_references_container_3416_1').is(':hidden')) { footnote_expand_reference_container_3416_1(); } else { footnote_collapse_reference_container_3416_1(); } } function footnote_moveToReference_3416_1(p_str_TargetID) { footnote_expand_reference_container_3416_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_3416_1(p_str_TargetID) { footnote_expand_reference_container_3416_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>","protected":false},"excerpt":{"rendered":"<p>Fatigu\u00e9 de vous occuper plus souvent d\u2019outillages que de d\u00e9velopper vos webapps&nbsp;? Passez \u00e0&nbsp;Snowpack et embarquez dans le train du Bare Modules Dev&nbsp;!<\/p>\n","protected":false},"author":12,"featured_media":3413,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[230,1],"tags":[126,266,263,267,264],"class_list":["post-3416","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized-fr","category-uncategorized","tag-devops","tag-frontend-fr","tag-frontend","tag-outils-fr","tag-tools"],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/3416","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=3416"}],"version-history":[{"count":0,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/3416\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media\/3413"}],"wp:attachment":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media?parent=3416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/categories?post=3416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/tags?post=3416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}