knip 2.14.0-next.0 → 2.14.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 +10 -1
- package/dist/ProjectPrincipal.d.ts +7 -2
- package/dist/ProjectPrincipal.js +9 -5
- package/dist/index.js +6 -6
- package/dist/plugins/webpack/index.js +2 -0
- package/dist/typescript/getImportsAndExports.d.ts +1 -0
- package/dist/typescript/getImportsAndExports.js +2 -0
- package/dist/util/cli-arguments.d.ts +1 -1
- package/dist/util/cli-arguments.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,7 +142,7 @@ Using workspaces in a monorepo? Please see [workspaces][1] for more details abou
|
|
|
142
142
|
--exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
|
|
143
143
|
--dependencies Shortcut for --include dependencies,unlisted,unresolved
|
|
144
144
|
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
145
|
-
--include-entry-exports
|
|
145
|
+
--include-entry-exports Include entry files when reporting unused exports
|
|
146
146
|
-n, --no-progress Don't show dynamic progress updates
|
|
147
147
|
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
148
148
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
@@ -579,6 +579,15 @@ export const split = function () {};
|
|
|
579
579
|
|
|
580
580
|
Knip does not report public exports and types as unused.
|
|
581
581
|
|
|
582
|
+
## Include exports in entry files
|
|
583
|
+
|
|
584
|
+
When a repository is self-contained or private, you may want to include entry files when reporting unused exports:
|
|
585
|
+
|
|
586
|
+
knip --include-entry-exports
|
|
587
|
+
|
|
588
|
+
Knip will also report unused exports in entry source files and scripts (such as those referenced in `package.json`). But
|
|
589
|
+
not in entry and configuration files from plugins, such as `next.config.js` or `src/routes/+page.svelte`.
|
|
590
|
+
|
|
582
591
|
## Handling Issues
|
|
583
592
|
|
|
584
593
|
How to handle a long list of reported issues? Seeing too many false positives? Read more about [handling issues][17]
|
|
@@ -10,6 +10,7 @@ type ProjectPrincipalOptions = {
|
|
|
10
10
|
export declare class ProjectPrincipal {
|
|
11
11
|
entryPaths: Set<string>;
|
|
12
12
|
projectPaths: Set<string>;
|
|
13
|
+
skipExportsAnalysis: Set<string>;
|
|
13
14
|
cwd: string;
|
|
14
15
|
compilerOptions: ts.CompilerOptions;
|
|
15
16
|
extensions: Set<string>;
|
|
@@ -25,8 +26,12 @@ export declare class ProjectPrincipal {
|
|
|
25
26
|
constructor({ compilerOptions, cwd, compilers }: ProjectPrincipalOptions);
|
|
26
27
|
private createProgram;
|
|
27
28
|
private hasAcceptedExtension;
|
|
28
|
-
addEntryPath(filePath: string
|
|
29
|
-
|
|
29
|
+
addEntryPath(filePath: string, options?: {
|
|
30
|
+
skipExportsAnalysis: boolean;
|
|
31
|
+
}): void;
|
|
32
|
+
addEntryPaths(filePaths: Set<string> | string[], options?: {
|
|
33
|
+
skipExportsAnalysis: boolean;
|
|
34
|
+
}): void;
|
|
30
35
|
addProjectPath(filePath: string): void;
|
|
31
36
|
runAsyncCompilers(): Promise<void>;
|
|
32
37
|
getUsedResolvedFiles(): string[];
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -22,6 +22,7 @@ const tsCreateProgram = timerify(ts.createProgram);
|
|
|
22
22
|
export class ProjectPrincipal {
|
|
23
23
|
entryPaths = new Set();
|
|
24
24
|
projectPaths = new Set();
|
|
25
|
+
skipExportsAnalysis = new Set();
|
|
25
26
|
cwd;
|
|
26
27
|
compilerOptions;
|
|
27
28
|
extensions;
|
|
@@ -62,14 +63,16 @@ export class ProjectPrincipal {
|
|
|
62
63
|
hasAcceptedExtension(filePath) {
|
|
63
64
|
return this.extensions.has(extname(filePath));
|
|
64
65
|
}
|
|
65
|
-
addEntryPath(filePath) {
|
|
66
|
+
addEntryPath(filePath, options) {
|
|
66
67
|
if (!isInNodeModules(filePath) && this.hasAcceptedExtension(filePath)) {
|
|
67
68
|
this.entryPaths.add(filePath);
|
|
68
69
|
this.projectPaths.add(filePath);
|
|
70
|
+
if (options?.skipExportsAnalysis)
|
|
71
|
+
this.skipExportsAnalysis.add(filePath);
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
|
-
addEntryPaths(filePaths) {
|
|
72
|
-
filePaths.forEach(filePath => this.addEntryPath(filePath));
|
|
74
|
+
addEntryPaths(filePaths, options) {
|
|
75
|
+
filePaths.forEach(filePath => this.addEntryPath(filePath, options));
|
|
73
76
|
}
|
|
74
77
|
addProjectPath(filePath) {
|
|
75
78
|
if (!isInNodeModules(filePath) && this.hasAcceptedExtension(filePath)) {
|
|
@@ -101,7 +104,8 @@ export class ProjectPrincipal {
|
|
|
101
104
|
const sourceFile = this.backend.program?.getSourceFile(filePath);
|
|
102
105
|
if (!sourceFile)
|
|
103
106
|
throw new Error(`Unable to find ${filePath}`);
|
|
104
|
-
const
|
|
107
|
+
const skipExports = this.skipExportsAnalysis.has(filePath);
|
|
108
|
+
const { imports, exports, scripts } = getImportsAndExports(sourceFile, { skipTypeOnly, skipExports });
|
|
105
109
|
const { internal, unresolved, external } = imports;
|
|
106
110
|
const unresolvedImports = new Set();
|
|
107
111
|
unresolved.forEach(specifier => {
|
|
@@ -114,7 +118,7 @@ export class ProjectPrincipal {
|
|
|
114
118
|
external.add(specifier);
|
|
115
119
|
}
|
|
116
120
|
else {
|
|
117
|
-
this.addEntryPath(resolvedModule.resolvedFileName);
|
|
121
|
+
this.addEntryPath(resolvedModule.resolvedFileName, { skipExportsAnalysis: true });
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
else {
|
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
71
71
|
if (otherWorkspace) {
|
|
72
72
|
const filePath = _resolveSpecifier(otherWorkspace.dir, specifier);
|
|
73
73
|
if (filePath) {
|
|
74
|
-
principal.addEntryPath(filePath);
|
|
74
|
+
principal.addEntryPath(filePath, { skipExportsAnalysis: true });
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
77
|
collector.addIssue({ type: 'unresolved', filePath: containingFilePath, symbol: specifier });
|
|
@@ -121,7 +121,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
121
121
|
const patterns = worker.getProductionPluginEntryFilePatterns();
|
|
122
122
|
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
|
|
123
123
|
debugLogArray(`Found production plugin entry paths (${name})`, pluginWorkspaceEntryPaths);
|
|
124
|
-
principal.addEntryPaths(pluginWorkspaceEntryPaths);
|
|
124
|
+
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
125
125
|
}
|
|
126
126
|
{
|
|
127
127
|
const patterns = worker.getProductionProjectFilePatterns();
|
|
@@ -147,7 +147,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
147
147
|
const patterns = worker.getPluginEntryFilePatterns();
|
|
148
148
|
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
|
|
149
149
|
debugLogArray(`Found plugin entry paths (${name})`, pluginWorkspaceEntryPaths);
|
|
150
|
-
principal.addEntryPaths(pluginWorkspaceEntryPaths);
|
|
150
|
+
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
151
151
|
}
|
|
152
152
|
{
|
|
153
153
|
const patterns = worker.getPluginProjectFilePatterns();
|
|
@@ -159,11 +159,11 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
159
159
|
const patterns = compact(worker.getPluginConfigPatterns());
|
|
160
160
|
const configurationEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
|
|
161
161
|
debugLogArray(`Found plugin configuration paths (${name})`, configurationEntryPaths);
|
|
162
|
-
principal.addEntryPaths(configurationEntryPaths);
|
|
162
|
+
principal.addEntryPaths(configurationEntryPaths, { skipExportsAnalysis: true });
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
if (chief.resolvedConfigFilePath)
|
|
166
|
-
principal.addEntryPath(chief.resolvedConfigFilePath);
|
|
166
|
+
principal.addEntryPath(chief.resolvedConfigFilePath, { skipExportsAnalysis: true });
|
|
167
167
|
const dependencies = await worker.findAllDependencies();
|
|
168
168
|
const { referencedDependencies, peerDependencies, installedBinaries, enabledPlugins } = dependencies;
|
|
169
169
|
deputy.addPeerDependencies(name, peerDependencies);
|
|
@@ -288,7 +288,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
288
288
|
continue;
|
|
289
289
|
}
|
|
290
290
|
const isStar = Boolean(importedModule?.isStar);
|
|
291
|
-
const isReExportedByEntryFile = isStar && isExportedInEntryFile(importedModule);
|
|
291
|
+
const isReExportedByEntryFile = !isIncludeEntryExports && isStar && isExportedInEntryFile(importedModule);
|
|
292
292
|
if (!isReExportedByEntryFile && !isExportedItemReferenced(exportedItem, filePath)) {
|
|
293
293
|
if (['enum', 'type', 'interface'].includes(exportedItem.type)) {
|
|
294
294
|
if (isProduction)
|
|
@@ -22,6 +22,8 @@ const resolveRuleSetDependencies = (rule) => {
|
|
|
22
22
|
if (typeof useItem === 'function')
|
|
23
23
|
useItem = useItem(info);
|
|
24
24
|
return [useItem].flat().flatMap((useItem) => {
|
|
25
|
+
if (!useItem)
|
|
26
|
+
return [];
|
|
25
27
|
if (hasBabelOptions(useItem)) {
|
|
26
28
|
return [
|
|
27
29
|
...resolveUseItem(useItem),
|
|
@@ -4,6 +4,7 @@ import type { ExportItems as Exports, ExportItem } from '../types/exports.js';
|
|
|
4
4
|
import type { Imports } from '../types/imports.js';
|
|
5
5
|
export type GetImportsAndExportsOptions = {
|
|
6
6
|
skipTypeOnly: boolean;
|
|
7
|
+
skipExports: boolean;
|
|
7
8
|
};
|
|
8
9
|
export type AddImportOptions = {
|
|
9
10
|
specifier: string;
|
|
@@ -86,6 +86,8 @@ export const getImportsAndExports = (sourceFile, options) => {
|
|
|
86
86
|
}
|
|
87
87
|
};
|
|
88
88
|
const addExport = ({ node, identifier, type, pos, members }) => {
|
|
89
|
+
if (options.skipExports)
|
|
90
|
+
return;
|
|
89
91
|
if (exports.has(identifier)) {
|
|
90
92
|
const item = exports.get(identifier);
|
|
91
93
|
exports.set(identifier, { ...item, node, type, pos, members });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts 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 --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,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports
|
|
1
|
+
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts 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 --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,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n -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-config-hints Suppress configuration hints\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 -d, --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure count and running time of expensive functions and display stats table\n --h, --help Print this help text\n --V, version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, 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 documentation and bug reports: https://github.com/webpro/knip";
|
|
2
2
|
declare const _default: {
|
|
3
3
|
config: string | undefined;
|
|
4
4
|
debug: boolean | undefined;
|
|
@@ -14,7 +14,7 @@ Options:
|
|
|
14
14
|
--exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
|
|
15
15
|
--dependencies Shortcut for --include dependencies,unlisted,unresolved
|
|
16
16
|
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
17
|
-
--include-entry-exports
|
|
17
|
+
--include-entry-exports Include entry files when reporting unused exports
|
|
18
18
|
-n, --no-progress Don't show dynamic progress updates
|
|
19
19
|
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
20
20
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.14.0
|
|
1
|
+
export declare const version = "2.14.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.14.0
|
|
1
|
+
export const version = '2.14.0';
|
package/package.json
CHANGED