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,584 lines (1,500 loc) • 391 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>Jouer avec Node.js</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>Jouer avec Node.js</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table des matières</div>
<ul class="sectlevel1">
<li><a href="#interagir_avec_linterpréteur_node">1. Interagir avec l’interpréteur Node</a>
<ul class="sectlevel2">
<li><a href="#node-version">1.1. Afficher la version</a></li>
<li><a href="#script">1.2. Avec un script</a></li>
<li><a href="#repl">1.3. Avec l’invite de commandes interactive (REPL)</a></li>
</ul>
</li>
<li><a href="#modules-builtin">2. Les modules de base</a>
<ul class="sectlevel2">
<li><a href="#console">2.1. console : déboguer rapidement des variables</a></li>
<li><a href="#path">2.2. path : manipuler des chemins de fichiers</a></li>
<li><a href="#url">2.3. url : manipuler des URL</a></li>
<li><a href="#fs">2.4. fs : manipuler le système de fichiers</a></li>
<li><a href="#events">2.5. events : programmer des événements</a></li>
<li><a href="#util">2.6. util : transformer des fonctions de rappel en promesses</a></li>
<li><a href="#http">2.7. http : créer et interroger des ressources via le protocole HTTP</a></li>
<li><a href="#os">2.8. os : en savoir plus sur les capacités de l’ordinateur</a></li>
<li><a href="#child_process">2.9. child_process : appeler un exécutable système</a></li>
<li><a href="#process">2.10. process : en savoir plus sur le processus en cours</a></li>
<li><a href="#stream">2.11. stream : manipuler des flux de données</a></li>
<li><a href="#dautres_modules_pour_aller_plus_loin">2.12. D’autres modules pour aller plus loin</a></li>
</ul>
</li>
<li><a href="#modules">3. Créer ses propres modules Node</a>
<ul class="sectlevel2">
<li><a href="#modules.require">3.1. Importer et exporter des valeurs</a></li>
<li><a href="#require">3.2. Aller plus loin avec <code>require()</code></a></li>
<li><a href="#esm">3.3. Le futur : les modules ECMAScript</a></li>
</ul>
</li>
<li><a href="#errors">4. S’en sortir quand ça ne se passe pas comme prévu</a>
<ul class="sectlevel2">
<li><a href="#une_erreur_est_nichée_dans_notrecode">4.1. Une erreur est nichée dans notre code</a></li>
<li><a href="#une_erreur_est_retournée_dans_une_fonction_de_rappel">4.2. Une erreur est retournée dans une fonction de rappel</a></li>
<li><a href="#une_erreur_est_retournée_dans_une_promesse">4.3. Une erreur est retournée dans une promesse</a></li>
<li><a href="#une_erreur_est_retournée_dans_un_événement">4.4. Une erreur est retournée dans un événement</a></li>
<li><a href="#errors.system">4.5. Une erreur est renvoyée par le système d’exploitation</a></li>
<li><a href="#le_programme_ne_se_termine_pas">4.6. Le programme ne se termine pas</a></li>
<li><a href="#deprecation">4.7. Une alerte de dépréciation s’affiche</a></li>
</ul>
</li>
<li><a href="#les_différences_decmascript_entre_node_et_les_navigateursweb">5. Les différences d’ECMAScript entre Node et les navigateurs web</a>
<ul class="sectlevel2">
<li><a href="#labsence_du_dom_et_des_variables_window_et_document">5.1. L’absence du DOM et des variables <code>window</code> et <code>document</code></a></li>
<li><a href="#il_ny_a_pas_dinterface_graphique">5.2. Il n’y a pas d’interface graphique</a></li>
<li><a href="#le_mécanisme_de_modules">5.3. Le mécanisme de modules</a></li>
<li><a href="#linterfaçage_avec_le_système_dexploitation">5.4. L’interfaçage avec le système d’exploitation</a></li>
<li><a href="#node_est_un_processus_système">5.5. Node est un processus système</a></li>
</ul>
</li>
<li><a href="#options">6. Options utiles pour démarrer Node</a>
<ul class="sectlevel2">
<li><a href="#print-eval">6.1. Afficher le résultat d’une expression, sans script</a></li>
<li><a href="#options-require">6.2. Précharger un module</a></li>
<li><a href="#inspect">6.3. Inspecter notre code avec Google Chrome</a></li>
<li><a href="#options-v8">6.4. Ajuster les options de compatibilité et de traçabilité de V8</a></li>
</ul>
</li>
<li><a href="#conclusion">7. Conclusion</a></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
le Chapitre 4
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>Nous allons faire un tour d’horizon des capacités de Node et de son système
de modules pour nous interfacer avec les systèmes d’exploitation Linux, macOS
et Windows.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="ulist">
<div class="title">Sommaire</div>
<ul>
<li>
<p>Interagir avec l’interpréteur Node</p>
</li>
<li>
<p>Les modules de base</p>
</li>
<li>
<p>Créer ses propres modules</p>
</li>
<li>
<p>S’en sortir quand ça ne se passe pas comme prévu</p>
</li>
<li>
<p>Les différences de JavaScript entre Node et les navigateurs web</p>
</li>
<li>
<p>Options utiles pour démarrer Node</p>
</li>
</ul>
</div>
</div>
</div>
<div class="quoteblock abstract">
<blockquote>
<div class="paragraph">
<p>Après avoir exécuté notre premier script Node, nous allons découvrir
l’étendue des modules Node et ce qu’ils nous offrent en termes de capacité
d’interaction avec le système d’exploitation – disque, réseau, calculs, etc.</p>
</div>
<div class="paragraph">
<p>Nous apprendrons ensuite à créer et organiser nos propres modules – nous
découvrirons comment les partager et les distribuer dans le chapitre 5.</p>
</div>
<div class="paragraph">
<p>Enfin, nous passerons en revue des erreurs typiques pour apprendre à les lire
et à mieux réagir avant de terminer sur des manières alternatives d’exécuter
des scripts Node, par exemple pour débogueur ou charger d’autres modules.</p>
</div>
</blockquote>
</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>
</div>
<div class="sect1">
<h2 id="interagir_avec_linterpréteur_node">1. Interagir avec l’interpréteur Node</h2>
<div class="sectionbody">
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p>L’interpréteur Node est le programme qui nous fournit des résultats
en échange d’instructions ECMAScript.
Le terminal est un autre programme permettant de faire dialoguer
un ordinateur avec les programmes installés.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">💬</div>
</td>
<td class="content">
<div class="paragraph">
<p>Le <a href="../chapter-02/index.html">chapitre 2</a> détaille comment installer
Node et un terminal.
Il contient également des conseils pour utiliser Node depuis un
navigateur web.
Cela peut rendre l’accès au terminal plus facile.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Ce chapitre se base sur le principe que vous avez un terminal installé,
sur lequel vous allez saisir des instructions ECMAScript.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="./images/terminal.png" alt="terminal" width="85%">
</div>
<div class="title">Figure 1. Exemple de terminal sous macOS</div>
</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 chapter-04
<span data-bash-subs="$"></span>cd $(nodebook dir chapter-04)</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 class="sect2">
<h3 id="node-version">1.1. Afficher la version</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p>Commençons par afficher la version de l’interpréteur Node.
Nous nous assurons ainsi que nous pouvons interagir avec
lui avec succès et qu’il est celui que nous attendons, dans la bonne version.
La version de Node conditionne la liste des fonctionnalités du langage
ECMAScript à disposition.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Compatibilité</span> Syntaxe ECMAScript</div>
<div class="paragraph">
<p>Le site web <span class="URL"><a href="https://node.green" class="bare">node.green</a></span> liste le niveau de compatibilité
des fonctionnalités ECMAScript.</p>
</div>
<div class="paragraph">
<p>Cette page vous aidera à comprendre quelles fonctionnalités utiliser en toute
sécurité, version par version de Node.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Une fois votre terminal ouvert, saisissez la commande suivante :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node --version</pre>
</div>
</div>
<div class="paragraph">
<p>Le numéro de version de l’interpréteur Node s’affiche alors,
par exemple <code>v10.9.0</code>.</p>
</div>
<div class="paragraph">
<p>Si c’est ce à quoi vous vous attendiez, passez à la suite.
À l’inverse, si une erreur se produit ou si la version
n’est pas la bonne, retournez à la section
“<a href="../chapter-02/index.html#install">Installer Node.js</a>” du chapitre 2.</p>
</div>
</div>
<div class="sect2">
<h3 id="script">1.2. Avec un script</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p>L’exécution d’un script Node est très certainement la pratique la plus courante.</p>
</div>
<div class="paragraph">
<p>L’interpréteur Node lit le contenu d’un fichier et exécute les instructions.
L’interpréteur reste actif jusqu’à ce que toutes les instructions
soient traitées.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">script.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">+</span> <span class="token number">2</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><span class="token string">'abc'</span><span class="token punctuation">.</span><span class="token function">toLocaleUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Le fichier exemple <code>script.js</code> contient deux instructions.
Node les interprète lorsqu’on lui passe le chemin du fichier en paramètre
dans une invite de commandes :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node script.js
4
ABC</pre>
</div>
</div>
<div class="paragraph">
<p>Node nous rend ensuite la main pour exécuter d’autres commandes.</p>
</div>
<div class="paragraph">
<p>On apprendra à passer des <a href="#process.argv">arguments d’exécution</a>
dans la section sur le <a href="#process">module <code>process</code></a>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Performances</span> Ressources machine</div>
<div class="paragraph">
<p>Démarrer un processus Node a un coût incompressible en ressources machine :
environ <strong>30 Mo de RAM</strong> et <strong>40 ms de CPU</strong> avant d’exécuter nos
instructions.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="repl">1.3. Avec l’invite de commandes interactive (REPL)</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p>L’invite de commandes interactive est un moyen de parler
à l’interpréteur Node sans écrire de fichier.
Je l’utilise pour tester des idées et des éléments de syntaxe
quand je ne m’en rappelle plus.</p>
</div>
<div class="paragraph">
<p>Le mode interactif s’active en exécutant Node sans aucun argument :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span></pre>
</div>
</div>
<div class="paragraph">
<p>On notera au passage que l’invite est préfixée par le caractère `>`
afin de marquer notre présence dans un environnement différent.
On retrouve un comportement similaire dans les invites de commande
des langages Ruby (<code>irb</code>), Python (<code>python</code>) et PHP (<code>php -a</code>)</p>
</div>
<div class="paragraph">
<p>Lorsque nous sommes dans l’interpréteur interactif,
toutes les expressions sont interprétées par Node :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span>2 + 2
4
<span data-bash-subs=">"></span>"abc".toLocaleUpperCase()
'ABC'
<span data-bash-subs=">"></span></pre>
</div>
</div>
<div class="paragraph">
<p>Des expressions sont réservées pour obtenir de l’aide, sortir de l’interpréteur
ou simplement nettoyer ce que l’on voit à l’écran.
Pour cela on fait appel à l’instruction <code>.help</code> :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span>.help
.break Sometimes you get stuck, this gets you out
.clear Alias for .break
.editor Enter editor mode
.exit Exit the repl
.help Print this help message
.load Load JS from a file into the REPL session
.save Save all evaluated commands in this REPL session to a file</pre>
</div>
</div>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p>Les touches ou combinaisons de touches suivantes sont utiles pour naviguer dans
l’invite de commandes :</p>
</div>
<div class="ulist">
<ul>
<li>
<p><span class="keyseq"><kbd>Ctrl</kbd>+<kbd>C</kbd></span> annule
la saisie de la ligne en cours – c’est <span class="keyseq"><kbd>⌃</kbd>+<kbd>C</kbd></span> sous macOS.</p>
</li>
<li>
<p><kbd>⬆</kbd> et <kbd>⬇</kbd> aident à naviguer dans l’historique des commandes.</p>
</li>
<li>
<p><kbd>TAB</kbd> tente de compléter la saisie avec une expression ou variable connue.
</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span>conso<kbd>TAB</kbd>
<span data-bash-subs=">"></span>console
<span data-bash-subs=">"></span>console.<kbd>TAB</kbd>
...
console.assert console.clear console.count
...</pre>
</div>
</div>
<div class="paragraph">
<p>On notera que l’utilisation de <kbd>TAB</kbd> après un caractère <em>point</em> (<code>.</code>)
liste l’intégralité des propriétés de cet objet.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Raccourci</span> Afficher toutes les variables connues</div>
<div class="paragraph">
<p>La touche <kbd>TAB</kbd> affiche toutes les variables connues
de la session interactive en cours.
Il suffit d’appuyer une ou deux fois dessus dans une invite vide :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span><kbd>TAB</kbd><kbd>TAB</kbd>
Array Boolean Date
Error EvalError Function
Infinity JSON Math
NaN Number Object
...</pre>
</div>
</div>
<div class="paragraph">
<p>C’est un excellent moyen de découvrir des éléments du langage qui nous
étaient inconnus jusque-là.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>La sortie de l’invite de commandes se fait à l’aide de
l’utilisation répétée de la combinaison de touches <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>C</kbd></span>
(ou <span class="keyseq"><kbd>⌃</kbd>+<kbd>C</kbd></span> sous macOS).
On revient ainsi à l’état initial où l’on était avant de
saisir la commande `node` :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span>
(To exit, press ^C again or type .exit)
<span data-bash-subs=">"></span>
<span data-bash-subs="$"></span></pre>
</div>
</div>
<div class="paragraph">
<p>Ce même résultat s’obtient en saisissant <code>.exit</code>
ou en utilisant la combinaison de touches <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>D</kbd></span> (ou <span class="keyseq"><kbd>⌃</kbd>+<kbd>D</kbd></span> sous macOS).
</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Raccourci</span> Variable magique <code>_</code></div>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p>La variable <code>_</code> est spécifique à l’invite de commandes Node.
Elle contient systématiquement le résultat retourné par
la dernière évaluation de code :</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node
<span data-bash-subs=">"></span>2 + 2
4
<span data-bash-subs=">"></span>_ + 2
6</pre>
</div>
</div>
<div class="paragraph">
<p>Elle est équivalente à la variable <code>$_</code> dans la console
des outils de développement des navigateurs web.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="modules-builtin">2. Les modules de base</h2>
<div class="sectionbody">
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p>Les modules de base <strong>étendent le champ d’action de Node</strong>.
Ils servent d’interfaces pour communiquer avec le système d’exploitation,
le système de fichiers, des ressources HTTP et des connexions réseau, entre autres.
Ils sont inclus avec chaque installation de Node.
On peut donc en bénéficier sans effort supplémentaire.</p>
</div>
<div class="paragraph">
<p>Un module de base se charge en passant son identifiant
à la fonction <code>require()</code>, qui retourne alors un objet avec un certain nombre
de propriétés et de fonctions.</p>
</div>
<div class="paragraph">
<p>Ainsi, on charge le <a href="#fs">module <code>fs</code></a> (pour <em>file system</em> – <em>système de fichiers</em>)
afin d’interagir avec les fichiers et les répertoires présents sur l’ordinateur :
</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">fs/read-dir.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'fs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(1)</b>
fs<span class="token punctuation">.</span><span class="token function">readdir</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> files</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> // <b class="conum">(2)</b>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(3)</b>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>On charge les fonctions et attributs du module <code>fs</code> dans la variable du même nom (on pourrait l’appeler autrement).</p>
</li>
<li>
<p>L’appel à la fonction <code>fs.readdir()</code> passe un objet d’erreur ainsi que la liste des fichiers et répertoires contenus dans le chemin indiqué.</p>
</li>
<li>
<p>Affiche un tableau contenant les noms de fichiers et de répertoires présents dans le dossier courant.
</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Ces modules de base représentent la pierre angulaire de nos applications Node.
Ils fournissent le nécessaire pour tout faire !
On apprendra à étendre encore plus le champ des possibles dans
le <a href="../chapter-05/index.html">chapitre 5</a>,
grâce aux <a href="../chapter-05/index.html#modules">modules <code>npm</code></a>.
</p>
</div>
<div class="paragraph">
<p>Les modules de base changent au fil du temps :
les nouvelles versions de Node ajoutent, corrigent et complètent les modules et
fonctions existants.
La documentation officielle de Node reflète ces changements et
affiche un indice de stabilité pour savoir à quoi s’en tenir.
</p>
</div>
<div class="imageblock">
<div class="content">
<img src="./images/api-fs.png" alt="api fs" width="85%">
</div>
<div class="title">Figure 2. Documentation du module <code>fs</code> et son indice de stabilité</div>
</div>
<div class="paragraph">
<p>Exceptionnellement, un module de base (ou une de ses fonctions) peut être supprimé.
L’équipe de Node annonce ces changements en dépréciant le module en question :
le code reste en place et sera supprimé dans une version ultérieure.
En général, c’est une question de mois voire d’années.
On verra plus loin comment <a href="#deprecation">afficher les alertes de dépréciation</a>.
</p>
</div>
<div class="imageblock">
<div class="content">
<img src="./images/api-deprecation-fs-exists.png" alt="api deprecation fs exists" width="85%">
</div>
<div class="title">Figure 3. Documentation de la fonction <code>fs.exists()</code>, affichée comme dépréciée depuis Node v1</div>
</div>
<div class="paragraph">
<p></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">Documentation</span> Lecture des indices de stabilité</div>
<div class="paragraph">
<p>Node communique un indice de stabilité pour les modules de base.
Cette échelle se décompose en trois niveaux :</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Déprécié</strong> : le module sera supprimé dans une prochaine version majeure.
À l’avenir, il vaut mieux ne pas se compter dessus.</p>
</li>
<li>
<p><strong>Expérimental</strong> : le module est en cours de développement.
Une fonctionnalité expérimentale peut changer radicalement entre deux
versions de Node.</p>
</li>
<li>
<p><strong>Stable</strong> : on peut faire confiance à ce module.
Des choses peuvent changer exceptionnellement mais l’intention est d’offrir
une stabilité.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>L’indice est parfois appliqué à des fonctions dont les attentes
changeraient d’une version à l’autre de Node.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Les sections suivantes illustrent des usages courants des modules de base
pour mieux comprendre ce qu’on peut en attendre et comment les utiliser.</p>
</div>
<div class="sect2">
<h3 id="console">2.1. console : déboguer rapidement des variables</h3>
<div class="paragraph">
<p>
</p>
</div>
<div class="paragraph">
<p>L’objet <code>console</code> est une boîte à outils pour afficher
ce qui se passe à un moment donné dans un de nos scripts.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">console/log.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
count<span class="token operator">++</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Valeur de count :'</span><span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>La fonction écrit les messages et la valeur des variables dans la
<a href="#process.std">sortie standard</a> du terminal :
</p>
</div>
<div class="listingblock">
<div class="content">
<pre><span data-bash-subs="$"></span>node console/log.js
Valeur de count : 3</pre>
</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">💡</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Raccourci</span> Variable globale console</div>
<div class="paragraph">
<p>Node charge automatiquement le module pour nous et
le rend utilisable à tout moment à travers la variable globale <code>console</code>.</p>
</div>
<div class="paragraph">
<p>Il est donc inutile de charger le module manuellement avec <code>require('console')</code>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><code>console.log()</code> sait interpoler les valeurs passées en argument avec le marqueur <code>%s</code>.
C’est utile pour structurer un message complexe en gardant les variables à part :
</p>
</div>
<div class="listingblock">
<div class="title">console/interpolate.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Soupe %s et carottes'</span><span class="token punctuation">,</span> <span class="token string">'lentilles'</span><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>Soupe lentilles et carottes</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><code>%s</code> ne sait afficher que des chaînes de caractères.
D’autres marqueurs savent afficher d’autres types de données :</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<code>%d</code>
</td>
<td class="hdlist2">
<p>Affiche la valeur en tant que <a href="../chapter-03/index.html#number">nombre</a>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>%j</code>
</td>
<td class="hdlist2">
<p>Affiche la valeur en tant que <a href="../chapter-03/index.html#json">structure JSON</a>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>%O</code>
</td>
<td class="hdlist2">
<p>Affiche l’objet avec une profondeur maximum de 4 éléments.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>%o</code>
</td>
<td class="hdlist2">
<p>Idem que <code>%O</code> mais sur une profondeur maximum de 2 éléments.</p>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<div class="title">Propriétés notables</div>
<table>
<tr>
<td class="hdlist1">
<code>console.log()</code>
</td>
<td class="hdlist2">
<p>Affichage de messages et de variables dans le terminal.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>console.error()</code>
</td>
<td class="hdlist2">
<p>Comportement identique à <code>console.log()</code> mais à réserver aux erreurs.
La fonction écrit dans la <a href="#process.std">sortie erreur</a>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>console.dir()</code>
</td>
<td class="hdlist2">
<p>Affichage dédié aux objets et tableaux.
On peut paramétrer la profondeur d’affichage
(par défaut, jusqu’à deux niveaux).</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>console.group()</code>
</td>
<td class="hdlist2">
<p>Regroupe visuellement les appels à <code>console.log</code> et <code>console.error</code>.
Un groupe se clôt avec <code>console.groupEnd()</code>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>console.time()</code>
</td>
<td class="hdlist2">
<p>Démarre un chronomètre en lui attribuant un nom.
Le chronomètre s’arrête et sa durée s’affiche avec <code>console.timeEnd()</code>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
classe <code>Console</code>
</td>
<td class="hdlist2">
<p> Crée un objet similaire à <code>console</code> mais en dirigeant l’affichage ailleurs
que vers les <a href="#process.std">flux standards</a>.
</p>
</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">Web</span> Console et navigateurs web</div>
<div class="paragraph">
<p>L’objet <code>console</code> est originaire du monde des navigateurs web.
C’est un onglet de la boîte à outils de développement.
On peut y lire des messages placés dans le code JavaScript de la page web.
On l’utilise aussi pour inspecter la page et interagir avec du code.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="./images/web-console.png" alt="web console">
</div>
<div class="title">Figure 4. Console web dans le navigateur web Firefox</div>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">💬</div>
</td>
<td class="content">
<div class="title"><span class="RemarquePreTitre">Documentation</span> Module console</div>
<div class="paragraph">
<p>La documentation du module <code>console</code> est disponible sur le site officiel de Node :</p>
</div>
<div class="ulist">
<ul>
<li>
<p><span class="URL"><a href="https://nodejs.org/docs/latest-v10.x/api/console.html" class="bare">nodejs.org/docs/latest-v10.x/api/console.html</a></span></p>
</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>
</p>
</div>
</div>
<div class="sect2">
<h3 id="path">2.2. path : manipuler des chemins de fichiers</h3>
<div class="paragraph">
<p></p>
</div>
<div class="paragraph">
<p>Le module <code>path</code> offre un ensemble de fonctions et de propriétés pour
manipuler et construire des chemins vers des fichiers et répertoires.</p>
</div>
<div class="paragraph">
<p>Ces opérations permettent à notre code de fonctionner de manière identique
sur des systèmes d’exploitation qui expriment différemment les chemins –
Linux et Windows par exemple.</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">path/intro.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</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>path<span class="token punctuation">.</span><span class="token function">dirname</span><span class="token punctuation">(</span><span class="token string">'/tmp/package.json'</span><span class="token punctuation">)</span><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>path<span class="token punctuation">.</span><span class="token function">basename</span><span class="token punctuation">(</span><span class="token string">'/tmp/package.json'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> // <b class="conum">(2)</b>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>path<span class="token punctuation">.</span><span class="token function">extname</span><span class="token punctuation">(</span><span class="token string">'/tmp/package.json'</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>Affiche <code>/tmp</code>.</p>
</li>
<li>
<p>Affiche <code>package.json</code>.</p>
</li>
<li>
<p>Affiche <code>.json</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Certaines fonctions comme <code>path.join()</code> tiennent compte de la nature du système
d’exploitation.
Le résultat d’un même appel de fonction sera différent, mais correspondra
à la même intention :
</p>
</div>
<div class="listingblock interactive interactive--javascript interactive--runtime--node-v10">
<div class="title">path/platform.js</div>
<div class="content">
<pre class="highlight highlight-prismjs prismjs language-javascript"><code class="language-javascript" data-lang="javascript"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</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>path<span class="token punctuation">.</span>sep<sp