@knip/mcp 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/docs/blog/brief-history.md +30 -0
- package/docs/docs/blog/for-editors-and-agents.md +124 -0
- package/docs/docs/blog/knip-v3.mdx +88 -0
- package/docs/docs/blog/knip-v4.mdx +149 -0
- package/docs/docs/blog/knip-v5.mdx +190 -0
- package/docs/docs/blog/migration-to-v1.md +65 -0
- package/docs/docs/blog/release-notes-v2.md +46 -0
- package/docs/docs/blog/slim-down-to-speed-up.md +269 -0
- package/docs/docs/blog/state-of-knip.md +191 -0
- package/docs/docs/blog/two-years.mdx +107 -0
- package/docs/docs/explanations/comparison-and-migration.md +129 -0
- package/docs/docs/explanations/entry-files.md +70 -0
- package/docs/docs/explanations/plugins.md +318 -0
- package/docs/docs/explanations/why-use-knip.md +128 -0
- package/docs/docs/features/auto-fix.mdx +333 -0
- package/docs/docs/features/compilers.md +172 -0
- package/docs/docs/features/integrated-monorepos.md +52 -0
- package/docs/docs/features/monorepos-and-workspaces.md +134 -0
- package/docs/docs/features/production-mode.md +95 -0
- package/docs/docs/features/reporters.md +302 -0
- package/docs/docs/features/rules-and-filters.md +102 -0
- package/docs/docs/features/script-parser.md +156 -0
- package/docs/docs/features/source-mapping.md +100 -0
- package/docs/docs/guides/configuring-project-files.md +205 -0
- package/docs/docs/guides/contributing.md +24 -0
- package/docs/docs/guides/handling-issues.mdx +646 -0
- package/docs/docs/guides/issue-reproduction.md +94 -0
- package/docs/docs/guides/namespace-imports.md +125 -0
- package/docs/docs/guides/performance.md +97 -0
- package/docs/docs/guides/troubleshooting.md +136 -0
- package/docs/docs/guides/using-knip-in-ci.md +54 -0
- package/docs/docs/guides/working-with-commonjs.md +72 -0
- package/docs/docs/index.mdx +160 -0
- package/docs/docs/overview/configuration.md +104 -0
- package/docs/docs/overview/features.md +66 -0
- package/docs/docs/overview/getting-started.mdx +195 -0
- package/docs/docs/overview/screenshots-videos.md +42 -0
- package/docs/docs/playground.mdx +38 -0
- package/docs/docs/reference/cli.md +485 -0
- package/docs/docs/reference/configuration.md +413 -0
- package/docs/docs/reference/dynamic-configuration.mdx +72 -0
- package/docs/docs/reference/faq.md +441 -0
- package/docs/docs/reference/issue-types.md +43 -0
- package/docs/docs/reference/jsdoc-tsdoc-tags.md +122 -0
- package/docs/docs/reference/known-issues.md +64 -0
- package/docs/docs/reference/plugins/.gitkeep +0 -0
- package/docs/docs/reference/plugins.md +238 -0
- package/docs/docs/reference/related-tooling.md +46 -0
- package/docs/docs/sponsors.mdx +65 -0
- package/docs/docs/typescript/unused-dependencies.md +86 -0
- package/docs/docs/typescript/unused-exports.md +87 -0
- package/docs/docs/writing-a-plugin/argument-parsing.md +202 -0
- package/docs/docs/writing-a-plugin/index.md +376 -0
- package/docs/docs/writing-a-plugin/inputs.md +162 -0
- package/package.json +8 -6
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Handling Issues
|
|
3
|
+
sidebar:
|
|
4
|
+
order: 3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { Tabs, TabItem } from '@astrojs/starlight/components';
|
|
8
|
+
|
|
9
|
+
A long report can be frustrating. The list may contain false positives, but also
|
|
10
|
+
tons of useful information. To get the most value out of Knip, it may require
|
|
11
|
+
some initial configuration.
|
|
12
|
+
|
|
13
|
+
This guide helps you deal with false positives to find solutions and create the
|
|
14
|
+
perfect report, with minimal configuration that will keep your project tidy.
|
|
15
|
+
|
|
16
|
+
If you start out using Knip in a large project and have a long report, it makes
|
|
17
|
+
sense to go over the issue types one by one. For instance, reducing the number
|
|
18
|
+
of unused files will also reduce the number of unused dependencies.
|
|
19
|
+
|
|
20
|
+
1. [Unused files][1]
|
|
21
|
+
2. [Unused dependencies][2]
|
|
22
|
+
3. [Unresolved imports][3]
|
|
23
|
+
4. [Unused exports][4]
|
|
24
|
+
|
|
25
|
+
## Unused files
|
|
26
|
+
|
|
27
|
+
Getting the list of unused files right trickles down into the other issue types
|
|
28
|
+
as well, so we start here. Files are reported as unused if they are in the set
|
|
29
|
+
of `project` files, but not in the set of files resolved from the `entry` files:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
unused files = project files - (entry files + resolved files)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Let's go over common causes for unused files:
|
|
36
|
+
|
|
37
|
+
- [Missing generated files][5]
|
|
38
|
+
- [Dynamic import specifiers][6]
|
|
39
|
+
- [Unsupported arguments in scripts][7]
|
|
40
|
+
- [Unsupported file formats][8]
|
|
41
|
+
- [Missing plugin][9]
|
|
42
|
+
- [Incomplete plugin][10]
|
|
43
|
+
- [TypeScript path aliases in monorepos][11]
|
|
44
|
+
- [Relative paths across workspaces][12]
|
|
45
|
+
- [Integrated monorepos][13]
|
|
46
|
+
- [Auto-mocking or auto-imports][14]
|
|
47
|
+
|
|
48
|
+
In most cases you can add `entry` patterns manually.
|
|
49
|
+
|
|
50
|
+
Use `--files` to [filter the report][15] and focus only on unused files:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
knip --files
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This works with other issue types as well. For instance, use `--dependencies` to
|
|
57
|
+
focus only on dependencies and exclude issues related to unused files and
|
|
58
|
+
exports.
|
|
59
|
+
|
|
60
|
+
:::caution
|
|
61
|
+
|
|
62
|
+
Don't add unused files to the `ignore` option before reading [configuring
|
|
63
|
+
project files][16]. Learn why and when to use `entry`, `project`, production
|
|
64
|
+
mode and `ignore` patterns for better results and performance.
|
|
65
|
+
|
|
66
|
+
:::
|
|
67
|
+
|
|
68
|
+
### Missing generated files
|
|
69
|
+
|
|
70
|
+
For certain features, Knip needs to run after relevant files are generated. For
|
|
71
|
+
instance, [source mapping][17] in a monorepo may require files to be built into
|
|
72
|
+
`dist` folders first. And generated files in the `src` directory may import
|
|
73
|
+
other files. For instance, the `src/routeTree.gen.ts` file generated by
|
|
74
|
+
`@tanstack/router` must exist so Knip can find the imported route files.
|
|
75
|
+
|
|
76
|
+
**Solution**: compile and/or generate the relevant files first so Knip can
|
|
77
|
+
resolve and find the source files.
|
|
78
|
+
|
|
79
|
+
If Knip still reports false positives, you may need to strategically add an
|
|
80
|
+
`entry` file manually.
|
|
81
|
+
|
|
82
|
+
### Dynamic import specifiers
|
|
83
|
+
|
|
84
|
+
Dynamic import specifiers aren't resolved, such as:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const entry = await import(path.join(baseDir, 'entry.ts'));
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Solution**: add `entry.ts` to `entry` patterns.
|
|
91
|
+
|
|
92
|
+
### Unsupported arguments in scripts
|
|
93
|
+
|
|
94
|
+
Some tooling command arguments aren't recognized:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"name": "my-lib",
|
|
99
|
+
"version": "1.0.0",
|
|
100
|
+
"scripts": {
|
|
101
|
+
"build": "unknown-build-cli --entry production.ts"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Solution**: add `production.ts` to `entry` patterns.
|
|
107
|
+
|
|
108
|
+
This works the same for any script, also those in GitHub Actions workflows or
|
|
109
|
+
Git hooks. See [script parser][18] for more details about Knip's script parser.
|
|
110
|
+
|
|
111
|
+
### Unsupported file formats
|
|
112
|
+
|
|
113
|
+
Entry files referenced in HTML files (e.g. `<script src="production.js">`).
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<html>
|
|
117
|
+
<body>
|
|
118
|
+
<script type="module" src="production.js"></script>
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Solution**: add `production.js` to `entry` patterns. Or add an `.html`
|
|
124
|
+
compiler to extract and resolve the value of `<script src>` elements.
|
|
125
|
+
|
|
126
|
+
Knip has support for some popular framework formats through [compilers][19], and
|
|
127
|
+
additional compilers can be added for for any file type. The recommended
|
|
128
|
+
solution is usually to add the file as shown in each example as an `entry` file.
|
|
129
|
+
|
|
130
|
+
### Missing plugin
|
|
131
|
+
|
|
132
|
+
You might be using a tool or framework for which Knip doesn't have a plugin
|
|
133
|
+
(yet). Configuration and entry files (and related dependencies) may be reported
|
|
134
|
+
as unused because there is no plugin yet that would include those files. Two
|
|
135
|
+
examples:
|
|
136
|
+
|
|
137
|
+
- Configuration file `tool.config.js` contains a reference to the package
|
|
138
|
+
`"@tool/plugin"` → both the file and the dependency are reported as unused.
|
|
139
|
+
- A framework automatically imports all files matching `src/models/*.ts` → those
|
|
140
|
+
files are reported as unused.
|
|
141
|
+
|
|
142
|
+
**Solution**: [create a new plugin][20] for the tool or framework that's not [in
|
|
143
|
+
the list][21] yet. Or work around it and add `entry` patterns and maybe ignore a
|
|
144
|
+
dependency or two (using [`ignoreDependencies`][22]).
|
|
145
|
+
|
|
146
|
+
### Incomplete plugin
|
|
147
|
+
|
|
148
|
+
Files may be reported as unused if existing plugins do not include that entry
|
|
149
|
+
file pattern yet. See the [plugins section of entry files][23] for more details.
|
|
150
|
+
|
|
151
|
+
**Solution**: [override plugin configuration][24] to customize default patterns
|
|
152
|
+
for existing plugins. Or even better: send a pull request to improve the plugin.
|
|
153
|
+
|
|
154
|
+
### TypeScript path aliases in monorepos
|
|
155
|
+
|
|
156
|
+
When using TypeScript path aliases in import specifiers, aliases referencing
|
|
157
|
+
other workspaces are not special-cased. This may cause false positives. For
|
|
158
|
+
Knip, it's better to be explicit and list other workspaces as dependencies in
|
|
159
|
+
`package.json`.
|
|
160
|
+
|
|
161
|
+
**Solution**: move such "workspace aliases" from `compilerOptions`...
|
|
162
|
+
|
|
163
|
+
```json title="tsconfig.json"
|
|
164
|
+
{
|
|
165
|
+
"compilerOptions": {
|
|
166
|
+
"paths": {
|
|
167
|
+
"@org/common/*": ["packages/common/*"]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
...to `dependencies` or `devDependencies` in `package.json`:
|
|
174
|
+
|
|
175
|
+
```json title="package.json"
|
|
176
|
+
{
|
|
177
|
+
"name": "@org/lib",
|
|
178
|
+
"dependencies": {
|
|
179
|
+
"@org/common": "workspace:*"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
An additional benefit is that Knip will report unused and unlisted dependencies
|
|
185
|
+
from now on.
|
|
186
|
+
|
|
187
|
+
Also see [FAQ: Why can't I use path aliases to reference other workspaces?][25]
|
|
188
|
+
|
|
189
|
+
### Relative paths across workspaces
|
|
190
|
+
|
|
191
|
+
Relative paths to import from other workspaces are not special-cased. For Knip,
|
|
192
|
+
it's better to be explicit and list other workspaces as dependencies in
|
|
193
|
+
`package.json` to be used in imports.
|
|
194
|
+
|
|
195
|
+
**Solution**: migrate from relative paths...
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { something } from '../../common/file.ts';
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
...to dependency-based imports...
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { something } from '@org/common';
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
An additional benefit is that Knip will report unused and unlisted dependencies
|
|
208
|
+
from now on.
|
|
209
|
+
|
|
210
|
+
Also see [TypeScript path aliases in monorepos][11].
|
|
211
|
+
|
|
212
|
+
### Integrated monorepos
|
|
213
|
+
|
|
214
|
+
Multiple instances of configuration files like `.eslintrc` and
|
|
215
|
+
`jest.config.json` across the repository may be reported as unused when working
|
|
216
|
+
in a (mono)repo with a single `package.json`.
|
|
217
|
+
|
|
218
|
+
**Solution**: see [integrated monorepos][26] for more details and how to
|
|
219
|
+
configure plugins to target those configuration files.
|
|
220
|
+
|
|
221
|
+
### Auto-mocking or auto-imports
|
|
222
|
+
|
|
223
|
+
Some frameworks have features like "auto-mocking" or "auto-imports" enabled,
|
|
224
|
+
such as Jest and Nuxt.
|
|
225
|
+
|
|
226
|
+
**Solution**: include such entry files by extending the `entry` file patterns.
|
|
227
|
+
This is recommended in most cases:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"entry": ["src/index.ts", "src/models/*.ts"]
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Alternatively, exceptions and outliers can be excluded from the analysis using
|
|
236
|
+
negated `project` patterns:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"project": ["src/**/*.ts", "!**/__mocks__/**"]
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Unused dependencies
|
|
245
|
+
|
|
246
|
+
Dependencies imported in unused files are reported as unused dependencies.
|
|
247
|
+
That's why it's strongly recommended to try and remedy [unused files][1] first.
|
|
248
|
+
Better `entry` and `project` file coverage will solve many cases of reported
|
|
249
|
+
unused dependencies.
|
|
250
|
+
|
|
251
|
+
The most common causes for unused dependencies include:
|
|
252
|
+
|
|
253
|
+
- [Missing or incomplete plugins][27]
|
|
254
|
+
- [Unrecognized references][28]
|
|
255
|
+
- [Type Definition Packages][29]
|
|
256
|
+
|
|
257
|
+
Use `--dependencies` to [filter the report][15] and focus only on issues related
|
|
258
|
+
to dependencies:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
knip --dependencies
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
:::caution[Monorepo]
|
|
265
|
+
|
|
266
|
+
In a monorepo, a dependency is unused in the root workspace's `package.json` if
|
|
267
|
+
it's also listed in an descendent workspace, and referenced only in the
|
|
268
|
+
descendent workspace.
|
|
269
|
+
|
|
270
|
+
:::
|
|
271
|
+
|
|
272
|
+
### Missing or incomplete plugin
|
|
273
|
+
|
|
274
|
+
If a plugin exists and the dependency is referenced in the configuration file,
|
|
275
|
+
but its custom dependency finder does not detect it, then that's a false
|
|
276
|
+
positive. Please open a pull request or issue to fix it.
|
|
277
|
+
|
|
278
|
+
**Solution**: adding the configuration file as an `entry` file pattern may be a
|
|
279
|
+
temporary stopgap that fixes your situation, but it's better to create a new
|
|
280
|
+
plugin or fix an existing one.
|
|
281
|
+
|
|
282
|
+
### Unrecognized reference
|
|
283
|
+
|
|
284
|
+
Sometimes a reference to a dependency is unrecognizable or unreachable to Knip,
|
|
285
|
+
so it's a false positive and incorrectly reported as unused.
|
|
286
|
+
|
|
287
|
+
**Solution**: add a new plugin or improve an existing one. If you don't feel
|
|
288
|
+
like a plugin could solve it, a last resort is to use [ignoreDependencies][22].
|
|
289
|
+
|
|
290
|
+
If a binary (or "executable") is referenced you'll want to use `ignoreBinaries`
|
|
291
|
+
instead. See [unlisted binaries][30].
|
|
292
|
+
|
|
293
|
+
### Type Definition Packages
|
|
294
|
+
|
|
295
|
+
#### Bundled types
|
|
296
|
+
|
|
297
|
+
Many packages come with their type definitions bundled. This means the
|
|
298
|
+
`package.json#types` field in the package points to an internal/local type
|
|
299
|
+
definition file. In this case, the separate types package is obsolete.
|
|
300
|
+
|
|
301
|
+
Knip reporting this is also useful for future regressions: if a package had a
|
|
302
|
+
DefinitelyTyped or similar package for its types before and later on starts
|
|
303
|
+
shipping those types bundled with the source code, Knip will report the obsolete
|
|
304
|
+
types dependency as unused.
|
|
305
|
+
|
|
306
|
+
Examples include ESLint, Webpack and React Router, rendering the
|
|
307
|
+
`@types/eslint`, `@types/webpack` and `@types/react-router` dependencies
|
|
308
|
+
obsolete respectively.
|
|
309
|
+
|
|
310
|
+
**Solution**: remove the types dependency (often `@types/...`)
|
|
311
|
+
|
|
312
|
+
#### Production types
|
|
313
|
+
|
|
314
|
+
Knip is strict in the divide between `dependencies` and `devDependencies`. Some
|
|
315
|
+
packages are published with one or more type packages listed in `dependencies`.
|
|
316
|
+
In strict production mode, even when re-exported and part of the package's
|
|
317
|
+
public API, Knip does not try to figure out what exactly are "production types"
|
|
318
|
+
and expects those in `devDependencies`.
|
|
319
|
+
|
|
320
|
+
**Solution**: list exceptions in [ignoreDependencies][22].
|
|
321
|
+
|
|
322
|
+
### Unlisted dependencies
|
|
323
|
+
|
|
324
|
+
This means that a dependency is referenced directly in source code or
|
|
325
|
+
configuration, but not listed in `package.json`.
|
|
326
|
+
|
|
327
|
+
An unlisted dependency is usually a transitive dependency that's imported or
|
|
328
|
+
referenced directly. The dependency is installed (since it's a dependency of
|
|
329
|
+
another dependency) and lives in `node_modules`, but it's not listed explicitly
|
|
330
|
+
in `package.json`.
|
|
331
|
+
|
|
332
|
+
You should not rely on transitive dependencies for various reasons, including
|
|
333
|
+
control, security and stability.
|
|
334
|
+
|
|
335
|
+
**Solution**: install and list the dependency in `dependencies` or
|
|
336
|
+
`devDependencies`.
|
|
337
|
+
|
|
338
|
+
### Unlisted binaries
|
|
339
|
+
|
|
340
|
+
Binaries are executable Node.js scripts. Some npm packages, when installed, add
|
|
341
|
+
one or more executable files to be used from scripts in `package.json`. Examples
|
|
342
|
+
include TypeScript that comes with the `tsc` binary, ESLint comes with `eslint`,
|
|
343
|
+
Next.js with `next`, and so on.
|
|
344
|
+
|
|
345
|
+
Knip detects such binaries in scripts and checks whether there's a package
|
|
346
|
+
installed that includes that binary. It looks up the `bin` field in the
|
|
347
|
+
`package.json` file of installed packages. If it doesn't find it, it will be
|
|
348
|
+
reported as an unlisted binary as there is no package that contains it.
|
|
349
|
+
|
|
350
|
+
Binaries that are installed on the OS already and thus likely not meant to be
|
|
351
|
+
installed from npm are not reported as unlisted (details: [list of ignored
|
|
352
|
+
binaries in source][31]).
|
|
353
|
+
|
|
354
|
+
#### Missing binaries
|
|
355
|
+
|
|
356
|
+
An unused dependency and an unlisted binary with the same name indicates
|
|
357
|
+
`node_modules` not containing the relevant package. And this might be caused by
|
|
358
|
+
either the way your package manager installs dependencies and binaries, or by
|
|
359
|
+
not running Knip from the root of the repository.
|
|
360
|
+
|
|
361
|
+
**Solution**: run Knip from the project root. If needed, [lint workspaces
|
|
362
|
+
individually][32].
|
|
363
|
+
|
|
364
|
+
Sometimes binaries and how they're reported can be a bit confusing. See this
|
|
365
|
+
example:
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"name": "lib",
|
|
370
|
+
"scripts": {
|
|
371
|
+
"commitlint": "commitlint --edit"
|
|
372
|
+
},
|
|
373
|
+
"devDependencies": {
|
|
374
|
+
"@commitlint/cli": "*"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
This example works fine without anything reported, as the `@commitlint/cli`
|
|
380
|
+
package includes the `commitlint` binary. However, some script may contain
|
|
381
|
+
`npx commitlint` and here Knip assumes `commitlint` is the name of the package.
|
|
382
|
+
This technically works, as `commitlint` is a transitive dependency of
|
|
383
|
+
`@commitlint/cli`.
|
|
384
|
+
|
|
385
|
+
**Solution**: use `npx @commitlint/cli`
|
|
386
|
+
|
|
387
|
+
In some cases, using `npx` in a script may result in Knip not understanding
|
|
388
|
+
intention without an explicit `--yes` or `--no-install` flag.
|
|
389
|
+
|
|
390
|
+
**Solution**: use `npx --yes` or `npx --no-install` so Knip will either ignore
|
|
391
|
+
or consider the binary and package(s) referenced, respectively.
|
|
392
|
+
|
|
393
|
+
## Unresolved imports
|
|
394
|
+
|
|
395
|
+
Knip may ignore or be unable to resolve an import specifier or dependency
|
|
396
|
+
references. The most common causes for unresolved imports:
|
|
397
|
+
|
|
398
|
+
- [Template strings][33]
|
|
399
|
+
- [Extensionless imports][28]
|
|
400
|
+
- [Unrecognized path aliases][34]
|
|
401
|
+
- [External aliased imports][35]
|
|
402
|
+
|
|
403
|
+
### Template strings
|
|
404
|
+
|
|
405
|
+
Using template strings in dynamic imports might be ignored or not handled
|
|
406
|
+
properly by Knip, resulting in false positives. Examples of dynamic import
|
|
407
|
+
template strings:
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
import(`./${value}.ts`);
|
|
411
|
+
import(`@org/name/dist/${value}.js`);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Solution**: for internal source files, add the file(s) to the `entry`
|
|
415
|
+
patterns. For external dependencies, add the dependency to the
|
|
416
|
+
`ignoreDependencies` list.
|
|
417
|
+
|
|
418
|
+
### Extensionless imports
|
|
419
|
+
|
|
420
|
+
Knip does not support extensionless imports for some non-standard extensions,
|
|
421
|
+
such as for `.svg` files. Bundlers like Webpack may support this, but Knip does
|
|
422
|
+
not. Here's an example:
|
|
423
|
+
|
|
424
|
+
```ts title="App.vue"
|
|
425
|
+
import Component from './Component'; // → Should resolve to ./Component.vue
|
|
426
|
+
import ArrowIcon from '../icons/Arrow'; // → Does NOT resolve to ../icons/Arrow.svg
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
The first import is resolved properly, because `.vue` is a known extension if
|
|
430
|
+
the Vue plugin is enabled. The second import might not be resolved, because
|
|
431
|
+
`.svg` is not a known extension.
|
|
432
|
+
|
|
433
|
+
The recommendation is to always add the extension when importing such files,
|
|
434
|
+
similar to how standard ES Modules specifies file extensions are necessary.
|
|
435
|
+
|
|
436
|
+
### Unrecognized path aliases
|
|
437
|
+
|
|
438
|
+
Knip considers TS config path aliases and [paths configured in knip.json][36],
|
|
439
|
+
but not those in e.g. Webpack or Vite configurations.
|
|
440
|
+
|
|
441
|
+
**Solution**: configure [paths][36] or try relative imports. Otherwise, use
|
|
442
|
+
[`ignoreUnresolved`][37] as a last resort.
|
|
443
|
+
|
|
444
|
+
### External aliased imports
|
|
445
|
+
|
|
446
|
+
External libraries may use aliased imports that aren't resolved by Knip.
|
|
447
|
+
|
|
448
|
+
For instance, [unplugin-icons][10] does this to import icons from icon sets as
|
|
449
|
+
components. Such imports are reported as unused. Use the [`paths` configuration
|
|
450
|
+
option][13] to tell Knip where to find the icon types:
|
|
451
|
+
|
|
452
|
+
```json title="knip.json"
|
|
453
|
+
{
|
|
454
|
+
"paths": {
|
|
455
|
+
"~icons/*": ["node_modules/unplugin-icons/types/[framework].d.ts"]
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Where `[framework]` is the name of the framework you're using (see [available
|
|
461
|
+
types][38]).
|
|
462
|
+
|
|
463
|
+
**Solution**: try [--include-libs][39] or configure [paths][36].
|
|
464
|
+
|
|
465
|
+
## Unused exports
|
|
466
|
+
|
|
467
|
+
By default, Knip does not report unused exports of `entry` files.
|
|
468
|
+
|
|
469
|
+
The most common causes for unused exports include:
|
|
470
|
+
|
|
471
|
+
- [Namespace enumerations][40]
|
|
472
|
+
- [External libraries][39]
|
|
473
|
+
|
|
474
|
+
Use the `--exports` flag to [filter][15] and focus only on issues related to
|
|
475
|
+
exports:
|
|
476
|
+
|
|
477
|
+
```sh
|
|
478
|
+
knip --exports
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Use [includeEntryExports][41] to report unused exports of entry files as well.
|
|
482
|
+
This can be set per workspace.
|
|
483
|
+
|
|
484
|
+
### Namespace enumerations
|
|
485
|
+
|
|
486
|
+
For exports on an imported namespace, Knip considers all exports referenced if
|
|
487
|
+
that namespace is used in certain patterns like enumeration. Individual exports
|
|
488
|
+
are then **not** reported.
|
|
489
|
+
|
|
490
|
+
**Solution**: if all exports on imported namespaces should be considered
|
|
491
|
+
individually, include the `nsExports` issue type to disable the heuristic.
|
|
492
|
+
|
|
493
|
+
See [namespace imports][42] to see all related patterns.
|
|
494
|
+
|
|
495
|
+
### External libraries
|
|
496
|
+
|
|
497
|
+
Are the exports consumed or imported by an external library, resulting in a
|
|
498
|
+
non-standard consumption of your exports? Here's an example:
|
|
499
|
+
|
|
500
|
+
<Tabs>
|
|
501
|
+
<TabItem label="index.js">
|
|
502
|
+
```ts
|
|
503
|
+
import loadable from '@loadable/component';
|
|
504
|
+
|
|
505
|
+
export const DynamicApple = dynamic(() =>
|
|
506
|
+
import('./components.js').then(mod => mod.Apple)
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
export const LoadableOrange = loadable(() => import('./components.js'), {
|
|
510
|
+
resolveComponent: components => components.Orange,
|
|
511
|
+
});
|
|
512
|
+
```
|
|
513
|
+
</TabItem>
|
|
514
|
+
|
|
515
|
+
<TabItem label="components.js">
|
|
516
|
+
```ts
|
|
517
|
+
export const Apple = () => 'Apple';
|
|
518
|
+
export const Orange = () => 'Orange';
|
|
519
|
+
```
|
|
520
|
+
</TabItem>
|
|
521
|
+
</Tabs>
|
|
522
|
+
|
|
523
|
+
Knip understands `Apple` is used, since it's standard usage. But `Orange` is
|
|
524
|
+
referenced through a function of an external library. For performance reasons,
|
|
525
|
+
Knip does not include external type definitions by default so it won't see the
|
|
526
|
+
export being referenced.
|
|
527
|
+
|
|
528
|
+
**Solution**: include the type definitions of external libraries with the
|
|
529
|
+
[--include-libs][43] flag:
|
|
530
|
+
|
|
531
|
+
```shell
|
|
532
|
+
knip --include-libs
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
This comes at a performance and memory penalty, but should give better results
|
|
536
|
+
if you need it. This flag is implied when [classMembers][44] are included (that
|
|
537
|
+
feature comes with roughly the same performance penalty).
|
|
538
|
+
|
|
539
|
+
### Exclude exports from the report
|
|
540
|
+
|
|
541
|
+
To exclude false positives from the report, there are a few options:
|
|
542
|
+
|
|
543
|
+
- [Ignore exports used in file][45] for exports used internally.
|
|
544
|
+
- Individual exports can be [tagged using JSDoc syntax][46].
|
|
545
|
+
- Have the export in an entry file:
|
|
546
|
+
- Add the file to the `entry` file patterns array in the configuration.
|
|
547
|
+
- Move the export(s) to an entry file.
|
|
548
|
+
- Add the file to the `exports` field of `package.json`
|
|
549
|
+
- Re-export the unused export(s) from an entry file.
|
|
550
|
+
|
|
551
|
+
### Missing unused exports?
|
|
552
|
+
|
|
553
|
+
Did you expect certain exports in the report, but are they missing? They might
|
|
554
|
+
be exported from an entry file. In that case, use [--include-entry-exports][41]
|
|
555
|
+
to make Knip also report unused exports in entry files.
|
|
556
|
+
|
|
557
|
+
The exports of non-standard extensions like `.astro`, `.mdx`, `.vue` or
|
|
558
|
+
`.svelte` are not available by default. See [compilers][19] for more details on
|
|
559
|
+
how to include them.
|
|
560
|
+
|
|
561
|
+
### Class members
|
|
562
|
+
|
|
563
|
+
Unused members of exported classes are not reported by default, here's how to
|
|
564
|
+
enable them:
|
|
565
|
+
|
|
566
|
+
```sh
|
|
567
|
+
knip --include classMembers
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
This option is also available in the Knip configuration file. Note that this
|
|
571
|
+
feature comes at a cost: linting will take more time and more memory.
|
|
572
|
+
|
|
573
|
+
Individual class members can be [tagged using JSDoc syntax][46].
|
|
574
|
+
|
|
575
|
+
Classes exported from entry files are ignored, and so are their members. Use
|
|
576
|
+
[--include-entry-exports][41] to make Knip also report members of unused exports
|
|
577
|
+
in entry files.
|
|
578
|
+
|
|
579
|
+
### Enum members
|
|
580
|
+
|
|
581
|
+
Unused enums and unused members of exported enums are reported by default.
|
|
582
|
+
Reporting such members can be disabled:
|
|
583
|
+
|
|
584
|
+
```sh
|
|
585
|
+
knip --exclude enumMembers
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Individual enum members can be [tagged using JSDoc syntax][46].
|
|
589
|
+
|
|
590
|
+
Enums exported from entry files are ignored, and so are their members. Use
|
|
591
|
+
[--include-entry-exports][41] to make Knip also report members of unused exports
|
|
592
|
+
in entry files.
|
|
593
|
+
|
|
594
|
+
## Feedback or false positives?
|
|
595
|
+
|
|
596
|
+
If you believe Knip incorrectly reports something as unused (i.e. there's a
|
|
597
|
+
false positive), feel free to create a [minimal reproduction][47] and open an
|
|
598
|
+
issue on GitHub. It'll make Knip better for everyone!
|
|
599
|
+
|
|
600
|
+
[1]: #unused-files
|
|
601
|
+
[2]: #unused-dependencies
|
|
602
|
+
[3]: #unresolved-imports
|
|
603
|
+
[4]: #unused-exports
|
|
604
|
+
[5]: #missing-generated-files
|
|
605
|
+
[6]: #dynamic-import-specifiers
|
|
606
|
+
[7]: #unsupported-arguments-in-scripts
|
|
607
|
+
[8]: #unsupported-file-formats
|
|
608
|
+
[9]: #missing-plugin
|
|
609
|
+
[10]: #incomplete-plugin
|
|
610
|
+
[11]: #typescript-path-aliases-in-monorepos
|
|
611
|
+
[12]: #relative-paths-across-workspaces
|
|
612
|
+
[13]: #integrated-monorepos
|
|
613
|
+
[14]: #auto-mocking-or-auto-imports
|
|
614
|
+
[15]: ../features/rules-and-filters.md#filters
|
|
615
|
+
[16]: ./configuring-project-files.md
|
|
616
|
+
[17]: ../features/source-mapping.md
|
|
617
|
+
[18]: ../features/script-parser.md
|
|
618
|
+
[19]: ../features/compilers.md
|
|
619
|
+
[20]: ./writing-a-plugin.md
|
|
620
|
+
[21]: ../reference/plugins.md
|
|
621
|
+
[22]: ../reference/configuration.md#ignoredependencies
|
|
622
|
+
[23]: ../explanations/plugins.md#entry-files
|
|
623
|
+
[24]: ../explanations/entry-files.md#plugins
|
|
624
|
+
[25]: ../reference/faq.md#why-cant-i-use-path-aliases-to-reference-other-workspaces
|
|
625
|
+
[26]: ../features/integrated-monorepos.md
|
|
626
|
+
[27]: #missing-or-incomplete-plugin
|
|
627
|
+
[28]: #unrecognized-reference
|
|
628
|
+
[29]: #type-definition-packages
|
|
629
|
+
[30]: #unlisted-binaries
|
|
630
|
+
[31]: https://github.com/webpro-nl/knip/blob/b70958a58ea255ee7a7831e404786da807ca93d7/packages/knip/src/constants.ts#L37-L139
|
|
631
|
+
[32]: ../features/monorepos-and-workspaces.md#lint-a-single-workspace
|
|
632
|
+
[33]: #template-strings
|
|
633
|
+
[34]: #unrecognized-path-aliases
|
|
634
|
+
[35]: #external-aliased-imports
|
|
635
|
+
[36]: ../reference/configuration.md#paths
|
|
636
|
+
[37]: ../reference/configuration.md#ignoreunresolved
|
|
637
|
+
[38]: #build-artifacts-and-ignored-files
|
|
638
|
+
[39]: #external-libraries
|
|
639
|
+
[40]: #namespace-enumerations
|
|
640
|
+
[41]: ../reference/configuration.md#includeentryexports
|
|
641
|
+
[42]: ../guides/namespace-imports.md
|
|
642
|
+
[43]: ../reference/cli#--include-libs
|
|
643
|
+
[44]: #class-members
|
|
644
|
+
[45]: ../reference/configuration.md#ignoreexportsusedinfile
|
|
645
|
+
[46]: ../reference/jsdoc-tsdoc-tags.md
|
|
646
|
+
[47]: ../guides/issue-reproduction
|