moduleResolution în TypeScript

Alege regulile după care tsc găsește fișierul din spatele unui import ("./calcul.js", "react", "@/utile").

Sintaxă
"compilerOptions": { "moduleResolution": "bundler" }

tsc --moduleResolution nodenext

Ce face moduleResolution

Când scrii import { cuTva } from "./calcul.js", tsc trebuie să găsească fișierul cu tipuri din spatele textului "./calcul.js". moduleResolution alege regulile: cum se tratează extensiile, dacă se citește câmpul exports din package.json, cum se caută în node_modules.

nodenext și node16 urmează exact regulile Node.js: în modulele ES, importurile relative trebuie să aibă extensie ("./calcul.js", chiar dacă fișierul sursă este calcul.ts). bundler (TypeScript 5.0) urmează regulile bundlerelor: citește exports, dar permite importuri fără extensie. node10 (fostul node) este algoritmul vechi din Node.js, fără exports; classic este cel mai vechi și nu caută în node_modules pentru importuri relative.

De obicei nu o scrii: este dedusă din module. Pentru nodenext este nodenext; pentru node16/node18/node20 este node16; pentru preserve este bundler; pentru commonjs este node10; pentru es2015/esnext este classic (deci la acestea scrie-o explicit, de obicei bundler).

Parametri

Parametru Descriere
nodenext / node16 Regulile Node.js: extensii obligatorii în modulele ES, exports/imports din package.json.
bundler Regulile bundlerelor (Vite, esbuild, webpack): exports da, extensii opționale. Merge cu module preserve sau esnext.
node10 (node) Algoritmul vechi din Node.js, fără exports. Pentru proiecte CommonJS vechi.
classic Algoritmul inițial al lui TypeScript. Nu îl alege în cod nou.

Exemple

Exemplul 1: Extensie lipsă cu nodenext

În modulele ES din Node.js, "./calcul" nu funcționează. tsc spune ce trebuie scris: "./calcul.js" (extensia fișierului generat, nu .ts). Același import fără extensie trece cu "module": "preserve" și "moduleResolution": "bundler".

// package.json
{ "type": "module" }

// tsconfig.json
{
  "compilerOptions": {
    "module": "nodenext",
    "noEmit": true
  }
}

// calcul.ts
export function cuTva(pret: number): number {
  return Math.round(pret * 1.19 * 100) / 100;
}

// index.ts
import { cuTva } from "./calcul";

console.log(cuTva(100));

Rezultat (tsc 5.9)

$ npx tsc
index.ts(1,23): error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './calcul.js'?

Exemplul 2: Cum a fost găsit fișierul

--traceResolution afișează pașii. Se vede că "./calcul.js" duce la calcul.ts: tsc scoate extensia .js și caută sursa TypeScript (rândurile despre bibliotecile standard au fost scoase).

// tsconfig.json
{
  "compilerOptions": {
    "module": "nodenext",
    "noEmit": true
  }
}

// index.ts
import { cuTva } from "./calcul.js";
console.log(cuTva(100));

Rezultat (tsc 5.9)

$ npx tsc --traceResolution
Found 'package.json' at '/proiect/package.json'.
File '/proiect/package.json' exists according to earlier cached lookups.
======== Resolving module './calcul.js' from '/proiect/index.ts'. ========
Module resolution kind is not specified, using 'NodeNext'.
Resolving in ESM mode with conditions 'import', 'types', 'node'.
Loading module as file / folder, candidate module location '/proiect/calcul.js', target file types: TypeScript, JavaScript, Declaration, JSON.
File name '/proiect/calcul.js' has a '.js' extension - stripping it.
File '/proiect/calcul.ts' exists - use it as a name resolution result.
======== Module name './calcul.js' was successfully resolved to '/proiect/calcul.ts'. ========

Greșeli frecvente

  • Să scrii importul cu .ts ("./calcul.ts") ca să scapi de eroare. Fără allowImportingTsExtensions sau rewriteRelativeImportExtensions, tsc dă eroarea TS5097.
  • Să combini "module": "esnext" cu rezolvarea implicită și să nu găsești pachetele din node_modules. Pentru esnext, implicit este classic; scrie "moduleResolution": "bundler".

Comenzi înrudite

  • module: Alege formatul de module din JavaScript-ul generat (ES modules, CommonJS) și regulile de import pe care le verifică tsc.
  • paths: Definește prescurtări pentru importuri (de exemplu „@/utile/calcul” pentru ./src/utile/calcul) folosite la verificarea tipurilor.
  • resolvePackageJsonExports: Folosește câmpurile exports și imports din package.json la rezolvarea importurilor de pachete și a celor cu #.
  • traceResolution: Afișează pas cu pas cum găsește tsc fișierul din spatele fiecărui import; util la erori TS2307.
  • allowImportingTsExtensions: Permite importuri cu extensia .ts („./calcul.ts”), când codul este rulat direct de Node.js, Deno, Bun sau de un bundler.