knip 1.0.0-beta.7 → 1.0.0-beta.8
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 +79 -90
- package/dist/plugins/babel/index.d.ts +2 -0
- package/dist/plugins/babel/index.js +1 -1
- package/dist/plugins/webpack/index.js +24 -10
- package/dist/plugins/webpack/types.d.ts +10 -0
- package/dist/plugins/webpack/types.js +1 -0
- package/dist/types/plugins.d.ts +2 -1
- package/dist/workspace-worker.js +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -36,16 +36,11 @@ with OpenAI_</sup>
|
|
|
36
36
|
|
|
37
37
|
## Migrating to v1.0.0
|
|
38
38
|
|
|
39
|
-
When coming from version v0.13.3 or before,
|
|
40
|
-
|
|
41
|
-
- The `entryFiles` and `projectFiles` options have been renamed to `entry` and `project`.
|
|
42
|
-
- The `--dev` argument and `dev: true` option are gone, this is now the default mode (see [production mode][7]).
|
|
43
|
-
- Workspaces have been moved from the root of the config to the `workspaces` key (see [workspaces][8]).
|
|
44
|
-
- The `--dir` argument has been renamed to `--workspace`.
|
|
39
|
+
When coming from version v0.13.3 or before, please see [migration to v1][7].
|
|
45
40
|
|
|
46
41
|
## Issues
|
|
47
42
|
|
|
48
|
-
Please report any false positives by [opening an issue in this repo][
|
|
43
|
+
Please report any false positives by [opening an issue in this repo][8]. Bonus points for linking to a public repository
|
|
49
44
|
using Knip, or even opening a pull request with a directory and example files in `test/fixtures`. Correctness and bug
|
|
50
45
|
fixes have priority over performance and new features.
|
|
51
46
|
|
|
@@ -182,24 +177,18 @@ As always, make sure to backup files or use Git before deleting files or making
|
|
|
182
177
|
## Workspaces & Monorepos
|
|
183
178
|
|
|
184
179
|
Workspaces and monorepos are handled out-of-the-box by Knip. Every workspace that is part of the Knip configuration will
|
|
185
|
-
be part of the analysis. Here's
|
|
180
|
+
be part of the analysis. Here's an example:
|
|
186
181
|
|
|
187
182
|
```jsonc
|
|
188
183
|
{
|
|
189
|
-
"ignore": "**/fixtures/**",
|
|
190
|
-
"ignoreBinaries": ["rm", "docker-compose"],
|
|
191
184
|
"ignoreWorkspaces": ["packages/ignore-me"],
|
|
192
185
|
"workspaces": {
|
|
193
186
|
"packages/*": {
|
|
194
|
-
"entry": "{index,cli}.ts
|
|
187
|
+
"entry": "{index,cli}.ts",
|
|
195
188
|
"project": "**/*.ts"
|
|
196
189
|
},
|
|
197
|
-
"packages/
|
|
198
|
-
"entry": "
|
|
199
|
-
},
|
|
200
|
-
"not-a-workspace/in-package.json/but-has-package.json": {
|
|
201
|
-
"entry": ["src/index.ts"],
|
|
202
|
-
"project": "src/**/*.ts"
|
|
190
|
+
"packages/my-lib": {
|
|
191
|
+
"entry": "main.js"
|
|
203
192
|
}
|
|
204
193
|
}
|
|
205
194
|
}
|
|
@@ -219,29 +208,29 @@ Here's a small output example when running Knip in a workspace:
|
|
|
219
208
|
|
|
220
209
|
Knip contains a growing list of plugins:
|
|
221
210
|
|
|
222
|
-
- [Babel][
|
|
223
|
-
- [Capacitor][
|
|
224
|
-
- [Changesets][
|
|
225
|
-
- [commitlint][
|
|
226
|
-
- [Cypress][
|
|
227
|
-
- [ESLint][
|
|
228
|
-
- [Gatsby][
|
|
229
|
-
- [Jest][
|
|
230
|
-
- [Mocha][
|
|
231
|
-
- [Next.js][
|
|
232
|
-
- [Nx][
|
|
233
|
-
- [nyc][
|
|
234
|
-
- [Playwright][
|
|
235
|
-
- [PostCSS][
|
|
236
|
-
- [Prettier][
|
|
237
|
-
- [Remark][
|
|
238
|
-
- [Remix][
|
|
239
|
-
- [Rollup][
|
|
240
|
-
- [Sentry][
|
|
241
|
-
- [Storybook][
|
|
242
|
-
- [Stryker][
|
|
243
|
-
- [TypeScript][
|
|
244
|
-
- [Webpack][
|
|
211
|
+
- [Babel][9]
|
|
212
|
+
- [Capacitor][10]
|
|
213
|
+
- [Changesets][11]
|
|
214
|
+
- [commitlint][12]
|
|
215
|
+
- [Cypress][13]
|
|
216
|
+
- [ESLint][14]
|
|
217
|
+
- [Gatsby][15]
|
|
218
|
+
- [Jest][16]
|
|
219
|
+
- [Mocha][17]
|
|
220
|
+
- [Next.js][18]
|
|
221
|
+
- [Nx][19]
|
|
222
|
+
- [nyc][20]
|
|
223
|
+
- [Playwright][21]
|
|
224
|
+
- [PostCSS][22]
|
|
225
|
+
- [Prettier][23]
|
|
226
|
+
- [Remark][24]
|
|
227
|
+
- [Remix][25]
|
|
228
|
+
- [Rollup][26]
|
|
229
|
+
- [Sentry][27]
|
|
230
|
+
- [Storybook][28]
|
|
231
|
+
- [Stryker][29]
|
|
232
|
+
- [TypeScript][30]
|
|
233
|
+
- [Webpack][31]
|
|
245
234
|
|
|
246
235
|
Plugins are automatically activated, no need to enable anything. Each plugin is automatically enabled based on simple
|
|
247
236
|
heuristics. Most of them check whether one or one of a few (dev) dependencies are listed in `package.json`. Once
|
|
@@ -249,7 +238,7 @@ enabled, they add a set of configuration and/or entry files for Knip to analyze.
|
|
|
249
238
|
|
|
250
239
|
Most plugins use one or both of the following file types:
|
|
251
240
|
|
|
252
|
-
- `config` - custom dependency resolvers are applied to the [config files][
|
|
241
|
+
- `config` - custom dependency resolvers are applied to the [config files][32]
|
|
253
242
|
- `entry` - files to include with the analysis of the rest of the source code
|
|
254
243
|
|
|
255
244
|
### `config`
|
|
@@ -341,10 +330,10 @@ locations. The more plugins Knip will have, the more projects can be analyzed ou
|
|
|
341
330
|
|
|
342
331
|
Knip provides the following built-in reporters:
|
|
343
332
|
|
|
344
|
-
- [`codeowners`][
|
|
345
|
-
- [`compact`][
|
|
346
|
-
- [`json`][
|
|
347
|
-
- [`symbol`][
|
|
333
|
+
- [`codeowners`][33]
|
|
334
|
+
- [`compact`][34]
|
|
335
|
+
- [`json`][35]
|
|
336
|
+
- [`symbol`][36] (default)
|
|
348
337
|
|
|
349
338
|
The `compact` reporter shows the sorted files first, and then a list of symbols:
|
|
350
339
|
|
|
@@ -352,7 +341,7 @@ The `compact` reporter shows the sorted files first, and then a list of symbols:
|
|
|
352
341
|
|
|
353
342
|
### Custom Reporters
|
|
354
343
|
|
|
355
|
-
When the provided built-in reporters are not
|
|
344
|
+
When the provided built-in reporters are not sufficient, a custom reporter can be implemented.
|
|
356
345
|
|
|
357
346
|
Pass `--reporter ./my-reporter`, with the default export of that module having this interface:
|
|
358
347
|
|
|
@@ -371,7 +360,7 @@ type ReporterOptions = {
|
|
|
371
360
|
|
|
372
361
|
The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service.
|
|
373
362
|
|
|
374
|
-
Find more details and ideas in [custom reporters][
|
|
363
|
+
Find more details and ideas in [custom reporters][37].
|
|
375
364
|
|
|
376
365
|
## Really, another unused file/dependency/export finder?
|
|
377
366
|
|
|
@@ -385,12 +374,12 @@ all of this, why not collect the various issues in one go?
|
|
|
385
374
|
|
|
386
375
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
387
376
|
|
|
388
|
-
| Feature | **knip** | [depcheck][
|
|
377
|
+
| Feature | **knip** | [depcheck][38] | [unimported][39] | [ts-unused-exports][40] | [ts-prune][41] | [find-unused-exports][42] |
|
|
389
378
|
| :--------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: | :-----------------------: |
|
|
390
379
|
| Unused files | ✅ | - | ✅ | - | - | - |
|
|
391
380
|
| Unused dependencies | ✅ | ✅ | ✅ | - | - | - |
|
|
392
381
|
| Unlisted dependencies | ✅ | ✅ | ✅ | - | - | - |
|
|
393
|
-
| [Custom dependency resolvers][
|
|
382
|
+
| [Custom dependency resolvers][43] | ✅ | ✅ | ❌ | - | - | - |
|
|
394
383
|
| Unused exports | ✅ | - | - | ✅ | ✅ | ✅ |
|
|
395
384
|
| Unused class members | ✅ | - | - | - | - | - |
|
|
396
385
|
| Unused enum members | ✅ | - | - | - | - | - |
|
|
@@ -399,7 +388,7 @@ This table is an ongoing comparison. Based on their docs (please report any mist
|
|
|
399
388
|
| Custom reporters | ✅ | - | - | - | - | - |
|
|
400
389
|
| JavaScript support | ✅ | ✅ | ✅ | - | - | ✅ |
|
|
401
390
|
| Configure entry files | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
|
402
|
-
| [Support workspaces/monorepos][
|
|
391
|
+
| [Support workspaces/monorepos][44] | ✅ | ❌ | ❌ | - | - | - |
|
|
403
392
|
| ESLint plugin available | - | - | - | ✅ | - | - |
|
|
404
393
|
|
|
405
394
|
✅ = Supported, ❌ = Not supported, - = Out of scope
|
|
@@ -422,7 +411,7 @@ The following commands are similar:
|
|
|
422
411
|
unimported
|
|
423
412
|
knip --production --include files,dependencies,unlisted
|
|
424
413
|
|
|
425
|
-
See [production mode][
|
|
414
|
+
See [production mode][45].
|
|
426
415
|
|
|
427
416
|
## TypeScript language services
|
|
428
417
|
|
|
@@ -442,42 +431,42 @@ for the job. I'm motivated to make knip perfectly suited for the job of cutting
|
|
|
442
431
|
[4]: #really-another-unused-filedependencyexport-finder
|
|
443
432
|
[5]: https://labs.openai.com/s/xZQACaLepaKya0PRUPtIN5dC
|
|
444
433
|
[6]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
|
|
445
|
-
[7]:
|
|
446
|
-
[8]:
|
|
447
|
-
[9]:
|
|
448
|
-
[10]: ./src/plugins/
|
|
449
|
-
[11]: ./src/plugins/
|
|
450
|
-
[12]: ./src/plugins/
|
|
451
|
-
[13]: ./src/plugins/
|
|
452
|
-
[14]: ./src/plugins/
|
|
453
|
-
[15]: ./src/plugins/
|
|
454
|
-
[16]: ./src/plugins/
|
|
455
|
-
[17]: ./src/plugins/
|
|
456
|
-
[18]: ./src/plugins/
|
|
457
|
-
[19]: ./src/plugins/
|
|
458
|
-
[20]: ./src/plugins/
|
|
459
|
-
[21]: ./src/plugins/
|
|
460
|
-
[22]: ./src/plugins/
|
|
461
|
-
[23]: ./src/plugins/
|
|
462
|
-
[24]: ./src/plugins/
|
|
463
|
-
[25]: ./src/plugins/
|
|
464
|
-
[26]: ./src/plugins/
|
|
465
|
-
[27]: ./src/plugins/
|
|
466
|
-
[28]: ./src/plugins/
|
|
467
|
-
[29]: ./src/plugins/
|
|
468
|
-
[30]: ./src/plugins/
|
|
469
|
-
[31]: ./src/plugins/
|
|
470
|
-
[32]:
|
|
471
|
-
[33]: #
|
|
472
|
-
[34]: #
|
|
473
|
-
[35]: #
|
|
474
|
-
[36]: #
|
|
475
|
-
[37]:
|
|
476
|
-
[38]:
|
|
477
|
-
[39]: https://github.com/
|
|
478
|
-
[40]: https://github.com/
|
|
479
|
-
[41]: https://github.com/
|
|
480
|
-
[42]: https://github.com/
|
|
481
|
-
[43]:
|
|
482
|
-
[44]: #
|
|
483
|
-
[45]: #
|
|
434
|
+
[7]: ./docs/migration-to-v1.md
|
|
435
|
+
[8]: https://github.com/webpro/knip/issues
|
|
436
|
+
[9]: ./src/plugins/babel
|
|
437
|
+
[10]: ./src/plugins/capacitor
|
|
438
|
+
[11]: ./src/plugins/changesets
|
|
439
|
+
[12]: ./src/plugins/commitlint
|
|
440
|
+
[13]: ./src/plugins/cypress
|
|
441
|
+
[14]: ./src/plugins/eslint
|
|
442
|
+
[15]: ./src/plugins/gatsby
|
|
443
|
+
[16]: ./src/plugins/jest
|
|
444
|
+
[17]: ./src/plugins/mocha
|
|
445
|
+
[18]: ./src/plugins/next
|
|
446
|
+
[19]: ./src/plugins/nx
|
|
447
|
+
[20]: ./src/plugins/nyc
|
|
448
|
+
[21]: ./src/plugins/playwright
|
|
449
|
+
[22]: ./src/plugins/postcss
|
|
450
|
+
[23]: ./src/plugins/prettier
|
|
451
|
+
[24]: ./src/plugins/remark
|
|
452
|
+
[25]: ./src/plugins/remix
|
|
453
|
+
[26]: ./src/plugins/rollup
|
|
454
|
+
[27]: ./src/plugins/sentry
|
|
455
|
+
[28]: ./src/plugins/storybook
|
|
456
|
+
[29]: ./src/plugins/stryker
|
|
457
|
+
[30]: ./src/plugins/typescript
|
|
458
|
+
[31]: ./src/plugins/webpack
|
|
459
|
+
[32]: #config
|
|
460
|
+
[33]: #code-owners
|
|
461
|
+
[34]: #compact
|
|
462
|
+
[35]: #json
|
|
463
|
+
[36]: #symbol-default
|
|
464
|
+
[37]: ./docs/custom-reporters.md
|
|
465
|
+
[38]: https://github.com/depcheck/depcheck
|
|
466
|
+
[39]: https://github.com/smeijer/unimported
|
|
467
|
+
[40]: https://github.com/pzavolinsky/ts-unused-exports
|
|
468
|
+
[41]: https://github.com/nadeesha/ts-prune
|
|
469
|
+
[42]: https://github.com/jaydenseric/find-unused-exports
|
|
470
|
+
[43]: #custom-dependency-resolvers
|
|
471
|
+
[44]: #workspaces--monorepos
|
|
472
|
+
[45]: #production-mode
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
|
|
2
|
+
import type { BabelConfig } from './types.js';
|
|
2
3
|
export declare const NAME = "Babel";
|
|
3
4
|
export declare const ENABLERS: string[];
|
|
4
5
|
export declare const isEnabled: IsPluginEnabledCallback;
|
|
5
6
|
export declare const CONFIG_FILE_PATTERNS: string[];
|
|
7
|
+
export declare const getDependenciesFromConfig: (config: BabelConfig) => string[];
|
|
6
8
|
export declare const findDependencies: GenericPluginCallback;
|
|
@@ -17,7 +17,7 @@ export const CONFIG_FILE_PATTERNS = [
|
|
|
17
17
|
const api = {
|
|
18
18
|
caller: () => true,
|
|
19
19
|
};
|
|
20
|
-
const getDependenciesFromConfig = (config) => {
|
|
20
|
+
export const getDependenciesFromConfig = (config) => {
|
|
21
21
|
const presets = config.presets?.map(preset => (typeof preset === 'string' ? preset : preset[0])).map(resolvePresetName) ?? [];
|
|
22
22
|
const plugins = config.plugins?.map(plugin => (typeof plugin === 'string' ? plugin : plugin[0])).map(resolvePluginName) ?? [];
|
|
23
23
|
const nested = config.env ? Object.values(config.env).flatMap(getDependenciesFromConfig) : [];
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import { compact } from '../../util/array.js';
|
|
2
2
|
import { _load } from '../../util/loader.js';
|
|
3
3
|
import { timerify } from '../../util/performance.js';
|
|
4
|
+
import { getDependenciesFromConfig } from '../babel/index.js';
|
|
4
5
|
export const NAME = 'Webpack';
|
|
5
6
|
export const ENABLERS = ['webpack'];
|
|
6
7
|
export const isEnabled = ({ dependencies }) => ENABLERS.some(enabler => dependencies.has(enabler));
|
|
7
8
|
export const CONFIG_FILE_PATTERNS = ['webpack.config*.{js,ts}'];
|
|
8
|
-
const
|
|
9
|
+
const hasBabelOptions = (use) => Boolean(use) &&
|
|
10
|
+
typeof use !== 'string' &&
|
|
11
|
+
'loader' in use &&
|
|
12
|
+
typeof use.loader === 'string' &&
|
|
13
|
+
use.loader === 'babel-loader' &&
|
|
14
|
+
typeof use.options === 'object';
|
|
15
|
+
const resolveRuleSetDependencies = (rule) => {
|
|
9
16
|
if (!rule || typeof rule === 'string')
|
|
10
17
|
return [];
|
|
11
18
|
if (typeof rule.use === 'string')
|
|
12
19
|
return [rule.use];
|
|
13
|
-
if (
|
|
14
|
-
return
|
|
15
|
-
return rule.use
|
|
20
|
+
if (!rule.use || typeof rule.use === 'function')
|
|
21
|
+
return [];
|
|
22
|
+
return [rule.use].flat().flatMap((use) => {
|
|
23
|
+
if (hasBabelOptions(use)) {
|
|
24
|
+
return [...resolveUseItemLoader(use), ...getDependenciesFromConfig(use.options)];
|
|
25
|
+
}
|
|
26
|
+
return resolveUseItemLoader(use);
|
|
27
|
+
});
|
|
16
28
|
};
|
|
17
29
|
const resolveUseItemLoader = (use) => {
|
|
18
30
|
if (!use)
|
|
@@ -23,17 +35,19 @@ const resolveUseItemLoader = (use) => {
|
|
|
23
35
|
return [use.loader];
|
|
24
36
|
return [];
|
|
25
37
|
};
|
|
26
|
-
const findWebpackDependencies = async (configFilePath, { manifest }) => {
|
|
38
|
+
const findWebpackDependencies = async (configFilePath, { manifest, isProduction }) => {
|
|
27
39
|
let config = await _load(configFilePath);
|
|
28
40
|
if (typeof config === 'function') {
|
|
29
|
-
config = config();
|
|
41
|
+
config = config({ production: isProduction }, { mode: isProduction ? 'production' : 'development' });
|
|
30
42
|
}
|
|
31
|
-
const
|
|
32
|
-
.
|
|
33
|
-
|
|
43
|
+
const dependencies = [config].flat().flatMap(config => {
|
|
44
|
+
return (config.module?.rules?.flatMap(resolveRuleSetDependencies) ?? [])
|
|
45
|
+
.map(loader => loader.replace(/\?.*/, ''))
|
|
46
|
+
.filter(loader => !loader.startsWith('/'));
|
|
47
|
+
});
|
|
34
48
|
const scripts = Object.values(manifest.scripts ?? {});
|
|
35
49
|
const webpackCLI = scripts.some(script => script?.includes('webpack ')) ? ['webpack-cli'] : [];
|
|
36
50
|
const webpackDevServer = scripts.some(script => script?.includes('webpack serve')) ? ['webpack-dev-server'] : [];
|
|
37
|
-
return compact([...
|
|
51
|
+
return compact([...dependencies, ...webpackCLI, ...webpackDevServer]);
|
|
38
52
|
};
|
|
39
53
|
export const findDependencies = timerify(findWebpackDependencies);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Configuration } from 'webpack';
|
|
2
|
+
type Mode = 'none' | 'development' | 'production';
|
|
3
|
+
type Env = {
|
|
4
|
+
production: boolean;
|
|
5
|
+
};
|
|
6
|
+
type Argv = {
|
|
7
|
+
mode: Mode;
|
|
8
|
+
};
|
|
9
|
+
export type WebpackConfig = Configuration | ((env: Env, argv: Argv) => Configuration);
|
|
10
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ type GenericPluginCallbackOptions = {
|
|
|
10
10
|
manifest: PackageJson;
|
|
11
11
|
config: PluginConfiguration;
|
|
12
12
|
workspaceConfig: WorkspaceConfiguration;
|
|
13
|
+
isProduction: boolean;
|
|
13
14
|
};
|
|
14
|
-
export type GenericPluginCallback = (configFilePath: string, { cwd, manifest, config, workspaceConfig }: GenericPluginCallbackOptions) => Promise<string[]> | string[];
|
|
15
|
+
export type GenericPluginCallback = (configFilePath: string, { cwd, manifest, config, workspaceConfig, isProduction }: GenericPluginCallbackOptions) => Promise<string[]> | string[];
|
|
15
16
|
export {};
|
package/dist/workspace-worker.js
CHANGED
|
@@ -230,6 +230,7 @@ export default class WorkspaceWorker {
|
|
|
230
230
|
manifest: this.manifest,
|
|
231
231
|
config: pluginConfig,
|
|
232
232
|
workspaceConfig: this.config,
|
|
233
|
+
isProduction: this.isProduction,
|
|
233
234
|
});
|
|
234
235
|
return dependencies.map(symbol => ({ type: 'unlisted', filePath: configFilePath, symbol }));
|
|
235
236
|
}))).flat();
|
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.8",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"find",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"docs": "npm run docs:cli && npm run docs:plugins && npm run docs:format",
|
|
43
43
|
"docs:cli": "tsx ./scripts/update-cli-usage-in-readme.ts",
|
|
44
44
|
"docs:plugins": "tsx ./scripts/generate-plugin-docs.ts",
|
|
45
|
-
"docs:format": "remark README.md src/plugins/*/README.md -o",
|
|
45
|
+
"docs:format": "remark README.md docs/*.md src/plugins/*/README.md -o",
|
|
46
46
|
"release": "release-it",
|
|
47
47
|
"postinstall": "patch-package",
|
|
48
48
|
"create-plugin": "tsx ./scripts/create-new-plugin.ts"
|