Ce face Module ES (import) și CommonJS (require)
Node.js are două feluri de module. CommonJS este sistemul vechi: încarci cu require() și exporți prin module.exports. Modulele ES sunt standardul JavaScript: import și export, la fel ca în browser. Proiectele noi folosesc module ES.
Node.js decide tipul fișierului după extensie: .mjs = modul ES, .cjs = CommonJS. Pentru .js contează câmpul "type" din package.json ("module" sau "commonjs"); fără el, Node.js detectează singur după sintaxă. Modulele de bază se scriu cu prefixul node: (node:fs), ca să nu fie confundate cu pachete din npm.
Diferențe practice: în modulele ES căile relative au nevoie de extensie (./utile.mjs), await merge la nivelul de sus, iar __dirname și require nu există (folosești import.meta.dirname și createRequire). Un modul ES poate importa CommonJS (primește module.exports ca export implicit), iar require() poate încărca un modul ES fără await la nivelul de sus.
Exemple
Exemplul 1: Import dintr-un modul CommonJS
Scriem un modul .cjs și îl importăm dintr-un modul ES. Obiectul module.exports devine exportul implicit; Node.js încearcă să ofere și exporturi cu nume.
import { writeFileSync } from "node:fs";
writeFileSync("preturi.cjs", `
const TVA = 0.21;
function cuTva(pret) { return Math.round(pret * (1 + TVA) * 100) / 100; }
module.exports = { TVA, cuTva };
`);
const preturi = await import("./preturi.cjs");
console.log(preturi.default.cuTva(100));
const { cuTva, TVA } = await import("./preturi.cjs");
console.log(cuTva(49.99), TVA);
Rezultat
121
60.49 0.21
Exemplul 2: require într-un modul ES, cu createRequire
Uneori ai nevoie de require și într-un modul ES (de exemplu pentru un fișier JSON citit sincron). createRequire îl creează.
import { createRequire } from "node:module";
import { writeFileSync } from "node:fs";
writeFileSync("orase.json", JSON.stringify(["Iași", "Cluj", "Timișoara"]));
const require = createRequire(import.meta.url);
const orase = require("./orase.json");
console.log(orase.length, orase[0]);
console.log(typeof globalThis.require);
Rezultat
3 Iași
undefined
Exemplul 3: require încarcă un modul ES
Un fișier CommonJS poate folosi require() pentru un modul ES (fără await la nivelul de sus). Primește obiectul cu toate exporturile.
import { writeFileSync } from "node:fs";
import { createRequire } from "node:module";
writeFileSync("formatare.mjs", `
export const moneda = "lei";
export default function pret(suma) { return suma.toFixed(2) + " " + moneda; }
`);
writeFileSync("app.cjs", `
const formatare = require("./formatare.mjs");
console.log(formatare.default(12.5), formatare.moneda);
`);
createRequire(import.meta.url)("./app.cjs");
Rezultat
12.50 lei lei
Greșeli frecvente
- Scrii
import { f } from "./utile"fără extensie: în modulele ES primeștiERR_MODULE_NOT_FOUND. Scrie calea completă,./utile.mjssau./utile.js. - Folosești
__dirnameîntr-un modul ES și primeștiReferenceError: __dirname is not defined. Înlocuiește-l cuimport.meta.dirname. - Amesteci
module.exportsșiexportîn același fișier: un fișier este fie CommonJS, fie modul ES. Alege una dintre variante. - Încarci cu
require()un modul ES care areawaitla nivelul de sus: primeștiERR_REQUIRE_ASYNC_MODULE. Foloseșteawait import().
Comenzi înrudite
import.meta.dirname / filename: Calea directorului și a fișierului modulului curent: înlocuitorii pentru __dirname și __filename în module ES.package.json: Fișierul de configurare al unui proiect Node.js: nume, versiune, tipul modulelor, scripturi, dependențe și versiunea Node cerută.package.json "exports" și "imports": Alege ce fișiere ale unui pachet pot fi importate din afară (exports) și definește alias-uri interne cu # (imports).node script.js: Rulează un fișier JavaScript în terminal sau o bucată de cod dată direct în comandă (-e, -p).