Skip to content

Мёртвые экспорты ​

devtoolz dead-exports находит именованные экспорты, которые нигде в проекте не импортируются.

bash
devtoolz dead-exports [paths...] [options]

Команда только читает код — ничего не удаляет и не переписывает, у неё нет --fix. Задача не в том, чтобы автоматически подчистить, а в том, чтобы показать, на что вообще стоит посмотреть, прежде чем удалять руками.

Реальный вывод — маленький пакет с точкой входа src/index.ts, ре-экспортирующей formatPrice и applyDiscount, где roundToNearestNickel объявлена рядом с formatPrice, но нигде не ре-экспортирована и не используется:

🧰 devtoolz — chores, automated

Scanned 4 files.

1 dead export found:
  src/pricing.ts:5  roundToNearestNickel

formatPrice не попадает в отчёт — она ре-экспортируется из публичной точки входа и, отдельно, реально используется в src/cart.ts. applyDiscount тоже не попадает — она ре-экспортируется из точки входа, и по умолчанию этого достаточно, чтобы не считаться мёртвой, даже если внутри репозитория её никто не вызывает.

Что считается «мёртвым» ​

Экспорт не попадает в отчёт, если выполняется любое из:

  • на него есть хотя бы один import где-то в просканированных файлах;
  • он реально достижим из публичной точки входа пакета — не только объявлен прямо в файле точки входа, но и ре-экспортирован через цепочку export { x } from './y'/export * from './y' любой глубины. Именованный ре-экспорт освобождает от подозрений только сам ре-экспортированный символ, а не весь файл, из которого он идёт — если рядом в том же файле объявлена вторая, не ре-экспортированная функция, она по-прежнему может оказаться мёртвой;
  • модуль импортируется целиком (import * as ns from './x') — тогда используемым считается вообще всё, что экспортирует ./x;
  • это тип, импортированный через import type — тоже считается использованием.

Публичные точки входа определяются автоматически по package.json's exports/main/module/bin, плюс src/index.ts/src/index.tsx, если он существует, даже без package.json. --entry добавляет дополнительные файлы к этому списку.

Workspace ​

pnpm/npm/yarn-воркспейс определяется автоматически (по pnpm-workspace.yaml либо workspaces в корневом package.json) — импорт вашего экспорта из соседнего пакета того же воркспейса не читается как мёртвый, даже если внутри текущего пакета на него никто не ссылается. --no-workspace отключает это и проверяет только сам просканированный код.

Опции ​

--strict ​

Проверять и публичные точки входа тоже, не только внутренние файлы — то, что ре-экспортируется наружу, но реально никем не используется даже вне репозитория (внешние потребители неизвестны инструменту, так что это осознанный компромисс, а не гарантия). На том же примере выше:

🧰 devtoolz

Scanned 4 files.

2 dead exports found:
  src/discounts.ts:1  applyDiscount
  src/pricing.ts:5    roundToNearestNickel

--entry <path> ​

Дополнительный файл публичной точки входа (можно указать несколько раз) — экспорты из него исключаются из отчёта так же, как и у автоопределённых точек входа.

--no-workspace ​

Не автоопределять pnpm/npm/yarn-воркспейс для резолва между пакетами.

--cwd <path> ​

Корень, от которого резолвятся относительные пути.

--ext <list> ​

Через запятую, какие расширения обрабатывать. По умолчанию: .ts,.tsx,.js,.jsx,.cjs,.mjs.

--ignore <glob> ​

Дополнительный паттерн игнорирования (повторяемый) поверх встроенных дефолтов. Файлы конфигурации сборки (*.config.ts/*.config.js/*.config.mjs/*.config.cjs) исключены из обхода по умолчанию всегда — их default-экспорт обычно подхватывается соответствующим инструментом по имени файла, а не через import где-то в репозитории, и иначе читался бы как мёртвый практически в каждом проекте.

--no-respect-gitignore ​

Не учитывать .gitignore проекта.

Пример:

bash
devtoolz dead-exports src                       # обычная проверка
devtoolz dead-exports src --strict               # и публичные точки входа тоже
devtoolz dead-exports src --entry src/testing.ts  # ещё одна точка входа, например testing-утилиты
devtoolz dead-exports . --no-workspace            # игнорировать соседние пакеты воркспейса