👁️ 132 vues

CommonJS vs ECMAScript (ESM)

📘 Comprendre les fichiers .mjs dans Node.js

🧩 1. .mjs, c’est quoi ?

Un fichier .mjs est un module ECMAScript — c’est-à-dire un fichier JavaScript utilisant la syntaxe moderne des imports et exports, comme celle des navigateurs.

// fichier.mjs
import express from "express";
import { maFonction } from "./utils.mjs";

export const app = express();

👉 L’extension .mjs indique à Node.js que le fichier doit être interprété en mode ESM (ECMAScript Module)
et non en CommonJS (le système historique de Node).


⚙️ 2. Contexte historique

Avant 2020, Node.js utilisait uniquement le système CommonJS :

const express = require("express");
module.exports = app;

Mais depuis Node.js 14+, il supporte aussi les modules ECMAScript (mêmes modules que les navigateurs).

Pour éviter toute ambiguïté, Node a introduit une distinction stricte entre :

  • .js (fichiers interprétés comme CommonJS par défaut)
  • .mjs (fichiers interprétés comme modules ECMAScript)

⚙️ 3. Les deux systèmes de modules

Aspect CommonJS (.js) ESM (.mjs ou type: "module")
Importation const X = require("x") import X from "x"
Exportation module.exports = X export default X
Chargement Synchrone Asynchrone
Scope Global par fichier Strict (par module)
Compatibilité historique ✅ Node.js classique ✅ Node 14+
Syntaxe moderne ❌ Non ✅ Oui

🧠 4. Exemple comparatif

🟠 CommonJS (.js)

// utils.js
const sum = (a, b) => a + b;
module.exports = { sum };

// app.js
const { sum } = require("./utils.js");
console.log(sum(2, 3));

🔵 ECMAScript (.mjs)

// utils.mjs
export function sum(a, b) {
  return a + b;
}

// app.mjs
import { sum } from "./utils.mjs";
console.log(sum(2, 3));

🧩 5. Et si je veux rester en .js ?

Tu peux utiliser la syntaxe import/export sans passer en .mjs
en ajoutant ce paramètre dans ton package.json :

{
  "type": "module"
}

➡️ Dans ce cas, tous les fichiers .js du projet sont interprétés comme des modules ESM.
Tu n’as donc plus besoin de .mjs.

⚠️ Mais attention :

  • Tu ne pourras plus utiliser require() ni module.exports directement.
  • Tu devras tout passer en import/export.

🧱 6. Quand utiliser .mjs plutôt que .js ?

Situation Recommandation
Petit projet Node classique (Express, Mongo, etc.) ✅ Reste en .js (CommonJS)
Projet moderne, TypeScript, ou compatible navigateur ✅ Utilise .mjs ou "type": "module"
Tu veux mélanger les deux systèmes ⚠️ Possible mais à éviter
Librairie NPM moderne à publier .mjs recommandé pour compatibilité ESM

🧩 7. Mélanger CommonJS et ESM (cas avancé)

Il est possible de mélanger les deux, mais c’est souvent source de confusion.

Exemple :

  • main.mjs (ESM) peut importer du CommonJS :
    import pkg from "./legacy.js";
  • legacy.js (CommonJS) peut importer un ESM avec import() dynamique :
    const module = await import("./modern.mjs");

Mais cela complique la maintenance : le mieux est de choisir un seul style.


✅ 8. En résumé

Élément .js (CommonJS) .mjs (ESM)
Import require() import
Export module.exports export
Système Ancien (Node) Standard ECMAScript
Compatibilité Universelle Moderne
Recommandé en 2025 ⚙️ pour rétrocompatibilité 🟢 pour les projets modernes

💡 En clair :

  • .js = modules CommonJS (require, module.exports)
  • .mjs = modules ECMAScript (import, export)
  • Tu peux aussi garder .js et déclarer "type": "module" dans ton package.json si tu veux la syntaxe moderne partout.

Il n'y a actuellement aucun commentaire, alors soyez le premier !