Plugins
This page describes why Knip uses plugins and the difference between config
and entry
files.
Knip has an extensive and growing list of built-in plugins. Currently it’s not possible to add custom plugins, but feel free to request a plugin or even write a plugin so others can benefit too.
Enabled
Plugins are enabled if the related package is listed in the list of dependencies
in package.json
. For instance, if astro
is listed in dependencies
or
devDependencies
, then the Astro plugin is enabled.
Configuration files
Knip uses entry files as starting points to scan your source code and
resolve other internal files and external dependencies. The dependency graph can
be statically resolved through the require
and import
statements in those
source files. However, configuration files reference external dependencies in
various ways. Knip uses a plugin for each tool to parse configuration files and
find those dependencies.
In this example we look at Knip’s ESLint plugin. The default config
file
patterns include .eslintrc.json
. Here’s a minimal example:
Configuration files like this don’t import
or require
anything, but they do
require the referenced dependencies to be installed.
In this case, the plugin will return the eslint-config-airbnb
,
eslint-config-prettier
and @typescript-eslint/eslint-plugin
dependencies, so
Knip knows they should be listed in package.json
.
Some tools allow configuration to be stored in package.json
, that’s why some
of the relevant plugins contain package.json
in the list of config
files.
Entry files
Many plugins have default entry
files configured. When the plugin is enabled,
Knip will add entry files as configured by the plugin to resolve used files and
dependencies.
For example, if next
is listed as a dependency in package.json
, the Next.js
plugin will automatically add multiple patterns as entry files, such as
pages/**/*.{js,jsx,ts,tsx}
. If vitest
is listed, the Vitest plugin adds
**/*.{test,test-d,spec}.ts
as entry file patterns. Most plugins have entry
files configured, so you don’t have to.
It’s mostly plugins for meta frameworks and test runners that have entry
files
configured.
For example, let’s say your Playwright configuration contains the following:
The Playwright plugin will read this configuration file and return those entry
patterns (integration/**/*-test.ts
). Knip will then not use the default entry
patterns.
You can still override this behavior in your Knip configuration:
This should not be necessary though. Please consider opening a pull request or a bug report if any plugin is not behaving as expected.
Entry files from config files
Entry files are part of plugin configuration (as described in the previous section). Yet plugins can also return additional entry files after parsing configuration files. Below are some examples of configuration files parsed by plugins to return additional entry files. The goal of these examples is to give you an idea about the various ways Knip and its plugins try to find entry files so you don’t need to configure them yourself.
Angular
The Angular plugin parses the Angular configuration file. Here’s a fragment:
This will result in src/main.ts
being added as an entry file (and
@angular-devkit/build-angular
as a referenced dependency).
GitHub Actions
This plugin parses workflow YAML files. This fragment contains three run
scripts:
From these scripts, the scripts/build.js
and scripts/deploy.ts
files will be
added as entry files by the GitHub Actions plugin.
Read more about this in Script Parser.
webpack
Let’s take a look at this example webpack configuration file:
The webpack plugin will parse this and add ./src/app.ts
and ./src/vendor.ts
as entry files. It will also add base64-inline-loader
as a referenced
dependency.
Bringing it all together
Sometimes a configuration file is a JavaScript or TypeScript file that imports dependencies, but also contains configuration that needs to be parsed by a plugin to find additional dependencies.
Let’s take a look at this example Vite configuration file:
This file imports vite
and @vitejs/plugin-react
directly, but also
indirectly references the happy-dom
and @vitest/coverage-c8
packages.
The Vite plugin of Knip will dynamically load this configuration file and
parse the exported configuration. But it’s not aware of the vite
and
@vitejs/plugin-react
imports. This is why such config
files are also
automatically added as entry
files for Knip to statically resolve the
import
and require
statements.
Additionally, ./setup-tests.ts
will be added as an entry
file.
ISC License © 2024 Lars Kappert