diff options
Diffstat (limited to 'files/fr/web/javascript/guide/modules/index.md')
-rw-r--r-- | files/fr/web/javascript/guide/modules/index.md | 467 |
1 files changed, 253 insertions, 214 deletions
diff --git a/files/fr/web/javascript/guide/modules/index.md b/files/fr/web/javascript/guide/modules/index.md index aab9361aa6..1411ef6c26 100644 --- a/files/fr/web/javascript/guide/modules/index.md +++ b/files/fr/web/javascript/guide/modules/index.md @@ -9,87 +9,76 @@ tags: - import translation_of: Web/JavaScript/Guide/Modules --- -<div>{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Métaprogrammation")}}</div> +{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Métaprogrammation")}} -<p>Ce guide aborde l'ensemble des notions vous permettant d'utiliser la syntaxe des modules en JavaScript.</p> +Ce guide aborde l'ensemble des notions vous permettant d'utiliser la syntaxe des modules en JavaScript. -<h2 id="Un_peu_de_contexte">Un peu de contexte</h2> +## Un peu de contexte -<p>Les programmes JavaScript ont commencé par être assez petits, réalisant des tâches isolées uniquement là où l'interactivité était nécessaire. Après plusieurs années, nous avons maintenant des applications complètes qui sont exécutées dans les navigateurs avec des codes complexes et volumineux. Des programmes JavaScript sont également exécutés dans d'autres contextes (<a href="/fr/docs/Glossaire/Node.js">Node.js</a> par exemple).</p> +Les programmes JavaScript ont commencé par être assez petits, réalisant des tâches isolées uniquement là où l'interactivité était nécessaire. Après plusieurs années, nous avons maintenant des applications complètes qui sont exécutées dans les navigateurs avec des codes complexes et volumineux. Des programmes JavaScript sont également exécutés dans d'autres contextes ([Node.js](/fr/docs/Glossaire/Node.js) par exemple). -<p>Il a donc été question de fournir un mécanisme pour diviser les programmes JavaScript en plusieurs modules qu'on pourrait importer les uns dans les autres. Cette fonctionnalité était présente dans Node.js depuis longtemps et plusieurs bibliothèques et <em>frameworks</em> JavaScript ont permis l'utilisation de modules (<a href="https://en.wikipedia.org/wiki/CommonJS">CommonJS</a>, <a href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md">AMD</a>, <a href="https://requirejs.org/">RequireJS</a> ou, plus récemment, <a href="https://webpack.github.io/">Webpack</a> et <a href="https://babeljs.io/">Babel</a>).</p> +Il a donc été question de fournir un mécanisme pour diviser les programmes JavaScript en plusieurs modules qu'on pourrait importer les uns dans les autres. Cette fonctionnalité était présente dans Node.js depuis longtemps et plusieurs bibliothèques et _frameworks_ JavaScript ont permis l'utilisation de modules ([CommonJS](https://en.wikipedia.org/wiki/CommonJS), [AMD](https://github.com/amdjs/amdjs-api/blob/master/AMD.md), [RequireJS](https://requirejs.org/) ou, plus récemment, [Webpack](https://webpack.github.io/) et [Babel](https://babeljs.io/)). -<p>Bonne nouvelle, les navigateurs ont également commencé à prendre en charge ces fonctionnalités nativement. C'est le sujet de ce guide.</p> +Bonne nouvelle, les navigateurs ont également commencé à prendre en charge ces fonctionnalités nativement. C'est le sujet de ce guide. -<p>Cette implémentation permettra aux navigateurs d'optimiser le chargement des modules, rendant le fonctionnement plus efficace qu'une bibliothèque tierce avec un traitement côté client des allers-retours sur le réseau.</p> +Cette implémentation permettra aux navigateurs d'optimiser le chargement des modules, rendant le fonctionnement plus efficace qu'une bibliothèque tierce avec un traitement côté client des allers-retours sur le réseau. -<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> +## Compatibilité des navigateurs -<p>L'utilisation des modules natifs JavaScript repose sur les instructions <code><a href="/fr/docs/Web/JavaScript/Reference/Instructions/import">import</a></code> and <code><a href="/fr/docs/Web/JavaScript/Reference/Instructions/export">export</a></code> dont vous pouvez voir l'état de la compatibilité ici :</p> +L'utilisation des modules natifs JavaScript repose sur les instructions [`import`](/fr/docs/Web/JavaScript/Reference/Instructions/import) and [`export`](/fr/docs/Web/JavaScript/Reference/Instructions/export) dont vous pouvez voir l'état de la compatibilité ici : -<h3 id="import"><code>import</code></h3> +### `import` -<p>{{Compat("javascript.statements.import")}}</p> +{{Compat("javascript.statements.import")}} -<h3 id="export"><code>export</code></h3> +### `export` -<p>{{Compat("javascript.statements.export")}}</p> +{{Compat("javascript.statements.export")}} -<h2 id="Commençons_par_un_exemple">Commençons par un exemple</h2> +## Commençons par un exemple -<p>Pour illustrer le fonctionnement des modules, nous avons créé <a href="https://github.com/mdn/js-examples/tree/master/modules">un ensemble d'exemples disponibles sur GitHub</a>. Ces exemples illustrent un ensemble de modules pour créer un élément {{htmlelement("canvas")}} sur une page web puis dessiner (et afficher des informations) sur les différentes formes du canevas.</p> +Pour illustrer le fonctionnement des modules, nous avons créé [un ensemble d'exemples disponibles sur GitHub](https://github.com/mdn/js-examples/tree/master/modules). Ces exemples illustrent un ensemble de modules pour créer un élément {{htmlelement("canvas")}} sur une page web puis dessiner (et afficher des informations) sur les différentes formes du canevas. -<p>Ces opérations sont assez simples mais nous les avons choisies pour nous concentrer plutôt sur le fonctionnement des modules.</p> +Ces opérations sont assez simples mais nous les avons choisies pour nous concentrer plutôt sur le fonctionnement des modules. -<div class="note"> -<p><strong>Note :</strong> Si vous souhaitez télécharger les exemples et les exécuter en local, vous devrez utiliser un serveur web local.</p> -</div> +> **Note :** Si vous souhaitez télécharger les exemples et les exécuter en local, vous devrez utiliser un serveur web local. -<h2 id="Structure_de_lexemple">Structure de l'exemple</h2> +## Structure de l'exemple -<p>Dans notre premier exemple (cf. <a href="https://github.com/mdn/js-examples/tree/master/modules/basic-modules">basic-modules</a>), nous avons l'arborescence de fichier suivante :</p> +Dans notre premier exemple (cf. [basic-modules](https://github.com/mdn/js-examples/tree/master/modules/basic-modules)), nous avons l'arborescence de fichier suivante : -<pre>index.html -main.mjs -modules/ - canvas.mjs - square.mjs</pre> + index.html + main.mjs + modules/ + canvas.mjs + square.mjs -<div class="note"> -<p><strong>Note :</strong> Tous les exemples de ce guide suivent la même structure.</p> -</div> +> **Note :** Tous les exemples de ce guide suivent la même structure. -<p>Le répertoire dédié aux modules contient deux modules :</p> +Le répertoire dédié aux modules contient deux modules : -<ul> - <li><code>canvas.mjs</code> — responsable de fonctions pour gérer le canevas +- `canvas.mjs` — responsable de fonctions pour gérer le canevas - <ul> - <li><code>create()</code> — crée un canevas avec les dimensions souhaitées (<code>width</code> / <code>height</code>) à l'intérieur d'un élément {{htmlelement("div")}} doté d'un identifiant et qui est ajouté à l'intérieur d'un élément indiqué. Cette fonction renvoie l'objet contenant le contexte du canevas et l'identifiant du conteneur.</li> - <li><code>createReportList()</code> — crée une liste non ordonnée à l'intérieur d'un élément indiqué et dans lequel on affiche des données. Cette fonction renvoie l'identifiant de la liste.</li> - </ul> - </li> - <li><code>square.mjs</code> : - <ul> - <li><code>name</code> — une constante qui est une chaîne de caractères : <code>"square"</code>.</li> - <li><code>draw()</code> — dessine un carré avec une taille/position/couleur données sur le canevas indiqué. Cette fonction renvoie un objet contenant la taille du carré, sa position et sa couleur.</li> - <li><code>reportArea()</code> — écrit la surface d'un carré dans une liste donnée en fonction de la longueur de son côté.</li> - <li><code>reportPerimeter()</code> — écrit le périmètre d'un carré dans une liste donnée en fonction de la longueur de son côté.</li> - </ul> - </li> -</ul> + - `create()` — crée un canevas avec les dimensions souhaitées (`width` / `height`) à l'intérieur d'un élément {{htmlelement("div")}} doté d'un identifiant et qui est ajouté à l'intérieur d'un élément indiqué. Cette fonction renvoie l'objet contenant le contexte du canevas et l'identifiant du conteneur. + - `createReportList()` — crée une liste non ordonnée à l'intérieur d'un élément indiqué et dans lequel on affiche des données. Cette fonction renvoie l'identifiant de la liste. -<div class="note"> -<p><strong>Note :</strong> Pour les modules JavaScript natifs, l'extension <code>.mjs</code> a son importance car elle permet d'importer des fichiers avec un type MIME <code>javascript/esm</code> (on pourra utiliser une autre extension qui fournira le type MIME <code>application/javascript</code>) afin d'éviter les erreurs liées à la vérification des types MIME. L'extension <code>.mjs</code> est notamment utile afin de distinguer plus clairement les scripts « classiques » des modules et pourra être exploitée par d'autres outils. Pour plus de détails, voir <a href="https://v8.dev/features/modules#mjs">cette note de Google</a>.</p> -</div> +- `square.mjs` : -<h2 id="Exporter_des_fonctionnalités">Exporter des fonctionnalités</h2> + - `name` — une constante qui est une chaîne de caractères : `"square"`. + - `draw()` — dessine un carré avec une taille/position/couleur données sur le canevas indiqué. Cette fonction renvoie un objet contenant la taille du carré, sa position et sa couleur. + - `reportArea()` — écrit la surface d'un carré dans une liste donnée en fonction de la longueur de son côté. + - `reportPerimeter()` — écrit le périmètre d'un carré dans une liste donnée en fonction de la longueur de son côté. -<p>Pour commencer et afin d'utiliser les fonctionnalités d'un module, on devra les exporter. Pour cela, on utilisera l'instruction <code><a href="/fr/docs/Web/JavaScript/Reference/Instructions/export">export</a></code>.</p> +> **Note :** Pour les modules JavaScript natifs, l'extension `.mjs` a son importance car elle permet d'importer des fichiers avec un type MIME `javascript/esm` (on pourra utiliser une autre extension qui fournira le type MIME `application/javascript`) afin d'éviter les erreurs liées à la vérification des types MIME. L'extension `.mjs` est notamment utile afin de distinguer plus clairement les scripts « classiques » des modules et pourra être exploitée par d'autres outils. Pour plus de détails, voir [cette note de Google](https://v8.dev/features/modules#mjs). -<p>La méthode la plus simple consiste à placer cette instruction devant chaque valeur qu'on souhaite exporter, par exemple :</p> +## Exporter des fonctionnalités -<pre class="brush: js">export const name = 'square'; +Pour commencer et afin d'utiliser les fonctionnalités d'un module, on devra les exporter. Pour cela, on utilisera l'instruction [`export`](/fr/docs/Web/JavaScript/Reference/Instructions/export). + +La méthode la plus simple consiste à placer cette instruction devant chaque valeur qu'on souhaite exporter, par exemple : + +```js +export const name = 'square'; export function draw(ctx, length, x, y, color) { ctx.fillStyle = color; @@ -101,148 +90,165 @@ export function draw(ctx, length, x, y, color) { y: y, color: color }; -}</pre> +} +``` -<p>Il est possible d'exporter des fonctions, des variables (qu'elles soient définies avec <code>var</code>, <code>let</code> ou <code>const</code>) et aussi des classes (que nous verrons par la suite). Les valeurs exportées doivent être présentes au plus haut niveau du script, il n'est pas possible d'utiliser <code>export</code> dans une fonction.</p> +Il est possible d'exporter des fonctions, des variables (qu'elles soient définies avec `var`, `let` ou `const`) et aussi des classes (que nous verrons par la suite). Les valeurs exportées doivent être présentes au plus haut niveau du script, il n'est pas possible d'utiliser `export` dans une fonction. -<p>Une méthode plus concise consiste à exporter l'ensemble des valeurs grâce à une seule instruction située à la fin du fichier : les valeurs sont séparées par des virgules et la liste est délimitée entre accolades :</p> +Une méthode plus concise consiste à exporter l'ensemble des valeurs grâce à une seule instruction située à la fin du fichier : les valeurs sont séparées par des virgules et la liste est délimitée entre accolades : -<pre class="brush: js">export { name, draw, reportArea, reportPerimeter };</pre> +```js +export { name, draw, reportArea, reportPerimeter }; +``` -<h2 id="Importer_des_fonctionnalités">Importer des fonctionnalités</h2> +## Importer des fonctionnalités -<p>Lorsque des fonctionnalités sont exportées par un premier module, on peut les importer dans un script afin de les utiliser. Voici la méthode la plus simple pour ce faire :</p> +Lorsque des fonctionnalités sont exportées par un premier module, on peut les importer dans un script afin de les utiliser. Voici la méthode la plus simple pour ce faire : -<pre class="brush: js">import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs';</pre> +```js +import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs'; +``` -<p>On utilise ici l'instruction <code><a href="/fr/docs/Web/JavaScript/Reference/Instructions/import">import</a></code>, suivi d'une liste d'identifiants séparées par des virgules et délimitée par des accolades, suivie du mot-clé <code>from</code> puis du chemin vers le fichier du module. Le chemin est relatif à la racine du site. Dans notre cas, pour <code>basic-module</code>, on écrira <code>/js-examples/modules/basic-modules</code>.</p> +On utilise ici l'instruction [`import`](/fr/docs/Web/JavaScript/Reference/Instructions/import), suivi d'une liste d'identifiants séparées par des virgules et délimitée par des accolades, suivie du mot-clé `from` puis du chemin vers le fichier du module. Le chemin est relatif à la racine du site. Dans notre cas, pour `basic-module`, on écrira `/js-examples/modules/basic-modules`. -<p>Ici, nous avons écrit le chemin d'une façon légèrement différente : on utilise le point (<code>.</code>) afin d'indiquer « l'emplacement courant », suivi du chemin vers le fichier. Cela permet d'éviter d'avoir à écrire l'intégralité du chemin à chaque fois, c'est aussi plus court et cela permet de déplacer le script et le modules sans avoir à modifier les scripts.</p> +Ici, nous avons écrit le chemin d'une façon légèrement différente : on utilise le point (`.`) afin d'indiquer « l'emplacement courant », suivi du chemin vers le fichier. Cela permet d'éviter d'avoir à écrire l'intégralité du chemin à chaque fois, c'est aussi plus court et cela permet de déplacer le script et le modules sans avoir à modifier les scripts. -<p>Ainsi :</p> +Ainsi : -<pre>/js-examples/modules/basic-modules/modules/square.mjs</pre> + /js-examples/modules/basic-modules/modules/square.mjs -<p>devient :</p> +devient : -<pre>./modules/square.mjs</pre> + ./modules/square.mjs -<p>Vous pouvez voir ces lignes dans <code><a href="https://github.com/mdn/js-examples/blob/master/modules/basic-modules/main.js">main.mjs</a></code>.</p> +Vous pouvez voir ces lignes dans [`main.mjs`](https://github.com/mdn/js-examples/blob/master/modules/basic-modules/main.js). -<div class="note"> -<p><strong>Note :</strong> Pour certains systèmes de module, on peut omettre l'extension de fichier et le point (c'est-à-dire qu'on peut écrire <code>'/modules/square'</code>). Cela ne fonctionne pas pour les modules JavaScript !</p> -</div> +> **Note :** Pour certains systèmes de module, on peut omettre l'extension de fichier et le point (c'est-à-dire qu'on peut écrire `'/modules/square'`). Cela ne fonctionne pas pour les modules JavaScript ! -<p>Une fois les fonctionnalités importées dans le script, vous pouvez utiliser les valeurs dans votre script. Dans <code>main.mjs</code>, après les lignes d'import, on trouvera :</p> +Une fois les fonctionnalités importées dans le script, vous pouvez utiliser les valeurs dans votre script. Dans `main.mjs`, après les lignes d'import, on trouvera : -<pre class="brush: js">let myCanvas = create('myCanvas', document.body, 480, 320); +```js +let myCanvas = create('myCanvas', document.body, 480, 320); let reportList = createReportList(myCanvas.id); let square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue'); reportArea(square1.length, reportList); reportPerimeter(square1.length, reportList); -</pre> +``` -<h2 id="Charger_le_module_via_le_document_HTML">Charger le module via le document HTML</h2> +## Charger le module via le document HTML -<p>Il faut ensuite pouvoir charger le script <code>main.mjs</code> sur la page HTML. Pour cela, nous allons voir qu'il y a quelques différences avec le chargement d'un script « classique ».</p> +Il faut ensuite pouvoir charger le script `main.mjs` sur la page HTML. Pour cela, nous allons voir qu'il y a quelques différences avec le chargement d'un script « classique ». -<p>Tout d'abord, il est nécessaire d'indiquer <code>type="module"</code> dans l'élément {{htmlelement("script")}} afin d'indiquer qu'on charge des modules :</p> +Tout d'abord, il est nécessaire d'indiquer `type="module"` dans l'élément {{htmlelement("script")}} afin d'indiquer qu'on charge des modules : -<pre class="brush: js"><script type="module" src="main.mjs"></script></pre> +```js +<script type="module" src="main.mjs"></script> +``` -<p>Le script qu'on importe ici agit comme le module de plus haut niveau. Si on oublie ce type, Firefox déclenchera une erreur "<em>SyntaxError: import declarations may only appear at top level of a module</em>".</p> +Le script qu'on importe ici agit comme le module de plus haut niveau. Si on oublie ce type, Firefox déclenchera une erreur "_SyntaxError: import declarations may only appear at top level of a module_". -<p>Les instructions <code>import</code> et <code>export</code> ne peuvent être utilisées qu'à l'intérieur de modules et pas à l'intérieur de scripts « classiques ».</p> +Les instructions `import` et `export` ne peuvent être utilisées qu'à l'intérieur de modules et pas à l'intérieur de scripts « classiques ». -<div class="note"> -<p><strong>Note :</strong> Il est aussi possible d'importer des modules dans des scripts qui sont déclarés en incise si on indique bien <code>type="module"</code>. On pourra donc écrire <code><script type="module"> //code du script utilisant les modules ici </script></code>.</p> -</div> +> **Note :** Il est aussi possible d'importer des modules dans des scripts qui sont déclarés en incise si on indique bien `type="module"`. On pourra donc écrire `<script type="module"> //code du script utilisant les modules ici </script>`. -<h2 id="Différences_entre_les_modules_et_les_scripts_«_classiques_»">Différences entre les modules et les scripts « classiques »</h2> +## Différences entre les modules et les scripts « classiques » -<ul> - <li>Attention aux tests sur un environnement local : si vous chargez le fichier HTML directement depuis le système de fichier dans le navigateur (en double-cliquant dessus par exemple, ce qui donnera une URL <code>file://</code>), vous rencontrerez des erreurs CORS pour des raisons de sécurité. Il faut donc un serveur local afin de pouvoir tester.</li> - <li>On pourra avoir un comportement différent entre un même script utilisé comme un module et un script utilisé de façon « classique ». En effet, les modules utilisent automatiquement <a href="/fr/docs/Web/JavaScript/Reference/Strict_mode">le mode strict</a>.</li> - <li>Il n'est pas nécessaire d'utiliser l'attribut <code>defer</code> (voir <a href="/fr/docs/Web/HTML/Element/script#Attributs">les attributs de <code><script></code></a>) lors du chargement d'un module, ceux-ci sont automatiquement chargés à la demande.</li> - <li>Enfin, les fonctionnalités importées ne sont disponibles qu'au sein de la portée du script qui les utilise ! Les valeurs importées ne sont manipulables que depuis le script, elles ne sont pas rattachées à la portée globale. On ne pourra par exemple pas y accéder depuis la console JavaScript. Bien que les erreurs soient toujours indiquées dans les outils de développement, certaines techniques de débogage ne seront pas disponibles.</li> -</ul> +- Attention aux tests sur un environnement local : si vous chargez le fichier HTML directement depuis le système de fichier dans le navigateur (en double-cliquant dessus par exemple, ce qui donnera une URL `file://`), vous rencontrerez des erreurs CORS pour des raisons de sécurité. Il faut donc un serveur local afin de pouvoir tester. +- On pourra avoir un comportement différent entre un même script utilisé comme un module et un script utilisé de façon « classique ». En effet, les modules utilisent automatiquement [le mode strict](/fr/docs/Web/JavaScript/Reference/Strict_mode). +- Il n'est pas nécessaire d'utiliser l'attribut `defer` (voir [les attributs de `<script>`](/fr/docs/Web/HTML/Element/script#Attributs)) lors du chargement d'un module, ceux-ci sont automatiquement chargés à la demande. +- Enfin, les fonctionnalités importées ne sont disponibles qu'au sein de la portée du script qui les utilise ! Les valeurs importées ne sont manipulables que depuis le script, elles ne sont pas rattachées à la portée globale. On ne pourra par exemple pas y accéder depuis la console JavaScript. Bien que les erreurs soient toujours indiquées dans les outils de développement, certaines techniques de débogage ne seront pas disponibles. -<h2 id="Exports_par_défaut_et_exports_nommés">Exports par défaut et exports nommés</h2> +## Exports par défaut et exports nommés -<p>Jusqu'à présent, nous avons utilisé des <strong>exports nommés</strong> — chaque valeur est exportée avec un nom et c'est ce nom qui est également utilisé lorsqu'on réalise l'import.</p> +Jusqu'à présent, nous avons utilisé des **exports nommés** — chaque valeur est exportée avec un nom et c'est ce nom qui est également utilisé lorsqu'on réalise l'import. -<p>Il existe également un <strong>export par défaut</strong> — conçu pour simplifier l'export d'une fonction par module et pour faciliter l'interopérabilité avec les systèmes de module CommonJS et AMD (pour plus d'informations, voir <a href="https://tech.mozfr.org/post/2015/08/21/ES6-en-details-%3A-les-modules">ES6 en détails : les modules</a>).</p> +Il existe également un **export par défaut** — conçu pour simplifier l'export d'une fonction par module et pour faciliter l'interopérabilité avec les systèmes de module CommonJS et AMD (pour plus d'informations, voir [ES6 en détails : les modules](https://tech.mozfr.org/post/2015/08/21/ES6-en-details-%3A-les-modules)). -<p>Prenons un exemple pour comprendre le fonctionnement des exports par défaut. Dans <code>square.mjs</code>, on a une fonction intitulée <code>randomSquare()</code> qui crée un carré avec une taille/couleur/position aléatoires. On souhaite exporter cette fonction par défaut et on écrit donc ceci à la fin du fichier :</p> +Prenons un exemple pour comprendre le fonctionnement des exports par défaut. Dans `square.mjs`, on a une fonction intitulée `randomSquare()` qui crée un carré avec une taille/couleur/position aléatoires. On souhaite exporter cette fonction par défaut et on écrit donc ceci à la fin du fichier : -<pre class="brush: js">export default randomSquare;</pre> +```js +export default randomSquare; +``` -<p>On notera ici l'absence d'accolades.</p> +On notera ici l'absence d'accolades. -<p>On aurait également pu ajouter <code>export default</code> devant le mot-clé <code>function</code> et la définir comme fonction anonyme :</p> +On aurait également pu ajouter `export default` devant le mot-clé `function` et la définir comme fonction anonyme : -<pre class="brush: js">export default function(ctx) { +```js +export default function(ctx) { ... -}</pre> +} +``` -<p>Dans le fichier <code>main.mjs</code>, on importe la fonction par défaut avec cette ligne</p> +Dans le fichier `main.mjs`, on importe la fonction par défaut avec cette ligne -<pre class="brush: js">import randomSquare from './modules/square.mjs';</pre> +```js +import randomSquare from './modules/square.mjs'; +``` -<p>On voit ici aussi l'absence d'accolade car il n'y a qu'un seul export par défaut possible par module (et ici, on sait qu'il s'agit de <code>randomSquare</code>). La ligne ci-avant est en fait une notation raccourcie équivalente à :</p> +On voit ici aussi l'absence d'accolade car il n'y a qu'un seul export par défaut possible par module (et ici, on sait qu'il s'agit de `randomSquare`). La ligne ci-avant est en fait une notation raccourcie équivalente à : -<pre class="brush: js">import {default as randomSquare} from './modules/square.mjs';</pre> +```js +import {default as randomSquare} from './modules/square.mjs'; +``` -<div class="note"> -<p><strong>Note :</strong> Pour en savoir plus sur le renommage des objets exportés, voir ci-après {{anch("Renommage des imports et des exports")}}.</p> -</div> +> **Note :** Pour en savoir plus sur le renommage des objets exportés, voir ci-après {{anch("Renommage des imports et des exports")}}. -<h2 id="Gestion_des_conflits_de_nommage">Gestion des conflits de nommage</h2> +## Gestion des conflits de nommage -<p>Jusqu'à présent, notre exemple fonctionne. Mais que se passerait-il si nous ajoutions un module permettant de dessiner une autre forme comme un cercle ou un triangle ? Ces formes disposeraient sans doute également de fonctions telles que <code>draw()</code>, <code>reportArea()</code>, etc. Si on essaie d'importer ces fonctions avec les mêmes noms dans le module de plus haut niveau, nous allons avoir des conflits et des erreurs.</p> +Jusqu'à présent, notre exemple fonctionne. Mais que se passerait-il si nous ajoutions un module permettant de dessiner une autre forme comme un cercle ou un triangle ? Ces formes disposeraient sans doute également de fonctions telles que `draw()`, `reportArea()`, etc. Si on essaie d'importer ces fonctions avec les mêmes noms dans le module de plus haut niveau, nous allons avoir des conflits et des erreurs. -<p>Heureusement, il existe différentes façons de résoudre ce problème.</p> +Heureusement, il existe différentes façons de résoudre ce problème. -<h3 id="Renommage_des_imports_et_des_exports">Renommage des imports et des exports</h3> +### Renommage des imports et des exports -<p>Entre les accolades utilisées pour les instructions <code>import</code> et <code>export</code>, on peut utiliser le mot-clé <code>as</code> avec un autre nom afin de modifier le nom par lequel on souhaite identifier la fonctionnalité.</p> +Entre les accolades utilisées pour les instructions `import` et `export`, on peut utiliser le mot-clé `as` avec un autre nom afin de modifier le nom par lequel on souhaite identifier la fonctionnalité. -<p>Ainsi, les deux fragments qui suivent permettraient d'obtenir le même résultat de façons différentes :</p> +Ainsi, les deux fragments qui suivent permettraient d'obtenir le même résultat de façons différentes : -<pre class="brush: js">// dans module.mjs +```js +// dans module.mjs export { fonction1 as nouveauNomDeFonction, fonction2 as autreNouveauNomDeFonction }; // dans main.mjs -import { nouveauNomDeFonction, autreNouveauNomDeFonction } from './modules/module.mjs';</pre> +import { nouveauNomDeFonction, autreNouveauNomDeFonction } from './modules/module.mjs'; +``` -<pre class="brush: js">// dans module.mjs +```js +// dans module.mjs export { fonction1, fonction2 }; // dans main.mjs import { fonction1 as nouveauNomDeFonction, - fonction2 as autreNouveauNomDeFonction } from './modules/module.mjs';</pre> + fonction2 as autreNouveauNomDeFonction } from './modules/module.mjs'; +``` -<p>Prenons un exemple concret. Dans le répertoire <code><a href="https://github.com/mdn/js-examples/tree/master/modules/renaming">renaming</a></code>, vous verrez le même système de modules que précédemment auquel nous avons ajouté <code>circle.mjs</code> et <code>triangle.mjs</code> afin de dessiner et d'écrire des informations sur des cercles et des triangles.</p> +Prenons un exemple concret. Dans le répertoire [`renaming`](https://github.com/mdn/js-examples/tree/master/modules/renaming), vous verrez le même système de modules que précédemment auquel nous avons ajouté `circle.mjs` et `triangle.mjs` afin de dessiner et d'écrire des informations sur des cercles et des triangles. -<p>Dans chaque module, on exporte les fonctionnalités avec des noms identiques : l'instruction <code>export</code> utilisée est la même à chaque fin de fichier :</p> +Dans chaque module, on exporte les fonctionnalités avec des noms identiques : l'instruction `export` utilisée est la même à chaque fin de fichier : -<pre class="brush: js">export { name, draw, reportArea, reportPerimeter };</pre> +```js +export { name, draw, reportArea, reportPerimeter }; +``` -<p>Lorsqu'on importe les valeurs dans <code>main.mjs</code>, si on essaie d'utiliser</p> +Lorsqu'on importe les valeurs dans `main.mjs`, si on essaie d'utiliser -<pre class="brush: js">import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs'; +```js +import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs'; import { name, draw, reportArea, reportPerimeter } from './modules/circle.mjs'; -import { name, draw, reportArea, reportPerimeter } from './modules/triangle.mjs';</pre> +import { name, draw, reportArea, reportPerimeter } from './modules/triangle.mjs'; +``` -<p>Le navigateur déclenchera une erreur telle que "<em>SyntaxError: redeclaration of import name</em>" (Firefox).</p> +Le navigateur déclenchera une erreur telle que "_SyntaxError: redeclaration of import name_" (Firefox). -<p>Pour éviter ce problème, on renomme les imports afin qu'ils soient uniques :</p> +Pour éviter ce problème, on renomme les imports afin qu'ils soient uniques : -<pre class="brush: js">import { name as squareName, +```js +import { name as squareName, draw as drawSquare, reportArea as reportSquareArea, reportPerimeter as reportSquarePerimeter } from './modules/square.mjs'; @@ -255,60 +261,76 @@ import { name as circleName, import { name as triangleName, draw as drawTriangle, reportArea as reportTriangleArea, - reportPerimeter as reportTrianglePerimeter } from './modules/triangle.mjs';</pre> + reportPerimeter as reportTrianglePerimeter } from './modules/triangle.mjs'; +``` -<p>On aurait pu également résoudre le problème dans les fichiers de chaque module.</p> +On aurait pu également résoudre le problème dans les fichiers de chaque module. -<pre class="brush: js">// dans square.mjs +```js +// dans square.mjs export { name as squareName, draw as drawSquare, reportArea as reportSquareArea, - reportPerimeter as reportSquarePerimeter };</pre> + reportPerimeter as reportSquarePerimeter }; +``` -<pre class="brush: js">// dans main.mjs -import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.mjs';</pre> +```js +// dans main.mjs +import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.mjs'; +``` -<p>Les deux approches fonctionnent. C'est à vous de choisir le style. Toutefois, il est souvent plus pratique d'effectuer le renommage à l'import, notamment lorsqu'on importe des fonctionnalités de modules tiers sur lesquels on n'a pas le contrôle.</p> +Les deux approches fonctionnent. C'est à vous de choisir le style. Toutefois, il est souvent plus pratique d'effectuer le renommage à l'import, notamment lorsqu'on importe des fonctionnalités de modules tiers sur lesquels on n'a pas le contrôle. -<h3 id="Créer_un_objet_module">Créer un objet module</h3> +### Créer un objet module -<p>La méthode précédente fonctionne mais reste « brouillonne ». Pour faire mieux, on peut importer l'ensemble des fonctionnalités de chaque module dans un objet, de la façon suivante :</p> +La méthode précédente fonctionne mais reste « brouillonne ». Pour faire mieux, on peut importer l'ensemble des fonctionnalités de chaque module dans un objet, de la façon suivante : -<pre class="brush: js">import * as Module from './modules/module.mjs';</pre> +```js +import * as Module from './modules/module.mjs'; +``` -<p>Cela récupère tous les exports disponibles depuis <code>module.mjs</code> et les transforme en propriétés et méthodes rattachées à l'objet <code>Module</code> qui fournit alors un espace de noms (<em>namespace</em>) :</p> +Cela récupère tous les exports disponibles depuis `module.mjs` et les transforme en propriétés et méthodes rattachées à l'objet `Module` qui fournit alors un espace de noms (_namespace_) : -<pre class="brush: js">Module.function1() +```js +Module.function1() Module.function2() -etc.</pre> +etc. +``` -<p>Là encore, prenons un exemple concret avec le répertoire <a href="https://github.com/mdn/js-examples/tree/master/modules/module-objects">module-objects</a>. Il s'agit du même exemple que précédemment mais qui a été réécrit afin de tirer parti de cette syntaxe. Dans les modules, les exports sont tous écrits ainsi :</p> +Là encore, prenons un exemple concret avec le répertoire [module-objects](https://github.com/mdn/js-examples/tree/master/modules/module-objects). Il s'agit du même exemple que précédemment mais qui a été réécrit afin de tirer parti de cette syntaxe. Dans les modules, les exports sont tous écrits ainsi : -<pre class="brush: js">export { name, draw, reportArea, reportPerimeter };</pre> +```js +export { name, draw, reportArea, reportPerimeter }; +``` -<p>En revanche, pour les imports, on les récupère ainsi :</p> +En revanche, pour les imports, on les récupère ainsi : -<pre class="brush: js">import * as Canvas from './modules/canvas.mjs'; +```js +import * as Canvas from './modules/canvas.mjs'; import * as Square from './modules/square.mjs'; import * as Circle from './modules/circle.mjs'; -import * as Triangle from './modules/triangle.mjs';</pre> +import * as Triangle from './modules/triangle.mjs'; +``` -<p>Dans chaque cas, on peut accéder aux imports comme propriétés des objets ainsi créés :</p> +Dans chaque cas, on peut accéder aux imports comme propriétés des objets ainsi créés : -<pre class="brush: js">let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue'); +```js +let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue'); Square.reportArea(square1.length, reportList); -Square.reportPerimeter(square1.length, reportList);</pre> +Square.reportPerimeter(square1.length, reportList); +``` -<p>On obtient alors un code plus lisible.</p> +On obtient alors un code plus lisible. -<h2 id="Classes_et_modules">Classes et modules</h2> +## Classes et modules -<p>Comme mentionné avant, il est possible d'importer et d'exporter des classes. Cette méthode peut aussi être utilisée afin d'éviter les conflits de nommage. Elle s'avère notamment utile lorsque vous utilisez déjà des classes pour construire vos objets (cela permet de garder une certaine cohérence dans le style).</p> +Comme mentionné avant, il est possible d'importer et d'exporter des classes. Cette méthode peut aussi être utilisée afin d'éviter les conflits de nommage. Elle s'avère notamment utile lorsque vous utilisez déjà des classes pour construire vos objets (cela permet de garder une certaine cohérence dans le style). -<p>Pour voir le résultat obtenu, vous pouvez consulter le répertoire <a href="https://github.com/mdn/js-examples/tree/master/modules/classes">classes</a> du dépôt où l'ensemble a été réécrit pour tirer parti des classes ECMAScript. Ainsi, <code><a href="https://github.com/mdn/js-examples/blob/master/modules/classes/modules/square.js">square.mjs</a></code> contient désormais l'ensemble des fonctionnalités via une classe :</p> +Pour voir le résultat obtenu, vous pouvez consulter le répertoire [classes](https://github.com/mdn/js-examples/tree/master/modules/classes) du dépôt où l'ensemble a été réécrit pour tirer parti des classes ECMAScript. Ainsi, [`square.mjs`](https://github.com/mdn/js-examples/blob/master/modules/classes/modules/square.js) contient désormais l'ensemble des fonctionnalités via une classe : -<pre class="brush: js">class Square { +```js +class Square { constructor(ctx, listId, length, x, y, color) { ... } @@ -318,115 +340,132 @@ Square.reportPerimeter(square1.length, reportList);</pre> } ... -}</pre> +} +``` -<p>Il suffit d'exporter cette classe :</p> +Il suffit d'exporter cette classe : -<pre class="brush: js">export { Square };</pre> +```js +export { Square }; +``` -<p>Puis de l'importer ainsi dans <code><a href="https://github.com/mdn/js-examples/blob/master/modules/classes/main.js">main.mjs</a></code> :</p> +Puis de l'importer ainsi dans [`main.mjs`](https://github.com/mdn/js-examples/blob/master/modules/classes/main.js) : -<pre class="brush: js">import { Square } from './modules/square.mjs';</pre> +```js +import { Square } from './modules/square.mjs'; +``` -<p>Ensuite, on peut utiliser cette classe afin de dessiner le carré :</p> +Ensuite, on peut utiliser cette classe afin de dessiner le carré : -<pre class="brush: js">let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); +```js +let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); square1.draw(); square1.reportArea(); -square1.reportPerimeter();</pre> +square1.reportPerimeter(); +``` -<h2 id="Agréger_des_modules">Agréger des modules</h2> +## Agréger des modules -<p>Il arrivera qu'on veuille agréger des modules entre eux. On peut avoir plusieurs niveaux de dépendances et vouloir simplifier les choses en combinant différents sous-modules en un seul module parent. Pour cela, on pourra utiliser la notation raccourcie suivante :</p> +Il arrivera qu'on veuille agréger des modules entre eux. On peut avoir plusieurs niveaux de dépendances et vouloir simplifier les choses en combinant différents sous-modules en un seul module parent. Pour cela, on pourra utiliser la notation raccourcie suivante : -<pre class="brush: js">export * from 'x.mjs' -export { name } from 'x.mjs'</pre> +```js +export * from 'x.mjs' +export { name } from 'x.mjs' +``` -<p>Pour voir cela en pratique, vous pouvez consulter le répertoire <a href="https://github.com/mdn/js-examples/tree/master/modules/module-aggregation">module-aggregation</a>. Dans cet exemple (construit sur le précédent qui utilise les classes), on a un module supplémentaire intitulé <code>shapes.mjs</code> qui agrège les fonctionnalités fournies par <code>circle.mjs</code>, <code>square.mjs</code> et <code>triangle.mjs</code>. Les sous-modules ont également été déplacés dans un répertoire <code>shapes</code> situé dans un répertoire <code>modules</code>. L'arborescence utilisée est donc :</p> +Pour voir cela en pratique, vous pouvez consulter le répertoire [module-aggregation](https://github.com/mdn/js-examples/tree/master/modules/module-aggregation). Dans cet exemple (construit sur le précédent qui utilise les classes), on a un module supplémentaire intitulé `shapes.mjs` qui agrège les fonctionnalités fournies par `circle.mjs`, `square.mjs` et `triangle.mjs`. Les sous-modules ont également été déplacés dans un répertoire `shapes` situé dans un répertoire `modules`. L'arborescence utilisée est donc : -<pre>modules/ - canvas.mjs - shapes.mjs - shapes/ - circle.mjs - square.mjs - triangle.mjs</pre> + modules/ + canvas.mjs + shapes.mjs + shapes/ + circle.mjs + square.mjs + triangle.mjs -<p>Dans chaque sous-module, l'export aura la même forme :</p> +Dans chaque sous-module, l'export aura la même forme : -<pre class="brush: js">export { Square };</pre> +```js +export { Square }; +``` -<p>Pour l'agrégation au sein de <code><a href="https://github.com/mdn/js-examples/blob/master/modules/module-aggregation/modules/shapes.js">shapes.mjs</a></code>, on écrit les lignes suivantes :</p> +Pour l'agrégation au sein de [`shapes.mjs`](https://github.com/mdn/js-examples/blob/master/modules/module-aggregation/modules/shapes.js), on écrit les lignes suivantes : -<pre class="brush: js">export { Square } from './shapes/square.mjs'; +```js +export { Square } from './shapes/square.mjs'; export { Triangle } from './shapes/triangle.mjs'; -export { Circle } from './shapes/circle.mjs';</pre> +export { Circle } from './shapes/circle.mjs'; +``` -<p>On récupère ainsi l'ensemble des exports de chaque module et on les rend disponibles via <code>shapes.mjs</code>.</p> +On récupère ainsi l'ensemble des exports de chaque module et on les rend disponibles via `shapes.mjs`. -<div class="note"> -<p><strong>Note :</strong> Cette notation ne permet que de rediriger les exports via le fichier. Les objets importés/exportés n'existent pas vraiment dans <code>shapes.mjs</code> et on ne peut donc pas écrire de code <em>utile</em> qui les manipule.</p> -</div> +> **Note :** Cette notation ne permet que de rediriger les exports via le fichier. Les objets importés/exportés n'existent pas vraiment dans `shapes.mjs` et on ne peut donc pas écrire de code _utile_ qui les manipule. -<p>Dans le fichier <code>main.mjs</code>, on pourra alors remplacer :</p> +Dans le fichier `main.mjs`, on pourra alors remplacer : -<pre class="brush: js">import { Square } from './modules/square.mjs'; +```js +import { Square } from './modules/square.mjs'; import { Circle } from './modules/circle.mjs'; -import { Triangle } from './modules/triangle.mjs';</pre> +import { Triangle } from './modules/triangle.mjs'; +``` -<p>par :</p> +par : -<pre class="brush: js">import { Square, Circle, Triangle } from './modules/shapes.mjs';</pre> +```js +import { Square, Circle, Triangle } from './modules/shapes.mjs'; +``` -<h2 id="Chargement_dynamique_de_modules">Chargement dynamique de modules</h2> +## Chargement dynamique de modules -<p>Cette nouvelle fonctionnalité permet aux navigateurs de charger les modules lorsqu'ils sont nécessaires plutôt que de tout précharger en avance de phase. Cette méthode offre de nombreux avantages quant aux performances. Voyons comment cela fonctionne.</p> +Cette nouvelle fonctionnalité permet aux navigateurs de charger les modules lorsqu'ils sont nécessaires plutôt que de tout précharger en avance de phase. Cette méthode offre de nombreux avantages quant aux performances. Voyons comment cela fonctionne. -<p>Pour utiliser cette fonctionnalité, on pourra utiliser <code>import()</code> comme une fonction et lui passer le chemin du module en argument. Cette fonction renverra <a href="/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise">une promesse</a>, qui sera résolue en un module objet donnant accès aux exports.</p> +Pour utiliser cette fonctionnalité, on pourra utiliser `import()` comme une fonction et lui passer le chemin du module en argument. Cette fonction renverra [une promesse](/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise), qui sera résolue en un module objet donnant accès aux exports. -<pre class="brush: js">import('./modules/monModule.mjs') - .then((module) => { +```js +import('./modules/monModule.mjs') + .then((module) => { // Faire qqc avec le module. - });</pre> + }); +``` -<p>Dans nos exemples, regardons le répertoire <a href="https://github.com/mdn/js-examples/tree/master/modules/dynamic-module-imports">dynamic-module-imports</a>, également basé sur les classes. Cette fois, on ne dessine rien au chargement de l'exemple mais on ajoute trois boutons — "Circle", "Square" et "Triangle" — qui, lorsqu'ils seront utilisés, chargeront dynamiquement les modules nécessaires et les utiliseront pour charger la forme associée.</p> +Dans nos exemples, regardons le répertoire [dynamic-module-imports](https://github.com/mdn/js-examples/tree/master/modules/dynamic-module-imports), également basé sur les classes. Cette fois, on ne dessine rien au chargement de l'exemple mais on ajoute trois boutons — "Circle", "Square" et "Triangle" — qui, lorsqu'ils seront utilisés, chargeront dynamiquement les modules nécessaires et les utiliseront pour charger la forme associée. -<p>Dans cet exemple, nous avons uniquement modifié <a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/index.html">index.html</a> et <a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/main.js">main.js</a> — les exports restent les mêmes.</p> +Dans cet exemple, nous avons uniquement modifié [index.html](https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/index.html) et [main.js](https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/main.js) — les exports restent les mêmes. -<p>Dans <code>main.js</code>, on récupère une référence à chaque bouton en utilisant <code><a href="/fr/docs/Web/API/Document/querySelector">document.querySelector()</a></code>. Par exemple :</p> +Dans `main.js`, on récupère une référence à chaque bouton en utilisant [`document.querySelector()`](/fr/docs/Web/API/Document/querySelector). Par exemple : -<pre class="brush: js">let squareBtn = document.querySelector('.square');</pre> +```js +let squareBtn = document.querySelector('.square'); +``` -<p>Ensuite, on attache un gestionnaire d'évènement à chaque bouton afin qu'on puisse appuyer dessus. Le module correspondant est alors chargé dynamiquement et utilisé pour dessiner la forme :</p> +Ensuite, on attache un gestionnaire d'évènement à chaque bouton afin qu'on puisse appuyer dessus. Le module correspondant est alors chargé dynamiquement et utilisé pour dessiner la forme : -<pre class="brush: js">squareBtn.addEventListener('click', () => { - import('./modules/square.mjs').then((Module) => { +```js +squareBtn.addEventListener('click', () => { + import('./modules/square.mjs').then((Module) => { let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); square1.draw(); square1.reportArea(); square1.reportPerimeter(); }) -});</pre> +}); +``` -<p>On voit ici que, parce que la promesse renvoie un objet module à la résolution, la classe est une propriété de cet objet et qu'il faut ajouter cet espace de nom devant le constructeur exporté pour l'utiliser. Autrement dit, avec cette méthode, on doit ajouter <code>Module.</code> devant <code>Square</code> (plutôt que d'utiliser uniquement <code>Square</code>).</p> +On voit ici que, parce que la promesse renvoie un objet module à la résolution, la classe est une propriété de cet objet et qu'il faut ajouter cet espace de nom devant le constructeur exporté pour l'utiliser. Autrement dit, avec cette méthode, on doit ajouter `Module.` devant `Square` (plutôt que d'utiliser uniquement `Square`). -<h2 id="Diagnostiquer_les_problèmes_avec_les_modules">Diagnostiquer les problèmes avec les modules</h2> +## Diagnostiquer les problèmes avec les modules -<p>Voici quelques notes pour aider à comprendre et à diagnostiquer les problèmes parfois rencontrés avec les modules. N'hésitez pas à ajouter vos conseils à cette liste si vous en avez.</p> +Voici quelques notes pour aider à comprendre et à diagnostiquer les problèmes parfois rencontrés avec les modules. N'hésitez pas à ajouter vos conseils à cette liste si vous en avez. -<ul> - <li>Comme indiqué ci-avant, les fichiers <code>.mjs</code> doivent être chargés avec le type MIME <code>javascript/esm</code> (ou avec un autre type MIME compatible JavaScript tel que <code>application/javascript</code>), sinon on aura une erreur lors de la vérification du type MIME.</li> - <li>Si on essaie de charger des fichiers HTML en local à l'aide d'une URL <code>file://</code>, on aura des erreurs CORS relatives à la sécurité. Pour tester les modules, on doit donc mettre en place un serveur (ou, par exemple, utiliser les pages GitHub).</li> - <li><code>.mjs</code> est une extension relativement récente et certains systèmes d'exploitation ne la reconnaîtront pas et/ou tenteront de la remplacer (ex. macOS pourra silencieusement ajouter un <code>.js</code> après le <code>.mjs</code>). Dans ce cas, afficher les extensions de tous les fichiers par défaut pourra permettre de vérifier.</li> -</ul> +- Comme indiqué ci-avant, les fichiers `.mjs` doivent être chargés avec le type MIME `javascript/esm` (ou avec un autre type MIME compatible JavaScript tel que `application/javascript`), sinon on aura une erreur lors de la vérification du type MIME. +- Si on essaie de charger des fichiers HTML en local à l'aide d'une URL `file://`, on aura des erreurs CORS relatives à la sécurité. Pour tester les modules, on doit donc mettre en place un serveur (ou, par exemple, utiliser les pages GitHub). +- `.mjs` est une extension relativement récente et certains systèmes d'exploitation ne la reconnaîtront pas et/ou tenteront de la remplacer (ex. macOS pourra silencieusement ajouter un `.js` après le `.mjs`). Dans ce cas, afficher les extensions de tous les fichiers par défaut pourra permettre de vérifier. -<h2 id="Voir_aussi">Voir aussi</h2> +## Voir aussi -<ul> - <li><a href="https://tech.mozfr.org/post/2018/04/06/Une-plongee-illustree-dans-les-modules-ECMAScript">Une plongée illustrée dans les modules ECMAScript</a></li> - <li><a href="https://tech.mozfr.org/post/2015/08/21/ES6-en-details-%3A-les-modules">ES6 en détails : les modules</a></li> - <li><a href="https://developers.google.com/web/fundamentals/primers/modules#mjs">Utiliser les modules JavaScript sur le Web</a>, un article par Addy Osmani et Mathias Bynens (en anglais)</li> - <li>Livre de Axel Rauschmayer (en anglais) : <a href="http://exploringjs.com/es6/ch_modules.html">Exploring JS: Modules</a></li> -</ul> +- [Une plongée illustrée dans les modules ECMAScript](https://tech.mozfr.org/post/2018/04/06/Une-plongee-illustree-dans-les-modules-ECMAScript) +- [ES6 en détails : les modules](https://tech.mozfr.org/post/2015/08/21/ES6-en-details-%3A-les-modules) +- [Utiliser les modules JavaScript sur le Web](https://developers.google.com/web/fundamentals/primers/modules#mjs), un article par Addy Osmani et Mathias Bynens (en anglais) +- Livre de Axel Rauschmayer (en anglais) : [Exploring JS: Modules](http://exploringjs.com/es6/ch_modules.html) -<p>{{Previous("Web/JavaScript/Guide/Métaprogrammation")}}</p> +{{Previous("Web/JavaScript/Guide/Métaprogrammation")}} |