From bf8e099b9c8b3c60d60b3712b4fc97b052c39887 Mon Sep 17 00:00:00 2001 From: julieng Date: Tue, 3 Aug 2021 08:03:23 +0200 Subject: convert content to md --- files/fr/web/javascript/guide/modules/index.md | 467 ++++++++++++++----------- 1 file changed, 253 insertions(+), 214 deletions(-) (limited to 'files/fr/web/javascript/guide/modules') 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 --- -
{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Métaprogrammation")}}
+{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Métaprogrammation")}} -

Ce guide aborde l'ensemble des notions vous permettant d'utiliser la syntaxe des modules en JavaScript.

+Ce guide aborde l'ensemble des notions vous permettant d'utiliser la syntaxe des modules en JavaScript. -

Un peu de contexte

+## Un peu de contexte -

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 par exemple).

+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). -

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, AMD, RequireJS ou, plus récemment, Webpack et Babel).

+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/)). -

Bonne nouvelle, les navigateurs ont également commencé à prendre en charge ces fonctionnalités nativement. C'est le sujet de ce guide.

+Bonne nouvelle, les navigateurs ont également commencé à prendre en charge ces fonctionnalités nativement. C'est le sujet de ce guide. -

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.

+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. -

Compatibilité des navigateurs

+## Compatibilité des navigateurs -

L'utilisation des modules natifs JavaScript repose sur les instructions import and export dont vous pouvez voir l'état de la compatibilité ici :

+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 : -

import

+### `import` -

{{Compat("javascript.statements.import")}}

+{{Compat("javascript.statements.import")}} -

export

+### `export` -

{{Compat("javascript.statements.export")}}

+{{Compat("javascript.statements.export")}} -

Commençons par un exemple

+## Commençons par un exemple -

Pour illustrer le fonctionnement des modules, nous avons créé un ensemble d'exemples disponibles sur GitHub. 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.

+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. -

Ces opérations sont assez simples mais nous les avons choisies pour nous concentrer plutôt sur le fonctionnement des modules.

+Ces opérations sont assez simples mais nous les avons choisies pour nous concentrer plutôt sur le fonctionnement des modules. -
-

Note : Si vous souhaitez télécharger les exemples et les exécuter en local, vous devrez utiliser un serveur web local.

-
+> **Note :** Si vous souhaitez télécharger les exemples et les exécuter en local, vous devrez utiliser un serveur web local. -

Structure de l'exemple

+## Structure de l'exemple -

Dans notre premier exemple (cf. basic-modules), nous avons l'arborescence de fichier suivante :

+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 : -
index.html
-main.mjs
-modules/
-    canvas.mjs
-    square.mjs
+ index.html + main.mjs + modules/ + canvas.mjs + square.mjs -
-

Note : Tous les exemples de ce guide suivent la même structure.

-
+> **Note :** Tous les exemples de ce guide suivent la même structure. -

Le répertoire dédié aux modules contient deux modules :

+Le répertoire dédié aux modules contient deux modules : - + - `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. -
-

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.

-
+- `square.mjs` : -

Exporter des fonctionnalités

+ - `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é. -

Pour commencer et afin d'utiliser les fonctionnalités d'un module, on devra les exporter. Pour cela, on utilisera l'instruction export.

+> **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). -

La méthode la plus simple consiste à placer cette instruction devant chaque valeur qu'on souhaite exporter, par exemple :

+## Exporter des fonctionnalités -
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
   };
-}
+} +``` -

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.

+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. -

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 :

+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 : -
export { name, draw, reportArea, reportPerimeter };
+```js +export { name, draw, reportArea, reportPerimeter }; +``` -

Importer des fonctionnalités

+## Importer des fonctionnalités -

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 :

+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 : -
import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs';
+```js +import { name, draw, reportArea, reportPerimeter } from './modules/square.mjs'; +``` -

On utilise ici l'instruction 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.

+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`. -

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.

+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. -

Ainsi :

+Ainsi : -
/js-examples/modules/basic-modules/modules/square.mjs
+ /js-examples/modules/basic-modules/modules/square.mjs -

devient :

+devient : -
./modules/square.mjs
+ ./modules/square.mjs -

Vous pouvez voir ces lignes dans main.mjs.

+Vous pouvez voir ces lignes dans [`main.mjs`](https://github.com/mdn/js-examples/blob/master/modules/basic-modules/main.js). -
-

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 !

-
+> **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 ! -

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 :

+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 : -
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);
-
+``` -

Charger le module via le document HTML

+## Charger le module via le document HTML -

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 ».

+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 ». -

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 :

+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 : -
<script type="module" src="main.mjs"></script>
+```js + +``` -

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".

+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_". -

Les instructions import et export ne peuvent être utilisées qu'à l'intérieur de modules et pas à l'intérieur de scripts « classiques ».

+Les instructions `import` et `export` ne peuvent être utilisées qu'à l'intérieur de modules et pas à l'intérieur de scripts « classiques ». -
-

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>.

-
+> **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 ``. -

Différences entre les modules et les scripts « classiques »

+## Différences entre les modules et les scripts « classiques » - +- 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 `