knip 2.10.2 → 2.10.4
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/README.md +55 -46
- package/dist/ConfigurationChief.d.ts +1 -0
- package/dist/ConfigurationChief.js +15 -14
- package/dist/binaries/resolvers/pnpm.js +1 -0
- package/dist/typescript/getImportsAndExports.js +1 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -38,6 +38,11 @@ with OpenAI_</sup>
|
|
|
38
38
|
|
|
39
39
|
Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.6.
|
|
40
40
|
|
|
41
|
+
## Experimental: knowledge base
|
|
42
|
+
|
|
43
|
+
You might want to ask your questions in the [Knip knowledge base][8] (powered by OpenAI and [7-docs][9]). This is an
|
|
44
|
+
experimental knowledge base, answers may be incorrect.
|
|
45
|
+
|
|
41
46
|
## Configuration
|
|
42
47
|
|
|
43
48
|
Knip has good defaults and you can run it without any configuration. Here's the default:
|
|
@@ -194,7 +199,7 @@ The report contains the following types of issues:
|
|
|
194
199
|
|
|
195
200
|
When an issue type has zero issues, it is not shown.
|
|
196
201
|
|
|
197
|
-
Getting too many reported issues and false positives? Read more about [handling issues][
|
|
202
|
+
Getting too many reported issues and false positives? Read more about [handling issues][10].
|
|
198
203
|
|
|
199
204
|
_(1)_ The variable or type is not referenced directly and has become a member of a namespace. Knip can't find a
|
|
200
205
|
reference to it, so you can _probably_ remove it.
|
|
@@ -222,7 +227,7 @@ Example:
|
|
|
222
227
|
}
|
|
223
228
|
```
|
|
224
229
|
|
|
225
|
-
See [reading the report][
|
|
230
|
+
See [reading the report][11] for the list of issue types.
|
|
226
231
|
|
|
227
232
|
The rules are modeled after the ESLint `rules` configuration, and could be extended in the future. For instance, to
|
|
228
233
|
apply filters or configurations only to a specific issue type.
|
|
@@ -243,7 +248,7 @@ Use `--exclude` to ignore reports you're not interested in:
|
|
|
243
248
|
|
|
244
249
|
Use `--dependencies` or `--exports` as shortcuts to combine groups of related types.
|
|
245
250
|
|
|
246
|
-
See [reading the report][
|
|
251
|
+
See [reading the report][11] for the list of issue types.
|
|
247
252
|
|
|
248
253
|
### When to use rules or filters
|
|
249
254
|
|
|
@@ -285,7 +290,7 @@ As always, make sure to back up files or use Git before deleting files or making
|
|
|
285
290
|
|
|
286
291
|
🔁 Repeat the process to reveal new unused files and exports. Sometimes it's so liberating to remove things!
|
|
287
292
|
|
|
288
|
-
Getting too many reported issues and false positives? Read more about [handling issues][
|
|
293
|
+
Getting too many reported issues and false positives? Read more about [handling issues][10].
|
|
289
294
|
|
|
290
295
|
## Workspaces
|
|
291
296
|
|
|
@@ -315,7 +320,7 @@ Here's an example `knip.json` configuration with some custom `entry` and `projec
|
|
|
315
320
|
```
|
|
316
321
|
|
|
317
322
|
It might be useful to run Knip first with no or little configuration to see where it needs custom `entry` and/or
|
|
318
|
-
`project` files. Each workspace has the same [default configuration][
|
|
323
|
+
`project` files. Each workspace has the same [default configuration][12].
|
|
319
324
|
|
|
320
325
|
The root workspace is named `"."` under `workspaces` (like in the example).
|
|
321
326
|
|
|
@@ -434,7 +439,7 @@ has them at `e2e-tests/*.spec.ts`. Here's how to configure this:
|
|
|
434
439
|
### Multi-project repositories
|
|
435
440
|
|
|
436
441
|
Some repositories have a single `package.json`, but consist of multiple projects with configuration files across the
|
|
437
|
-
repository (such as the [Nx "intregrated repo" style][
|
|
442
|
+
repository (such as the [Nx "intregrated repo" style][13]). Let's assume some of these projects are apps and have their
|
|
438
443
|
own Cypress configuration and test files. In that case, we could configure the Cypress plugin like this:
|
|
439
444
|
|
|
440
445
|
```json
|
|
@@ -451,7 +456,7 @@ In case a plugin causes issues, it can be disabled by using `false` as its value
|
|
|
451
456
|
|
|
452
457
|
### Create a new plugin
|
|
453
458
|
|
|
454
|
-
Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][
|
|
459
|
+
Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][14]. This
|
|
455
460
|
guide also contains more details if you want to learn more about plugins and why they are useful.
|
|
456
461
|
|
|
457
462
|
## Compilers
|
|
@@ -474,7 +479,7 @@ export default {
|
|
|
474
479
|
};
|
|
475
480
|
```
|
|
476
481
|
|
|
477
|
-
Read [Compilers][
|
|
482
|
+
Read [Compilers][15] for more details and examples.
|
|
478
483
|
|
|
479
484
|
## Production Mode
|
|
480
485
|
|
|
@@ -551,7 +556,7 @@ When the provided built-in reporters are not sufficient, a custom reporter can b
|
|
|
551
556
|
Pass `--reporter ./my-reporter` from the command line. The data can then be used to write issues to `stdout`, a JSON or
|
|
552
557
|
CSV file, or sent to a service.
|
|
553
558
|
|
|
554
|
-
Find more details and ideas in [custom reporters][
|
|
559
|
+
Find more details and ideas in [custom reporters][16].
|
|
555
560
|
|
|
556
561
|
## Public exports
|
|
557
562
|
|
|
@@ -575,14 +580,14 @@ Knip does not report public exports and types as unused.
|
|
|
575
580
|
|
|
576
581
|
## Handling Issues
|
|
577
582
|
|
|
578
|
-
How to handle a long list of reported issues? Seeing too many false positives? Read more about [handling issues][
|
|
583
|
+
How to handle a long list of reported issues? Seeing too many false positives? Read more about [handling issues][17]
|
|
579
584
|
describing potential causes for false positives, and how to handle them.
|
|
580
585
|
|
|
581
586
|
## Comparison
|
|
582
587
|
|
|
583
588
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
584
589
|
|
|
585
|
-
| Feature | **knip** | [depcheck][
|
|
590
|
+
| Feature | **knip** | [depcheck][18] | [unimported][19] | [ts-unused-exports][20] | [ts-prune][21] |
|
|
586
591
|
| :---------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
|
|
587
592
|
| Unused files | ✅ | - | ✅ | - | - |
|
|
588
593
|
| Unused dependencies | ✅ | ✅ | ✅ | - | - |
|
|
@@ -618,7 +623,7 @@ The following commands are similar:
|
|
|
618
623
|
unimported
|
|
619
624
|
knip --production --dependencies --include files
|
|
620
625
|
|
|
621
|
-
Also see [production mode][
|
|
626
|
+
Also see [production mode][22].
|
|
622
627
|
|
|
623
628
|
### ts-unused-exports
|
|
624
629
|
|
|
@@ -640,16 +645,17 @@ The following commands are similar:
|
|
|
640
645
|
|
|
641
646
|
Many thanks to some of the early adopters of Knip:
|
|
642
647
|
|
|
643
|
-
- [
|
|
644
|
-
- [
|
|
645
|
-
- [
|
|
646
|
-
- [
|
|
647
|
-
- [
|
|
648
|
-
- [
|
|
649
|
-
- [
|
|
650
|
-
- [
|
|
648
|
+
- [Abracabra][23]
|
|
649
|
+
- [Block Protocol][24]
|
|
650
|
+
- [Cursor][25]
|
|
651
|
+
- [DeepmergeTS][26]
|
|
652
|
+
- [eslint-plugin-functional][27]
|
|
653
|
+
- [freeCodeCamp.org][28]
|
|
654
|
+
- [is-immutable-type][29]
|
|
655
|
+
- [release-it][30]
|
|
656
|
+
- [Template TypeScript Node Package][31]
|
|
651
657
|
|
|
652
|
-
##
|
|
658
|
+
## Potential boost with `--no-gitignore`
|
|
653
659
|
|
|
654
660
|
Running Knip on large workspaces with many packages may feel a bit sluggish. Knip looks up `.gitignore` files and uses
|
|
655
661
|
them to filter out matching entry and project files. This increases correctness. However, you might want to disable that
|
|
@@ -667,7 +673,7 @@ And to measure the difference of this flag in seconds:
|
|
|
667
673
|
SECONDS=0; knip > /dev/null; t1=$SECONDS; SECONDS=0; knip --no-gitignore > /dev/null; t2=$SECONDS; echo "Difference: $((t1 - t2)) seconds"
|
|
668
674
|
```
|
|
669
675
|
|
|
670
|
-
⏲️ Analysis on a large project went from 33 down to 9 seconds (that's >70% faster).
|
|
676
|
+
⏲️ Analysis on a large project went from 33 down to 9 seconds (that's >70% faster).
|
|
671
677
|
|
|
672
678
|
## Knip
|
|
673
679
|
|
|
@@ -685,7 +691,7 @@ each file, and traversing all of this, why not collect the various issues in one
|
|
|
685
691
|
|
|
686
692
|
Special thanks to the wonderful people who have contributed to this project:
|
|
687
693
|
|
|
688
|
-
[![Contributors][
|
|
694
|
+
[![Contributors][33]][32]
|
|
689
695
|
|
|
690
696
|
[1]: #workspaces
|
|
691
697
|
[2]: #plugins
|
|
@@ -694,29 +700,32 @@ Special thanks to the wonderful people who have contributed to this project:
|
|
|
694
700
|
[5]: #custom-reporters
|
|
695
701
|
[6]: https://labs.openai.com/s/xZQACaLepaKya0PRUPtIN5dC
|
|
696
702
|
[7]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
|
|
697
|
-
[8]:
|
|
698
|
-
[9]:
|
|
699
|
-
[10]: #
|
|
700
|
-
[11]:
|
|
701
|
-
[12]:
|
|
702
|
-
[13]:
|
|
703
|
-
[14]: ./docs/
|
|
704
|
-
[15]: ./docs/
|
|
705
|
-
[16]:
|
|
706
|
-
[17]:
|
|
707
|
-
[18]: https://github.com/
|
|
708
|
-
[19]: https://github.com/
|
|
709
|
-
[20]:
|
|
710
|
-
[21]: https://github.com/
|
|
711
|
-
[22]:
|
|
712
|
-
[23]: https://github.com/
|
|
713
|
-
[24]: https://github.com/
|
|
714
|
-
[25]: https://github.com/
|
|
715
|
-
[26]: https://github.com/RebeccaStevens/
|
|
716
|
-
[27]: https://github.com/
|
|
717
|
-
[28]: https://github.com/
|
|
718
|
-
[29]: https://github.com/
|
|
719
|
-
[30]: https://
|
|
703
|
+
[8]: https://knip.deno.dev
|
|
704
|
+
[9]: https://github.com/7-docs/7-docs
|
|
705
|
+
[10]: #handling-issues
|
|
706
|
+
[11]: #reading-the-report
|
|
707
|
+
[12]: #configuration
|
|
708
|
+
[13]: https://nx.dev/concepts/integrated-vs-package-based
|
|
709
|
+
[14]: ./docs/writing-a-plugin.md
|
|
710
|
+
[15]: ./docs/compilers.md
|
|
711
|
+
[16]: ./docs/custom-reporters.md
|
|
712
|
+
[17]: ./docs/handling-issues.md
|
|
713
|
+
[18]: https://github.com/depcheck/depcheck
|
|
714
|
+
[19]: https://github.com/smeijer/unimported
|
|
715
|
+
[20]: https://github.com/pzavolinsky/ts-unused-exports
|
|
716
|
+
[21]: https://github.com/nadeesha/ts-prune
|
|
717
|
+
[22]: #production-mode
|
|
718
|
+
[23]: https://github.com/nicoespeon/abracadabra
|
|
719
|
+
[24]: https://github.com/blockprotocol/blockprotocol
|
|
720
|
+
[25]: https://github.com/getcursor/cursor
|
|
721
|
+
[26]: https://github.com/RebeccaStevens/deepmerge-ts
|
|
722
|
+
[27]: https://github.com/eslint-functional/eslint-plugin-functional
|
|
723
|
+
[28]: https://github.com/freeCodeCamp/freeCodeCamp
|
|
724
|
+
[29]: https://github.com/RebeccaStevens/is-immutable-type
|
|
725
|
+
[30]: https://github.com/release-it/release-it
|
|
726
|
+
[31]: https://github.com/JoshuaKGoldberg/template-typescript-node-package
|
|
727
|
+
[32]: https://github.com/webpro/knip/graphs/contributors
|
|
728
|
+
[33]: https://contrib.rocks/image?repo=webpro/knip
|
|
720
729
|
[plugin-ava]: ./src/plugins/ava
|
|
721
730
|
[plugin-babel]: ./src/plugins/babel
|
|
722
731
|
[plugin-capacitor]: ./src/plugins/capacitor
|
|
@@ -59,6 +59,7 @@ export declare class ConfigurationChief {
|
|
|
59
59
|
setWorkspaces(): Promise<void>;
|
|
60
60
|
private getManifestWorkspaces;
|
|
61
61
|
private getAdditionalWorkspaces;
|
|
62
|
+
private getAllWorkspaceNames;
|
|
62
63
|
private getAllWorkspaces;
|
|
63
64
|
getEnabledWorkspaces(): Workspace[];
|
|
64
65
|
getDescendentWorkspaces(name: string): string[];
|
|
@@ -165,9 +165,9 @@ export class ConfigurationChief {
|
|
|
165
165
|
this.ignoreWorkspaces = this.getIgnoredWorkspaces();
|
|
166
166
|
this.manifestWorkspaces = await this.getManifestWorkspaces();
|
|
167
167
|
this.additionalWorkspaces = await this.getAdditionalWorkspaces();
|
|
168
|
-
this.localWorkspaces = new Set(compact(this.
|
|
168
|
+
this.localWorkspaces = new Set(compact(this.getAllWorkspaces().map(w => w.pkgName)));
|
|
169
169
|
this.workspaces = this.getEnabledWorkspaces();
|
|
170
|
-
this.workspaceDirs = this.
|
|
170
|
+
this.workspaceDirs = this.getAllWorkspaceNames()
|
|
171
171
|
.sort(byPathDepth)
|
|
172
172
|
.reverse()
|
|
173
173
|
.map(dir => join(this.cwd, dir));
|
|
@@ -190,12 +190,11 @@ export class ConfigurationChief {
|
|
|
190
190
|
const globbedDirs = await _dirGlob({ patterns, cwd: this.cwd });
|
|
191
191
|
return new Set([...dirs, ...globbedDirs].filter(name => name !== ROOT_WORKSPACE_NAME && !this.manifestWorkspaces.has(name) && !this.ignoreWorkspaces.includes(name)));
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
getAllWorkspaceNames() {
|
|
194
194
|
return compact([ROOT_WORKSPACE_NAME, ...this.manifestWorkspaces.keys(), ...this.additionalWorkspaces]);
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
const
|
|
198
|
-
const ignoredWorkspaces = this.getIgnoredWorkspaces();
|
|
196
|
+
getAllWorkspaces() {
|
|
197
|
+
const workspaceDirs = this.getAllWorkspaceNames();
|
|
199
198
|
const getAncestors = (name) => (ancestors, ancestorName) => {
|
|
200
199
|
if (name === ancestorName)
|
|
201
200
|
return ancestors;
|
|
@@ -203,20 +202,22 @@ export class ConfigurationChief {
|
|
|
203
202
|
ancestors.push(ancestorName);
|
|
204
203
|
return ancestors;
|
|
205
204
|
};
|
|
206
|
-
|
|
207
|
-
return workspaces
|
|
208
|
-
.filter(w => !ignoredWorkspaces.includes(w))
|
|
209
|
-
.sort(byPathDepth)
|
|
210
|
-
.map((name) => ({
|
|
205
|
+
return workspaceDirs.sort(byPathDepth).map((name) => ({
|
|
211
206
|
name,
|
|
212
207
|
pkgName: this.manifestWorkspaces.get(name) ?? this.manifest?.name,
|
|
213
208
|
dir: join(this.cwd, name),
|
|
214
209
|
config: this.getConfigForWorkspace(name),
|
|
215
|
-
ancestors:
|
|
210
|
+
ancestors: workspaceDirs.reduce(getAncestors(name), []),
|
|
216
211
|
}));
|
|
217
212
|
}
|
|
213
|
+
getEnabledWorkspaces() {
|
|
214
|
+
const allWorkspaces = this.getAllWorkspaces();
|
|
215
|
+
const ignoredWorkspaces = this.getIgnoredWorkspaces();
|
|
216
|
+
const workspaces = workspaceArg ? allWorkspaces.filter(w => w.name === workspaceArg) : allWorkspaces;
|
|
217
|
+
return workspaces.filter(w => !ignoredWorkspaces.includes(w.name));
|
|
218
|
+
}
|
|
218
219
|
getDescendentWorkspaces(name) {
|
|
219
|
-
return this.
|
|
220
|
+
return this.getAllWorkspaceNames()
|
|
220
221
|
.filter(workspaceName => workspaceName !== name)
|
|
221
222
|
.filter(workspaceName => name === ROOT_WORKSPACE_NAME || workspaceName.startsWith(name + '/'));
|
|
222
223
|
}
|
|
@@ -273,7 +274,7 @@ export class ConfigurationChief {
|
|
|
273
274
|
}
|
|
274
275
|
getUnusedIgnoredWorkspaces() {
|
|
275
276
|
const ignoredWorkspaceNames = this.config.ignoreWorkspaces;
|
|
276
|
-
const workspaceNames = this.
|
|
277
|
+
const workspaceNames = this.getAllWorkspaceNames();
|
|
277
278
|
return ignoredWorkspaceNames.filter(workspaceName => !workspaceNames.includes(workspaceName));
|
|
278
279
|
}
|
|
279
280
|
}
|
|
@@ -117,10 +117,8 @@ export const getImportsAndExports = (sourceFile, options) => {
|
|
|
117
117
|
for (const visitor of visitors.export) {
|
|
118
118
|
if (visitor) {
|
|
119
119
|
const results = visitor(node, options);
|
|
120
|
-
if (results)
|
|
120
|
+
if (results)
|
|
121
121
|
[results].flat().forEach(addExport);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
124
|
for (const visitor of visitors.script) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.10.
|
|
1
|
+
export declare const version = "2.10.4";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.10.
|
|
1
|
+
export const version = '2.10.4';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.4",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://github.com/webpro/knip",
|
|
6
6
|
"repository": "github:webpro/knip",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"lint": "eslint scripts src tests",
|
|
23
23
|
"lint:fix": "eslint scripts src tests --fix",
|
|
24
24
|
"format": "prettier scripts src tests schema.json --with-node-modules --write --config .prettierrc",
|
|
25
|
-
"test": "
|
|
25
|
+
"test": "glob -c \"node --no-warnings --loader tsx --test\" \"tests/**/*.test.ts\"",
|
|
26
26
|
"coverage": "c8 npm test",
|
|
27
27
|
"watch": "tsc --watch",
|
|
28
28
|
"prebuild": "node -e \"require('fs').rmSync('dist', { force: true, recursive: true })\"",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"schema.json"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@npmcli/map-workspaces": "^3.0.
|
|
44
|
+
"@npmcli/map-workspaces": "^3.0.4",
|
|
45
45
|
"@snyk/github-codeowners": "^1.1.0",
|
|
46
46
|
"bash-parser": "^0.5.0",
|
|
47
47
|
"chalk": "^5.2.0",
|
|
@@ -67,23 +67,23 @@
|
|
|
67
67
|
"@types/js-yaml": "4.0.5",
|
|
68
68
|
"@types/micromatch": "4.0.2",
|
|
69
69
|
"@types/minimist": "1.2.2",
|
|
70
|
-
"@types/node": "
|
|
70
|
+
"@types/node": "20.1.0",
|
|
71
71
|
"@types/npmcli__map-workspaces": "3.0.1",
|
|
72
72
|
"@types/webpack": "5.28.1",
|
|
73
|
-
"@typescript-eslint/eslint-plugin": "5.59.
|
|
74
|
-
"@typescript-eslint/parser": "5.59.
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "5.59.2",
|
|
74
|
+
"@typescript-eslint/parser": "5.59.2",
|
|
75
75
|
"c8": "7.13.0",
|
|
76
|
-
"eslint": "8.
|
|
76
|
+
"eslint": "8.40.0",
|
|
77
77
|
"eslint-import-resolver-typescript": "3.5.5",
|
|
78
78
|
"eslint-plugin-import": "2.27.5",
|
|
79
79
|
"eslint-plugin-n": "15.7.0",
|
|
80
|
-
"
|
|
80
|
+
"glob": "10.2.2",
|
|
81
81
|
"prettier": "2.8.8",
|
|
82
|
-
"release-it": "15.10.
|
|
82
|
+
"release-it": "15.10.3",
|
|
83
83
|
"remark-cli": "11.0.0",
|
|
84
84
|
"remark-preset-webpro": "0.0.2",
|
|
85
|
-
"tsx": "3.12.
|
|
86
|
-
"type-fest": "3.
|
|
85
|
+
"tsx": "3.12.7",
|
|
86
|
+
"type-fest": "3.10.0"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": ">=16.17.0 <17 || >=18.6.0"
|