nodebook
Version:
Node.js • Apprendre par la pratique. Familiarisez-vous avec JavaScript, Node.js et l'écosystème de modules npm. Apprenez à concevoir et à déployer des *applications web* et des *outils en ligne de commande*.
1,299 lines (1,214 loc) • 172 kB
HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.9">
<title>Sélection de modules npm</title>
<style>
#header,
#content,
#footer {
margin: 2rem auto;
max-width: 46rem;
}
#header {
margin-top: 0;
}
.title,
#toctitle {
color: var(--dark-accent);
}
a {
/* white-space: nowrap; */
}
img, iframe, video, audio {
max-width: 100%;
}
p {
font-weight: normal;
}
/* Taken out from book.css */
dl dt {
margin-bottom: 0.3125em;
font-weight: bold;
}
dl dd {
margin-bottom: 1.25em;
}
dt,
th.tableblock,
td.content,
div.footnote {
text-rendering: optimizeLegibility;
}
.literalblock pre,
.literalblock pre[class],
.listingblock pre,
.listingblock pre[class] {
overflow: auto;
word-wrap: break-word;
}
.literalblock pre.nowrap,
.literalblock pre[class].nowrap,
.listingblock pre.nowrap,
.listingblock pre[class].nowrap {
overflow-x: auto;
white-space: pre;
word-wrap: normal;
}
.listingblock {
margin: 0 0 2em;
}
.listingblock > .content {
position: relative;
}
.listingblock > .title {
font-weight: bold;
}
.listingblock code[data-lang]::before {
display: none;
content: attr(data-lang);
position: absolute;
font-size: 0.75em;
top: 1em;
right: 1em;
line-height: 1;
text-transform: uppercase;
color: #999;
}
.listingblock:hover code[data-lang]::before {
display: block;
}
.listingblock.terminal pre .command::before {
content: attr(data-prompt);
padding-right: 0.5em;
color: #999;
}
td.hdlist1,
td.hdlist2 {
vertical-align: top;
padding-right: 0.625em;
}
td.hdlist1 {
font-weight: bold;
}
.literalblock + .colist,
.listingblock + .colist {
margin-top: -1.5em;
}
.colist td:not([class]):first-child {
padding: 0.4em 0.75em 0 0.75em;
line-height: 1;
vertical-align: top;
}
.colist td:not([class]):first-child img {
max-width: none;
}
.colist td:not([class]):last-child {
padding: 0.25em 0;
}
/* Custom classes */
.line-through {
text-decoration: line-through;
}
.RemarquePreTitre,
#toctitle {
font-style: normal;
font-weight: bold;
}
.RemarquePreTitre::after {
content: "•";
padding-left: 5px;
}
.admonitionblock {
}
.admonitionblock > table,
.exampleblock {
--commented: rgba(17, 17, 68, .65);
--border-radius-base: 8px;
background-color: #fafafa;
border: 1px solid var(--dark-shade);
border-left: none;
border-right: none;
margin: 1.5em 0;
padding: 1em;
}
.exampleblock .title {
font-weight: bold;
}
.icon .title {
font-size: 2em;
}
.admonitionblock > table td.icon {
display: none;
vertical-align: middle;
}
@media screen and (min-width: 769px) {
.admonitionblock > table td.icon {
display: table-cell;
}
}
.admonitionblock > table td.icon {
padding-right: 1em;
}
.admonitionblock > table td.icon img {
max-width: none;
}
.colist ol {
margin-left: 1.5em; /* aligns with the listing edge */
padding-left: 0;
font-weight: bold; /* makes it stand out more */
}
.colist ol p {
margin: 0 0 .5em;
}
.listingblock:not(.prismjs) pre,
.language-bash.hljs {
background: #323232;
color: wheat;
margin: 0;
padding: 1rem;
}
.language-bash.hljs .hljs-built_in,
.language-bash.hljs .hljs-builtin-name {
color: white;
}
.language-bash.hljs .hljs-string {
color: lightgreen;
}
.language-bash.hljs .hljs-variable {
color: lightskyblue;
}
.keyseq {
font-weight: normal;
white-space: nowrap;
}
.language-bash.hljs .keyseq {
color: white;
}
.language-bash.hljs kbd {
background: transparent;
box-shadow: none;
color: white;
font-size: 0.8em;
font-weight: bold;
padding: 0.1em 0.4em;
}
.listingblock pre.highlightjs,
.listingblock pre.prismjs {
background-color: transparent;
margin: 0;
padding: 0;
}
.listingblock pre.highlightjs > code,
.listingblock pre.prismjs {
border-left: 4px solid var(--dark-accent);
padding-left: 1em;
font-size: .8em;
}
.listingblock pre.highlightjs > code.language-bash {
border-left-color: limegreen;
}
.token.comment .conum {
font-weight: normal;
}
.hdlist .hdlist1 {
text-align: right;
white-space: nowrap;
}
td > p:first-child {
margin-top: 0;
}
.hljs-comment {
font-style: normal !important;
}
#toc.toc2 a {
text-decoration: none;
white-space: normal;
}
#toc.toc2 a:hover,
#toc.toc2 a:focus {
text-decoration: underline;
}
#toc.toc2 ul {
list-style: none;
}
#toc.toc2 > ul {
padding-left: 0;
}
#toc.toc2 ul ul {
padding-left: 1em;
}
@media screen and (min-width: 769px) {
body {
padding-left: 25vw !important;
}
#header,
#content,
#footer {
margin-left: 0;
}
#toc.toc2 {
height: 100%;
left: 0;
max-width: 20vw;
overflow: auto;
padding: 1rem;
position: fixed;
top: 0;
z-index: 1000;
}
#toc.toc2 > ul {
font-size: 0.85em;
}
#toc li.active > a[href^="#"],
[id]:target {
background: #ffc;
}
}
.admonitionblock.context-callout > table {
border-width: 5px;
border-color: var(--brand-color);
}
</style>
<style type="text/css" class="prism-theme">/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
</style>
<link rel="stylesheet" href="https://oncletom.io/styles/blog.css?v=v3.3.2">
<!-- WebMentions -->
<link rel="pingback" href="https://webmention.io/oncletom.io/xmlrpc">
<link rel="webmention" href="https://webmention.io/oncletom.io/webmention">
<!-- Open Graph -->
<meta property="og:type" content="book">
<meta property="og:image" content="https://oncletom.io/images/publications/nodejs-cover.png">
<meta property="og:book:author" content="Thomas Parisot">
<meta property="og:book:isbn" content="978-2212139938">
<meta property="og:book:release_date" content="2018-12-06">
<meta property="og:book:tag" content="Node.js">
<meta property="og:book:tag" content="JavaScript">
<meta property="og:book:tag" content="npm">
<meta property="og:book:tag" content="Développement front-end">
<meta property="og:book:tag" content="Développement back-end">
<meta property="og:locale" content="fr_FR">
<meta property="og:site_name" content="Node.js • Apprendre par la pratique">
<!-- Twitter OpenGraph -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@oncletom">
<meta name="twitter:creator" content="@oncletom">
<style type="text/css" class="extension-interactive-runner">[data-interactive-runtime="loaded"] .interactive--javascript code[data-lang]:before {
background-color: #fcfcfc;
border: 1px solid #0c2;
border-radius: 1px;
color: #0c2;
cursor: pointer;
display: inline-block;
font-weight: bold;
padding: .5em 1em;
top: -2em;
}
[lang="en"] [data-interactive-runtime="loaded"] .interactive--javascript code[data-lang]:before {
content: "▶ run code";
}
[lang="fr"] [data-interactive-runtime="loaded"] .interactive--javascript code[data-lang]:before {
content: "▶ voir le résultat";
}
.interactive--javascript code[data-label]:before {
content: attr(data-label);
}
.interactive iframe {
position: absolute;
visibility: hidden;
}
.interactive.status--loaded iframe {
position: inherit;
visibility: visible;
}
.interactive.status--loading {
opacity: .5;
}
</style>
<script class="extension-interactive-runner">
(function(d){
document.addEventListener('DOMContentLoaded', function(){
const script = d.createElement('script');
script.src = 'https://embed.runkit.com/';
script.async = true;
script.onload = function(){
function makeListingInteractive (element){
if (element.classList.contains('interactive--installed') || element.classList.contains('status--loading')) {
return;
}
const code = element.querySelector('code');
const nodeVersion = /interactive--runtime--node-([^\s]+)/.exec(element.className)[1];
const isEndpoint = element.classList.contains('interactive--endpoint');
const mode = isEndpoint ? 'endpoint' : null;
let preamble = '';
const source = code
.textContent
.replace(/\/\/\s*\(\d+\)$/gm, '')
.replace(/^["']?use strict["'][; ]*\n/, '');
if (isEndpoint) {
preamble = `process.nextTick(() => {
if (typeof module.exports === 'function') {
exports.endpoint = module.exports;
}
else if (typeof server !== 'undefined') {
exports.endpoint = server.listeners("request").pop();
}
});`
}
element.classList.add('status--loading');
// eslint-disable-next-line no-undef
RunKit.createNotebook({
nodeVersion,
element,
source,
mode,
preamble,
onLoad: function(ntbk) {
element.classList.add('interactive--installed');
element.classList.remove('status--loading');
element.classList.add('status--loaded');
code.parentNode.setAttribute('hidden', true);
ntbk.evaluate();
}
});
}
function installEvents () {
function getParent(el, condition) {
let parent = el;
while(parent = parent.parentNode) {
if (condition(parent)) {
return parent;
}
}
}
function hasClass(className) {
return function check(el) {
return el.classList.contains(className);
}
}
document.querySelector('body').addEventListener('click', function(el) {
if (el.target.classList.contains('language-javascript') || el.target.classList.contains('language-js')) {
const parentNode = getParent(
el.target,
hasClass('interactive--javascript')
);
makeListingInteractive(parentNode);
}
});
}
installEvents();
document.body.dataset.interactiveRuntime = 'loaded';
};
document.body.appendChild(script);
});
})(document);</script>
<style type="text/css">
.listingblock [data-bash-subs]::before {
content: attr(data-bash-subs) " ";
opacity: .5; }
.listingblock [data-bash-conum]::before {
content: "(" attr(data-bash-conum) ")";
font-weight: bold;
opacity: .7;
}</style>
<script>
(function(d){
d.addEventListener('DOMContentLoaded', function(){
const {origin} = window.location;
Array.from(document.querySelectorAll('a[href]'))
.filter(link => link.href.indexOf(origin) !== 0)
.forEach(link => {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener');
});
});
})(document);</script>
<script>
(function(d){
d.addEventListener('DOMContentLoaded', function(){
const script = d.createElement('script');
script.src = 'https://unpkg.com/menuspy@1.3.0/dist/menuspy.js';
script.async = true;
script.onload = () => new MenuSpy(document.querySelector('#toc'), {enableLocationHash: false});
d.body.appendChild(script);
});
})(document);</script>
<style type="text/css">
#toc li.active > a[href^="#"] {
font-weight: bold;
}
#toc li.active > a[href^="#"]::before {
content: "▶ ";
display: inline-block;
position: absolute;
margin-left: -1.2em;
font-size: .8em;
margin-top: 3px;
}
</style>
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Sélection de modules npm</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table des matières</div>
<ul class="sectlevel1">
<li><a href="#boîte_à_outils_du_quotidien">1. Boîte à outils du quotidien</a>
<ul class="sectlevel2">
<li><a href="#lodash">1.1. lodash</a></li>
<li><a href="#he">1.2. he</a></li>
<li><a href="#chance">1.3. chance</a></li>
<li><a href="#date_fns">1.4. date-fns</a></li>
<li><a href="#tcomb">1.5. tcomb</a></li>
<li><a href="#eventemitter3">1.6. eventemitter3</a></li>
</ul>
</li>
<li><a href="#dev">2. Pendant le développement</a>
<ul class="sectlevel2">
<li><a href="#debug">2.1. debug</a></li>
<li><a href="#nodemon">2.2. nodemon</a></li>
<li><a href="#npm_run_all">2.3. npm-run-all</a></li>
<li><a href="#husky">2.4. husky</a></li>
<li><a href="#onchange">2.5. onchange</a></li>
<li><a href="#tiny_lr">2.6. tiny-lr</a></li>
<li><a href="#livereactload">2.7. livereactload</a></li>
</ul>
</li>
<li><a href="#protéger_nos_applications">3. Protéger nos applications</a>
<ul class="sectlevel2">
<li><a href="#sanitize_filename">3.1. sanitize-filename</a></li>
<li><a href="#helmet">3.2. helmet</a></li>
<li><a href="#dompurify">3.3. dompurify</a></li>
<li><a href="#filenamify">3.4. filenamify</a></li>
<li><a href="#retire_js">3.5. retire.js</a></li>
<li><a href="#snyk">3.6. snyk</a></li>
</ul>
</li>
<li><a href="#vérifier_la_syntaxe_de_notrecode">4. Vérifier la syntaxe de notre code</a>
<ul class="sectlevel2">
<li><a href="#htmlhint">4.1. htmlhint</a></li>
<li><a href="#eslint">4.2. eslint</a></li>
<li><a href="#csslint">4.3. csslint</a></li>
<li><a href="#doiuse">4.4. doiuse</a></li>
</ul>
</li>
<li><a href="#optimize">5. Optimiser notre code</a>
<ul class="sectlevel2">
<li><a href="#uglify_es">5.1. uglify-es</a></li>
<li><a href="#postcss">5.2. postcss</a></li>
<li><a href="#autoprefixer">5.3. autoprefixer</a></li>
<li><a href="#uncss">5.4. uncss</a></li>
<li><a href="#csswring">5.5. csswring</a></li>
<li><a href="#google_closure_compiler_js">5.6. google-closure-compiler-js</a></li>
<li><a href="#csso">5.7. csso</a></li>
<li><a href="#svgo">5.8. svgo</a></li>
<li><a href="#wawoff2">5.9. wawoff2</a></li>
</ul>
</li>
<li><a href="#transpiling">6. Passer d’un langage à un autre</a>
<ul class="sectlevel2">
<li><a href="#less">6.1. less</a></li>
<li><a href="#sass">6.2. sass</a></li>
<li><a href="#browserify">6.3. browserify</a></li>
<li><a href="#babel">6.4. babel</a></li>
<li><a href="#typescript">6.5. typescript</a></li>
</ul>
</li>
<li><a href="#fs">7. Gérer des fichiers</a>
<ul class="sectlevel2">
<li><a href="#mkdirp">7.1. mkdirp</a></li>
<li><a href="#rimraf">7.2. rimraf</a></li>
<li><a href="#glob">7.3. glob</a></li>
<li><a href="#fs_extra">7.4. fs-extra</a></li>
<li><a href="#graceful_fs">7.5. graceful-fs</a></li>
<li><a href="#chokidar">7.6. chokidar</a></li>
</ul>
</li>
<li><a href="#databases">8. Stocker dans des bases de données</a>
<ul class="sectlevel2">
<li><a href="#db_migrate">8.1. db-migrate</a></li>
<li><a href="#knex">8.2. knex</a></li>
<li><a href="#bookshelf">8.3. bookshelf</a></li>
<li><a href="#sequelize">8.4. sequelize</a></li>
<li><a href="#mongoose">8.5. mongoose</a></li>
<li><a href="#levelup">8.6. levelup</a></li>
<li><a href="#redis">8.7. redis</a></li>
<li><a href="#elasticsearch">8.8. elasticsearch</a></li>
</ul>
</li>
<li><a href="#cli">9. Ligne de commande</a>
<ul class="sectlevel2">
<li><a href="#yargs_parser">9.1. yargs-parser</a></li>
<li><a href="#args">9.2. args</a></li>
<li><a href="#caporal">9.3. caporal</a></li>
<li><a href="#promptly">9.4. promptly</a></li>
<li><a href="#supports_color">9.5. supports-color</a></li>
</ul>
</li>
<li><a href="#webapp">10. Applications web</a>
<ul class="sectlevel2">
<li><a href="#fastify">10.1. fastify</a></li>
<li><a href="#passport">10.2. passport</a></li>
<li><a href="#restify">10.3. restify</a></li>
<li><a href="#faye">10.4. faye</a></li>
<li><a href="#swagger_client">10.5. swagger-client</a></li>
</ul>
</li>
<li><a href="#templating">11. Modules front-end et templating</a>
<ul class="sectlevel2">
<li><a href="#nunjucks">11.1. nunjucks</a></li>
<li><a href="#handlebars">11.2. handlebars</a></li>
<li><a href="#pug">11.3. pug</a></li>
<li><a href="#ejs">11.4. ejs</a></li>
<li><a href="#react">11.5. react</a></li>
<li><a href="#storybook">11.6. storybook</a></li>
</ul>
</li>
<li><a href="#testing">12. Tester notre code</a>
<ul class="sectlevel2">
<li><a href="#tape">12.1. tape</a></li>
<li><a href="#chai">12.2. chai</a></li>
<li><a href="#sinon">12.3. sinon</a></li>
<li><a href="#nyc">12.4. nyc</a></li>
<li><a href="#karma">12.5. karma</a></li>
<li><a href="#supertest">12.6. supertest</a></li>
</ul>
</li>
<li><a href="#internet-of-things">13. Objets connectés</a>
<ul class="sectlevel2">
<li><a href="#nitrogen">13.1. nitrogen</a></li>
<li><a href="#serialport">13.2. serialport</a></li>
<li><a href="#firmata">13.3. firmata</a></li>
<li><a href="#johnny_five">13.4. johnny-five</a></li>
<li><a href="#node_red">13.5. node-red</a></li>
</ul>
</li>
<li><a href="#accessibilité">14. Accessibilité</a>
<ul class="sectlevel2">
<li><a href="#a11y">14.1. a11y</a></li>
<li><a href="#a11y_css">14.2. a11y.css</a></li>
<li><a href="#lighthouse">14.3. lighthouse</a></li>
<li><a href="#storybook_addon_a11y">14.4. storybook-addon-a11y</a></li>
</ul>
</li>
<li><a href="#travailler_avec_des_images_des_sons_et_des_vidéos">15. Travailler avec des images, des sons et des vidéos</a>
<ul class="sectlevel2">
<li><a href="#sharp">15.1. sharp</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="admonitionblock tip context-callout">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="paragraph">
<p>Vous êtes en train de lire
l’Annexe A
du <a href="https://oncletom.io/node.js/">livre “Node.js”</a>, écrit par
<a href="https://oncletom.io">Thomas Parisot</a> et publié aux
<a href="https://editions-eyrolles.com/Livre/9782212139938">Éditions Eyrolles</a>.</p>
</div>
<div class="paragraph">
<p>L’ouvrage vous plaît ? Achetez-le sur <a href="https://amzn.to/2E58PEw">Amazon.fr</a> ou en
<a href="https://www.placedeslibraires.fr/livre/9782212139938">librairie</a>.
<a href="https://opencollective.com/nodebook">Donnez quelques euros</a> pour contribuer
à sa gratuité en ligne.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Cette annexe est une sélection de modules <code>npm</code> (<span class="URL"><a href="https://npmjs.com" class="bare">npmjs.com</a></span>)
à laquelle vous référer pour démarrer rapidement, mais aussi pour découvrir
des usages et des domaines d’application insoupçonnés.</p>
</div>
<div class="paragraph">
<p>J’ai bâti cette liste à partir de mon expérience personnelle et sur la confiance
que je porte aux personnes à l’origine de ces modules.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">💬</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Remarque</span> Versions de Node et npm</div>
<div class="paragraph">
<p>Le contenu de ce chapitre utilise les versions <strong>Node v10</strong>
et <strong>npm v6</strong>.
Ce sont les versions stables recommandées en 2019.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Pratique</span> Jouer avec les exemples dans un terminal</div>
<div class="paragraph">
<p>Les exemples titrés d’un nom de fichier peuvent être installés sur votre ordinateur.
Exécutez-les dans un terminal et amusez-vous à les modifier en parallèle de
votre lecture pour voir ce qui change.</p>
</div>
<div class="listingblock">
<div class="title">Installation des exemples via le module npm <code>nodebook</code></div>
<div class="content">
<pre><span data-bash-subs="$"></span>npm install --global nodebook
<span data-bash-subs="$"></span>nodebook install appendix-a
<span data-bash-subs="$"></span>cd $(nodebook dir appendix-a)</pre>
</div>
</div>
<div class="paragraph">
<p>La commande suivante devrait afficher un résultat qui confirme que vous êtes
au bon endroit :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node hello.js</pre>
</div>
</div>
<div class="paragraph">
<p>Suivez à nouveau les instructions d’installation pour rétablir les exemples
dans leur état initial.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="boîte_à_outils_du_quotidien">1. Boîte à outils du quotidien</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Ces modules répondent à des besoins quotidiens, pour travailler plus rapidement
sur des structures ECMAScript.</p>
</div>
<div class="sect2">
<h3 id="lodash">1.1. lodash</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p><em>lodash</em> (<span class="URL"><a href="https://npmjs.com/lodash" class="bare">npmjs.com/lodash</a></span>) est une collection de plusieurs
dizaines de fonctions pour travailler plus facilement avec des chaînes de caractères,
des tableaux, des fonctions et des objets.</p>
</div>
<div class="paragraph">
<p>Vous pourrez ainsi filtrer, sélectionner, fusionner, vérifier et composer
de nouvelles variables, aussi bien pour Node que dans les navigateurs.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">lodash.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span> intersection<span class="token punctuation">,</span> first <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'lodash'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">DC</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'Batman'</span><span class="token punctuation">,</span> <span class="token string">'Brainiac'</span><span class="token punctuation">,</span> <span class="token string">'Thor'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> Marvel <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'Spiderman'</span><span class="token punctuation">,</span> <span class="token string">'Thor'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token function">first</span><span class="token punctuation">(</span><span class="token function">intersection</span><span class="token punctuation">(</span><span class="token constant">DC</span><span class="token punctuation">,</span> Marvel<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>Affiche <code>Thor</code>.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="he">1.2. he</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p><em>he</em> (<span class="URL"><a href="https://npmjs.com/he" class="bare">npmjs.com/he</a></span>) est un utilitaire pour encoder et décoder
des entités HTML dans des chaînes de caractères.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">he.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span>encode<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'he'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> html <span class="token operator">=</span> <span class="token string">'<h1>Blog Post</h1>'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(1)</b>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">encode</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(2)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>Affiche <code><h1>Blog Post</h1></code>.</p>
</li>
<li>
<p>Affiche <code>&#x3C;h1&#x3E;Blog Post&#x3C;/h1&#x3E;</code>.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="chance">1.3. chance</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p><em>chance</em> (<span class="URL"><a href="https://npmjs.com/chance" class="bare">npmjs.com/chance</a></span>) crée des données de manière aléatoire.
Le module retourne aussi des prénoms fictifs, mais aussi des numéros de téléphone,
des nombres, des paragraphes, des dates d’anniversaire, des identifiants Android
ou Apple, etc.</p>
</div>
<div class="paragraph">
<p>Il s’utilise surtout pour générer des données factices à des fins de tests,
en attendant les vraies données.</p>
</div>
</div>
<div class="sect2">
<h3 id="date_fns">1.4. date-fns</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>date-fns</em> (<span class="URL"><a href="https://npmjs.com/date-fns" class="bare">npmjs.com/date-fns</a></span>) est une collection de fonctions
pour travailler avec des dates, plus facilement qu’avec l’objet natif <code>Date</code>.</p>
</div>
<div class="paragraph">
<p>Vous pouvez formater, ajouter ou retirer des jours, vérifier si deux périodes
de temps se chevauchent ou si deux dates font partie d’une même semaine calendaire.</p>
</div>
</div>
<div class="sect2">
<h3 id="tcomb">1.5. tcomb</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>tcomb</em> (<span class="URL"><a href="https://npmjs.com/tcomb" class="bare">npmjs.com/tcomb</a></span>) renforce la création de structures
typées et non mutables.
Cela réduit les effets de bord de nos applications lorsque les
données n’ont pas la structure attendue.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">tcomb.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> t <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'tcomb'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">GPS</span> <span class="token operator">=</span> t<span class="token punctuation">.</span><span class="token function">struct</span><span class="token punctuation">(</span><span class="token punctuation">{</span> // <b class="conum">(1)</b>
lat<span class="token punctuation">:</span> t<span class="token punctuation">.</span>Number<span class="token punctuation">,</span>
lon<span class="token punctuation">:</span> t<span class="token punctuation">.</span>Number<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>strict<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> Bordeaux <span class="token operator">=</span> <span class="token constant">GPS</span><span class="token punctuation">(</span><span class="token punctuation">{</span> lat<span class="token punctuation">:</span> <span class="token number">44.8638</span><span class="token punctuation">,</span> lon<span class="token punctuation">:</span> <span class="token operator">-</span><span class="token number">0.6561</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> Crest <span class="token operator">=</span> <span class="token constant">GPS</span><span class="token punctuation">(</span><span class="token punctuation">{</span> lat<span class="token punctuation">:</span> <span class="token number">44.7311</span><span class="token punctuation">,</span> long<span class="token punctuation">:</span> <span class="token number">4.9861</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(2)</b>
<span class="token keyword">const</span> Toulouse <span class="token operator">=</span> <span class="token constant">GPS</span><span class="token punctuation">(</span><span class="token punctuation">{</span> lat<span class="token punctuation">:</span> <span class="token number">43.6008</span><span class="token punctuation">,</span> lon<span class="token punctuation">:</span> <span class="token string">'r0s3'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(3)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>Définition d’une structure stricte qui a pour propriétés <code>lat</code> et <code>lon</code>, pour <em>latitude</em> et <em>longitude</em>.</p>
</li>
<li>
<p>Cet appel va lancer une exception car la propriété <code>long</code> est inconnue.</p>
</li>
<li>
<p>Cet appel va lancer une exception car la propriété <code>lon</code> doit être un nombre.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="eventemitter3">1.6. eventemitter3</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>eventemitter3</em> (<span class="URL"><a href="https://npmjs.com/eventemitter3" class="bare">npmjs.com/eventemitter3</a></span>) sert à gérer
des événements de manière uniforme dans un script Node et dans les navigateurs.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">eventemitter3.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> EventEmitter <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'eventemitter3'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> emitter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventEmitter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
emitter<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token parameter">data</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'on: %s'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
emitter<span class="token punctuation">.</span><span class="token function">once</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token parameter">data</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'once: %s'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>emitter<span class="token punctuation">.</span><span class="token function">listeners</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(1)</b>
emitter<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token string">'ping'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(2)</b>
emitter<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'pong'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(3)</b>
emitter<span class="token punctuation">.</span><span class="token function">removeListener</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
emitter<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'ping'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'pong'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(4)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>Affiche <code>[ [Function], [Function] ]</code>.</p>
</li>
<li>
<p>Affiche <code>on: ping,ping</code> puis <code>once: ping,ping</code>.</p>
</li>
<li>
<p>Affiche <code>on: ping,ping</code>.</p>
</li>
<li>
<p>N’affiche rien, l’événement étant désormais déconnecté.</p>
</li>
</ol>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dev">2. Pendant le développement</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="debug">2.1. debug</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>debug</em> (<span class="URL"><a href="https://npmjs.com/debug" class="bare">npmjs.com/debug</a></span>) rend optionnel l’affichage de
messages de débogage.
Les messages s’affichent en présence d’une variable d’environnement.
Nous pouvons ainsi lancer un processus et retracer un cheminement complexe de
données.</p>
</div>
<div class="paragraph">
<p>Par défaut, les messages ne s’affichent pas :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node examples/debug.js</pre>
</div>
</div>
<div class="paragraph">
<p>Les messages du débogueur <code>app</code> s’affichent désormais :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span><mark>DEBUG=app</mark> node examples/debug.js
app fromages [ 'livarot', 'chaource' ] +0ms</pre>
</div>
</div>
<div class="paragraph">
<p>Nous pouvons en afficher plusieurs en même temps, en usant du caractère <code>*</code>
ou en séparant les noms de débogueurs avec des virgules :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>DEBUG=app<mark>*</mark> node examples/debug.js
app fromages [ 'livarot', 'chaource' ] +0ms
app:timer now 1531304027271 +0ms</pre>
</div>
</div>
<div class="listingblock">
<div class="title">debug.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> debug <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'debug'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> log <span class="token operator">=</span> <span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">'app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(1)</b>
<span class="token keyword">const</span> logInterval <span class="token operator">=</span> <span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">'app:timer'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(2)</b>
<span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'fromages %o'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'livarot'</span><span class="token punctuation">,</span> <span class="token string">'chaource'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(3)</b>
<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token function">logInterval</span><span class="token punctuation">(</span><span class="token string">'now %d'</span><span class="token punctuation">,</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(4)</b>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>Création du débogueur <code>app</code>.</p>
</li>
<li>
<p>Création du débogueur <code>app:timer</code>.</p>
</li>
<li>
<p>La fonction de débogage s’utilise de la même manière que <code>console.log</code>.</p>
</li>
<li>
<p>Cette fonction fait appel au débogueur <code>app:timer</code>.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="nodemon">2.2. nodemon</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p><em>nodemon</em> (<span class="URL"><a href="https://npmjs.com/nodemon" class="bare">npmjs.com/nodemon</a></span>) relance le processus actif
dès qu’un fichier ECMAScript ou JSON est modifié.
C’est un module exécutable particulièrement utile lorsque nous voulons prendre
en compte les changements dans une application qui tourne en continu.
C’est le cas des applications web, entre autres.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">💬</div>
</td>
<td class="content">
<div class="paragraph">
<p>Pour en savoir plus, rendez-vous à la section
“<a href="../chapter-07/index.html#dev">Pendant le développement : relancer le serveur automatiquement</a>”
du <a href="../chapter-07/index.html">chapitre 7</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="npm_run_all">2.3. npm-run-all</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>npm-run-all</em> (<span class="URL"><a href="https://npmjs.com/npm-run-all" class="bare">npmjs.com/npm-run-all</a></span>) est mon outil favori
pour composer avec les scripts <code>npm</code>.
Il a l’avantage d’être adaptable, de régler finement ce qui
doit être exécuté en parallèle ou séquentiellement.
Le module transfère les arguments aux sous-scripts.</p>
</div>
<div class="listingblock">
<div class="title">package.json</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-json"><code class="language-json" data-lang="json"><span class="token punctuation">{</span>
<span class="token property">"..."</span><span class="token operator">:</span> <span class="token string">"..."</span><span class="token punctuation">,</span>
<span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"build"</span><span class="token operator">:</span> <span class="token string">"npm-run-all -p 'build:*' -s start"</span><span class="token punctuation">,</span>
<span class="token property">"build:css"</span><span class="token operator">:</span> <span class="token string">"sass ..."</span><span class="token punctuation">,</span>
<span class="token property">"build:js"</span><span class="token operator">:</span> <span class="token string">"browserify ..."</span><span class="token punctuation">,</span>
<span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"node server.js"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="husky">2.4. husky</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>husky</em> (<span class="URL"><a href="https://npmjs.com/husky" class="bare">npmjs.com/husky</a></span>) intègre Git aux
<a href="../chapter-05/index.html#scripts">scripts <code>npm</code></a>.
Autrement dit, vous pouvez déclencher des scripts lors d’événements Git,
lors d’un <code>push</code>, avant un <code>commit</code> ou après avoir rapatrié des changements.</p>
</div>
<div class="listingblock">
<div class="title">package.json</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-json"><code class="language-json" data-lang="json"><span class="token punctuation">{</span>
<span class="token property">"..."</span><span class="token operator">:</span> <span class="token string">"..."</span><span class="token punctuation">,</span>
<span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"precommit"</span><span class="token operator">:</span> <span class="token string">"lint-staged"</span><span class="token punctuation">,</span>
<span class="token property">"post-merge"</span><span class="token operator">:</span> <span class="token string">"npm install"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>La liste complète des <em>hooks</em> Git se trouve dans la documentation
officielle : <span class="URL"><a href="https://git-scm.com/docs/githooks" class="bare">git-scm.com/docs/githooks</a></span>.</p>
</div>
</div>
<div class="sect2">
<h3 id="onchange">2.5. onchange</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>onchange</em> (<span class="URL"><a href="https://npmjs.com/onchange" class="bare">npmjs.com/onchange</a></span>) observe une liste de fichiers
en continu et déclenche une commande dès que l’un d’entre eux est modifié.
C’est particulièrement utile pour reconstruire automatiquement des fichiers
de configuration ou des fichiers <em>front-end</em> pendant le développement.</p>
</div>
<div class="listingblock">
<div class="title">package.json</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-json"><code class="language-json" data-lang="json"><span class="token punctuation">{</span>
<span class="token property">"..."</span><span class="token operator">:</span> <span class="token string">"..."</span><span class="token punctuation">,</span>
<span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"build:css"</span><span class="token operator">:</span> <span class="token string">"sass ..."</span><span class="token punctuation">,</span>
<span class="token property">"dev"</span><span class="token operator">:</span> <span class="token string">"npm-run-script -p 'watch:*' start"</span><span class="token punctuation">,</span>
<span class="token property">"watch:css"</span><span class="token operator">:</span> <span class="token string">"onchange '**/*.scss' -- npm run build:css"</span><span class="token punctuation">,</span>
<span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"node server.js"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="tiny_lr">2.6. tiny-lr</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>tiny-lr</em> (<span class="URL"><a href="https://npmjs.com/tiny-lr" class="bare">npmjs.com/tiny-lr</a></span>) est une implémentation minimale
du protocole <em>livereload</em> (<span class="URL"><a href="http://livereload.com" class="bare">livereload.com</a></span>).
Il s’intègre à un serveur HTTP ou à une application <em>Express</em> pour relayer
la liste des fichiers modifiés côté client.</p>
</div>
<div class="paragraph">
<p>Le script ou l’extension navigateur client remplace les anciens fichiers
par les nouveaux pour refléter les changements sans recharger la page.</p>
</div>
</div>
<div class="sect2">
<h3 id="livereactload">2.7. livereactload</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p><em>livereactload</em> (<span class="URL"><a href="https://npmjs.com/livereactload" class="bare">npmjs.com/livereactload</a></span>) recherche les composants
<a href="#react"><em>React</em></a> à chaud, c’est-à-dire sans rafraîchir la page ni perdre l’état des données.
C’est un module indispensable pour développer des applications <em>front-end</em