Удаление неиспользуемых файлов и зависимостей с помощью 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 выводит отчёт, сгруппированный по типам проблем: неиспользуемые файлы, неиспользуемые экспорты, неиспользуемые зависимости и неуказанные зависимости. При первом запуске в старом проекте список может быть длинным — это ожидаемо.
Discover how at OpenReplay.com.
Безопасное применение исправлений
После того как вы изучите отчёт и убедитесь в его корректности, 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.