import.meta.resolve()
=====================

**`import.meta.resolve()`** est une fonction native, définie sur l'objet `import.meta` d'un module JavaScript qui résout un spécificateur de module en une URL, en utilisant l'URL du module courant comme base.

Syntaxe
-------


```js
import.meta.resolve(nomModule)
```

### Paramètres

`nomModule`

Une chaîne de caractères indiquant un module qui peut être importé. Il peut s'agir d'un chemin relatif (comme `"./lib/helper.js"`), d'un nom seul (par exemple `"mon-module"`), ou d'une URL absolue (telle que `"https://example.com/lib/helper.js"`).

### Valeur de retour

Cette fonction renvoie une chaîne de caractères correspondant au chemin qui serait importé si l'argument avait été passé à `import()`.

Description
-----------

`import.meta.resolve()` permet à un script d'accéder à l'algorithme de *résolution des spécificateurs de modules* pour un nom donné :


```js
// Script situé à https://example.com/main.js

const helperPath = import.meta.resolve("./lib/helper.js");
console.log(helperPath); // "https://example.com/lib/helper.js"
```


On notera que `import.meta.resolve()` effectue uniquement la résolution, elle ne tente pas de chargement ou d'import du chemin obtenu (l'explication de la spécification (en anglais) décrit le raisonnement pour ce comportement). Aussi, la valeur de retour sera la même *qu'un fichier existe ou non à l'emplacement indiqué par le chemin obtenu et quel que soit le contenu de cet éventuel fichier (du code valide ou non pour un module)*.

Cette fonction est différente de l'opérateur d'import dynamique. Bien qu'ils acceptent tous les deux un spécificateur de module comme premier argument, `import.meta.resolve()` renvoie uniquement le chemin qui *serait importé* sans tenter d'accéder à ce chemin. Autrement dit, les deux approches suivantes seront équivalentes :


```js
// Première approche
console.log(await import("./lib/helper.js"));

// Deuxième approche
const chemin = import.meta.resolve("./lib/helper.js");
console.log(await import(chemin));
```


Toutefois, si `"./lib/helper.js"` ne peut pas être importé correctement, la seconde approche déclenchera une erreur au moment de tenter l'import sur la deuxième ligne.

### Noms de modules seuls

Il est possible de passer un nom de module seul (*bare module name*) à cette fonction, tant qu'une résolution est bien définie pour ce nom. On pourra par exemple utiliser une carte d'import dans un navigateur :


```html
<!-- index.html -->
<script type="importmap">
 {
 "imports": {
 "mon-module": "./modules/mon-module/index.js"
 }
 }
</script>

<script type="module">
 const cheminModule = import.meta.resolve("mon-module");
 console.log(cheminModule);
</script>
```


Là encore, ce fragment de code ne déclenchera pas d'import pour `cheminModule` (la carte ne déclenche pas d'import non plus). L'URL fournie par la résolution sera affichée dans la console, que `./modules/mon-module/index.js` existe ou non.

### Comparaison avec `new URL()`

Le constructeur `URL()` accepte un deuxième argument qui fournit une URL de base. Lorsque le premier argument est un chemin relatif et que l'URL de base correspond à `import.meta.url`, l'effet sera similaire à `import.meta.resolve()`.


```js
const helperPath = new URL("./lib/helper.js", import.meta.url).href;
console.log(helperPath);
```


Cela peut aider comme remplacement lorsqu'il s'agit de cibler les anciens navigateurs. Toutefois, on notera quelques différences :

* `import.meta.resolve()` renvoie une chaîne de caractères tandis que `new URL()` renvoie un objet `URL`. Il est possible d'utiliser `href` (en-US) ou `toString()` sur l'objet `URL` pour passer à une chaîne de caractères, mais le résultat pourra être différent selon l'environnement JavaScript ou si on utilise des outils comme des empaqueteurs de code pour de l'analyse statique.
* `import.meta.resolve()` prendra en compte les configurations de résolution supplémentaires comme la résolution de noms seuls à l'aide de cartes d'import (voir ci-avant). `new URL()` ne prendra pas en compte les cartes d'import et considèrera les noms seuls comme des chemins relatifs (par exemple `new URL("mon-module", import.meta.url)` sera équivalent à `new URL("./mon-module", import.meta.url)`).

Certains outils reconnaîtront `new URL("./lib/helper.js", import.meta.url).href` comme une dépendance à `"./lib/helper.js"` (semblable à un import) et prendront cela en compte pour l'empaquetage, la réécriture des imports pour les fichiers déplacés, les fonctionnalités d'inspection des sources, etc. Toutefois `import.meta.resolve()` est moins ambigu et conçu spécifiquement pour indiquer une résolution de chemin de module. Aussi, mieux vaudra utiliser `import.meta.resolve(nomModule)` plutôt que `new URL(nomModule, import.meta.url)` pour ces cas d'usage.

### Ne fait pas partie d'ECMAScript

`import.meta.resolve()` n'est pas spécifiée ou documentée au sein de la spécification ECMAScript pour les modules JavaScript. La spécification définit l'objet `import.meta` et délègue la définition de ses propriétés aux environnements hôtes. Le standard WHATWG HTML reprend donc là où s'arrête le standard ECMAScript et définit `import.meta.resolve()` avec la résolution de spécificateur de module.

Cela signifie que `import.meta.resolve()` ne fait pas nécessairement partie de toutes les implémentations conformes de JavaScript. Toutefois, `import.meta.resolve()` peut également faire partie d'environnements qui ne sont pas des navigateurs :

* Deno implémente une compatibilité avec le comportement des navigateurs.
* Node.js expose une implémentation disponible avec l'option `--experimental-import-meta-resolve` et qui renvoie une promesse (`Promise`) plutôt qu'une chaîne de caractères. Cela pourra éventuellement changer pour correspondre au comportement des navigateurs.
Exemples
--------

### Résoudre un chemin pour le passer au constructeur `Worker()`

`import.meta.resolve()` s'avère particulièrement utile pour les API qui prennent comme argument un chemin d'un fichier de script, comme le constructeur `Worker()` :


```js
// main.js
const workerPath = import.meta.resolve("./worker.js");
const worker = new Worker(workerPath, { type: "module" });
worker.addEventListener("message", console.log);
```



```js
// worker.js
self.postMessage("coucou !");
```


Cette fonction peut aussi être utile pour le calcul des chemins d'autres *workers* (comme les *service workers* et les *workers* partagés). Toutefois, si vous utilisez un chemin relatif pour calculer l'URL d'un *service worker*, il faudra garder à l'esprit que le répertoire du chemin résolu détermine sa portée d'enregistrement par défaut (une portée différente pouvant être définie lors de l'enregistrement).

Spécifications
--------------

| Specification |
| --- |
| HTML Standard # hostgetimportmetaproperties |

Compatibilité des navigateurs
-----------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Voir aussi
----------

* L'instruction `import`
* L'opérateur `import()` pour les imports dynamiques
* `import.meta`