knip 1.0.0-beta.1 → 1.0.0-beta.3
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 +5 -5
- package/dist/configuration-chief.d.ts +3 -1
- package/dist/configuration-chief.js +20 -11
- package/dist/index.js +2 -2
- package/dist/plugins/_template/index.d.ts +7 -0
- package/dist/plugins/_template/index.js +14 -0
- package/dist/plugins/_template/types.d.ts +3 -0
- package/dist/plugins/_template/types.js +1 -0
- package/dist/plugins/postcss/index.d.ts +1 -0
- package/dist/plugins/postcss/index.js +4 -1
- package/dist/types/config.d.ts +6 -29
- package/dist/util/{externalImports.d.ts → find-import-specifiers.d.ts} +0 -0
- package/dist/util/{externalImports.js → find-import-specifiers.js} +6 -2
- package/dist/util/{resolveIncludedIssueTypes.d.ts → resolve-included-issue-types.d.ts} +0 -0
- package/dist/util/{resolveIncludedIssueTypes.js → resolve-included-issue-types.js} +0 -0
- package/dist/workspace-worker.js +18 -23
- package/package.json +9 -7
- package/schema.json +81 -4
package/README.md
CHANGED
|
@@ -61,14 +61,14 @@ Create a configuration file, let's give it the default name `knip.json` with the
|
|
|
61
61
|
|
|
62
62
|
```json
|
|
63
63
|
{
|
|
64
|
-
"$schema": "https://unpkg.com/knip@
|
|
64
|
+
"$schema": "https://unpkg.com/knip@next/schema.json",
|
|
65
65
|
"entry": ["src/index.ts"],
|
|
66
66
|
"project": ["src/**/*.ts"]
|
|
67
67
|
}
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
The `entry` files target the starting point(s) to resolve code
|
|
71
|
-
files
|
|
70
|
+
The `entry` files target the starting point(s) to resolve the rest of the imported code. The `project` files should
|
|
71
|
+
contain all files to match against the files resolved from the entry files, including potentially unused files.
|
|
72
72
|
|
|
73
73
|
Then run the checks:
|
|
74
74
|
|
|
@@ -184,7 +184,7 @@ be part of the analysis. Here's a simple example:
|
|
|
184
184
|
```jsonc
|
|
185
185
|
{
|
|
186
186
|
"ignore": "**/fixtures/**",
|
|
187
|
-
"ignoreBinaries": ["
|
|
187
|
+
"ignoreBinaries": ["rm", "docker-compose"],
|
|
188
188
|
"ignoreWorkspaces": ["packages/ignore-me"],
|
|
189
189
|
"workspaces": {
|
|
190
190
|
"packages/*": {
|
|
@@ -262,7 +262,7 @@ idea of how they work and why they are needed:
|
|
|
262
262
|
- Static configuration files such as JSON and YAML always require a custom dependency resolver.
|
|
263
263
|
|
|
264
264
|
Custom dependency resolvers return all referenced dependencies for the configuration files it is given. Knip handles the
|
|
265
|
-
rest.
|
|
265
|
+
rest to find which of those dependencies are unused or missing.
|
|
266
266
|
|
|
267
267
|
### `entry`
|
|
268
268
|
|
|
@@ -15,6 +15,7 @@ export default class ConfigurationChief {
|
|
|
15
15
|
config: Configuration;
|
|
16
16
|
manifestPath: undefined | string;
|
|
17
17
|
manifest: undefined | PackageJson;
|
|
18
|
+
manifestWorkspaces: undefined | string[];
|
|
18
19
|
constructor({ cwd, isStrict, isProduction }: ConfigurationManagerOptions);
|
|
19
20
|
loadLocalConfig(): Promise<void>;
|
|
20
21
|
normalize(rawLocalConfig: z.infer<typeof ConfigurationValidator>): {
|
|
@@ -35,7 +36,8 @@ export default class ConfigurationChief {
|
|
|
35
36
|
config: WorkspaceConfiguration;
|
|
36
37
|
ancestors: string[];
|
|
37
38
|
}[]>;
|
|
38
|
-
|
|
39
|
+
getDescendentWorkspaces(name: string): Promise<string[]>;
|
|
40
|
+
getNegatedWorkspacePatterns(name: string): Promise<string[]>;
|
|
39
41
|
private getConfigKeyForWorkspace;
|
|
40
42
|
private hasConfigForWorkspace;
|
|
41
43
|
getConfigForWorkspace(workspaceName: string): WorkspaceConfiguration;
|
|
@@ -8,12 +8,12 @@ import { arrayify } from './util/array.js';
|
|
|
8
8
|
import { ConfigurationError } from './util/errors.js';
|
|
9
9
|
import { findFile, loadJSON } from './util/fs.js';
|
|
10
10
|
import parsedArgs from './util/parseArgs.js';
|
|
11
|
-
import { resolveIncludedIssueTypes } from './util/
|
|
11
|
+
import { resolveIncludedIssueTypes } from './util/resolve-included-issue-types.js';
|
|
12
12
|
import { byPathDepth } from './util/workspace.js';
|
|
13
13
|
const { values: { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [] }, } = parsedArgs;
|
|
14
14
|
const defaultWorkspaceConfig = {
|
|
15
|
-
entry: ['index.{js,ts,tsx}', 'src/index.{js,ts,tsx}'],
|
|
16
|
-
project: ['**/*.{js,ts,tsx}'],
|
|
15
|
+
entry: ['index.{js,ts,tsx}!', 'src/index.{js,ts,tsx}!'],
|
|
16
|
+
project: ['**/*.{js,ts,tsx}!'],
|
|
17
17
|
ignore: [],
|
|
18
18
|
};
|
|
19
19
|
const defaultConfig = {
|
|
@@ -35,6 +35,7 @@ export default class ConfigurationChief {
|
|
|
35
35
|
config;
|
|
36
36
|
manifestPath;
|
|
37
37
|
manifest;
|
|
38
|
+
manifestWorkspaces;
|
|
38
39
|
constructor({ cwd, isStrict, isProduction }) {
|
|
39
40
|
this.cwd = cwd ?? this.cwd;
|
|
40
41
|
this.isStrict = isStrict;
|
|
@@ -99,8 +100,8 @@ export default class ConfigurationChief {
|
|
|
99
100
|
}
|
|
100
101
|
else {
|
|
101
102
|
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) :
|
|
103
|
+
const config = typeof pluginConfig === 'string' ? [pluginConfig] : isObject ? arrayify(pluginConfig.config) : null;
|
|
104
|
+
const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
|
|
104
105
|
const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
|
|
105
106
|
workspaces[workspaceName][pluginName] = {
|
|
106
107
|
config,
|
|
@@ -115,6 +116,8 @@ export default class ConfigurationChief {
|
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
118
|
async getManifestWorkspaces() {
|
|
119
|
+
if (this.manifestWorkspaces)
|
|
120
|
+
return this.manifestWorkspaces;
|
|
118
121
|
if (this.manifest) {
|
|
119
122
|
const workspaces = await mapWorkspaces({
|
|
120
123
|
pkg: this.manifest,
|
|
@@ -122,7 +125,8 @@ export default class ConfigurationChief {
|
|
|
122
125
|
ignore: this.config.ignoreWorkspaces,
|
|
123
126
|
absolute: false,
|
|
124
127
|
});
|
|
125
|
-
|
|
128
|
+
this.manifestWorkspaces = Array.from(workspaces.values()).map(dir => path.relative(this.cwd, dir));
|
|
129
|
+
return this.manifestWorkspaces;
|
|
126
130
|
}
|
|
127
131
|
return [];
|
|
128
132
|
}
|
|
@@ -172,11 +176,17 @@ export default class ConfigurationChief {
|
|
|
172
176
|
}, []),
|
|
173
177
|
}));
|
|
174
178
|
}
|
|
175
|
-
async
|
|
179
|
+
async getDescendentWorkspaces(name) {
|
|
176
180
|
const manifestWorkspaces = await this.getManifestWorkspaces();
|
|
177
181
|
const additionalWorkspaces = this.getAdditionalWorkspaces(manifestWorkspaces);
|
|
178
182
|
return [...manifestWorkspaces, ...additionalWorkspaces]
|
|
179
|
-
.filter(workspaceName => workspaceName !==
|
|
183
|
+
.filter(workspaceName => workspaceName !== name)
|
|
184
|
+
.filter(workspaceName => name === ROOT_WORKSPACE_NAME || workspaceName.startsWith(name));
|
|
185
|
+
}
|
|
186
|
+
async getNegatedWorkspacePatterns(name) {
|
|
187
|
+
const descendentWorkspaces = await this.getDescendentWorkspaces(name);
|
|
188
|
+
return descendentWorkspaces
|
|
189
|
+
.map(workspaceName => path.relative(path.join(this.cwd, name), workspaceName))
|
|
180
190
|
.map(workspaceName => `!${workspaceName}`);
|
|
181
191
|
}
|
|
182
192
|
getConfigKeyForWorkspace(workspaceName) {
|
|
@@ -191,9 +201,8 @@ export default class ConfigurationChief {
|
|
|
191
201
|
}
|
|
192
202
|
getConfigForWorkspace(workspaceName) {
|
|
193
203
|
const key = this.getConfigKeyForWorkspace(workspaceName);
|
|
194
|
-
if (key)
|
|
195
|
-
return this.config
|
|
196
|
-
}
|
|
204
|
+
if (key && this.config?.workspaces?.[key])
|
|
205
|
+
return this.config.workspaces[key];
|
|
197
206
|
return { entry: [], project: [], ignore: [] };
|
|
198
207
|
}
|
|
199
208
|
resolveIncludedIssueTypes() {
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import ProjectPrincipal from './project-principal.js';
|
|
|
7
7
|
import SourceLab from './source-lab.js';
|
|
8
8
|
import { compact } from './util/array.js';
|
|
9
9
|
import { debugLogObject, debugLogFiles } from './util/debug.js';
|
|
10
|
-
import { _findImportModuleSpecifiers } from './util/
|
|
10
|
+
import { _findImportModuleSpecifiers } from './util/find-import-specifiers.js';
|
|
11
11
|
import { findFile, loadJSON } from './util/fs.js';
|
|
12
12
|
import { _glob } from './util/glob.js';
|
|
13
13
|
import { getPackageNameFromModuleSpecifier } from './util/modules.js';
|
|
@@ -24,7 +24,6 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
24
24
|
await chief.loadLocalConfig();
|
|
25
25
|
const deputy = new DependencyDeputy({ ignoreDependencies: chief.config.ignoreDependencies });
|
|
26
26
|
const workspaces = await chief.getActiveWorkspaces();
|
|
27
|
-
const negatedWorkspacePatterns = await chief.getNegatedWorkspacePatterns();
|
|
28
27
|
debugLogObject('Included workspaces', workspaces);
|
|
29
28
|
const report = chief.resolveIncludedIssueTypes();
|
|
30
29
|
const workspaceDirs = Object.values(workspaces)
|
|
@@ -54,6 +53,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
54
53
|
const workspaceManifest = deputy.getWorkspaceManifest(name);
|
|
55
54
|
if (!workspaceManifest)
|
|
56
55
|
continue;
|
|
56
|
+
const negatedWorkspacePatterns = await chief.getNegatedWorkspacePatterns(name);
|
|
57
57
|
const worker = new WorkspaceWorker({
|
|
58
58
|
name,
|
|
59
59
|
dir,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
|
|
2
|
+
export declare const CONFIG_FILE_PATTERNS: never[];
|
|
3
|
+
export declare const ENTRY_FILE_PATTERNS: never[];
|
|
4
|
+
export declare const PRODUCTION_ENTRY_FILE_PATTERNS: never[];
|
|
5
|
+
export declare const PROJECT_FILE_PATTERNS: never[];
|
|
6
|
+
export declare const isEnabled: IsPluginEnabledCallback;
|
|
7
|
+
export declare const findDependencies: GenericPluginCallback;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { _load } from '../../util/loader.js';
|
|
2
|
+
import { timerify } from '../../util/performance.js';
|
|
3
|
+
export const CONFIG_FILE_PATTERNS = [];
|
|
4
|
+
export const ENTRY_FILE_PATTERNS = [];
|
|
5
|
+
export const PRODUCTION_ENTRY_FILE_PATTERNS = [];
|
|
6
|
+
export const PROJECT_FILE_PATTERNS = [];
|
|
7
|
+
export const isEnabled = ({ dependencies }) => {
|
|
8
|
+
return dependencies.has('[pkg]');
|
|
9
|
+
};
|
|
10
|
+
const findPluginDependencies = async (configFilePath, { manifest }) => {
|
|
11
|
+
const config = configFilePath.endsWith('package.json') ? manifest.plugin : await _load(configFilePath);
|
|
12
|
+
return config?.plugins ?? [];
|
|
13
|
+
};
|
|
14
|
+
export const findDependencies = timerify(findPluginDependencies);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,34 +1,12 @@
|
|
|
1
|
+
import * as Plugins from '../plugins/index.js';
|
|
1
2
|
type NormalizedGlob = string[];
|
|
3
|
+
export type PluginName = keyof typeof Plugins;
|
|
2
4
|
export type PluginConfiguration = {
|
|
3
|
-
config: NormalizedGlob;
|
|
4
|
-
entry: NormalizedGlob;
|
|
5
|
-
project: NormalizedGlob;
|
|
5
|
+
config: NormalizedGlob | null;
|
|
6
|
+
entry: NormalizedGlob | null;
|
|
7
|
+
project: NormalizedGlob | null;
|
|
6
8
|
} | false;
|
|
7
|
-
|
|
8
|
-
babel: PluginConfiguration;
|
|
9
|
-
capacitor: PluginConfiguration;
|
|
10
|
-
changesets: PluginConfiguration;
|
|
11
|
-
commitlint: PluginConfiguration;
|
|
12
|
-
cypress: PluginConfiguration;
|
|
13
|
-
eslint: PluginConfiguration;
|
|
14
|
-
gatsby: PluginConfiguration;
|
|
15
|
-
jest: PluginConfiguration;
|
|
16
|
-
mocha: PluginConfiguration;
|
|
17
|
-
next: PluginConfiguration;
|
|
18
|
-
nx: PluginConfiguration;
|
|
19
|
-
nyc: PluginConfiguration;
|
|
20
|
-
playwright: PluginConfiguration;
|
|
21
|
-
postcss: PluginConfiguration;
|
|
22
|
-
prettier: PluginConfiguration;
|
|
23
|
-
remark: PluginConfiguration;
|
|
24
|
-
remix: PluginConfiguration;
|
|
25
|
-
rollup: PluginConfiguration;
|
|
26
|
-
sentry: PluginConfiguration;
|
|
27
|
-
storybook: PluginConfiguration;
|
|
28
|
-
stryker: PluginConfiguration;
|
|
29
|
-
typescript: PluginConfiguration;
|
|
30
|
-
webpack: PluginConfiguration;
|
|
31
|
-
}
|
|
9
|
+
type PluginsConfiguration = Record<PluginName, PluginConfiguration>;
|
|
32
10
|
interface BaseWorkspaceConfiguration {
|
|
33
11
|
entry: NormalizedGlob;
|
|
34
12
|
project: NormalizedGlob;
|
|
@@ -36,7 +14,6 @@ interface BaseWorkspaceConfiguration {
|
|
|
36
14
|
}
|
|
37
15
|
export interface WorkspaceConfiguration extends BaseWorkspaceConfiguration, Partial<PluginsConfiguration> {
|
|
38
16
|
}
|
|
39
|
-
export type PluginName = keyof PluginsConfiguration;
|
|
40
17
|
export interface Configuration {
|
|
41
18
|
include: string[];
|
|
42
19
|
exclude: string[];
|
|
File without changes
|
|
@@ -30,8 +30,12 @@ const findImportModuleSpecifiers = (sourceFile, options = { skipInternal: false
|
|
|
30
30
|
const moduleSpecifiers = compact([...importLiterals, ...requireCallExpressions].map(importLiteral => {
|
|
31
31
|
if (!importLiteral)
|
|
32
32
|
return;
|
|
33
|
-
if (importLiteral.isKind(ts.SyntaxKind.TemplateExpression))
|
|
34
|
-
|
|
33
|
+
if (importLiteral.isKind(ts.SyntaxKind.TemplateExpression)) {
|
|
34
|
+
const literalText = importLiteral.getFullText();
|
|
35
|
+
if (literalText.includes('${'))
|
|
36
|
+
return;
|
|
37
|
+
return literalText.slice(1, -1);
|
|
38
|
+
}
|
|
35
39
|
return importLiteral?.getLiteralText();
|
|
36
40
|
}));
|
|
37
41
|
const internalModuleSpecifiers = options.skipInternal ? [] : resolveInternal(filePath, moduleSpecifiers);
|
|
File without changes
|
|
File without changes
|
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();
|
|
@@ -76,7 +76,7 @@ export default class WorkspaceWorker {
|
|
|
76
76
|
const { entry } = this.config;
|
|
77
77
|
if (entry.length === 0)
|
|
78
78
|
return [];
|
|
79
|
-
return [entry, TEST_FILE_PATTERNS, this.
|
|
79
|
+
return [entry, TEST_FILE_PATTERNS, this.negatedWorkspacePatterns].flat();
|
|
80
80
|
}
|
|
81
81
|
getProjectFilePatterns() {
|
|
82
82
|
const { project } = this.config;
|
|
@@ -91,7 +91,7 @@ export default class WorkspaceWorker {
|
|
|
91
91
|
negatedPluginEntryFilePatterns,
|
|
92
92
|
negatedPluginProjectFilePatterns,
|
|
93
93
|
TEST_FILE_PATTERNS,
|
|
94
|
-
this.
|
|
94
|
+
this.negatedWorkspacePatterns,
|
|
95
95
|
].flat();
|
|
96
96
|
}
|
|
97
97
|
getPluginEntryFilePatterns(isIncludeProductionEntryFiles = true) {
|
|
@@ -101,14 +101,14 @@ 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);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
return [patterns, this.
|
|
111
|
+
return [patterns, this.negatedWorkspacePatterns].flat();
|
|
112
112
|
}
|
|
113
113
|
getPluginProjectFilePatterns() {
|
|
114
114
|
const patterns = [];
|
|
@@ -116,18 +116,16 @@ 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
|
-
return [patterns, this.
|
|
128
|
+
return [patterns, this.negatedWorkspacePatterns].flat();
|
|
131
129
|
}
|
|
132
130
|
getPluginConfigPatterns() {
|
|
133
131
|
const patterns = [];
|
|
@@ -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;
|
|
@@ -146,7 +144,7 @@ export default class WorkspaceWorker {
|
|
|
146
144
|
if (entry.length === 0)
|
|
147
145
|
return [];
|
|
148
146
|
const negatedEntryFiles = this.config.entry.filter(hasNoProductionSuffix).map(negate);
|
|
149
|
-
return [entry, negatedEntryFiles, negatedTestFilePatterns, this.
|
|
147
|
+
return [entry, negatedEntryFiles, negatedTestFilePatterns, this.negatedWorkspacePatterns].flat();
|
|
150
148
|
}
|
|
151
149
|
getProductionProjectFilePatterns() {
|
|
152
150
|
const project = this.config.project;
|
|
@@ -168,7 +166,7 @@ export default class WorkspaceWorker {
|
|
|
168
166
|
negatedPluginEntryFilePatterns,
|
|
169
167
|
negatedPluginProjectFilePatterns,
|
|
170
168
|
negatedTestFilePatterns,
|
|
171
|
-
this.
|
|
169
|
+
this.negatedWorkspacePatterns,
|
|
172
170
|
].flat();
|
|
173
171
|
}
|
|
174
172
|
getProductionPluginEntryFilePatterns() {
|
|
@@ -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.3",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"find",
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
"prepublishOnly": "npm test && npm run build && npm run knip",
|
|
43
43
|
"format": "remark README.md -o",
|
|
44
44
|
"release": "release-it",
|
|
45
|
-
"postinstall": "patch-package"
|
|
45
|
+
"postinstall": "patch-package",
|
|
46
|
+
"add-plugin:help": "echo 'Usage: npm run add-plugin --name=[name] (and update README.md and schema.json)'",
|
|
47
|
+
"add-plugin": "cp -R src/plugins/_template src/plugins/$npm_config_name && echo \"export * as $npm_config_name from \\\"./$npm_config_name/index.js\\\";\" >> src/plugins/index.ts"
|
|
46
48
|
},
|
|
47
49
|
"files": [
|
|
48
50
|
"dist",
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
"@snyk/github-codeowners": "1.1.0",
|
|
60
62
|
"chalk": "5.2.0",
|
|
61
63
|
"easy-table": "1.2.0",
|
|
62
|
-
"esbuild": "0.16.
|
|
64
|
+
"esbuild": "0.16.11",
|
|
63
65
|
"esbuild-register": "3.4.2",
|
|
64
66
|
"eslint": "8.30.0",
|
|
65
67
|
"fast-glob": "3.2.12",
|
|
@@ -81,11 +83,11 @@
|
|
|
81
83
|
"@types/eslint": "8.4.10",
|
|
82
84
|
"@types/js-yaml": "4.0.5",
|
|
83
85
|
"@types/micromatch": "4.0.2",
|
|
84
|
-
"@types/node": "18.11.
|
|
86
|
+
"@types/node": "18.11.18",
|
|
85
87
|
"@types/npmcli__map-workspaces": "3.0.0",
|
|
86
88
|
"@types/webpack": "5.28.0",
|
|
87
|
-
"@typescript-eslint/eslint-plugin": "5.47.
|
|
88
|
-
"@typescript-eslint/parser": "5.47.
|
|
89
|
+
"@typescript-eslint/eslint-plugin": "5.47.1",
|
|
90
|
+
"@typescript-eslint/parser": "5.47.1",
|
|
89
91
|
"eslint-import-resolver-typescript": "3.5.2",
|
|
90
92
|
"eslint-plugin-import": "2.26.0",
|
|
91
93
|
"globstar": "1.0.0",
|
|
@@ -93,7 +95,7 @@
|
|
|
93
95
|
"remark-cli": "11.0.0",
|
|
94
96
|
"remark-preset-webpro": "0.0.1",
|
|
95
97
|
"tsx": "3.12.1",
|
|
96
|
-
"type-fest": "3.
|
|
98
|
+
"type-fest": "3.5.0",
|
|
97
99
|
"typescript": "4.9.4"
|
|
98
100
|
},
|
|
99
101
|
"release-it": {
|
package/schema.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Knip configuration",
|
|
4
|
+
"description": "See https://github.com/webpro/knip",
|
|
3
5
|
"type": "object",
|
|
4
6
|
"allOf": [
|
|
5
7
|
{
|
|
@@ -7,25 +9,45 @@
|
|
|
7
9
|
},
|
|
8
10
|
{
|
|
9
11
|
"$ref": "#/definitions/plugins"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"properties": {
|
|
15
|
+
"$schema": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"title": "JSON Schema",
|
|
18
|
+
"description": "Pointer to the schema against which this document should be validated."
|
|
19
|
+
}
|
|
20
|
+
}
|
|
10
21
|
}
|
|
11
22
|
],
|
|
12
23
|
"properties": {
|
|
13
24
|
"ignoreBinaries": {
|
|
25
|
+
"title": "Binaries to ignore",
|
|
26
|
+
"examples": ["rm", "docker-compose", "eslint"],
|
|
14
27
|
"$ref": "#/definitions/list"
|
|
15
28
|
},
|
|
16
29
|
"ignoreDependencies": {
|
|
30
|
+
"title": "Dependencies from package.json to ignore",
|
|
31
|
+
"examples": ["husky", "lint-staged"],
|
|
17
32
|
"$ref": "#/definitions/list"
|
|
18
33
|
},
|
|
19
34
|
"ignoreWorkspaces": {
|
|
35
|
+
"title": "Workspaces to ignore",
|
|
36
|
+
"examples": ["packages/ignore-me"],
|
|
20
37
|
"$ref": "#/definitions/list"
|
|
21
38
|
},
|
|
22
39
|
"include": {
|
|
23
|
-
"
|
|
40
|
+
"title": "Include issue types in the report",
|
|
41
|
+
"examples": ["files", "dependencies"],
|
|
42
|
+
"$ref": "#/definitions/issueTypes"
|
|
24
43
|
},
|
|
25
44
|
"exclude": {
|
|
26
|
-
"
|
|
45
|
+
"title": "Exclude issue types from the report",
|
|
46
|
+
"examples": ["classMembers", "enumMembers"],
|
|
47
|
+
"$ref": "#/definitions/issueTypes"
|
|
27
48
|
},
|
|
28
49
|
"workspaces": {
|
|
50
|
+
"title": "Configuration for workspaces",
|
|
29
51
|
"type": "object",
|
|
30
52
|
"additionalProperties": {
|
|
31
53
|
"allOf": [
|
|
@@ -48,7 +70,26 @@
|
|
|
48
70
|
"type": "string"
|
|
49
71
|
}
|
|
50
72
|
},
|
|
73
|
+
"issueTypes": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"items": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"enum": [
|
|
78
|
+
"files",
|
|
79
|
+
"dependencies",
|
|
80
|
+
"unlisted",
|
|
81
|
+
"exports",
|
|
82
|
+
"nsExports",
|
|
83
|
+
"classMembers",
|
|
84
|
+
"types",
|
|
85
|
+
"nsTypes",
|
|
86
|
+
"enumMembers",
|
|
87
|
+
"duplicates"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
},
|
|
51
91
|
"globPatterns": {
|
|
92
|
+
"description": "Use file paths and glob patterns to match files. Knip uses fast-glob and and minimatch (https://github.com/micromatch/micromatch#matching-features)",
|
|
52
93
|
"anyOf": [
|
|
53
94
|
{
|
|
54
95
|
"type": "string"
|
|
@@ -62,22 +103,30 @@
|
|
|
62
103
|
]
|
|
63
104
|
},
|
|
64
105
|
"workspace": {
|
|
65
|
-
"description": "Workspace configuration.",
|
|
66
106
|
"type": "object",
|
|
67
107
|
"properties": {
|
|
68
108
|
"entry": {
|
|
109
|
+
"title": "The entry files target the starting point(s) to resolve the rest of the imported code.",
|
|
110
|
+
"example": ["lib/index.ts"],
|
|
111
|
+
"default": ["index.{js,ts,tsx}", "src/index.{js,ts,tsx}"],
|
|
69
112
|
"$ref": "#/definitions/globPatterns"
|
|
70
113
|
},
|
|
71
114
|
"project": {
|
|
115
|
+
"title": "The project files should contain all files to match against the files resolved from the entry files, including potentially unused files.",
|
|
116
|
+
"example": ["lib/**/*.ts"],
|
|
117
|
+
"default": ["**/*.{js,ts,tsx}"],
|
|
72
118
|
"$ref": "#/definitions/globPatterns"
|
|
73
119
|
},
|
|
74
120
|
"ignore": {
|
|
121
|
+
"title": "Files to ignore in the analysis.",
|
|
122
|
+
"example": ["**/fixtures", "mocks"],
|
|
123
|
+
"default": [],
|
|
75
124
|
"$ref": "#/definitions/globPatterns"
|
|
76
125
|
}
|
|
77
126
|
}
|
|
78
127
|
},
|
|
79
128
|
"plugin": {
|
|
80
|
-
"description": "Knip plugin configuration. See https://github.com/webpro/knip#plugins",
|
|
129
|
+
"description": "Knip plugin configuration. See https://github.com/webpro/knip/blob/next/README.md#plugins",
|
|
81
130
|
"anyOf": [
|
|
82
131
|
{ "const": false },
|
|
83
132
|
{
|
|
@@ -87,12 +136,17 @@
|
|
|
87
136
|
"type": "object",
|
|
88
137
|
"properties": {
|
|
89
138
|
"config": {
|
|
139
|
+
"title": "The custom dependency resolver of this plugin is applied to the files listed here. Also see https://github.com/webpro/knip/blob/next/README.md#config",
|
|
140
|
+
"examples": [".eslintrc.json"],
|
|
90
141
|
"$ref": "#/definitions/globPatterns"
|
|
91
142
|
},
|
|
92
143
|
"entry": {
|
|
144
|
+
"title": "The entry files target the starting point(s) to resolve its imported dependencies, like regular source code.",
|
|
145
|
+
"examples": ["**/*.story.ts", "**/*.spec.ts"],
|
|
93
146
|
"$ref": "#/definitions/globPatterns"
|
|
94
147
|
},
|
|
95
148
|
"project": {
|
|
149
|
+
"title": "The project files should contain all files to match against the files resolved from the entry files for this plugin, including potentially unused files.",
|
|
96
150
|
"$ref": "#/definitions/globPatterns"
|
|
97
151
|
}
|
|
98
152
|
},
|
|
@@ -103,72 +157,95 @@
|
|
|
103
157
|
"plugins": {
|
|
104
158
|
"properties": {
|
|
105
159
|
"babel": {
|
|
160
|
+
"title": "Babel plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/babel/README.md)",
|
|
106
161
|
"$ref": "#/definitions/plugin"
|
|
107
162
|
},
|
|
108
163
|
"capacitor": {
|
|
164
|
+
"title": "Capacitor plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/capacitor/README.md)",
|
|
109
165
|
"$ref": "#/definitions/plugin"
|
|
110
166
|
},
|
|
111
167
|
"changesets": {
|
|
168
|
+
"title": "Changesets plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/changesets/README.md)",
|
|
112
169
|
"$ref": "#/definitions/plugin"
|
|
113
170
|
},
|
|
114
171
|
"commitlint": {
|
|
172
|
+
"title": "commitlint plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/commitlint/README.md)",
|
|
115
173
|
"$ref": "#/definitions/plugin"
|
|
116
174
|
},
|
|
117
175
|
"cypress": {
|
|
176
|
+
"title": "Cypress plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/cypress/README.md)",
|
|
118
177
|
"$ref": "#/definitions/plugin"
|
|
119
178
|
},
|
|
120
179
|
"eslint": {
|
|
180
|
+
"title": "ESLint plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/eslint/README.md)",
|
|
121
181
|
"$ref": "#/definitions/plugin"
|
|
122
182
|
},
|
|
123
183
|
"gatsby": {
|
|
184
|
+
"title": "Gatsby plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/gatsby/README.md)",
|
|
124
185
|
"$ref": "#/definitions/plugin"
|
|
125
186
|
},
|
|
126
187
|
"jest": {
|
|
188
|
+
"title": "Jest plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/jest/README.md)",
|
|
127
189
|
"$ref": "#/definitions/plugin"
|
|
128
190
|
},
|
|
129
191
|
"mocha": {
|
|
192
|
+
"title": "Mocha plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/mocha/README.md)",
|
|
130
193
|
"$ref": "#/definitions/plugin"
|
|
131
194
|
},
|
|
132
195
|
"next": {
|
|
196
|
+
"title": "Next.js plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/next/README.md)",
|
|
133
197
|
"$ref": "#/definitions/plugin"
|
|
134
198
|
},
|
|
135
199
|
"nx": {
|
|
200
|
+
"title": "Nx plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/nx/README.md)",
|
|
136
201
|
"$ref": "#/definitions/plugin"
|
|
137
202
|
},
|
|
138
203
|
"nyc": {
|
|
204
|
+
"title": "nyc plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/nyc/README.md)",
|
|
139
205
|
"$ref": "#/definitions/plugin"
|
|
140
206
|
},
|
|
141
207
|
"playwright": {
|
|
208
|
+
"title": "Playwright plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/playwright/README.md)",
|
|
142
209
|
"$ref": "#/definitions/plugin"
|
|
143
210
|
},
|
|
144
211
|
"postcss": {
|
|
212
|
+
"title": "PostCSS plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/postcss/README.md)",
|
|
145
213
|
"$ref": "#/definitions/plugin"
|
|
146
214
|
},
|
|
147
215
|
"prettier": {
|
|
216
|
+
"title": "Prettier plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/prettier/README.md)",
|
|
148
217
|
"$ref": "#/definitions/plugin"
|
|
149
218
|
},
|
|
150
219
|
"remark": {
|
|
220
|
+
"title": "Remark plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/remark/README.md)",
|
|
151
221
|
"$ref": "#/definitions/plugin"
|
|
152
222
|
},
|
|
153
223
|
"remix": {
|
|
224
|
+
"title": "Remix plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/remix/README.md)",
|
|
154
225
|
"$ref": "#/definitions/plugin"
|
|
155
226
|
},
|
|
156
227
|
"rollup": {
|
|
228
|
+
"title": "Rollup plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/rollup/README.md)",
|
|
157
229
|
"$ref": "#/definitions/plugin"
|
|
158
230
|
},
|
|
159
231
|
"sentry": {
|
|
232
|
+
"title": "Sentry plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/sentry/README.md)",
|
|
160
233
|
"$ref": "#/definitions/plugin"
|
|
161
234
|
},
|
|
162
235
|
"storybook": {
|
|
236
|
+
"title": "Storybook plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/storybook/README.md)",
|
|
163
237
|
"$ref": "#/definitions/plugin"
|
|
164
238
|
},
|
|
165
239
|
"stryker": {
|
|
240
|
+
"title": "Stryker plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/stryker/README.md)",
|
|
166
241
|
"$ref": "#/definitions/plugin"
|
|
167
242
|
},
|
|
168
243
|
"typescript": {
|
|
244
|
+
"title": "TypeScript plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/typescript/README.md)",
|
|
169
245
|
"$ref": "#/definitions/plugin"
|
|
170
246
|
},
|
|
171
247
|
"webpack": {
|
|
248
|
+
"title": "Webpack plugin configuration (https://github.com/webpro/knip/blob/next/src/plugins/webpack/README.md)",
|
|
172
249
|
"$ref": "#/definitions/plugin"
|
|
173
250
|
}
|
|
174
251
|
}
|