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 (упрощённо):
- Префикс `node:` или core — встроенный модуль.
- Подъём по `node_modules` от файла импорта.
- Чтение `exports` / `main` / `module` в `package.json`.
- Расширения `.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.