Import et module JavaScript simplifiés
Comment importer des modules JS de la façon la plus simple possible.
Les modules sont des bibliothèques d'objets, variables et fonctions à partager entre applications JavaScript, selon des règles d'encapsulation strictes. Dans cet article on se limitera à de courts exemples JavaScript.
- Les modules ne fonctionnent que sur le Web et non pas quand on affiche la page HTML sur le poste local.
- Le contenu est accessible seulement dans le script qui charge le module et pas dans le scope global à la page. Le scope est limité au module comme le scope d'un bloc ou d'une fonction leur est limité.
- Les fichiers de modules sont indépendants. On ne peut appeler une fonction de l'un dans un autre. Mais cela est possible dans le script qui les importe.
Un module se charge aussi uniquement dans la section <head> de la page, de sorte que le traitement soit effectué avant l'affichage. Le script qui charge et utilise le module à le format suivant
<script type="module">
... importation et utilisation
</script>
Sans l'attribut "module", l'importation ne sera pas réalisée.
Les variables qui sont assignées dans le script sont visibles seulement dans celui-ci. On ne peut les utiliser dans un autre script même s'il a l'attribut "module".
On utilisera les résultats des traitements dans la page en passant par le DOM.
Import et Export
Les objets définis dans le modules doivent être marqués comme exportables avec la commande export.
Exemple:
export var hello = function(who) { return "Hello " + who + "!"; }
Nous placerons ce code dans le fichier modulehello.js
La commande import charge le fichier dans une page web en créant une référence aux objets du module, par exemple:
import { hello } from './modulehello.js';
La fonction hello définie dans le module devient ainsi visible dans le script de la page.
On pourrait créer une référence avec un nom différent pour éviter une collision de noms:
import { hello as hellowho } from './modulehello.js';
hello est le nom de la fonction dans le module et hellowho son nom dans la page qui l'utilise.
Utilisation du contenu du module
Le contenu du module devient disponible dans la page après importation et on peut utiliser la fonction qui y est définie. Le résultat sera présenté dans la page avec les moyens d'accès du DOM.
On peut par exemple ajouter un conteneur dans la page avec l'identifiant hello:
<div id="hello"></div>
On y place le résultat du traitement qui consiste à ajouter un nom à la chaîne "hello":
var h = document.getElementById('hello');
h.innerHTML = hello("Vous")
Cela fait apparaître dans la page:
Hello Vous!
Communiquer avec la page
Comment conserver les résultats dans la page sans les afficher immédiatement?
On utilisera un exemple un peu plus élaboré avec deux fonctions et une variable dans le module et que l'on mettra dans le fichier modulemath.js.
export var fnadd = function(a, b) {
return a + b;
}
export var fnsub = function(a, b) {
return a - b;
}
export var value = 1000;
On référence tous ces éléments dans la page avec une seule commande:
import { fnadd, fnsub, value as val } from './modulemath.js';
Les retours de ces fonctions et la valeur de la variable ne sont visibles que dans le script qui importe le module et qui a l'attribut "module". Pour pouvoir les utiliser dans un autre script de la page, on peut se servir de localStorage ou sessionStorage.
localStorage.radd = fnadd(5,5);
localStorage.rsub = fnsub(100,5);
localStorage.val = val;
LocalStorage est dans le scope global. N'importe quel script dans la page peut y lire des données et les présenter dans la page.
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>
Puis:
var r1 = document.getElementById('result1');
r1.innerHTML = localStorage.radd
var r2 = document.getElementById('result2');
r2.innerHTML = localStorage.rsub
var r3 = document.getElementById('result3');
r3.innerHTML = localStorage.val
Simplifications
On peut simplifier l'exportation avec une commande unique.
var fnadd = function(a, b) {
return a + b;
}
var fnsub = function(a, b) {
return a - b;
}
var value = 1000;
export { fnadd, fnsub, value }
On peut aussi simplifier l'importation avec la création d'un espace de nom.
import * as mmath from './modulemath.js';
Après quoi on utilisera les fonctions avec le nom accolé à l'espace:
mmath.fnadd(10, 20)
mmath.fnsub(100, 1)
Exemple complet
<!DOCTYPE html>
<head>
<script type="module">
import { fnadd, fnsub, value as val } from './modulemath.js';
import { hello } from './modulehello.js';
var r1 = document.getElementById('result1');
r1.innerHTML = "fnadd: " + fnadd(5,5);
var r2 = document.getElementById('result2');
r2.innerHTML = "fnsub: " + fnsub(100,5);
var v = document.getElementById('value');
v.innerHTML = val
var h = document.getElementById('hello');
h.innerHTML = hello("Vous")
import * as mmath from './modulemath.js';
localStorage.radd = mmath.fnadd(5,5);
localStorage.rsub = mmath.fnsub(100,5);
localStorage.val = mmath.value;
document.getElementById('result4').innerHTML = localStorage.radd;
document.getElementById('result5').innerHTML = localStorage.rsub;
document.getElementById('result6').innerHTML = localStorage.val;
</script>
<title>Import Demo</title>
</head>
<body>
<h1>Import Demo</h1>
<div id="result1"></div>
<div id="result2"></div>
<div id="value"></div>
<div id="hello"></div>
<div id="result3"></div>
<div id="result4"></div>
<div id="result5"></div>
<div id="result6"></div>
</body>
</html>
Voir aussi
- Fetch vs. Ajax. Deux moyens de charger dynamiquement des resources dans une page.
Lien externe
- IndexedDB. Les limitations des modules, notamment l'encapsulation, disparaissent avec IndexedDB qui permet de placer des scripts dans une base de donnée et les utiliser dans différentes pages au besoin.