knip 2.20.0-preprocess.0 → 2.20.1
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 +137 -126
- package/dist/DependencyDeputy.d.ts +1 -1
- package/dist/DependencyDeputy.js +16 -13
- package/dist/ProjectPrincipal.d.ts +4 -1
- package/dist/ProjectPrincipal.js +13 -9
- package/dist/binaries/resolvers/pnpm.js +37 -21
- package/dist/binaries/resolvers/yarn.js +2 -2
- package/dist/cli.js +7 -15
- package/dist/constants.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -2
- package/dist/plugins/ava/index.js +1 -1
- package/dist/plugins/next/index.js +2 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/issues.d.ts +1 -1
- package/dist/typescript/visitors/exports/exportAssignment.js +2 -1
- package/dist/typescript/visitors/scripts/execa.js +4 -2
- package/dist/util/cli-arguments.d.ts +3 -3
- package/dist/util/cli-arguments.js +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -32,45 +32,46 @@ Knip shines in both small and large projects. It's a fresh take on keeping your
|
|
|
32
32
|
[![An orange cow with scissors, Van Gogh style][7]][6] <sup>_“An orange cow with scissors, Van Gogh style” - generated
|
|
33
33
|
with OpenAI_</sup>
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
For updates or questions, come hang out in [The Knip Barn (Discord)][8], or follow [@webprolific (Twitter)][9] or
|
|
36
|
+
[@webpro (fosstodon.org)][10]. Please use GitHub to [report issues][11].
|
|
36
37
|
|
|
37
38
|
## Contents
|
|
38
39
|
|
|
39
|
-
- [Getting Started][
|
|
40
|
-
- [Installation][
|
|
41
|
-
- [Default Configuration][
|
|
42
|
-
- [Let's Go!][
|
|
43
|
-
- [Configuration][
|
|
44
|
-
- [Entry Files][
|
|
40
|
+
- [Getting Started][12]
|
|
41
|
+
- [Installation][13]
|
|
42
|
+
- [Default Configuration][14]
|
|
43
|
+
- [Let's Go!][15]
|
|
44
|
+
- [Configuration][16]
|
|
45
|
+
- [Entry Files][17]
|
|
45
46
|
- [Workspaces][1]
|
|
46
47
|
- [Plugins][2]
|
|
47
48
|
- [Compilers][3]
|
|
48
|
-
- [Ignore files, binaries, dependencies and workspaces][
|
|
49
|
-
- [Public exports][
|
|
50
|
-
- [Ignore exports used in file][
|
|
51
|
-
- [Include exports in entry files][
|
|
52
|
-
- [Paths][
|
|
53
|
-
- [Production Mode][
|
|
54
|
-
- [Strict][
|
|
55
|
-
- [Plugins][
|
|
56
|
-
- [Output][
|
|
57
|
-
- [Screenshots][
|
|
58
|
-
- [Reading the report][
|
|
59
|
-
- [Rules & Filters][
|
|
49
|
+
- [Ignore files, binaries, dependencies and workspaces][18]
|
|
50
|
+
- [Public exports][19]
|
|
51
|
+
- [Ignore exports used in file][20]
|
|
52
|
+
- [Include exports in entry files][21]
|
|
53
|
+
- [Paths][22]
|
|
54
|
+
- [Production Mode][23]
|
|
55
|
+
- [Strict][24]
|
|
56
|
+
- [Plugins][25]
|
|
57
|
+
- [Output][26]
|
|
58
|
+
- [Screenshots][27]
|
|
59
|
+
- [Reading the report][28]
|
|
60
|
+
- [Rules & Filters][29]
|
|
60
61
|
- [Reporters][4]
|
|
61
|
-
- [Fixing Issues][
|
|
62
|
-
- [Command Line Options][
|
|
63
|
-
- [Potential boost with `--no-gitignore`][
|
|
64
|
-
- [Comparison & Migration][
|
|
65
|
-
- [depcheck][
|
|
66
|
-
- [unimported][
|
|
67
|
-
- [ts-unused-exports][
|
|
68
|
-
- [ts-prune][
|
|
69
|
-
- [Projects using Knip][
|
|
70
|
-
- [Articles, etc.][
|
|
71
|
-
- [Why "Knip"?][
|
|
72
|
-
- [Really, another unused file/dependency/export finder?][
|
|
73
|
-
- [Contributors][
|
|
62
|
+
- [Fixing Issues][30]
|
|
63
|
+
- [Command Line Options][31]
|
|
64
|
+
- [Potential boost with `--no-gitignore`][32]
|
|
65
|
+
- [Comparison & Migration][33]
|
|
66
|
+
- [depcheck][34]
|
|
67
|
+
- [unimported][35]
|
|
68
|
+
- [ts-unused-exports][36]
|
|
69
|
+
- [ts-prune][37]
|
|
70
|
+
- [Projects using Knip][38]
|
|
71
|
+
- [Articles, etc.][39]
|
|
72
|
+
- [Why "Knip"?][40]
|
|
73
|
+
- [Really, another unused file/dependency/export finder?][41]
|
|
74
|
+
- [Contributors][42]
|
|
74
75
|
|
|
75
76
|
## Getting Started
|
|
76
77
|
|
|
@@ -91,7 +92,7 @@ Knip has good defaults and you can run it without any configuration. The (simpli
|
|
|
91
92
|
}
|
|
92
93
|
```
|
|
93
94
|
|
|
94
|
-
There's more, jump to [Entry Files][
|
|
95
|
+
There's more, jump to [Entry Files][17] for details.
|
|
95
96
|
|
|
96
97
|
Places where Knip looks for configuration (ordered by priority):
|
|
97
98
|
|
|
@@ -133,7 +134,7 @@ Run the checks with `npx knip`. Or first add this script to `package.json`:
|
|
|
133
134
|
Then use `npm run knip` to analyze the project and output unused files, dependencies and exports. Knip works just fine
|
|
134
135
|
with `yarn` or `pnpm` as well.
|
|
135
136
|
|
|
136
|
-
See [Command Line Options][
|
|
137
|
+
See [Command Line Options][31] for an overview of available CLI options.
|
|
137
138
|
|
|
138
139
|
## Configuration
|
|
139
140
|
|
|
@@ -196,7 +197,7 @@ Here's an example `knip.json` configuration with some custom `entry` and `projec
|
|
|
196
197
|
```
|
|
197
198
|
|
|
198
199
|
It might be useful to run Knip first with no or little configuration to see where it needs custom `entry` and/or
|
|
199
|
-
`project` files. Each workspace has the same [default configuration][
|
|
200
|
+
`project` files. Each workspace has the same [default configuration][16].
|
|
200
201
|
|
|
201
202
|
The root workspace is named `"."` under `workspaces` (like in the example).
|
|
202
203
|
|
|
@@ -319,7 +320,7 @@ has them at `e2e-tests/*.spec.ts`. Here's how to configure this:
|
|
|
319
320
|
#### Multi-project repositories
|
|
320
321
|
|
|
321
322
|
Some repositories have a single `package.json`, but consist of multiple projects with configuration files across the
|
|
322
|
-
repository (such as the [Nx "intregrated repo" style][
|
|
323
|
+
repository (such as the [Nx "intregrated repo" style][43]). Let's assume some of these projects are apps and have their
|
|
323
324
|
own Cypress configuration and test files. In that case, we could configure the Cypress plugin like this:
|
|
324
325
|
|
|
325
326
|
```json
|
|
@@ -336,7 +337,7 @@ In case a plugin causes issues, it can be disabled by using `false` as its value
|
|
|
336
337
|
|
|
337
338
|
#### Create a new plugin
|
|
338
339
|
|
|
339
|
-
Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][
|
|
340
|
+
Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][44]. This
|
|
340
341
|
guide also contains more details if you want to learn more about plugins and why they are useful.
|
|
341
342
|
|
|
342
343
|
### Compilers
|
|
@@ -359,7 +360,7 @@ export default {
|
|
|
359
360
|
};
|
|
360
361
|
```
|
|
361
362
|
|
|
362
|
-
Read [Compilers][
|
|
363
|
+
Read [Compilers][45] for more details and examples.
|
|
363
364
|
|
|
364
365
|
### Ignore files, binaries, dependencies and workspaces
|
|
365
366
|
|
|
@@ -481,6 +482,11 @@ Additionally, the `--strict` flag can be used to:
|
|
|
481
482
|
- Ignore type-only imports (`import type {}`).
|
|
482
483
|
- Verify each workspace is self-contained: have their own `dependencies` (and not use packages of ancestor workspaces).
|
|
483
484
|
|
|
485
|
+
### Ignore `@internal` exports
|
|
486
|
+
|
|
487
|
+
In addition to the flags above, the `--ignore-internal` flag can be used to ignore exports tagged with `@internal`. This
|
|
488
|
+
can be useful in production mode, since `@internal` exports might be only imported from non-production code.
|
|
489
|
+
|
|
484
490
|
### Plugins
|
|
485
491
|
|
|
486
492
|
Plugins also have this distinction. For instance, Next.js entry files for pages (`pages/**/*.tsx`) and Remix routes
|
|
@@ -521,7 +527,7 @@ The report contains the following types of issues:
|
|
|
521
527
|
|
|
522
528
|
When an issue type has zero issues, it is not shown.
|
|
523
529
|
|
|
524
|
-
Getting too many reported issues and false positives? Read more about [handling issues][
|
|
530
|
+
Getting too many reported issues and false positives? Read more about [handling issues][46].
|
|
525
531
|
|
|
526
532
|
### Rules & Filters
|
|
527
533
|
|
|
@@ -548,7 +554,7 @@ Example:
|
|
|
548
554
|
}
|
|
549
555
|
```
|
|
550
556
|
|
|
551
|
-
See [reading the report][
|
|
557
|
+
See [reading the report][28] for the list of issue types.
|
|
552
558
|
|
|
553
559
|
The rules are modeled after the ESLint `rules` configuration, and could be extended in the future. For instance, to
|
|
554
560
|
apply filters or configurations only to a specific issue type.
|
|
@@ -569,7 +575,7 @@ Use `--exclude` to ignore reports you're not interested in:
|
|
|
569
575
|
|
|
570
576
|
Use `--dependencies` or `--exports` as shortcuts to combine groups of related types.
|
|
571
577
|
|
|
572
|
-
See [reading the report][
|
|
578
|
+
See [reading the report][28] for the list of issue types.
|
|
573
579
|
|
|
574
580
|
#### When to use rules or filters
|
|
575
581
|
|
|
@@ -596,7 +602,7 @@ When the provided built-in reporters are not sufficient, a custom reporter can b
|
|
|
596
602
|
Pass something like `--reporter ./my-reporter` from the command line. The results are passed to the function from its
|
|
597
603
|
default export and can be used to write issues to `stdout`, a JSON or CSV file, or sent to a service.
|
|
598
604
|
|
|
599
|
-
Find more details and ideas in [custom reporters][
|
|
605
|
+
Find more details and ideas in [custom reporters][47].
|
|
600
606
|
|
|
601
607
|
## Fixing Issues
|
|
602
608
|
|
|
@@ -614,7 +620,7 @@ Tip: back up files or use an VCS like Git before deleting files or making change
|
|
|
614
620
|
|
|
615
621
|
Repeat the process to reveal new unused files and exports. It's so liberating to remove unused things!
|
|
616
622
|
|
|
617
|
-
Getting too many reported issues and false positives? Read more about [handling issues][
|
|
623
|
+
Getting too many reported issues and false positives? Read more about [handling issues][48] describing potential causes
|
|
618
624
|
for false positives, and how to handle them.
|
|
619
625
|
|
|
620
626
|
## Command Line Options
|
|
@@ -629,6 +635,7 @@ for false positives, and how to handle them.
|
|
|
629
635
|
-t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)
|
|
630
636
|
--production Analyze only production source files (e.g. no tests, devDependencies, exported types)
|
|
631
637
|
--strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)
|
|
638
|
+
--ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)
|
|
632
639
|
--workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)
|
|
633
640
|
--no-gitignore Don't use .gitignore
|
|
634
641
|
--include Report only provided issue type(s), can be comma-separated or repeated (1)
|
|
@@ -637,8 +644,7 @@ for false positives, and how to handle them.
|
|
|
637
644
|
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
638
645
|
--include-entry-exports Include entry files when reporting unused exports
|
|
639
646
|
-n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
|
|
640
|
-
--
|
|
641
|
-
--reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)
|
|
647
|
+
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
642
648
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
643
649
|
--no-config-hints Suppress configuration hints
|
|
644
650
|
--no-exit-code Always exit with code zero (0)
|
|
@@ -664,13 +670,13 @@ for false positives, and how to handle them.
|
|
|
664
670
|
|
|
665
671
|
## Potential boost with `--no-gitignore`
|
|
666
672
|
|
|
667
|
-
To increase performance in a large monorepo, check out [Potential boost with `--no-gitignore`][
|
|
673
|
+
To increase performance in a large monorepo, check out [Potential boost with `--no-gitignore`][49].
|
|
668
674
|
|
|
669
675
|
## Comparison & Migration
|
|
670
676
|
|
|
671
677
|
This table is an ongoing comparison. Based on their docs (please report any mistakes):
|
|
672
678
|
|
|
673
|
-
| Feature | **knip** | [depcheck][
|
|
679
|
+
| Feature | **knip** | [depcheck][50] | [unimported][51] | [ts-unused-exports][52] | [ts-prune][53] |
|
|
674
680
|
| :---------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
|
|
675
681
|
| Unused files | ✅ | - | ✅ | - | - |
|
|
676
682
|
| Unused dependencies | ✅ | ✅ | ✅ | - | - |
|
|
@@ -706,7 +712,7 @@ The following commands are similar:
|
|
|
706
712
|
unimported
|
|
707
713
|
knip --production --dependencies --include files
|
|
708
714
|
|
|
709
|
-
Also see [production mode][
|
|
715
|
+
Also see [production mode][23].
|
|
710
716
|
|
|
711
717
|
### ts-unused-exports
|
|
712
718
|
|
|
@@ -728,28 +734,30 @@ The following commands are similar:
|
|
|
728
734
|
|
|
729
735
|
Many thanks to some of the early adopters of Knip:
|
|
730
736
|
|
|
731
|
-
- [Block Protocol][
|
|
732
|
-
- [DeepmergeTS][
|
|
733
|
-
- [eslint-plugin-functional][
|
|
734
|
-
- [freeCodeCamp.org][
|
|
735
|
-
- [is-immutable-type][
|
|
736
|
-
- [IsaacScript][
|
|
737
|
-
- [Nuxt][
|
|
738
|
-
- [Owncast][
|
|
739
|
-
- [release-it][
|
|
740
|
-
- [Template TypeScript Node Package][
|
|
741
|
-
- [Tipi][
|
|
737
|
+
- [Block Protocol][54]
|
|
738
|
+
- [DeepmergeTS][55]
|
|
739
|
+
- [eslint-plugin-functional][56]
|
|
740
|
+
- [freeCodeCamp.org][57]
|
|
741
|
+
- [is-immutable-type][58]
|
|
742
|
+
- [IsaacScript][59]
|
|
743
|
+
- [Nuxt][60]
|
|
744
|
+
- [Owncast][61]
|
|
745
|
+
- [release-it][62]
|
|
746
|
+
- [Template TypeScript Node Package][63]
|
|
747
|
+
- [Tipi][64]
|
|
742
748
|
|
|
743
749
|
## Articles, etc.
|
|
744
750
|
|
|
745
|
-
-
|
|
746
|
-
-
|
|
747
|
-
-
|
|
751
|
+
- Discord: hang out in [The Knip Barn][8]
|
|
752
|
+
- Ask your questions in the [Knip knowledge base][65] (powered by OpenAI and [7-docs][66], experimental!)
|
|
753
|
+
- Smashing Magazine: [Knip: An Automated Tool For Finding Unused Files, Exports, And Dependencies][67]
|
|
754
|
+
- Effective TypeScript: [Recommendation Update: ✂️ Use knip to detect dead code and types][68]
|
|
755
|
+
- Josh Goldberg: [Speeding Up Centered Part 4: Unused Code Bloat][69]
|
|
748
756
|
|
|
749
757
|
## Why "Knip"?
|
|
750
758
|
|
|
751
|
-
Knip is Dutch for a "cut". A Dutch expression is "
|
|
752
|
-
|
|
759
|
+
Knip is Dutch for a "cut". A Dutch expression is "ergens ge**knip**t voor zijn", which means to be perfectly suited for
|
|
760
|
+
the job. I'm motivated to make Knip perfectly suited for the job of cutting projects to perfection! ✂️
|
|
753
761
|
|
|
754
762
|
## Really, another unused file/dependency/export finder?
|
|
755
763
|
|
|
@@ -762,7 +770,7 @@ each file, and traversing all of this, why not collect the various issues in one
|
|
|
762
770
|
|
|
763
771
|
Special thanks to the wonderful people who have contributed to this project:
|
|
764
772
|
|
|
765
|
-
[![Contributors][
|
|
773
|
+
[![Contributors][71]][70]
|
|
766
774
|
|
|
767
775
|
[1]: #workspaces
|
|
768
776
|
[2]: #plugins
|
|
@@ -771,67 +779,70 @@ Special thanks to the wonderful people who have contributed to this project:
|
|
|
771
779
|
[5]: #custom-reporters
|
|
772
780
|
[6]: https://labs.openai.com/s/xZQACaLepaKya0PRUPtIN5dC
|
|
773
781
|
[7]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
|
|
774
|
-
[8]: https://
|
|
775
|
-
[9]: https://
|
|
776
|
-
[10]:
|
|
777
|
-
[11]:
|
|
778
|
-
[12]: #
|
|
779
|
-
[13]: #
|
|
780
|
-
[14]: #configuration
|
|
781
|
-
[15]: #
|
|
782
|
-
[16]: #
|
|
783
|
-
[17]: #
|
|
784
|
-
[18]: #ignore-
|
|
785
|
-
[19]: #
|
|
786
|
-
[20]: #
|
|
787
|
-
[21]: #
|
|
788
|
-
[22]: #
|
|
789
|
-
[23]: #
|
|
790
|
-
[24]: #
|
|
791
|
-
[25]: #
|
|
792
|
-
[26]: #
|
|
793
|
-
[27]: #
|
|
794
|
-
[28]: #
|
|
795
|
-
[29]: #
|
|
796
|
-
[30]: #
|
|
797
|
-
[31]: #
|
|
798
|
-
[32]: #
|
|
799
|
-
[33]: #
|
|
800
|
-
[34]: #
|
|
801
|
-
[35]: #
|
|
802
|
-
[36]: #
|
|
803
|
-
[37]: #
|
|
804
|
-
[38]: #
|
|
805
|
-
[39]: #
|
|
806
|
-
[40]: #
|
|
807
|
-
[41]:
|
|
808
|
-
[42]:
|
|
809
|
-
[43]:
|
|
810
|
-
[44]:
|
|
811
|
-
[45]: ./docs/
|
|
812
|
-
[46]:
|
|
813
|
-
[47]: ./docs/
|
|
814
|
-
[48]:
|
|
815
|
-
[49]:
|
|
816
|
-
[50]: https://github.com/
|
|
817
|
-
[51]: https://github.com/
|
|
818
|
-
[52]: https://github.com/
|
|
819
|
-
[53]: https://github.com/
|
|
820
|
-
[54]: https://github.com/
|
|
821
|
-
[55]: https://github.com/
|
|
822
|
-
[56]: https://github.com/
|
|
823
|
-
[57]: https://github.com/
|
|
824
|
-
[58]: https://github.com/
|
|
825
|
-
[59]: https://github.com/
|
|
826
|
-
[60]: https://github.com/
|
|
827
|
-
[61]: https://github.com/
|
|
828
|
-
[62]: https://github.com/
|
|
829
|
-
[63]: https://
|
|
830
|
-
[64]: https://github.com/
|
|
831
|
-
[65]: https://
|
|
832
|
-
[66]: https://
|
|
833
|
-
[67]: https://
|
|
834
|
-
[68]: https://
|
|
782
|
+
[8]: https://discord.gg/ya5yktTq
|
|
783
|
+
[9]: https://twitter.com/webprolific
|
|
784
|
+
[10]: https://fosstodon.org/@webpro
|
|
785
|
+
[11]: https://github.com/webpro/knip/issues
|
|
786
|
+
[12]: #getting-started
|
|
787
|
+
[13]: #installation
|
|
788
|
+
[14]: #default-configuration
|
|
789
|
+
[15]: #lets-go
|
|
790
|
+
[16]: #configuration
|
|
791
|
+
[17]: #entry-files
|
|
792
|
+
[18]: #ignore-files-binaries-dependencies-and-workspaces
|
|
793
|
+
[19]: #public-exports
|
|
794
|
+
[20]: #ignore-exports-used-in-file
|
|
795
|
+
[21]: #include-exports-in-entry-files
|
|
796
|
+
[22]: #paths
|
|
797
|
+
[23]: #production-mode
|
|
798
|
+
[24]: #strict
|
|
799
|
+
[25]: #plugins-1
|
|
800
|
+
[26]: #output
|
|
801
|
+
[27]: #screenshots
|
|
802
|
+
[28]: #reading-the-report
|
|
803
|
+
[29]: #rules--filters
|
|
804
|
+
[30]: #fixing-issues
|
|
805
|
+
[31]: #command-line-options
|
|
806
|
+
[32]: #potential-boost-with---no-gitignore
|
|
807
|
+
[33]: #comparison--migration
|
|
808
|
+
[34]: #depcheck
|
|
809
|
+
[35]: #unimported
|
|
810
|
+
[36]: #ts-unused-exports
|
|
811
|
+
[37]: #ts-prune
|
|
812
|
+
[38]: #projects-using-knip
|
|
813
|
+
[39]: #articles-etc
|
|
814
|
+
[40]: #why-knip
|
|
815
|
+
[41]: #really-another-unused-filedependencyexport-finder
|
|
816
|
+
[42]: #contributors
|
|
817
|
+
[43]: https://nx.dev/concepts/integrated-vs-package-based
|
|
818
|
+
[44]: ./docs/writing-a-plugin.md
|
|
819
|
+
[45]: ./docs/compilers.md
|
|
820
|
+
[46]: #handling-issues
|
|
821
|
+
[47]: ./docs/custom-reporters.md
|
|
822
|
+
[48]: ./docs/handling-issues.md
|
|
823
|
+
[49]: ./docs/perf-boost-with-no-gitignore.md
|
|
824
|
+
[50]: https://github.com/depcheck/depcheck
|
|
825
|
+
[51]: https://github.com/smeijer/unimported
|
|
826
|
+
[52]: https://github.com/pzavolinsky/ts-unused-exports
|
|
827
|
+
[53]: https://github.com/nadeesha/ts-prune
|
|
828
|
+
[54]: https://github.com/blockprotocol/blockprotocol
|
|
829
|
+
[55]: https://github.com/RebeccaStevens/deepmerge-ts
|
|
830
|
+
[56]: https://github.com/eslint-functional/eslint-plugin-functional
|
|
831
|
+
[57]: https://github.com/freeCodeCamp/freeCodeCamp
|
|
832
|
+
[58]: https://github.com/RebeccaStevens/is-immutable-type
|
|
833
|
+
[59]: https://github.com/IsaacScript/isaacscript
|
|
834
|
+
[60]: https://github.com/nuxt/nuxt
|
|
835
|
+
[61]: https://github.com/owncast/owncast
|
|
836
|
+
[62]: https://github.com/release-it/release-it
|
|
837
|
+
[63]: https://github.com/JoshuaKGoldberg/template-typescript-node-package
|
|
838
|
+
[64]: https://github.com/meienberger/runtipi
|
|
839
|
+
[65]: https://knip.deno.dev
|
|
840
|
+
[66]: https://github.com/7-docs/7-docs
|
|
841
|
+
[67]: https://www.smashingmagazine.com/2023/08/knip-automated-tool-find-unused-files-exports-dependencies/
|
|
842
|
+
[68]: https://effectivetypescript.com/2023/07/29/knip/
|
|
843
|
+
[69]: https://www.joshuakgoldberg.com/blog/speeding-up-centered-part-4-unused-code-bloat/
|
|
844
|
+
[70]: https://github.com/webpro/knip/graphs/contributors
|
|
845
|
+
[71]: https://contrib.rocks/image?repo=webpro/knip
|
|
835
846
|
[plugin-ava]: ./src/plugins/ava
|
|
836
847
|
[plugin-babel]: ./src/plugins/babel
|
|
837
848
|
[plugin-capacitor]: ./src/plugins/capacitor
|
|
@@ -45,7 +45,7 @@ export declare class DependencyDeputy {
|
|
|
45
45
|
addReferencedDependency(workspaceName: string, packageName: string): void;
|
|
46
46
|
addReferencedBinary(workspaceName: string, binaryName: string): void;
|
|
47
47
|
addPeerDependencies(workspaceName: string, peerDependencies: Map<string, Set<string>>): void;
|
|
48
|
-
|
|
48
|
+
getPeerDependenciesOf(workspaceName: string, dependency: string): string[];
|
|
49
49
|
maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string): boolean;
|
|
50
50
|
maybeAddReferencedBinary(workspace: Workspace, binaryName: string): boolean;
|
|
51
51
|
private isInDependencies;
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -76,7 +76,7 @@ export class DependencyDeputy {
|
|
|
76
76
|
addPeerDependencies(workspaceName, peerDependencies) {
|
|
77
77
|
this.peerDependencies.set(workspaceName, peerDependencies);
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
getPeerDependenciesOf(workspaceName, dependency) {
|
|
80
80
|
return Array.from(this.peerDependencies.get(workspaceName)?.get(dependency) ?? []);
|
|
81
81
|
}
|
|
82
82
|
maybeAddReferencedExternalDependency(workspace, packageName) {
|
|
@@ -150,35 +150,38 @@ export class DependencyDeputy {
|
|
|
150
150
|
return true;
|
|
151
151
|
};
|
|
152
152
|
const peerDepRecs = {};
|
|
153
|
-
const
|
|
153
|
+
const isReferencedDependency = (dependency, isPeerDep) => {
|
|
154
154
|
if (referencedDependencies?.has(dependency))
|
|
155
|
-
return false;
|
|
156
|
-
if (isPeerDep && peerDepRecs[dependency])
|
|
157
155
|
return true;
|
|
156
|
+
if (isPeerDep && peerDepRecs[dependency])
|
|
157
|
+
return false;
|
|
158
158
|
const [scope, typedDependency] = dependency.split('/');
|
|
159
159
|
if (scope === '@types') {
|
|
160
160
|
const typedPackageName = getPackageFromDefinitelyTyped(typedDependency);
|
|
161
161
|
if (IGNORE_DEFINITELY_TYPED.includes(typedPackageName))
|
|
162
|
-
return
|
|
163
|
-
const peerDependencies = this.
|
|
162
|
+
return true;
|
|
163
|
+
const peerDependencies = this.getPeerDependenciesOf(workspaceName, typedPackageName);
|
|
164
164
|
if (peerDependencies.length) {
|
|
165
|
-
return
|
|
165
|
+
return !!peerDependencies.find(peerDependency => isReferencedDependency(peerDependency, true));
|
|
166
166
|
}
|
|
167
|
-
|
|
167
|
+
if (!referencedDependencies)
|
|
168
|
+
return false;
|
|
169
|
+
return referencedDependencies.has(typedPackageName);
|
|
168
170
|
}
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
return
|
|
171
|
+
const peerDependenciesOf = this.getPeerDependenciesOf(workspaceName, dependency);
|
|
172
|
+
peerDependenciesOf.forEach(dep => (!peerDepRecs[dep] ? (peerDepRecs[dep] = 1) : peerDepRecs[dep]++));
|
|
173
|
+
return peerDependenciesOf.some(peerDependency => isReferencedDependency(peerDependency, true));
|
|
172
174
|
};
|
|
175
|
+
const isNotReferencedDependency = (dependency) => !isReferencedDependency(dependency);
|
|
173
176
|
const pd = this.getProductionDependencies(workspaceName);
|
|
174
177
|
const dd = this.getDevDependencies(workspaceName);
|
|
175
178
|
pd.filter(isNotIgnoredDependency)
|
|
176
179
|
.filter(isNotIgnoredBinary)
|
|
177
|
-
.filter(
|
|
180
|
+
.filter(isNotReferencedDependency)
|
|
178
181
|
.forEach(symbol => dependencyIssues.push({ type: 'dependencies', filePath: manifestPath, symbol }));
|
|
179
182
|
dd.filter(isNotIgnoredDependency)
|
|
180
183
|
.filter(isNotIgnoredBinary)
|
|
181
|
-
.filter(
|
|
184
|
+
.filter(isNotReferencedDependency)
|
|
182
185
|
.forEach(symbol => devDependencyIssues.push({ type: 'devDependencies', filePath: manifestPath, symbol }));
|
|
183
186
|
}
|
|
184
187
|
return { dependencyIssues, devDependencyIssues };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isGitIgnoredSync } from 'globby';
|
|
1
2
|
import ts from 'typescript';
|
|
2
3
|
import { SourceFileManager } from './typescript/SourceFileManager.js';
|
|
3
4
|
import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
|
|
@@ -11,6 +12,7 @@ export declare class ProjectPrincipal {
|
|
|
11
12
|
entryPaths: Set<string>;
|
|
12
13
|
projectPaths: Set<string>;
|
|
13
14
|
skipExportsAnalysis: Set<string>;
|
|
15
|
+
isGitIgnored: ReturnType<typeof isGitIgnoredSync>;
|
|
14
16
|
cwd: string;
|
|
15
17
|
compilerOptions: ts.CompilerOptions;
|
|
16
18
|
extensions: Set<string>;
|
|
@@ -58,6 +60,7 @@ export declare class ProjectPrincipal {
|
|
|
58
60
|
};
|
|
59
61
|
findUnusedMembers(filePath: string, members: ExportItemMember[]): string[];
|
|
60
62
|
private findReferences;
|
|
61
|
-
isPublicExport(exportedItem: ExportItem):
|
|
63
|
+
isPublicExport(exportedItem: ExportItem): boolean;
|
|
64
|
+
getJSDocTags(exportedItem: ExportItem): string[];
|
|
62
65
|
}
|
|
63
66
|
export {};
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createHosts } from './typescript/createHosts.js';
|
|
|
7
7
|
import { getImportsAndExports } from './typescript/getImportsAndExports.js';
|
|
8
8
|
import { SourceFileManager } from './typescript/SourceFileManager.js';
|
|
9
9
|
import { isMaybePackageName } from './util/modules.js';
|
|
10
|
-
import { extname, isInNodeModules, join } from './util/path.js';
|
|
10
|
+
import { dirname, extname, isInNodeModules, join } from './util/path.js';
|
|
11
11
|
import { timerify } from './util/Performance.js';
|
|
12
12
|
const baseCompilerOptions = {
|
|
13
13
|
allowJs: true,
|
|
@@ -23,11 +23,11 @@ const baseCompilerOptions = {
|
|
|
23
23
|
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
24
24
|
};
|
|
25
25
|
const tsCreateProgram = timerify(ts.createProgram);
|
|
26
|
-
const isGitIgnored = isGitIgnoredSync();
|
|
27
26
|
export class ProjectPrincipal {
|
|
28
27
|
entryPaths = new Set();
|
|
29
28
|
projectPaths = new Set();
|
|
30
29
|
skipExportsAnalysis = new Set();
|
|
30
|
+
isGitIgnored;
|
|
31
31
|
cwd;
|
|
32
32
|
compilerOptions;
|
|
33
33
|
extensions;
|
|
@@ -36,6 +36,7 @@ export class ProjectPrincipal {
|
|
|
36
36
|
backend;
|
|
37
37
|
constructor({ compilerOptions, cwd, compilers }) {
|
|
38
38
|
this.cwd = cwd;
|
|
39
|
+
this.isGitIgnored = isGitIgnoredSync({ cwd });
|
|
39
40
|
this.compilerOptions = {
|
|
40
41
|
...compilerOptions,
|
|
41
42
|
...baseCompilerOptions,
|
|
@@ -132,7 +133,7 @@ export class ProjectPrincipal {
|
|
|
132
133
|
external.add(sanitizedSpecifier);
|
|
133
134
|
}
|
|
134
135
|
else {
|
|
135
|
-
const isIgnored = isGitIgnored(join(filePath, sanitizedSpecifier));
|
|
136
|
+
const isIgnored = this.isGitIgnored(join(dirname(filePath), sanitizedSpecifier));
|
|
136
137
|
if (!isIgnored) {
|
|
137
138
|
const ext = extname(sanitizedSpecifier);
|
|
138
139
|
if (!ext || (ext !== '.json' && !IGNORED_FILE_EXTENSIONS.includes(ext))) {
|
|
@@ -158,8 +159,7 @@ export class ProjectPrincipal {
|
|
|
158
159
|
}
|
|
159
160
|
getHasReferences(filePath, exportedItem) {
|
|
160
161
|
const hasReferences = { external: false, internal: false };
|
|
161
|
-
const
|
|
162
|
-
const symbolReferences = this.findReferences(filePath, node).flatMap(f => f.references);
|
|
162
|
+
const symbolReferences = this.findReferences(filePath, exportedItem.pos).flatMap(f => f.references);
|
|
163
163
|
for (const reference of symbolReferences) {
|
|
164
164
|
if (reference.fileName === filePath) {
|
|
165
165
|
if (!reference.isDefinition) {
|
|
@@ -180,7 +180,7 @@ export class ProjectPrincipal {
|
|
|
180
180
|
.filter(member => {
|
|
181
181
|
if (this.isPublicExport(member))
|
|
182
182
|
return false;
|
|
183
|
-
const referencedSymbols = this.findReferences(filePath, member.
|
|
183
|
+
const referencedSymbols = this.findReferences(filePath, member.pos);
|
|
184
184
|
const files = referencedSymbols
|
|
185
185
|
.flatMap(refs => refs.references)
|
|
186
186
|
.filter(ref => !ref.isDefinition)
|
|
@@ -191,10 +191,14 @@ export class ProjectPrincipal {
|
|
|
191
191
|
})
|
|
192
192
|
.map(member => member.identifier);
|
|
193
193
|
}
|
|
194
|
-
findReferences(filePath,
|
|
195
|
-
return this.backend.lsFindReferences(filePath,
|
|
194
|
+
findReferences(filePath, pos) {
|
|
195
|
+
return this.backend.lsFindReferences(filePath, pos) ?? [];
|
|
196
196
|
}
|
|
197
197
|
isPublicExport(exportedItem) {
|
|
198
|
-
|
|
198
|
+
const tags = this.getJSDocTags(exportedItem);
|
|
199
|
+
return tags.includes('@public');
|
|
200
|
+
}
|
|
201
|
+
getJSDocTags(exportedItem) {
|
|
202
|
+
return ts.getJSDocTags(exportedItem.node).map(node => node.getText().match(/@\S+/)[0]);
|
|
199
203
|
}
|
|
200
204
|
}
|
|
@@ -2,38 +2,54 @@ import parseArgs from 'minimist';
|
|
|
2
2
|
import { toBinary } from '../util.js';
|
|
3
3
|
const commands = [
|
|
4
4
|
'add',
|
|
5
|
+
'audit',
|
|
6
|
+
'bin',
|
|
7
|
+
'config',
|
|
5
8
|
'dedupe',
|
|
9
|
+
'deploy',
|
|
6
10
|
'dlx',
|
|
7
|
-
'
|
|
11
|
+
'doctor',
|
|
12
|
+
'env',
|
|
13
|
+
'fetch',
|
|
8
14
|
'i',
|
|
9
|
-
'install',
|
|
10
|
-
'up',
|
|
11
|
-
'update',
|
|
12
|
-
'upgrade',
|
|
13
|
-
'remove',
|
|
14
|
-
'rm',
|
|
15
|
-
'uninstall',
|
|
16
|
-
'un',
|
|
17
|
-
'link',
|
|
18
|
-
'ln',
|
|
19
|
-
'unlink',
|
|
20
15
|
'import',
|
|
21
|
-
'
|
|
22
|
-
'rb',
|
|
23
|
-
'prune',
|
|
24
|
-
'fetch',
|
|
16
|
+
'init',
|
|
25
17
|
'install-test',
|
|
18
|
+
'install',
|
|
26
19
|
'it',
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'audit',
|
|
20
|
+
'licenses',
|
|
21
|
+
'link',
|
|
30
22
|
'list',
|
|
23
|
+
'ln',
|
|
31
24
|
'ls',
|
|
32
25
|
'outdated',
|
|
33
|
-
'
|
|
34
|
-
'
|
|
26
|
+
'outdated',
|
|
27
|
+
'pack',
|
|
28
|
+
'patch-commit',
|
|
29
|
+
'patch-remove',
|
|
30
|
+
'patch',
|
|
31
|
+
'prune',
|
|
32
|
+
'publish',
|
|
33
|
+
'rb',
|
|
34
|
+
'rebuild',
|
|
35
|
+
'remove',
|
|
36
|
+
'rm',
|
|
37
|
+
'root',
|
|
38
|
+
'run',
|
|
39
|
+
'server',
|
|
40
|
+
'setup',
|
|
41
|
+
'start',
|
|
42
|
+
'store',
|
|
35
43
|
't',
|
|
44
|
+
'test',
|
|
36
45
|
'tst',
|
|
46
|
+
'un',
|
|
47
|
+
'uninstall',
|
|
48
|
+
'unlink',
|
|
49
|
+
'up',
|
|
50
|
+
'update',
|
|
51
|
+
'upgrade',
|
|
52
|
+
'why',
|
|
37
53
|
];
|
|
38
54
|
export const resolve = (_binary, args, { manifest }) => {
|
|
39
55
|
const scripts = manifest.scripts ? Object.keys(manifest.scripts) : [];
|
|
@@ -14,8 +14,8 @@ const commands = [
|
|
|
14
14
|
'install',
|
|
15
15
|
'link',
|
|
16
16
|
'pack',
|
|
17
|
-
'patch',
|
|
18
17
|
'patch-commit',
|
|
18
|
+
'patch',
|
|
19
19
|
'plugin',
|
|
20
20
|
'rebuild',
|
|
21
21
|
'remove',
|
|
@@ -25,8 +25,8 @@ const commands = [
|
|
|
25
25
|
'unlink',
|
|
26
26
|
'unplug',
|
|
27
27
|
'up',
|
|
28
|
-
'upgrade',
|
|
29
28
|
'upgrade-interactive',
|
|
29
|
+
'upgrade',
|
|
30
30
|
'version',
|
|
31
31
|
'why',
|
|
32
32
|
'workspace',
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import './util/register.js';
|
|
3
3
|
import prettyMilliseconds from 'pretty-ms';
|
|
4
|
-
import
|
|
4
|
+
import reporters from './reporters/index.js';
|
|
5
5
|
import parsedArgValues, { helpText } from './util/cli-arguments.js';
|
|
6
6
|
import { isKnownError, getKnownError, isConfigurationError, hasCause } from './util/errors.js';
|
|
7
7
|
import { _load } from './util/loader.js';
|
|
@@ -9,7 +9,7 @@ import { cwd, resolve } from './util/path.js';
|
|
|
9
9
|
import { Performance } from './util/Performance.js';
|
|
10
10
|
import { version } from './version.js';
|
|
11
11
|
import { main } from './index.js';
|
|
12
|
-
const { debug: isDebug = false, help: isHelp, 'max-issues': maxIssues = '0', 'no-config-hints': noConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = false, 'include-entry-exports': isIncludeEntryExports = false, performance: isObservePerf = false, production: isProduction = false,
|
|
12
|
+
const { debug: isDebug = false, help: isHelp, 'max-issues': maxIssues = '0', 'no-config-hints': noConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = false, 'ignore-internal': isIgnoreInternal = false, 'include-entry-exports': isIncludeEntryExports = false, performance: isObservePerf = false, production: isProduction = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', strict: isStrict = false, tsConfig, version: isVersion, } = parsedArgValues;
|
|
13
13
|
if (isHelp) {
|
|
14
14
|
console.log(helpText);
|
|
15
15
|
process.exit(0);
|
|
@@ -19,13 +19,7 @@ if (isVersion) {
|
|
|
19
19
|
process.exit(0);
|
|
20
20
|
}
|
|
21
21
|
const isShowProgress = !isDebug && isNoProgress === false && process.stdout.isTTY && typeof process.stdout.cursorTo === 'function';
|
|
22
|
-
const
|
|
23
|
-
const processAsync = (data, processors) => processors.length === 0 ? Promise.resolve(data) : processAsync(processors[0](data), processors.slice(1));
|
|
24
|
-
const reporters = await Promise.all(reporter.map(async (reporter) => {
|
|
25
|
-
return reporter in internalReporters
|
|
26
|
-
? internalReporters[reporter]
|
|
27
|
-
: await _load(resolve(reporter));
|
|
28
|
-
}));
|
|
22
|
+
const printReport = reporter in reporters ? reporters[reporter] : await _load(resolve(reporter));
|
|
29
23
|
const run = async () => {
|
|
30
24
|
try {
|
|
31
25
|
const perfObserver = new Performance(isObservePerf);
|
|
@@ -33,12 +27,13 @@ const run = async () => {
|
|
|
33
27
|
cwd,
|
|
34
28
|
tsConfigFile: tsConfig,
|
|
35
29
|
gitignore: !isNoGitIgnore,
|
|
36
|
-
isStrict,
|
|
37
30
|
isProduction,
|
|
31
|
+
isStrict,
|
|
32
|
+
isIgnoreInternal,
|
|
38
33
|
isShowProgress,
|
|
39
34
|
isIncludeEntryExports,
|
|
40
35
|
});
|
|
41
|
-
|
|
36
|
+
await printReport({
|
|
42
37
|
report,
|
|
43
38
|
issues,
|
|
44
39
|
configurationHints,
|
|
@@ -47,10 +42,7 @@ const run = async () => {
|
|
|
47
42
|
isProduction,
|
|
48
43
|
isShowProgress,
|
|
49
44
|
options: reporterOptions,
|
|
50
|
-
};
|
|
51
|
-
const finalData = await processAsync(initialData, preprocessors);
|
|
52
|
-
for (const reporter of reporters)
|
|
53
|
-
await reporter(finalData);
|
|
45
|
+
});
|
|
54
46
|
const totalErrorCount = Object.keys(report)
|
|
55
47
|
.filter(reportGroup => report[reportGroup] && rules[reportGroup] === 'error')
|
|
56
48
|
.reduce((errorCount, reportGroup) => errorCount + counters[reportGroup], 0);
|
package/dist/constants.js
CHANGED
|
@@ -13,6 +13,7 @@ export const IGNORED_GLOBAL_BINARIES = [
|
|
|
13
13
|
'cd',
|
|
14
14
|
'cp',
|
|
15
15
|
'deno',
|
|
16
|
+
'dirname',
|
|
16
17
|
'echo',
|
|
17
18
|
'exec',
|
|
18
19
|
'exit',
|
|
@@ -28,6 +29,7 @@ export const IGNORED_GLOBAL_BINARIES = [
|
|
|
28
29
|
'rm',
|
|
29
30
|
'sh',
|
|
30
31
|
'sudo',
|
|
32
|
+
'test',
|
|
31
33
|
'true',
|
|
32
34
|
'yarn',
|
|
33
35
|
];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandLineOptions } from './types/cli.js';
|
|
2
2
|
export type { RawConfiguration as KnipConfig } from './types/config.js';
|
|
3
|
-
export type {
|
|
3
|
+
export type { Reporter, ReporterOptions } from './types/issues.js';
|
|
4
4
|
export declare const main: (unresolvedConfiguration: CommandLineOptions) => Promise<{
|
|
5
5
|
report: import("./types/issues.js").Report;
|
|
6
6
|
issues: import("./types/issues.js").Issues;
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { _require } from './util/require.js';
|
|
|
20
20
|
import { loadTSConfig as loadCompilerOptions } from './util/tsconfig-loader.js';
|
|
21
21
|
import { WorkspaceWorker } from './WorkspaceWorker.js';
|
|
22
22
|
export const main = async (unresolvedConfiguration) => {
|
|
23
|
-
const { cwd, tsConfigFile, gitignore, isStrict, isProduction, isShowProgress, isIncludeEntryExports } = unresolvedConfiguration;
|
|
23
|
+
const { cwd, tsConfigFile, gitignore, isStrict, isProduction, isIgnoreInternal, isShowProgress, isIncludeEntryExports, } = unresolvedConfiguration;
|
|
24
24
|
debugLogObject('Unresolved configuration (from CLI arguments)', unresolvedConfiguration);
|
|
25
25
|
const chief = new ConfigurationChief({ cwd, isProduction });
|
|
26
26
|
const deputy = new DependencyDeputy({ isStrict });
|
|
@@ -267,7 +267,10 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
267
267
|
continue;
|
|
268
268
|
const importedModule = importedSymbols.get(filePath);
|
|
269
269
|
for (const [symbol, exportedItem] of exportItems.entries()) {
|
|
270
|
-
|
|
270
|
+
const jsDocTags = principal.getJSDocTags(exportedItem);
|
|
271
|
+
if (jsDocTags.includes('@public') || jsDocTags.includes('@beta'))
|
|
272
|
+
continue;
|
|
273
|
+
if (isIgnoreInternal && jsDocTags.includes('@internal'))
|
|
271
274
|
continue;
|
|
272
275
|
if (importedModule?.symbols.has(symbol)) {
|
|
273
276
|
if (importedModule.isReExport && isExportedInEntryFile(importedModule))
|
|
@@ -10,7 +10,7 @@ const findAvaDependencies = async (configFilePath, { cwd, manifest }) => {
|
|
|
10
10
|
const config = configFilePath.endsWith('package.json') ? manifest.ava : await load(configFilePath);
|
|
11
11
|
const requireArgs = (config?.require ?? []).map(require => `--require ${require}`);
|
|
12
12
|
const otherArgs = config?.nodeArguments ?? [];
|
|
13
|
-
const cmd = `node ${otherArgs.join(' ')
|
|
13
|
+
const cmd = `node ${otherArgs.join(' ')} ${requireArgs.join(' ')}`;
|
|
14
14
|
return _getDependenciesFromScripts([cmd], {
|
|
15
15
|
cwd,
|
|
16
16
|
manifest,
|
package/dist/types/cli.d.ts
CHANGED
package/dist/types/issues.d.ts
CHANGED
|
@@ -45,12 +45,12 @@ export type ReporterOptions = {
|
|
|
45
45
|
configurationHints: ConfigurationHints;
|
|
46
46
|
noConfigHints: boolean;
|
|
47
47
|
cwd: string;
|
|
48
|
+
workingDir: string;
|
|
48
49
|
isProduction: boolean;
|
|
49
50
|
isShowProgress: boolean;
|
|
50
51
|
options: string;
|
|
51
52
|
};
|
|
52
53
|
export type Reporter = (options: ReporterOptions) => void;
|
|
53
|
-
export type Preprocessor = (options: ReporterOptions) => ReporterOptions;
|
|
54
54
|
export type IssueSeverity = 'error' | 'warn' | 'off';
|
|
55
55
|
export type Rules = Record<IssueType, IssueSeverity>;
|
|
56
56
|
export type ConfigurationHints = Set<ConfigurationHint>;
|
|
@@ -3,6 +3,7 @@ import { SymbolType } from '../../../types/issues.js';
|
|
|
3
3
|
import { exportVisitor as visit } from '../index.js';
|
|
4
4
|
export default visit(() => true, node => {
|
|
5
5
|
if (ts.isExportAssignment(node)) {
|
|
6
|
-
|
|
6
|
+
const pos = node.getChildAt(1).getStart();
|
|
7
|
+
return { node, identifier: 'default', type: SymbolType.UNKNOWN, pos };
|
|
7
8
|
}
|
|
8
9
|
});
|
|
@@ -2,8 +2,10 @@ import ts from 'typescript';
|
|
|
2
2
|
import { stripQuotes } from '../../ast-helpers.js';
|
|
3
3
|
import { scriptVisitor as visit } from '../index.js';
|
|
4
4
|
export default visit(sourceFile => sourceFile.statements.some(statementImportsExeca$), node => {
|
|
5
|
-
if (ts.isTaggedTemplateExpression(node)
|
|
6
|
-
|
|
5
|
+
if (ts.isTaggedTemplateExpression(node)) {
|
|
6
|
+
if (node.tag.getText() === '$' || (ts.isCallExpression(node.tag) && node.tag.expression.getText() === '$')) {
|
|
7
|
+
return stripQuotes(node.template.getText());
|
|
8
|
+
}
|
|
7
9
|
}
|
|
8
10
|
});
|
|
9
11
|
function statementImportsExeca$(node) {
|
|
@@ -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 [dir] 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 (automatically enabled in CI environments)\n --
|
|
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 --ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)\n --workspace [dir] 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 (automatically enabled in CI environments)\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;
|
|
@@ -7,6 +7,7 @@ declare const _default: {
|
|
|
7
7
|
exclude: string[] | undefined;
|
|
8
8
|
exports: boolean | undefined;
|
|
9
9
|
help: boolean | undefined;
|
|
10
|
+
'ignore-internal': boolean | undefined;
|
|
10
11
|
include: string[] | undefined;
|
|
11
12
|
'include-entry-exports': boolean | undefined;
|
|
12
13
|
'max-issues': string | undefined;
|
|
@@ -16,8 +17,7 @@ declare const _default: {
|
|
|
16
17
|
'no-progress': boolean | undefined;
|
|
17
18
|
performance: boolean | undefined;
|
|
18
19
|
production: boolean | undefined;
|
|
19
|
-
|
|
20
|
-
reporter: string[] | undefined;
|
|
20
|
+
reporter: string | undefined;
|
|
21
21
|
'reporter-options': string | undefined;
|
|
22
22
|
strict: boolean | undefined;
|
|
23
23
|
tsConfig: string | undefined;
|
|
@@ -8,6 +8,7 @@ Options:
|
|
|
8
8
|
-t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)
|
|
9
9
|
--production Analyze only production source files (e.g. no tests, devDependencies, exported types)
|
|
10
10
|
--strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)
|
|
11
|
+
--ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)
|
|
11
12
|
--workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)
|
|
12
13
|
--no-gitignore Don't use .gitignore
|
|
13
14
|
--include Report only provided issue type(s), can be comma-separated or repeated (1)
|
|
@@ -16,8 +17,7 @@ Options:
|
|
|
16
17
|
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
17
18
|
--include-entry-exports Include entry files when reporting unused exports
|
|
18
19
|
-n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
|
|
19
|
-
--
|
|
20
|
-
--reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)
|
|
20
|
+
--reporter Select reporter: symbols, compact, codeowners, json (default: symbols)
|
|
21
21
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
22
22
|
--no-config-hints Suppress configuration hints
|
|
23
23
|
--no-exit-code Always exit with code zero (0)
|
|
@@ -51,6 +51,7 @@ try {
|
|
|
51
51
|
exclude: { type: 'string', multiple: true },
|
|
52
52
|
exports: { type: 'boolean' },
|
|
53
53
|
help: { type: 'boolean', short: 'h' },
|
|
54
|
+
'ignore-internal': { type: 'boolean' },
|
|
54
55
|
include: { type: 'string', multiple: true },
|
|
55
56
|
'include-entry-exports': { type: 'boolean' },
|
|
56
57
|
'max-issues': { type: 'string' },
|
|
@@ -60,8 +61,7 @@ try {
|
|
|
60
61
|
'no-progress': { type: 'boolean', short: 'n' },
|
|
61
62
|
performance: { type: 'boolean' },
|
|
62
63
|
production: { type: 'boolean' },
|
|
63
|
-
|
|
64
|
-
reporter: { type: 'string', multiple: true },
|
|
64
|
+
reporter: { type: 'string' },
|
|
65
65
|
'reporter-options': { type: 'string' },
|
|
66
66
|
strict: { type: 'boolean' },
|
|
67
67
|
tsConfig: { type: 'string', short: 't' },
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.20.
|
|
1
|
+
export declare const version = "2.20.1";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.20.
|
|
1
|
+
export const version = '2.20.1';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "2.20.
|
|
3
|
+
"version": "2.20.1",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://github.com/webpro/knip",
|
|
6
6
|
"repository": "github:webpro/knip",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"scripts": {
|
|
20
20
|
"knip": "node ./dist/cli.js",
|
|
21
|
-
"knip:production": "node ./dist/cli.js --production --strict",
|
|
21
|
+
"knip:production": "node ./dist/cli.js --production --strict --ignore-internal",
|
|
22
22
|
"lint": "eslint scripts src tests",
|
|
23
23
|
"lint:fix": "eslint scripts src tests --fix",
|
|
24
24
|
"format": "prettier scripts src tests schema.json --with-node-modules --write --config .prettierrc",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"easy-table": "^1.2.0",
|
|
50
50
|
"fast-glob": "^3.2.12",
|
|
51
51
|
"globby": "^13.1.3",
|
|
52
|
-
"jiti": "1.19.
|
|
52
|
+
"jiti": "^1.19.3",
|
|
53
53
|
"js-yaml": "^4.1.0",
|
|
54
54
|
"micromatch": "^4.0.5",
|
|
55
55
|
"minimist": "^1.2.8",
|
|
@@ -57,35 +57,35 @@
|
|
|
57
57
|
"strip-json-comments": "^5.0.0",
|
|
58
58
|
"summary": "^2.1.0",
|
|
59
59
|
"typescript": "^5.0.2",
|
|
60
|
-
"zod": "^3.
|
|
61
|
-
"zod-validation-error": "1.
|
|
60
|
+
"zod": "^3.22.2",
|
|
61
|
+
"zod-validation-error": "^1.5.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@jest/types": "29.6.
|
|
64
|
+
"@jest/types": "29.6.3",
|
|
65
65
|
"@npmcli/package-json": "5.0.0",
|
|
66
66
|
"@release-it/bumper": "5.1.0",
|
|
67
67
|
"@swc/cli": "0.1.62",
|
|
68
|
-
"@swc/core": "1.3.
|
|
68
|
+
"@swc/core": "1.3.78",
|
|
69
69
|
"@types/eslint": "8.44.2",
|
|
70
70
|
"@types/js-yaml": "4.0.5",
|
|
71
71
|
"@types/micromatch": "4.0.2",
|
|
72
72
|
"@types/minimist": "1.2.2",
|
|
73
|
-
"@types/node": "20.5.
|
|
73
|
+
"@types/node": "20.5.6",
|
|
74
74
|
"@types/npmcli__map-workspaces": "3.0.1",
|
|
75
|
-
"@types/webpack": "5.28.
|
|
76
|
-
"@typescript-eslint/eslint-plugin": "6.4.
|
|
77
|
-
"@typescript-eslint/parser": "6.4.
|
|
75
|
+
"@types/webpack": "5.28.2",
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "6.4.1",
|
|
77
|
+
"@typescript-eslint/parser": "6.4.1",
|
|
78
78
|
"c8": "8.0.1",
|
|
79
|
-
"eslint": "8.
|
|
79
|
+
"eslint": "8.48.0",
|
|
80
80
|
"eslint-import-resolver-typescript": "3.6.0",
|
|
81
|
-
"eslint-plugin-import": "2.28.
|
|
82
|
-
"eslint-plugin-n": "16.0.
|
|
81
|
+
"eslint-plugin-import": "2.28.1",
|
|
82
|
+
"eslint-plugin-n": "16.0.2",
|
|
83
83
|
"prettier": "3.0.2",
|
|
84
84
|
"release-it": "16.1.5",
|
|
85
85
|
"remark-cli": "11.0.0",
|
|
86
86
|
"remark-preset-webpro": "0.0.3",
|
|
87
87
|
"tsx": "3.12.7",
|
|
88
|
-
"type-fest": "4.
|
|
88
|
+
"type-fest": "4.3.0"
|
|
89
89
|
},
|
|
90
90
|
"engines": {
|
|
91
91
|
"node": ">=16.17.0 <17 || >=18.6.0"
|