intermediate

Module resolution

Разрешайте relative paths, bare specifiers, node_modules traversal, built-ins, conditions, TypeScript paths и bundler gaps.

Node по-разному разрешает спецификаторы в ESM и CommonJS, но модель едина: относительные пути (`./`), bare (`lodash`), встроенные (`node:fs`).

Алгоритм bare (упрощённо):

  1. Префикс `node:` или core — встроенный модуль.
  2. Подъём по `node_modules` от файла импорта.
  3. Чтение `exports` / `main` / `module` в `package.json`.
  4. Расширения `.js`, `.json`, `.node`; в ESM часто нужно полное расширение.
					import fs from 'node:fs';
import { z } from 'zod';
import helper from './helper.js';
				

Алиасы `paths` в TypeScript — на этапе компиляции; Node их не видит без loader/bundler. Тот же разрыв между Jest/Vitest и production.

На интервью: как `import 'express'` находит файл; hoisting в `node_modules`; отличия bundler и Node.

Типовые ошибки: нет `.js` в ESM; TS paths в Node без tsx; глубокие импорты во внутренности пакета.

Компромисс — между простотой, производительностью, безопасностью и эксплуатацией: назовите, что оптимизировали и какую цену приняли.

Чеклист:

  • Префикс `node:` для built-in.
  • Подъём по `node_modules`.
  • Согласуйте runtime, bundler и тесты.
  • Не используйте неподдерживаемые deep imports.