knip 2.21.0 → 2.21.2
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 +43 -44
- package/dist/ConfigurationChief.d.ts +3 -3
- package/dist/ConfigurationChief.js +15 -12
- package/dist/index.js +14 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -624,7 +624,7 @@ Tip: back up files or use an VCS like Git before deleting files or making change
|
|
|
624
624
|
|
|
625
625
|
Repeat the process to reveal new unused files and exports. It's so liberating to remove unused things!
|
|
626
626
|
|
|
627
|
-
Getting too many reported issues and false positives? Read more about [handling issues][
|
|
627
|
+
Getting too many reported issues and false positives? Read more about [handling issues][48] describing potential causes
|
|
628
628
|
for false positives, and how to handle them.
|
|
629
629
|
|
|
630
630
|
## Command Line Options
|
|
@@ -675,13 +675,13 @@ for false positives, and how to handle them.
|
|
|
675
675
|
|
|
676
676
|
## Potential boost with `--no-gitignore`
|
|
677
677
|
|
|
678
|
-
To increase performance in a large monorepo, check out [Potential boost with `--no-gitignore`][
|
|
678
|
+
To increase performance in a large monorepo, check out [Potential boost with `--no-gitignore`][50].
|
|
679
679
|
|
|
680
680
|
## Comparison & Migration
|
|
681
681
|
|
|
682
682
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
683
683
|
|
|
684
|
-
| Feature | **knip** | [depcheck][
|
|
684
|
+
| Feature | **knip** | [depcheck][51] | [unimported][52] | [ts-unused-exports][53] | [ts-prune][54] |
|
|
685
685
|
| :---------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
|
|
686
686
|
| Unused files | ✅ | - | ✅ | - | - |
|
|
687
687
|
| Unused dependencies | ✅ | ✅ | ✅ | - | - |
|
|
@@ -739,25 +739,25 @@ The following commands are similar:
|
|
|
739
739
|
|
|
740
740
|
Many thanks to some of the early adopters of Knip:
|
|
741
741
|
|
|
742
|
-
- [Block Protocol][
|
|
743
|
-
- [DeepmergeTS][
|
|
744
|
-
- [eslint-plugin-functional][
|
|
745
|
-
- [freeCodeCamp.org][
|
|
746
|
-
- [is-immutable-type][
|
|
747
|
-
- [IsaacScript][
|
|
748
|
-
- [Nuxt][
|
|
749
|
-
- [Owncast][
|
|
750
|
-
- [release-it][
|
|
751
|
-
- [Template TypeScript Node Package][
|
|
752
|
-
- [Tipi][
|
|
742
|
+
- [Block Protocol][55]
|
|
743
|
+
- [DeepmergeTS][56]
|
|
744
|
+
- [eslint-plugin-functional][57]
|
|
745
|
+
- [freeCodeCamp.org][58]
|
|
746
|
+
- [is-immutable-type][59]
|
|
747
|
+
- [IsaacScript][60]
|
|
748
|
+
- [Nuxt][61]
|
|
749
|
+
- [Owncast][62]
|
|
750
|
+
- [release-it][63]
|
|
751
|
+
- [Template TypeScript Node Package][64]
|
|
752
|
+
- [Tipi][65]
|
|
753
753
|
|
|
754
754
|
## Articles, etc.
|
|
755
755
|
|
|
756
756
|
- Discord: hang out in [The Knip Barn][9]
|
|
757
|
-
- Ask your questions in the [Knip knowledge base][
|
|
758
|
-
- Smashing Magazine: [Knip: An Automated Tool For Finding Unused Files, Exports, And Dependencies][
|
|
759
|
-
- Effective TypeScript: [Recommendation Update: ✂️ Use knip to detect dead code and types][
|
|
760
|
-
- Josh Goldberg: [Speeding Up Centered Part 4: Unused Code Bloat][
|
|
757
|
+
- Ask your questions in the [Knip knowledge base][66] (powered by OpenAI and [7-docs][67], experimental!)
|
|
758
|
+
- Smashing Magazine: [Knip: An Automated Tool For Finding Unused Files, Exports, And Dependencies][68]
|
|
759
|
+
- Effective TypeScript: [Recommendation Update: ✂️ Use knip to detect dead code and types][69]
|
|
760
|
+
- Josh Goldberg: [Speeding Up Centered Part 4: Unused Code Bloat][70]
|
|
761
761
|
|
|
762
762
|
## Why "Knip"?
|
|
763
763
|
|
|
@@ -775,7 +775,7 @@ each file, and traversing all of this, why not collect the various issues in one
|
|
|
775
775
|
|
|
776
776
|
Special thanks to the wonderful people who have contributed to this project:
|
|
777
777
|
|
|
778
|
-
[![Contributors][
|
|
778
|
+
[![Contributors][72]][71]
|
|
779
779
|
|
|
780
780
|
[1]: #workspaces
|
|
781
781
|
[2]: #plugins
|
|
@@ -824,32 +824,31 @@ Special thanks to the wonderful people who have contributed to this project:
|
|
|
824
824
|
[45]: https://nx.dev/concepts/integrated-vs-package-based
|
|
825
825
|
[46]: ./docs/writing-a-plugin.md
|
|
826
826
|
[47]: ./docs/compilers.md
|
|
827
|
-
[48]:
|
|
827
|
+
[48]: ./docs/handling-issues.md
|
|
828
828
|
[49]: ./docs/reporters-and-preprocessors.md
|
|
829
|
-
[50]: ./docs/
|
|
830
|
-
[51]:
|
|
831
|
-
[52]: https://github.com/
|
|
832
|
-
[53]: https://github.com/
|
|
833
|
-
[54]: https://github.com/
|
|
834
|
-
[55]: https://github.com/
|
|
835
|
-
[56]: https://github.com/
|
|
836
|
-
[57]: https://github.com/
|
|
837
|
-
[58]: https://github.com/
|
|
838
|
-
[59]: https://github.com/
|
|
839
|
-
[60]: https://github.com/
|
|
840
|
-
[61]: https://github.com/
|
|
841
|
-
[62]: https://github.com/
|
|
842
|
-
[63]: https://github.com/
|
|
843
|
-
[64]: https://github.com/
|
|
844
|
-
[65]: https://github.com/
|
|
845
|
-
[66]: https://
|
|
846
|
-
[67]: https://
|
|
847
|
-
[68]: https://
|
|
848
|
-
[69]: https://
|
|
849
|
-
[70]: https://
|
|
850
|
-
[71]: https://
|
|
851
|
-
[72]: https://
|
|
852
|
-
[73]: https://contrib.rocks/image?repo=webpro/knip
|
|
829
|
+
[50]: ./docs/perf-boost-with-no-gitignore.md
|
|
830
|
+
[51]: https://github.com/depcheck/depcheck
|
|
831
|
+
[52]: https://github.com/smeijer/unimported
|
|
832
|
+
[53]: https://github.com/pzavolinsky/ts-unused-exports
|
|
833
|
+
[54]: https://github.com/nadeesha/ts-prune
|
|
834
|
+
[55]: https://github.com/blockprotocol/blockprotocol
|
|
835
|
+
[56]: https://github.com/RebeccaStevens/deepmerge-ts
|
|
836
|
+
[57]: https://github.com/eslint-functional/eslint-plugin-functional
|
|
837
|
+
[58]: https://github.com/freeCodeCamp/freeCodeCamp
|
|
838
|
+
[59]: https://github.com/RebeccaStevens/is-immutable-type
|
|
839
|
+
[60]: https://github.com/IsaacScript/isaacscript
|
|
840
|
+
[61]: https://github.com/nuxt/nuxt
|
|
841
|
+
[62]: https://github.com/owncast/owncast
|
|
842
|
+
[63]: https://github.com/release-it/release-it
|
|
843
|
+
[64]: https://github.com/JoshuaKGoldberg/template-typescript-node-package
|
|
844
|
+
[65]: https://github.com/meienberger/runtipi
|
|
845
|
+
[66]: https://knip.deno.dev
|
|
846
|
+
[67]: https://github.com/7-docs/7-docs
|
|
847
|
+
[68]: https://www.smashingmagazine.com/2023/08/knip-automated-tool-find-unused-files-exports-dependencies/
|
|
848
|
+
[69]: https://effectivetypescript.com/2023/07/29/knip/
|
|
849
|
+
[70]: https://www.joshuakgoldberg.com/blog/speeding-up-centered-part-4-unused-code-bloat/
|
|
850
|
+
[71]: https://github.com/webpro/knip/graphs/contributors
|
|
851
|
+
[72]: https://contrib.rocks/image?repo=webpro/knip
|
|
853
852
|
[plugin-ava]: ./src/plugins/ava
|
|
854
853
|
[plugin-babel]: ./src/plugins/babel
|
|
855
854
|
[plugin-capacitor]: ./src/plugins/capacitor
|
|
@@ -22,8 +22,8 @@ export declare class ConfigurationChief {
|
|
|
22
22
|
ignoredWorkspacePatterns: string[];
|
|
23
23
|
manifestWorkspaces: Map<string, string>;
|
|
24
24
|
additionalWorkspaceNames: Set<string>;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
availableWorkspaceNames: string[];
|
|
26
|
+
availableWorkspaceDirs: string[];
|
|
27
27
|
enabledWorkspaces: Workspace[];
|
|
28
28
|
localWorkspaces: Set<string>;
|
|
29
29
|
resolvedConfigFilePath?: string;
|
|
@@ -37,7 +37,7 @@ export declare class ConfigurationChief {
|
|
|
37
37
|
private getIgnoredWorkspacePatterns;
|
|
38
38
|
private getManifestWorkspaces;
|
|
39
39
|
private getAdditionalWorkspaceNames;
|
|
40
|
-
private
|
|
40
|
+
private getAvailableWorkspaceNames;
|
|
41
41
|
private getEnabledWorkspaces;
|
|
42
42
|
getWorkspaces(): Workspace[];
|
|
43
43
|
private getDescendentWorkspaces;
|
|
@@ -55,8 +55,8 @@ export class ConfigurationChief {
|
|
|
55
55
|
ignoredWorkspacePatterns = [];
|
|
56
56
|
manifestWorkspaces = new Map();
|
|
57
57
|
additionalWorkspaceNames = new Set();
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
availableWorkspaceNames = [];
|
|
59
|
+
availableWorkspaceDirs = [];
|
|
60
60
|
enabledWorkspaces = [];
|
|
61
61
|
localWorkspaces = new Set();
|
|
62
62
|
resolvedConfigFilePath;
|
|
@@ -170,12 +170,12 @@ export class ConfigurationChief {
|
|
|
170
170
|
this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
|
|
171
171
|
this.manifestWorkspaces = await this.getManifestWorkspaces();
|
|
172
172
|
this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
175
|
-
this.enabledWorkspaceDirs = this.enabledWorkspaceNames
|
|
173
|
+
this.availableWorkspaceNames = this.getAvailableWorkspaceNames();
|
|
174
|
+
this.availableWorkspaceDirs = this.availableWorkspaceNames
|
|
176
175
|
.sort(byPathDepth)
|
|
177
176
|
.reverse()
|
|
178
177
|
.map(dir => join(this.cwd, dir));
|
|
178
|
+
this.enabledWorkspaces = this.getEnabledWorkspaces();
|
|
179
179
|
this.localWorkspaces = new Set(compact(this.enabledWorkspaces.map(w => w.pkgName)));
|
|
180
180
|
}
|
|
181
181
|
getListedWorkspaces() {
|
|
@@ -211,16 +211,13 @@ export class ConfigurationChief {
|
|
|
211
211
|
!this.manifestWorkspaces.has(name) &&
|
|
212
212
|
!micromatch.isMatch(name, this.ignoredWorkspacePatterns)));
|
|
213
213
|
}
|
|
214
|
-
|
|
214
|
+
getAvailableWorkspaceNames() {
|
|
215
215
|
return [ROOT_WORKSPACE_NAME, ...this.manifestWorkspaces.keys(), ...this.additionalWorkspaceNames].filter(name => !micromatch.isMatch(name, this.ignoredWorkspacePatterns));
|
|
216
216
|
}
|
|
217
217
|
getEnabledWorkspaces() {
|
|
218
218
|
if (workspaceArg && !existsSync(workspaceArg)) {
|
|
219
219
|
throw new ConfigurationError(`Directory does not exist: ${workspaceArg}`);
|
|
220
220
|
}
|
|
221
|
-
const workspaceNames = workspaceArg
|
|
222
|
-
? this.enabledWorkspaceNames.filter(name => name === workspaceArg)
|
|
223
|
-
: this.enabledWorkspaceNames;
|
|
224
221
|
const getAncestors = (name) => (ancestors, ancestorName) => {
|
|
225
222
|
if (name === ancestorName)
|
|
226
223
|
return ancestors;
|
|
@@ -228,19 +225,25 @@ export class ConfigurationChief {
|
|
|
228
225
|
ancestors.push(ancestorName);
|
|
229
226
|
return ancestors;
|
|
230
227
|
};
|
|
228
|
+
const workspaceNames = workspaceArg
|
|
229
|
+
? [
|
|
230
|
+
...this.availableWorkspaceNames.reduce(getAncestors(workspaceArg), []),
|
|
231
|
+
...this.availableWorkspaceNames.filter(name => name === workspaceArg),
|
|
232
|
+
]
|
|
233
|
+
: this.availableWorkspaceNames;
|
|
231
234
|
return workspaceNames.sort(byPathDepth).map((name) => ({
|
|
232
235
|
name,
|
|
233
236
|
pkgName: this.manifestWorkspaces.get(name) ?? this.manifest?.name,
|
|
234
237
|
dir: join(this.cwd, name),
|
|
235
238
|
config: this.getConfigForWorkspace(name),
|
|
236
|
-
ancestors:
|
|
239
|
+
ancestors: this.availableWorkspaceNames.reduce(getAncestors(name), []),
|
|
237
240
|
}));
|
|
238
241
|
}
|
|
239
242
|
getWorkspaces() {
|
|
240
243
|
return this.enabledWorkspaces;
|
|
241
244
|
}
|
|
242
245
|
getDescendentWorkspaces(name) {
|
|
243
|
-
return this.
|
|
246
|
+
return this.availableWorkspaceNames
|
|
244
247
|
.filter(workspaceName => workspaceName !== name)
|
|
245
248
|
.filter(workspaceName => name === ROOT_WORKSPACE_NAME || workspaceName.startsWith(name + '/'));
|
|
246
249
|
}
|
|
@@ -280,7 +283,7 @@ export class ConfigurationChief {
|
|
|
280
283
|
return getIncludedIssueTypes(cliArgs, config);
|
|
281
284
|
}
|
|
282
285
|
findWorkspaceByFilePath(filePath) {
|
|
283
|
-
const workspaceDir = this.
|
|
286
|
+
const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(workspaceDir + '/'));
|
|
284
287
|
return this.enabledWorkspaces.find(workspace => workspace.dir === workspaceDir);
|
|
285
288
|
}
|
|
286
289
|
findWorkspaceByPackageName(packageName) {
|
package/dist/index.js
CHANGED
|
@@ -244,6 +244,15 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
244
244
|
const unusedFiles = principal.getUnreferencedFiles();
|
|
245
245
|
collector.addFilesIssues(unusedFiles);
|
|
246
246
|
collector.addFileCounts({ processed: analyzedFiles.size, unused: unusedFiles.length });
|
|
247
|
+
const isSymbolImported = (symbol, importingModule) => {
|
|
248
|
+
if (!importingModule)
|
|
249
|
+
return false;
|
|
250
|
+
if (importingModule.symbols.has(symbol))
|
|
251
|
+
return true;
|
|
252
|
+
const { isReExport, isReExportedBy } = importingModule;
|
|
253
|
+
const hasSymbol = (file) => isSymbolImported(symbol, importedSymbols.get(file));
|
|
254
|
+
return isReExport ? Array.from(isReExportedBy).some(hasSymbol) : false;
|
|
255
|
+
};
|
|
247
256
|
const isExportedInEntryFile = (importedModule) => {
|
|
248
257
|
if (!importedModule)
|
|
249
258
|
return false;
|
|
@@ -265,15 +274,15 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
265
274
|
for (const [filePath, exportItems] of exportedSymbols.entries()) {
|
|
266
275
|
if (!isIncludeEntryExports && principal.entryPaths.has(filePath))
|
|
267
276
|
continue;
|
|
268
|
-
const
|
|
277
|
+
const importingModule = importedSymbols.get(filePath);
|
|
269
278
|
for (const [symbol, exportedItem] of exportItems.entries()) {
|
|
270
279
|
const jsDocTags = principal.getJSDocTags(exportedItem);
|
|
271
280
|
if (jsDocTags.includes('@public') || jsDocTags.includes('@beta'))
|
|
272
281
|
continue;
|
|
273
282
|
if (isIgnoreInternal && jsDocTags.includes('@internal'))
|
|
274
283
|
continue;
|
|
275
|
-
if (
|
|
276
|
-
if (
|
|
284
|
+
if (importingModule && isSymbolImported(symbol, importingModule)) {
|
|
285
|
+
if (importingModule.isReExport && isExportedInEntryFile(importingModule))
|
|
277
286
|
continue;
|
|
278
287
|
if (report.enumMembers && exportedItem.type === 'enum' && exportedItem.members) {
|
|
279
288
|
if (isProduction)
|
|
@@ -289,8 +298,8 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
289
298
|
}
|
|
290
299
|
continue;
|
|
291
300
|
}
|
|
292
|
-
const isStar = Boolean(
|
|
293
|
-
const isReExportedByEntryFile = !isIncludeEntryExports && isStar && isExportedInEntryFile(
|
|
301
|
+
const isStar = Boolean(importingModule?.isStar);
|
|
302
|
+
const isReExportedByEntryFile = !isIncludeEntryExports && isStar && isExportedInEntryFile(importingModule);
|
|
294
303
|
if (!isReExportedByEntryFile && !isExportedItemReferenced(exportedItem, filePath)) {
|
|
295
304
|
if (['enum', 'type', 'interface'].includes(exportedItem.type)) {
|
|
296
305
|
if (isProduction)
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.21.
|
|
1
|
+
export declare const version = "2.21.2";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.21.
|
|
1
|
+
export const version = '2.21.2';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "2.21.
|
|
3
|
+
"version": "2.21.2",
|
|
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",
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
"@npmcli/package-json": "5.0.0",
|
|
66
66
|
"@release-it/bumper": "5.1.0",
|
|
67
67
|
"@swc/cli": "0.1.62",
|
|
68
|
-
"@swc/core": "1.3.
|
|
68
|
+
"@swc/core": "1.3.82",
|
|
69
69
|
"@types/eslint": "8.44.2",
|
|
70
70
|
"@types/js-yaml": "4.0.5",
|
|
71
71
|
"@types/micromatch": "4.0.2",
|
|
72
72
|
"@types/minimist": "1.2.2",
|
|
73
|
-
"@types/node": "20.5.
|
|
73
|
+
"@types/node": "20.5.9",
|
|
74
74
|
"@types/npmcli__map-workspaces": "3.0.1",
|
|
75
75
|
"@types/webpack": "5.28.2",
|
|
76
|
-
"@typescript-eslint/eslint-plugin": "6.
|
|
77
|
-
"@typescript-eslint/parser": "6.
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "6.6.0",
|
|
77
|
+
"@typescript-eslint/parser": "6.6.0",
|
|
78
78
|
"c8": "8.0.1",
|
|
79
79
|
"eslint": "8.48.0",
|
|
80
80
|
"eslint-import-resolver-typescript": "3.6.0",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"release-it": "16.1.5",
|
|
85
85
|
"remark-cli": "11.0.0",
|
|
86
86
|
"remark-preset-webpro": "0.0.3",
|
|
87
|
-
"tsx": "3.12.
|
|
87
|
+
"tsx": "3.12.8",
|
|
88
88
|
"type-fest": "4.3.1"
|
|
89
89
|
},
|
|
90
90
|
"engines": {
|