knip 1.0.0-beta.0 → 1.0.0-beta.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 +37 -17
- package/dist/configuration-chief.js +2 -2
- package/dist/plugins/eslint/helpers.js +1 -1
- package/dist/plugins/eslint/index.js +1 -1
- package/dist/plugins/postcss/index.d.ts +1 -0
- package/dist/plugins/postcss/index.js +4 -1
- package/dist/types/config.d.ts +3 -3
- package/dist/util/fs.js +2 -7
- package/dist/util/loader.js +5 -11
- package/dist/workspace-worker.js +12 -17
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -368,25 +368,45 @@ all of this, why not collect the various issues in one go?
|
|
|
368
368
|
|
|
369
369
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
370
370
|
|
|
371
|
-
| Feature
|
|
372
|
-
|
|
|
373
|
-
| Unused files
|
|
374
|
-
| Unused dependencies
|
|
375
|
-
| Unlisted dependencies
|
|
376
|
-
| [Custom dependency resolvers][44]
|
|
377
|
-
| Unused exports
|
|
378
|
-
| Unused class members
|
|
379
|
-
| Unused enum members
|
|
380
|
-
| Duplicate exports
|
|
381
|
-
| Search namespaces
|
|
382
|
-
| Custom reporters
|
|
383
|
-
| JavaScript support
|
|
384
|
-
| Configure entry files
|
|
385
|
-
| [Support monorepos][45]
|
|
386
|
-
| ESLint plugin available
|
|
371
|
+
| Feature | **knip** | [depcheck][39] | [unimported][40] | [ts-unused-exports][41] | [ts-prune][42] | [find-unused-exports][43] |
|
|
372
|
+
| :--------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: | :-----------------------: |
|
|
373
|
+
| Unused files | ✅ | - | ✅ | - | - | - |
|
|
374
|
+
| Unused dependencies | ✅ | ✅ | ✅ | - | - | - |
|
|
375
|
+
| Unlisted dependencies | ✅ | ✅ | ✅ | - | - | - |
|
|
376
|
+
| [Custom dependency resolvers][44] | ✅ | ✅ | ❌ | - | - | - |
|
|
377
|
+
| Unused exports | ✅ | - | - | ✅ | ✅ | ✅ |
|
|
378
|
+
| Unused class members | ✅ | - | - | - | - | - |
|
|
379
|
+
| Unused enum members | ✅ | - | - | - | - | - |
|
|
380
|
+
| Duplicate exports | ✅ | - | - | ❌ | ❌ | ❌ |
|
|
381
|
+
| Search namespaces | ✅ | - | - | ✅ | ❌ | ❌ |
|
|
382
|
+
| Custom reporters | ✅ | - | - | - | - | - |
|
|
383
|
+
| JavaScript support | ✅ | ✅ | ✅ | - | - | ✅ |
|
|
384
|
+
| Configure entry files | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
|
385
|
+
| [Support workspaces/monorepos][45] | ✅ | ❌ | ❌ | - | - | - |
|
|
386
|
+
| ESLint plugin available | - | - | - | ✅ | - | - |
|
|
387
387
|
|
|
388
388
|
✅ = Supported, ❌ = Not supported, - = Out of scope
|
|
389
389
|
|
|
390
|
+
### Migrating from other tools
|
|
391
|
+
|
|
392
|
+
WIP
|
|
393
|
+
|
|
394
|
+
### depcheck
|
|
395
|
+
|
|
396
|
+
The following commands are similar:
|
|
397
|
+
|
|
398
|
+
depcheck
|
|
399
|
+
knip --include dependencies,unlisted
|
|
400
|
+
|
|
401
|
+
### unimported
|
|
402
|
+
|
|
403
|
+
The following commands are similar:
|
|
404
|
+
|
|
405
|
+
unimported
|
|
406
|
+
knip --production --include files,dependencies,unlisted
|
|
407
|
+
|
|
408
|
+
See [production mode](#production-mode).
|
|
409
|
+
|
|
390
410
|
## TypeScript language services
|
|
391
411
|
|
|
392
412
|
TypeScript language services could play a major role in most of the "unused" areas, as they have an overview of the
|
|
@@ -443,4 +463,4 @@ for the job. I'm motivated to make knip perfectly suited for the job of cutting
|
|
|
443
463
|
[42]: https://github.com/nadeesha/ts-prune
|
|
444
464
|
[43]: https://github.com/jaydenseric/find-unused-exports
|
|
445
465
|
[44]: #custom-dependency-resolvers
|
|
446
|
-
[45]: #monorepos
|
|
466
|
+
[45]: #workspaces--monorepos
|
|
@@ -99,8 +99,8 @@ export default class ConfigurationChief {
|
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
101
101
|
const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
|
|
102
|
-
const config = isObject ? arrayify(pluginConfig.config) :
|
|
103
|
-
const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) :
|
|
102
|
+
const config = typeof pluginConfig === 'string' ? [pluginConfig] : isObject ? arrayify(pluginConfig.config) : null;
|
|
103
|
+
const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
|
|
104
104
|
const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
|
|
105
105
|
workspaces[workspaceName][pluginName] = {
|
|
106
106
|
config,
|
|
@@ -3,7 +3,7 @@ import { getPackageName } from '../../util/modules.js';
|
|
|
3
3
|
const resolvePackageName = (namespace, pluginName) => {
|
|
4
4
|
return pluginName.startsWith('@')
|
|
5
5
|
? pluginName.includes('/')
|
|
6
|
-
? pluginName
|
|
6
|
+
? pluginName.replace(/\//, `/${namespace}-`)
|
|
7
7
|
: `${pluginName}/${namespace}`
|
|
8
8
|
: `${namespace}-${pluginName}`;
|
|
9
9
|
};
|
|
@@ -7,7 +7,7 @@ import { getPackageName } from '../../util/modules.js';
|
|
|
7
7
|
import { timerify } from '../../util/performance.js';
|
|
8
8
|
import { resolvePluginPackageName, customResolvePluginPackageNames, getDependenciesFromSettings } from './helpers.js';
|
|
9
9
|
export const isEnabled = ({ dependencies }) => dependencies.has('eslint');
|
|
10
|
-
export const CONFIG_FILE_PATTERNS = ['.eslintrc', '.eslintrc.{js,json,cjs}', 'package.json'];
|
|
10
|
+
export const CONFIG_FILE_PATTERNS = ['.eslintrc', '.eslintrc.{js,json,cjs}', '.eslintrc.{yml,yaml}', 'package.json'];
|
|
11
11
|
export const ENTRY_FILE_PATTERNS = ['eslint.config.js'];
|
|
12
12
|
const findESLintDependencies = async (configFilePath, { cwd, manifest, workspaceConfig }) => {
|
|
13
13
|
if (configFilePath.endsWith('package.json') && !manifest.eslintConfig)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
|
|
2
2
|
export declare const isEnabled: IsPluginEnabledCallback;
|
|
3
3
|
export declare const CONFIG_FILE_PATTERNS: string[];
|
|
4
|
+
export declare const ENTRY_FILE_PATTERNS: string[];
|
|
4
5
|
export declare const findDependencies: GenericPluginCallback;
|
|
@@ -3,12 +3,15 @@ import { getPackageName } from '../../util/modules.js';
|
|
|
3
3
|
import { timerify } from '../../util/performance.js';
|
|
4
4
|
export const isEnabled = ({ dependencies }) => dependencies.has('postcss');
|
|
5
5
|
export const CONFIG_FILE_PATTERNS = ['postcss.config.js', 'package.json'];
|
|
6
|
+
export const ENTRY_FILE_PATTERNS = ['postcss.config.js'];
|
|
6
7
|
const findPostCSSDependencies = async (configFilePath, { manifest }) => {
|
|
7
8
|
const config = configFilePath.endsWith('package.json')
|
|
8
9
|
? manifest?.postcss
|
|
9
10
|
: await _load(configFilePath);
|
|
10
11
|
return config?.plugins
|
|
11
|
-
? (Array.isArray(config.plugins) ? config.plugins : Object.keys(config.plugins))
|
|
12
|
+
? (Array.isArray(config.plugins) ? config.plugins : Object.keys(config.plugins))
|
|
13
|
+
.filter(plugin => typeof plugin === 'string')
|
|
14
|
+
.map(getPackageName)
|
|
12
15
|
: [];
|
|
13
16
|
};
|
|
14
17
|
export const findDependencies = timerify(findPostCSSDependencies);
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
type NormalizedGlob = string[];
|
|
2
2
|
export type PluginConfiguration = {
|
|
3
|
-
config: NormalizedGlob;
|
|
4
|
-
entry: NormalizedGlob;
|
|
5
|
-
project: NormalizedGlob;
|
|
3
|
+
config: NormalizedGlob | null;
|
|
4
|
+
entry: NormalizedGlob | null;
|
|
5
|
+
project: NormalizedGlob | null;
|
|
6
6
|
} | false;
|
|
7
7
|
interface PluginsConfiguration {
|
|
8
8
|
babel: PluginConfiguration;
|
package/dist/util/fs.js
CHANGED
|
@@ -15,11 +15,6 @@ export const findFile = async (workingDir, fileName) => {
|
|
|
15
15
|
return (await isFile(filePath)) ? filePath : undefined;
|
|
16
16
|
};
|
|
17
17
|
export const loadJSON = async (filePath) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return JSON.parse(stripJsonComments(contents.toString()));
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
console.log(error?.toString());
|
|
24
|
-
}
|
|
18
|
+
const contents = await fs.readFile(filePath);
|
|
19
|
+
return JSON.parse(stripJsonComments(contents.toString()));
|
|
25
20
|
};
|
package/dist/util/loader.js
CHANGED
|
@@ -9,19 +9,13 @@ import { timerify } from './performance.js';
|
|
|
9
9
|
const require = createRequire(process.cwd());
|
|
10
10
|
const { values: { 'no-progress': noProgress = false }, } = parsedArgs;
|
|
11
11
|
const load = async (filePath) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (path.extname(filePath) === '.yaml' || path.extname(filePath) === '.yml') {
|
|
16
|
-
try {
|
|
17
|
-
return yaml.load((await fs.readFile(filePath)).toString());
|
|
12
|
+
try {
|
|
13
|
+
if (path.extname(filePath) === '.json' || /rc$/.test(filePath)) {
|
|
14
|
+
return loadJSON(filePath);
|
|
18
15
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
console.log(error?.toString());
|
|
16
|
+
if (path.extname(filePath) === '.yaml' || path.extname(filePath) === '.yml') {
|
|
17
|
+
return yaml.load((await fs.readFile(filePath)).toString());
|
|
22
18
|
}
|
|
23
|
-
}
|
|
24
|
-
try {
|
|
25
19
|
const imported = await esmLoad(filePath, {}, require);
|
|
26
20
|
return imported.default ?? imported;
|
|
27
21
|
}
|
package/dist/workspace-worker.js
CHANGED
|
@@ -37,7 +37,7 @@ export default class WorkspaceWorker {
|
|
|
37
37
|
this.enabled = Object.keys(plugins).reduce((enabled, pluginName) => ({ ...enabled, [pluginName]: false }), {});
|
|
38
38
|
}
|
|
39
39
|
getConfigForPlugin(pluginName) {
|
|
40
|
-
return this.config[pluginName] ?? { config:
|
|
40
|
+
return this.config[pluginName] ?? { config: null, entry: null, project: null };
|
|
41
41
|
}
|
|
42
42
|
async init() {
|
|
43
43
|
this.setEnabledPlugins();
|
|
@@ -101,7 +101,7 @@ export default class WorkspaceWorker {
|
|
|
101
101
|
if (this.enabled[pluginName] && pluginConfig) {
|
|
102
102
|
const { entry } = pluginConfig;
|
|
103
103
|
const defaultEntryFiles = 'ENTRY_FILE_PATTERNS' in plugin ? plugin.ENTRY_FILE_PATTERNS : [];
|
|
104
|
-
patterns.push(...(entry
|
|
104
|
+
patterns.push(...(entry ?? defaultEntryFiles));
|
|
105
105
|
if (isIncludeProductionEntryFiles) {
|
|
106
106
|
const entry = 'PRODUCTION_ENTRY_FILE_PATTERNS' in plugin ? plugin.PRODUCTION_ENTRY_FILE_PATTERNS : [];
|
|
107
107
|
patterns.push(...entry);
|
|
@@ -116,15 +116,13 @@ export default class WorkspaceWorker {
|
|
|
116
116
|
const pluginConfig = this.getConfigForPlugin(pluginName);
|
|
117
117
|
if (this.enabled[pluginName] && pluginConfig) {
|
|
118
118
|
const { entry, project } = pluginConfig;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
? entry
|
|
127
|
-
: defaultEntryFiles));
|
|
119
|
+
patterns.push(...(project ??
|
|
120
|
+
entry ??
|
|
121
|
+
('PROJECT_FILE_PATTERNS' in plugin
|
|
122
|
+
? plugin.PROJECT_FILE_PATTERNS
|
|
123
|
+
: 'ENTRY_FILE_PATTERNS' in plugin
|
|
124
|
+
? plugin.ENTRY_FILE_PATTERNS
|
|
125
|
+
: [])));
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
return [patterns, this.isRoot ? this.negatedWorkspacePatterns : []].flat();
|
|
@@ -136,7 +134,7 @@ export default class WorkspaceWorker {
|
|
|
136
134
|
if (this.enabled[pluginName] && pluginConfig) {
|
|
137
135
|
const { config } = pluginConfig;
|
|
138
136
|
const defaultConfigFiles = 'CONFIG_FILE_PATTERNS' in plugin ? plugin.CONFIG_FILE_PATTERNS : [];
|
|
139
|
-
patterns.push(...(config
|
|
137
|
+
patterns.push(...(config ?? defaultConfigFiles));
|
|
140
138
|
}
|
|
141
139
|
}
|
|
142
140
|
return patterns;
|
|
@@ -177,9 +175,7 @@ export default class WorkspaceWorker {
|
|
|
177
175
|
const pluginConfig = this.getConfigForPlugin(pluginName);
|
|
178
176
|
if (this.enabled[pluginName] && pluginConfig) {
|
|
179
177
|
if ('PRODUCTION_ENTRY_FILE_PATTERNS' in plugin) {
|
|
180
|
-
|
|
181
|
-
const defaultEntryFiles = plugin.PRODUCTION_ENTRY_FILE_PATTERNS;
|
|
182
|
-
patterns.push(...(entry.length > 0 ? entry : defaultEntryFiles));
|
|
178
|
+
patterns.push(...(pluginConfig.entry ?? plugin.PRODUCTION_ENTRY_FILE_PATTERNS));
|
|
183
179
|
}
|
|
184
180
|
}
|
|
185
181
|
}
|
|
@@ -191,9 +187,8 @@ export default class WorkspaceWorker {
|
|
|
191
187
|
const plugin = plugins[pluginName];
|
|
192
188
|
const pluginConfig = this.getConfigForPlugin(pluginName);
|
|
193
189
|
if (pluginConfig) {
|
|
194
|
-
const { config } = pluginConfig;
|
|
195
190
|
const defaultConfig = 'CONFIG_FILE_PATTERNS' in plugin ? plugin.CONFIG_FILE_PATTERNS : [];
|
|
196
|
-
return
|
|
191
|
+
return pluginConfig.config ?? defaultConfig;
|
|
197
192
|
}
|
|
198
193
|
return [];
|
|
199
194
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"find",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@snyk/github-codeowners": "1.1.0",
|
|
60
60
|
"chalk": "5.2.0",
|
|
61
61
|
"easy-table": "1.2.0",
|
|
62
|
-
"esbuild": "0.16.
|
|
62
|
+
"esbuild": "0.16.10",
|
|
63
63
|
"esbuild-register": "3.4.2",
|
|
64
64
|
"eslint": "8.30.0",
|
|
65
65
|
"fast-glob": "3.2.12",
|
|
@@ -81,11 +81,11 @@
|
|
|
81
81
|
"@types/eslint": "8.4.10",
|
|
82
82
|
"@types/js-yaml": "4.0.5",
|
|
83
83
|
"@types/micromatch": "4.0.2",
|
|
84
|
-
"@types/node": "18.11.
|
|
84
|
+
"@types/node": "18.11.17",
|
|
85
85
|
"@types/npmcli__map-workspaces": "3.0.0",
|
|
86
86
|
"@types/webpack": "5.28.0",
|
|
87
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
88
|
-
"@typescript-eslint/parser": "5.
|
|
87
|
+
"@typescript-eslint/eslint-plugin": "5.47.0",
|
|
88
|
+
"@typescript-eslint/parser": "5.47.0",
|
|
89
89
|
"eslint-import-resolver-typescript": "3.5.2",
|
|
90
90
|
"eslint-plugin-import": "2.26.0",
|
|
91
91
|
"globstar": "1.0.0",
|