knip 1.0.2 → 1.1.0
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 +20 -3
- package/dist/configuration-chief.js +7 -2
- package/dist/index.js +1 -1
- package/dist/source-lab.d.ts +3 -1
- package/dist/source-lab.js +10 -2
- package/dist/util/cli-arguments.d.ts +3 -1
- package/dist/util/cli-arguments.js +4 -0
- package/dist/util/resolve-included-issue-types.d.ts +9 -1
- package/dist/util/resolve-included-issue-types.js +10 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,6 +97,8 @@ Use `npm run knip` to analyze the project and output unused files, dependencies
|
|
|
97
97
|
--no-gitignore Don't use .gitignore
|
|
98
98
|
--include Report only provided issue type(s), can be comma-separated or repeated (1)
|
|
99
99
|
--exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
|
|
100
|
+
--dependencies Shortcut for --include dependencies,unlisted
|
|
101
|
+
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
100
102
|
--no-progress Don't show dynamic progress updates
|
|
101
103
|
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
102
104
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
@@ -159,6 +161,8 @@ Use `--exclude` to ignore reports you're not interested in:
|
|
|
159
161
|
|
|
160
162
|
knip --include files --exclude classMembers,enumMembers
|
|
161
163
|
|
|
164
|
+
Use `--dependencies` or `--exports` as shortcuts to combine groups of related types.
|
|
165
|
+
|
|
162
166
|
Still not happy with the results? Getting too much output/false positives? The [FAQ][9] may be useful. Feel free to open
|
|
163
167
|
an issue and I'm happy to look into it.
|
|
164
168
|
|
|
@@ -404,7 +408,7 @@ how many dependencies are used and how much the project diverges from the defaul
|
|
|
404
408
|
One important goal of Knip is to minimize the amount of configuration necessary. So when there are feasible ways to
|
|
405
409
|
infer things automatically, reducing the amount of configuration, please open an issue.
|
|
406
410
|
|
|
407
|
-
### How do I handle too
|
|
411
|
+
### How do I handle too many output/false positives?
|
|
408
412
|
|
|
409
413
|
#### Too many unused files
|
|
410
414
|
|
|
@@ -430,6 +434,17 @@ When the project is a library and the exports are meant to be used by consumers
|
|
|
430
434
|
1. By default, unused exports of `entry` files are not reported, so you can add the containing file to it.
|
|
431
435
|
2. The exported values or types can be marked [using the JSDoc `@public` tag][42].
|
|
432
436
|
|
|
437
|
+
### How to start using Knip in CI while having too many issues to sort out?
|
|
438
|
+
|
|
439
|
+
Eventually this type of QA only really works when it's tied to an automated workflow. But with too many issues to
|
|
440
|
+
resolve this might not be feasible right away, especially in existing larger codebase. Here are a few options:
|
|
441
|
+
|
|
442
|
+
- Use `--no-exit-code` for exit code 0 in CI.
|
|
443
|
+
- Use `--include` (or `--exclude`) to report only the issue types don't have errors.
|
|
444
|
+
- Use `ignore` (for files and directories) and `ignoreDependencies` to filter out some problematic areas.
|
|
445
|
+
|
|
446
|
+
All of this is hiding problems, so please make sure to plan for fixing them and/or open issues here for false positives.
|
|
447
|
+
|
|
433
448
|
## Comparison
|
|
434
449
|
|
|
435
450
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
@@ -460,14 +475,14 @@ This table is an ongoing comparison. Based on their docs (please report any mist
|
|
|
460
475
|
The following commands are similar:
|
|
461
476
|
|
|
462
477
|
depcheck
|
|
463
|
-
knip --
|
|
478
|
+
knip --dependencies
|
|
464
479
|
|
|
465
480
|
### unimported
|
|
466
481
|
|
|
467
482
|
The following commands are similar:
|
|
468
483
|
|
|
469
484
|
unimported
|
|
470
|
-
knip --production --include files
|
|
485
|
+
knip --production --dependencies --include files
|
|
471
486
|
|
|
472
487
|
Also see [production mode][48].
|
|
473
488
|
|
|
@@ -477,6 +492,7 @@ The following commands are similar:
|
|
|
477
492
|
|
|
478
493
|
ts-unused-exports
|
|
479
494
|
knip --include exports,types,nsExports,nsTypes
|
|
495
|
+
knip --exports # Adds unused enum and class members
|
|
480
496
|
|
|
481
497
|
### ts-prune
|
|
482
498
|
|
|
@@ -484,6 +500,7 @@ The following commands are similar:
|
|
|
484
500
|
|
|
485
501
|
ts-prune
|
|
486
502
|
knip --include exports,types
|
|
503
|
+
knip --exports # Adds unused exports/types in namespaces and unused enum/class members
|
|
487
504
|
|
|
488
505
|
## TypeScript language services
|
|
489
506
|
|
|
@@ -11,7 +11,7 @@ import { findFile, loadJSON } from './util/fs.js';
|
|
|
11
11
|
import { ensurePosixPath } from './util/glob.js';
|
|
12
12
|
import { resolveIncludedIssueTypes } from './util/resolve-included-issue-types.js';
|
|
13
13
|
import { byPathDepth } from './util/workspace.js';
|
|
14
|
-
const { values: { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [] }, } = parsedArgs;
|
|
14
|
+
const { values: { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [], dependencies = false, exports = false, }, } = parsedArgs;
|
|
15
15
|
const defaultWorkspaceConfig = {
|
|
16
16
|
entry: ['index.{js,ts,tsx}!', 'src/index.{js,ts,tsx}!'],
|
|
17
17
|
project: ['**/*.{js,ts,tsx}!'],
|
|
@@ -209,7 +209,12 @@ export default class ConfigurationChief {
|
|
|
209
209
|
return { entry: [], project: [], ignore: [] };
|
|
210
210
|
}
|
|
211
211
|
resolveIncludedIssueTypes() {
|
|
212
|
-
return resolveIncludedIssueTypes(
|
|
212
|
+
return resolveIncludedIssueTypes({
|
|
213
|
+
include,
|
|
214
|
+
exclude,
|
|
215
|
+
dependencies,
|
|
216
|
+
exports,
|
|
217
|
+
}, {
|
|
213
218
|
include: this.config.include ?? [],
|
|
214
219
|
exclude: this.config.exclude ?? [],
|
|
215
220
|
isProduction: this.isProduction,
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
29
29
|
.map(workspace => workspace.dir)
|
|
30
30
|
.sort(byPathDepth)
|
|
31
31
|
.reverse();
|
|
32
|
-
const lab = new SourceLab({ report, workspaceDirs });
|
|
32
|
+
const lab = new SourceLab({ report, workspaceDirs, isIncludeEntryExports });
|
|
33
33
|
const principal = new ProjectPrincipal();
|
|
34
34
|
for (const { name, dir, config, ancestors } of workspaces) {
|
|
35
35
|
const isRoot = name === ROOT_WORKSPACE_NAME;
|
package/dist/source-lab.d.ts
CHANGED
|
@@ -3,15 +3,17 @@ import type { Report, Issue } from './types/issues.js';
|
|
|
3
3
|
type FileLabOptions = {
|
|
4
4
|
report: Report;
|
|
5
5
|
workspaceDirs: string[];
|
|
6
|
+
isIncludeEntryExports: boolean;
|
|
6
7
|
};
|
|
7
8
|
export default class SourceLab {
|
|
8
9
|
report: Report;
|
|
9
10
|
workspaceDirs: string[];
|
|
11
|
+
isIncludeEntryExports: boolean;
|
|
10
12
|
skipExportsAnalysis: Set<unknown>;
|
|
11
13
|
isReportExports: boolean;
|
|
12
14
|
isReportValues: boolean;
|
|
13
15
|
isReportTypes: boolean;
|
|
14
|
-
constructor({ report, workspaceDirs }: FileLabOptions);
|
|
16
|
+
constructor({ report, workspaceDirs, isIncludeEntryExports }: FileLabOptions);
|
|
15
17
|
skipExportsAnalysisFor(filePath: string | string[]): void;
|
|
16
18
|
analyzeSourceFile(sourceFile: SourceFile): Set<Issue>;
|
|
17
19
|
private analyzeExports;
|
package/dist/source-lab.js
CHANGED
|
@@ -5,13 +5,15 @@ import { getType } from './util/type.js';
|
|
|
5
5
|
export default class SourceLab {
|
|
6
6
|
report;
|
|
7
7
|
workspaceDirs;
|
|
8
|
+
isIncludeEntryExports;
|
|
8
9
|
skipExportsAnalysis;
|
|
9
10
|
isReportExports;
|
|
10
11
|
isReportValues;
|
|
11
12
|
isReportTypes;
|
|
12
|
-
constructor({ report, workspaceDirs }) {
|
|
13
|
+
constructor({ report, workspaceDirs, isIncludeEntryExports }) {
|
|
13
14
|
this.report = report;
|
|
14
15
|
this.workspaceDirs = workspaceDirs;
|
|
16
|
+
this.isIncludeEntryExports = isIncludeEntryExports;
|
|
15
17
|
this.skipExportsAnalysis = new Set();
|
|
16
18
|
this.isReportValues = report.exports || report.nsExports || report.classMembers;
|
|
17
19
|
this.isReportTypes = report.types || report.nsTypes || report.enumMembers;
|
|
@@ -104,7 +106,13 @@ export default class SourceLab {
|
|
|
104
106
|
else {
|
|
105
107
|
if (hasExternalReferences(refs, filePath))
|
|
106
108
|
return;
|
|
107
|
-
|
|
109
|
+
const referencingNodes = _findReferencingNamespaceNodes(sourceFile);
|
|
110
|
+
if (referencingNodes.length > 0) {
|
|
111
|
+
if (!this.isIncludeEntryExports && referencingNodes.length === 1) {
|
|
112
|
+
const referencingSourceFile = referencingNodes.at(0)?.getSourceFile().getFilePath();
|
|
113
|
+
if (this.skipExportsAnalysis.has(referencingSourceFile))
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
108
116
|
if (type) {
|
|
109
117
|
issues.add({ type: 'nsTypes', filePath, symbol: identifierText, symbolType: type });
|
|
110
118
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
export declare const helpText = "knip [options]\n\nOptions:\n -c/--config [file] Configuration file path (default: knip.json, knip.jsonc or package.json#knip)\n -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\n --include-entry-exports Include unused exports in entry files (without `@public`)\n --ignore Ignore files matching this glob pattern, can be repeated\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --no-progress Don't show dynamic progress updates\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure running time of expensive functions and display stats table\n\n(1) Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore info: https://github.com/webpro/knip";
|
|
1
|
+
export declare const helpText = "knip [options]\n\nOptions:\n -c/--config [file] Configuration file path (default: knip.json, knip.jsonc or package.json#knip)\n -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\n --include-entry-exports Include unused exports in entry files (without `@public`)\n --ignore Ignore files matching this glob pattern, can be repeated\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --no-progress Don't show dynamic progress updates\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure running time of expensive functions and display stats table\n\n(1) Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore info: https://github.com/webpro/knip";
|
|
2
2
|
declare const _default: {
|
|
3
3
|
values: {
|
|
4
4
|
config: string | undefined;
|
|
5
5
|
debug: boolean | undefined;
|
|
6
6
|
'debug-file-filter': string | undefined;
|
|
7
|
+
dependencies: boolean | undefined;
|
|
7
8
|
exclude: string[] | undefined;
|
|
9
|
+
exports: boolean | undefined;
|
|
8
10
|
help: boolean | undefined;
|
|
9
11
|
ignore: string[] | undefined;
|
|
10
12
|
'include-entry-exports': boolean | undefined;
|
|
@@ -12,6 +12,8 @@ Options:
|
|
|
12
12
|
--no-gitignore Don't use .gitignore
|
|
13
13
|
--include Report only provided issue type(s), can be comma-separated or repeated (1)
|
|
14
14
|
--exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
|
|
15
|
+
--dependencies Shortcut for --include dependencies,unlisted
|
|
16
|
+
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
15
17
|
--no-progress Don't show dynamic progress updates
|
|
16
18
|
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
17
19
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
@@ -38,7 +40,9 @@ export default parseArgs({
|
|
|
38
40
|
config: { type: 'string', short: 'c' },
|
|
39
41
|
debug: { type: 'boolean' },
|
|
40
42
|
'debug-file-filter': { type: 'string' },
|
|
43
|
+
dependencies: { type: 'boolean' },
|
|
41
44
|
exclude: { type: 'string', multiple: true },
|
|
45
|
+
exports: { type: 'boolean' },
|
|
42
46
|
help: { type: 'boolean', short: 'h' },
|
|
43
47
|
ignore: { type: 'string', multiple: true },
|
|
44
48
|
'include-entry-exports': { type: 'boolean' },
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { Report } from '../types/issues.js';
|
|
2
|
+
type CLIArguments = {
|
|
3
|
+
include: string[];
|
|
4
|
+
exclude: string[];
|
|
5
|
+
dependencies: boolean;
|
|
6
|
+
exports: boolean;
|
|
7
|
+
};
|
|
2
8
|
type Options = {
|
|
3
9
|
isProduction?: boolean;
|
|
4
10
|
include?: string[];
|
|
5
11
|
exclude?: string[];
|
|
12
|
+
dependencies?: boolean;
|
|
13
|
+
exports?: boolean;
|
|
6
14
|
};
|
|
7
|
-
export declare const resolveIncludedIssueTypes: (
|
|
15
|
+
export declare const resolveIncludedIssueTypes: (cliArgs: CLIArguments, { include, exclude, isProduction }?: Options) => Report;
|
|
8
16
|
export {};
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { ISSUE_TYPES } from '../constants.js';
|
|
2
|
-
export const resolveIncludedIssueTypes = (
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export const resolveIncludedIssueTypes = (cliArgs, { include = [], exclude = [], isProduction = false } = {}) => {
|
|
3
|
+
if (cliArgs.dependencies) {
|
|
4
|
+
cliArgs.include = [...cliArgs.include, 'dependencies', 'unlisted'];
|
|
5
|
+
}
|
|
6
|
+
if (cliArgs.exports) {
|
|
7
|
+
const exports = ['exports', 'nsExports', 'classMembers', 'types', 'nsTypes', 'enumMembers', 'duplicates'];
|
|
8
|
+
cliArgs.include = [...cliArgs.include, ...exports];
|
|
9
|
+
}
|
|
10
|
+
const normalizedIncludesArg = cliArgs.include.map(value => value.split(',')).flat();
|
|
11
|
+
const normalizedExcludesArg = cliArgs.exclude.map(value => value.split(',')).flat();
|
|
5
12
|
const excludes = exclude.filter(exclude => !normalizedIncludesArg.includes(exclude));
|
|
6
13
|
const includes = include.filter(include => !normalizedExcludesArg.includes(include));
|
|
7
14
|
const _include = [normalizedIncludesArg, includes].flat();
|
package/package.json
CHANGED