Back

Удаление неиспользуемых файлов и зависимостей с помощью Knip

Удаление неиспользуемых файлов и зависимостей с помощью Knip

Любой JavaScript- или TypeScript-проект со временем обрастает «мусором»: зависимость, установленная для быстрого эксперимента, утилитный файл, забытый после рефакторинга, экспортируемая функция, которую никто больше не импортирует. По отдельности это кажется безобидным. В совокупности же это замедляет сборку, раздувает node_modules, создаёт шум в системе безопасности и затрудняет навигацию по кодовой базе.

Традиционный подход — ручной аудит: поиск имён пакетов через grep, проверка ссылок на файлы, сверка package.json вручную. Это работает, но не масштабируется. Здесь на сцену выходит Knip.

Ключевые выводы

  • Неиспользуемые зависимости и мёртвый код увеличивают время сборки, раздувают бандлы и создают шум в вопросах безопасности и лицензирования.
  • Knip анализирует весь репозиторий как линтер уровня проекта, сообщая о неиспользуемых файлах, экспортах, зависимостях и неуказанных импортах.
  • Флаг --fix применяет автоматические очистки, а --allow-remove-files расширяет это до удаления неиспользуемых файлов.
  • Запуск Knip в CI помогает предотвратить накопление мёртвого кода и дополняет ESLint и ваш форматтер.

Почему стоит избавляться от неиспользуемых зависимостей и мёртвого кода

Неиспользуемые пакеты в package.json — это не просто косметический шум. Они:

  • Увеличивают время установки и занимают место в node_modules
  • Могут попасть в продакшен-бандлы, если ваш сборщик некорректно выполняет tree-shaking
  • Провоцируют ложные срабатывания в инструментах безопасности вроде Dependabot
  • Могут включать ограничительные лицензии, которые формально распространяются на ваш проект
  • Тянут за собой транзитивные зависимости с теми же проблемами

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

Чем Knip отличается от других инструментов

Инструменты вроде depcheck и ts-prune решали часть этой задачи, но оба проекта были архивированы в 2025 году. Knip появился как современная замена, объединяющая анализ зависимостей, экспортов и файлов в одном активно поддерживаемом инструменте.

Думайте о Knip как о линтере уровня проекта. Если ESLint проверяет отдельные файлы, то Knip анализирует весь репозиторий целиком: точки входа, графы импортов, экспорты и package.json вместе. Он сообщает о неиспользуемых файлах, неиспользуемых экспортах, неиспользуемых зависимостях и пакетах, которые импортируются, но отсутствуют в package.json.

Knip работает с npm, pnpm, Yarn и Bun, и для запуска требует Node.js 20.19+ или Bun.

Быстрый старт за пять минут

Инициализируйте Knip в своём проекте командой:

npm init @knip/config

Это создаст файл конфигурации knip.json с разумными значениями по умолчанию. Затем запустите анализ:

npx knip

Knip выводит отчёт, сгруппированный по типам проблем: неиспользуемые файлы, неиспользуемые экспорты, неиспользуемые зависимости и неуказанные зависимости. При первом запуске в старом проекте список может быть длинным — это ожидаемо.

Безопасное применение исправлений

После того как вы изучите отчёт и убедитесь в его корректности, Knip может применить автоматические исправления, которые легко проверить:

npx knip --fix

Это удаляет ключевые слова export у неиспользуемых экспортов, очищает package.json и обрабатывает реэкспорты, а также члены TypeScript enum. Чтобы также удалить неиспользуемые файлы:

npx knip --fix --allow-remove-files

Всегда проверяйте изменения в Git перед коммитом. Knip консервативен по своей природе, но автоисправление изменяет реальные файлы. Быстрый git diff перед staging — хорошая привычка.

Вы также можете нацеливаться на конкретные типы проблем, чтобы изменения оставались небольшими и удобными для проверки:

npx knip --fix-type dependencies
npx knip --fix-type exports,types

Когда Knip нужна небольшая помощь

Knip не идеальный «чёрный ящик». В нескольких ситуациях требуется ручная настройка:

  • Динамические импорты (import(someVariable)) невозможно разрешить статически
  • Соглашения фреймворков (файлы страниц Next.js, виртуальные модули Vite) могут требовать настройки плагина или правил игнорирования
  • Сгенерированные файлы обычно следует исключать из анализа
  • Монорепозитории работают «из коробки», но ссылки между воркспейсами иногда требуют явной конфигурации

Если вы видите ложные срабатывания, добавьте запись ignore или ignoreDependencies в knip.json, а не отключайте целые разделы анализа.

Превращаем очистку в привычку

Наиболее эффективное применение Knip — это не разовый аудит, а регулярные запуски. Добавьте его в CI-пайплайн рядом с линтером и проверкой типов:

npx knip --reporter compact

Чистый отчёт на каждом pull request помогает не давать мёртвому коду накапливаться с самого начала. Сочетайте Knip с ESLint (для неиспользуемых переменных внутри файлов) и любым удобным форматтером — и вы получите надёжный автоматизированный цикл обслуживания, поддерживающий ваши JavaScript- и TypeScript-проекты в порядке без ручного «детективного» труда.

Заключение

Knip превращает утомительную задачу поиска неиспользуемых файлов, экспортов и зависимостей в повторяемый автоматизированный шаг. Воспринимая очистку как часть регулярного рабочего процесса, а не как разовую «генеральную уборку», вы поддерживаете проект компактным, сборку быстрой, а поверхность зависимостей — минимальной. Начните с одного запуска npx knip, встройте результаты в CI и позвольте инструменту выполнить ту детективную работу, которую раньше вы делали вручную.

Часто задаваемые вопросы

Да, по умолчанию Knip только сообщает о проблемах и не вносит никаких изменений, пока вы не передадите флаг --fix. Сначала запустите его, чтобы изучить отчёт, затем применяйте исправления постепенно, используя --fix-type для работы с одной категорией за раз. Всегда проверяйте Git diff перед коммитом, особенно при использовании --allow-remove-files.

Knip объединяет функциональность обоих инструментов в одном активно поддерживаемом пакете. Depcheck сосредоточен на зависимостях, а ts-prune — на неиспользуемых TypeScript-экспортах, но Knip анализирует файлы, экспорты и зависимости вместе по всем воркспейсам, обеспечивая более точные результаты для современных проектов.

Ложные срабатывания обычно возникают из-за динамических импортов, соглашений фреймворков или сгенерированных файлов, которые Knip не может разрешить статически. Проверьте, существует ли плагин Knip для вашего фреймворка, затем добавьте записи ignore или ignoreDependencies в knip.json для оставшихся случаев. Избегайте отключения целых разделов анализа, чтобы сохранить покрытие.

Да, и именно там он приносит наибольшую пользу. Добавьте npx knip --reporter compact в свой CI-пайплайн, чтобы каждый pull request проверялся на появление нового мёртвого кода. В сочетании с ESLint и вашим форматтером это создаёт автоматизированный цикл обслуживания, помогающий предотвратить накопление неиспользуемых файлов и зависимостей между релизами.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay