Comparing version 0.13.0-members.1 to 0.13.0
@@ -9,3 +9,3 @@ #!/usr/bin/env node | ||
import { measure } from './util/performance.js'; | ||
const { values: { help, dir, config: configFilePath, tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'include-entry-files': isIncludeEntryFiles = false, 'no-progress': noProgress = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', 'max-issues': maxIssues = '0', jsdoc: jsDoc = [], debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = parsedArgs; | ||
const { values: { help, dir, config: configFilePath, tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'include-entry-files': isIncludeEntryFiles = false, 'no-progress': noProgress = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', 'max-issues': maxIssues = '0', debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = parsedArgs; | ||
if (help) { | ||
@@ -33,3 +33,2 @@ printHelp(); | ||
isShowProgress, | ||
jsDoc, | ||
debug: { | ||
@@ -36,0 +35,0 @@ isEnabled: isDebug, |
@@ -18,3 +18,2 @@ export const printHelp = () => { | ||
--reporter-options Pass extra options to the reporter (as JSON string, see example) | ||
--jsdoc Enable JSDoc parsing, with options: public | ||
--debug Show debug output | ||
@@ -30,3 +29,3 @@ --debug-level Set verbosity of debug output (default: 1, max: 2) | ||
$ knip --dir packages/client --include files | ||
$ knip -c ./knip.js --reporter compact --jsdoc public | ||
$ knip -c ./knip.js --reporter compact | ||
$ knip --ignore 'lib/**/*.ts' --ignore build | ||
@@ -33,0 +32,0 @@ $ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}' |
@@ -12,3 +12,3 @@ import ts from 'typescript'; | ||
export const main = async (unresolvedConfiguration) => { | ||
const { cwd, workingDir, configFilePath: configFilePathArg, tsConfigFilePath: tsConfigFilePathArg, include, exclude, ignore, gitignore, isIncludeEntryFiles, isDev, isShowProgress, jsDoc, debug, } = unresolvedConfiguration; | ||
const { cwd, workingDir, configFilePath: configFilePathArg, tsConfigFilePath: tsConfigFilePathArg, include, exclude, ignore, gitignore, isIncludeEntryFiles, isDev, isShowProgress, debug, } = unresolvedConfiguration; | ||
const updateMessage = getMessageUpdater(unresolvedConfiguration); | ||
@@ -107,5 +107,2 @@ debugLogObject(debug, 1, 'Unresolved configuration', unresolvedConfiguration); | ||
isShowProgress, | ||
jsDocOptions: { | ||
isReadPublicTag: jsDoc.includes('public'), | ||
}, | ||
debug, | ||
@@ -112,0 +109,0 @@ }; |
import path from 'node:path'; | ||
import { ts } from 'ts-morph'; | ||
import { partitionSourceFiles, _findDuplicateExportedNames, _hasReferencingDefaultImport, _findReferencingNamespaceNodes, _getExportedDeclarations, _findReferences, hasExternalReferences, hasInternalReferences, } from './util/project.js'; | ||
import { partitionSourceFiles, _findDuplicateExportedNames, _hasReferencingDefaultImport, _findReferencingNamespaceNodes, _getExportedDeclarations, _findReferences, hasExternalReferences, } from './util/project.js'; | ||
import { findUnusedClassMembers, findUnusedEnumMembers } from './util/members.js'; | ||
import { getType } from './util/type.js'; | ||
@@ -9,3 +10,3 @@ import { getDependencyAnalyzer } from './util/dependencies.js'; | ||
export async function findIssues(configuration) { | ||
const { workingDir, report, jsDocOptions, debug } = configuration; | ||
const { workingDir, report, debug } = configuration; | ||
const { entryFiles, productionFiles, projectFiles, isIncludeEntryFiles } = configuration; | ||
@@ -59,5 +60,5 @@ const { manifestPath } = configuration; | ||
updateMessage('Connecting the dots...'); | ||
const isReportValues = report.exports || report.nsExports || report.classMembers; | ||
const isReportTypes = report.types || report.nsTypes || report.enumMembers; | ||
const isReportExports = report.exports || report.nsExports || report.classMembers; | ||
if (report.dependencies || report.unlisted || report.duplicates || isReportExports || isReportTypes) { | ||
if (report.dependencies || report.unlisted || report.duplicates || isReportValues || isReportTypes) { | ||
usedProductionFiles.forEach(sourceFile => { | ||
@@ -96,5 +97,5 @@ counters.processed++; | ||
return; | ||
if (!type && !isReportExports) | ||
if (!type && !isReportValues) | ||
return; | ||
if (jsDocOptions.isReadPublicTag && ts.getJSDocPublicTag(declaration.compilerNode)) | ||
if (ts.getJSDocPublicTag(declaration.compilerNode)) | ||
return; | ||
@@ -118,42 +119,24 @@ let identifier; | ||
declaration.isKind(ts.SyntaxKind.InterfaceDeclaration)) { | ||
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier); | ||
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier); | ||
} | ||
else if (declaration.isKind(ts.SyntaxKind.EnumDeclaration)) { | ||
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier); | ||
const members = declaration.getMembers(); | ||
members.forEach(member => { | ||
const refs = _findReferences(member); | ||
if (hasExternalReferences(refs, filePath)) | ||
return; | ||
if (hasInternalReferences(refs)) | ||
return; | ||
addSymbolIssue('enumMembers', { | ||
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier); | ||
if (report.enumMembers) | ||
findUnusedEnumMembers(declaration, filePath).forEach(member => addSymbolIssue('enumMembers', { | ||
filePath, | ||
symbol: member.getName(), | ||
parentSymbol: identifier?.getText(), | ||
}); | ||
}); | ||
})); | ||
} | ||
else if (declaration.isKind(ts.SyntaxKind.ClassDeclaration)) { | ||
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier); | ||
const members = declaration.getMembers(); | ||
members.forEach(member => { | ||
const isPrivate = member.getCombinedModifierFlags() & ts.ModifierFlags.Private; | ||
if (!isPrivate && | ||
(member.isKind(ts.SyntaxKind.PropertyDeclaration) || member.isKind(ts.SyntaxKind.MethodDeclaration))) { | ||
const refs = _findReferences(member); | ||
if (hasExternalReferences(refs, filePath)) | ||
return; | ||
if (hasInternalReferences(refs)) | ||
return; | ||
addSymbolIssue('classMembers', { | ||
filePath, | ||
symbol: member.getName(), | ||
parentSymbol: identifier?.getText(), | ||
}); | ||
} | ||
}); | ||
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier); | ||
if (report.classMembers) | ||
findUnusedClassMembers(declaration, filePath).forEach(member => addSymbolIssue('classMembers', { | ||
filePath, | ||
symbol: member.getName(), | ||
parentSymbol: identifier?.getText(), | ||
})); | ||
} | ||
else if (declaration.isKind(ts.SyntaxKind.PropertyAccessExpression)) { | ||
identifier = declaration.getLastChildByKindOrThrow(ts.SyntaxKind.Identifier); | ||
identifier = declaration.getLastChildByKind(ts.SyntaxKind.Identifier); | ||
} | ||
@@ -160,0 +143,0 @@ else { |
@@ -52,3 +52,2 @@ import { SourceFile } from 'ts-morph'; | ||
isShowProgress: boolean; | ||
jsDoc: string[]; | ||
debug: { | ||
@@ -74,5 +73,2 @@ isEnabled: boolean; | ||
isShowProgress: boolean; | ||
jsDocOptions: { | ||
isReadPublicTag: boolean; | ||
}; | ||
debug: { | ||
@@ -79,0 +75,0 @@ isEnabled: boolean; |
@@ -17,3 +17,2 @@ declare const _default: { | ||
'reporter-options': string | undefined; | ||
jsdoc: string[] | undefined; | ||
debug: boolean | undefined; | ||
@@ -20,0 +19,0 @@ 'debug-level': string | undefined; |
@@ -18,3 +18,2 @@ import { parseArgs } from 'node:util'; | ||
'reporter-options': { type: 'string' }, | ||
jsdoc: { type: 'string', multiple: true }, | ||
debug: { type: 'boolean' }, | ||
@@ -21,0 +20,0 @@ 'debug-level': { type: 'string' }, |
{ | ||
"name": "knip", | ||
"version": "0.13.0-members.1", | ||
"version": "0.13.0", | ||
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project", | ||
@@ -28,3 +28,3 @@ "keywords": [ | ||
"scripts": { | ||
"knip": "node ./dist/cli.js --jsdoc public", | ||
"knip": "node ./dist/cli.js", | ||
"test": "globstar -- node --loader tsx --test \"test/*.spec.ts\"", | ||
@@ -34,2 +34,3 @@ "watch": "tsc --watch", | ||
"prepublishOnly": "npm test && npm run build && npm run knip", | ||
"format": "remark README.md -o", | ||
"release": "release-it" | ||
@@ -60,2 +61,4 @@ }, | ||
"release-it": "15.5.0", | ||
"remark-cli": "11.0.0", | ||
"remark-preset-webpro": "0.0.1", | ||
"tsx": "3.11.0", | ||
@@ -70,2 +73,7 @@ "type-fest": "3.1.0", | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-webpro" | ||
] | ||
}, | ||
"engines": { | ||
@@ -72,0 +80,0 @@ "node": ">=16.17.0 <17 || >=18.6.0" |
227
README.md
@@ -20,8 +20,7 @@ # βοΈ Knip | ||
- [x] Finds **unused files, dependencies and exports**. | ||
- [x] Finds dependencies not listed in `package.json`. | ||
- [x] Verifies that exported symbols are actually used in other files, even when part of an imported namespace. | ||
- [x] Supports JavaScript inside TypeScript projects (`"allowJs": true`). | ||
- [x] Finds duplicate exports of the same symbol. | ||
- [x] Supports JavaScript ES Module-based projects without a `tsconfig.json`. | ||
- [x] Features multiple [reporters][1] and supports [custom reporters][2]. | ||
- [x] Finds used dependencies not listed in `package.json`. | ||
- [x] Finds duplicate exports. | ||
- [x] Supports JavaScript (without `tsconfig.json`, or TypeScript `allowJs: true`). | ||
- [x] Features multiple [reporters][1] and supports [custom reporters][2] (think JSON and `CODEOWNERS`) | ||
- [x] Run Knip as part of your CI environment to detect issues and prevent regressions. | ||
@@ -36,2 +35,18 @@ Knip really shines in larger projects. A little bit of configuration will pay off, I promise. A comparison with similar | ||
## Roadmap | ||
Please report any false positives by [opening an issue in this repo][6]. Bonus points for adding a public repository or | ||
opening a pull request with a directory and example files in `test/fixtures`. Correctness and bug fixes have priority | ||
over new features: | ||
### Upcoming Features | ||
- [ ] Find unused members of classes and enums (#11 and #20). | ||
- [ ] Custom dependency resolvers: find dependencies used in npm scripts. | ||
- [ ] Custom dependency resolvers: find unused and unlisted plugins for Webpack, ESLint & Babel, etc. (#7) | ||
- [ ] Smart default configurations and more fine-grained configuration options. | ||
- [ ] Full support for monorepos (partial [monorepos support][7] with `--dir` exists). | ||
- [ ] Fix issues: remove `export` keyword, uninstall unused dependencies, delete files (like `--fix` of ESLint). | ||
- [ ] Add more reporters and report customization options (#3). | ||
## Installation | ||
@@ -41,3 +56,3 @@ | ||
Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.3. Knip is _cutting edge!_ | ||
Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.6. Knip is _cutting edge!_ | ||
@@ -73,3 +88,3 @@ ## Usage | ||
![How it works][6] | ||
![How it works][8] | ||
@@ -85,5 +100,5 @@ ## Options | ||
--dir Working directory (default: current working directory) | ||
--include Report only listed issue type(s) (see below) | ||
--exclude Exclude issue type(s) from report (see below) | ||
--ignore Ignore files matching this glob pattern (can be set multiple times) | ||
--include Report only listed issue type(s), can be repeated | ||
--exclude Exclude issue type(s) from report, can be repeated | ||
--ignore Ignore files matching this glob pattern, can be repeated | ||
--no-gitignore Don't use .gitignore | ||
@@ -96,3 +111,2 @@ --dev Include `devDependencies` in report(s) | ||
--reporter-options Pass extra options to the reporter (as JSON string, see example) | ||
--jsdoc Enable JSDoc parsing, with options: public | ||
--debug Show debug output | ||
@@ -102,3 +116,3 @@ --debug-level Set verbosity of debug output (default: 1, max: 2) | ||
Issue types: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates | ||
Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates | ||
@@ -109,3 +123,3 @@ Examples: | ||
$ knip --dir packages/client --include files | ||
$ knip -c ./knip.js --reporter compact --jsdoc public | ||
$ knip -c ./knip.js --reporter compact | ||
$ knip --ignore 'lib/**/*.ts' --ignore build | ||
@@ -116,10 +130,2 @@ $ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}' | ||
## Performance | ||
π Knip is considerably faster when only the `files` and/or `duplicates` types are included. Finding unused exports | ||
requires deeper analysis (`exports`, `nsExports`, `types`, `nsTypes`). The following example commands do the same: | ||
knip --include files --include duplicates | ||
knip --include files,duplicates | ||
## Reading the report | ||
@@ -131,10 +137,17 @@ | ||
- `files` - Unused files: did not find references to this file | ||
- `dependencies` - Unused dependencies: did not find references to this dependency | ||
- `unlisted` - Unlisted dependencies: imported dependencies, but not listed in package.json (1) | ||
- `exports` - Unused exports: did not find references to this exported variable | ||
- `nsExports` - Unused exports in namespaces: did not find direct references to this exported variable (2) | ||
- `types` - Unused types: did not find references to this exported type | ||
- `nsTypes` - Unused types in namespaces: did not find direct references to this exported variable (2) | ||
- `duplicates` - Duplicate exports: the same thing is exported more than once with different names from the same file | ||
- Dependencies (`package.json`) | ||
- `dependencies` - Unused dependencies: did not find references to this dependency | ||
- `unlisted` - Unlisted dependencies: used dependencies, but not listed in package.json (1) | ||
- Values (JavaScript) | ||
- `exports` - Unused exports: did not find references to this exported variable | ||
- `nsExports` - Unused exports in namespaces: did not find direct references to this exported variable (2) | ||
- `classMembers` - Unused class members: did not find references to this member of the exported class | ||
- Types (TypeSscript) | ||
- `types` - Unused types: did not find references to this exported type | ||
- `nsTypes` - Unused types in namespaces: did not find direct references to this exported variable (2) | ||
- `enumMembers` - Unused enum members: did not find references to this member of the exported enum | ||
- `duplicates` - Duplicate exports: the same thing is exported more than once | ||
Notes: | ||
1. This includes dependencies that could not be resolved. For instance, what does `unresolved/dir/module` mean? | ||
@@ -160,10 +173,47 @@ - To target something in the (missing) `node_modules/unresolved` package? | ||
file. If this is not the case, it can be removed. | ||
- Duplicate exports can be removed to export only once, make sure to import that everywhere. | ||
π Repeat the process to reveal new unused files and exports. Sometimes it's so liberating to remove things! | ||
## Production versus non-production code | ||
## Performance | ||
π Knip finds issues of type `files`, `dependencies`, `unlisted` and `duplicates` very fast. Finding unused exports | ||
requires deeper analysis (`exports`, `nsExports`, `classMembers`, `types`, `nsTypes`, `enumMembers`). | ||
Use `--include` to report only specific issue types (the following example commands do the same): | ||
knip --include files --include dependencies | ||
knip --include files,dependencies | ||
Use `--exclude` to ignore reports you're not interested in: | ||
knip --include files --exclude classMembers,enumMembers | ||
Use `--performance` to see where most of the time is spent. | ||
## Configuration | ||
### Libraries versus Applications | ||
Libraries and applications are identical when it comes to files and dependencies: whatever is unused should be removed. | ||
Yet libraries usually have exports meant to be used by other libraries or applications. Such public variables and types | ||
in libraries can be marked with the JSDoc `@public` tag: | ||
```js | ||
/** | ||
* Merge two objects. | ||
* | ||
* @public | ||
*/ | ||
export const merge = function () {}; | ||
``` | ||
Knip does not report public exports and types as unused. | ||
### Production versus non-production code | ||
Feels like you're getting too many false positives? Let's talk about `entryFiles` and `projectFiles`. | ||
### Production code | ||
#### Production code | ||
@@ -180,3 +230,3 @@ The default configuration for Knip is very strict and targets production code. Non-production files such as tests should | ||
### Non-production code | ||
#### Non-production code | ||
@@ -260,5 +310,4 @@ Non-production code includes files such as unit tests, end-to-end tests, tooling, scripts, Storybook stories, etc. Think | ||
A good example of a large project setup is a monorepo. Let's take an example (Nx) project configuration using Next.js, | ||
Jest and Storybook, which has multiple apps and libs. They are not published separately and don't have their own | ||
`package.json`. | ||
Let's take another example Nx project configuration using Next.js, Jest and Storybook, which has multiple apps and libs. | ||
They are not published separately and don't have their own `package.json`. | ||
@@ -294,6 +343,6 @@ This configuration file can also be a JavaScript file, which allows to add logic and/or comments (e.g. `knip.js`): | ||
- [`json`](#json) | ||
- [`symbol`](#symbol-default) (default) | ||
- [`compact`](#compact) | ||
- [`codeowners`](#code-owners) | ||
- [`json`][9] | ||
- [`symbol`][10] (default) | ||
- [`compact`][11] | ||
- [`codeowners`][12] | ||
@@ -353,34 +402,27 @@ ### Custom Reporters | ||
The keys match the [known issue types](#reading-the-report). | ||
The keys match the [known issue types][13]. | ||
#### Usage Ideas | ||
Use tools like [miller](https://github.com/johnkerl/miller) or [jtbl](https://github.com/kellyjonbrazil/jtbl) to consume | ||
the JSON and render a table in the terminal. | ||
Use tools like [miller][14] or [jtbl][15] to consume the JSON and render a table in the terminal. | ||
##### Table | ||
``` | ||
$ npx knip --reporter json | mlr --ijson --opprint --no-auto-flatten cat | ||
file owners files unlisted exports types duplicates | ||
src/Registration.tsx @org/owner true react lowercaseFirstLetter, RegistrationBox RegistrationServices, RegistrationAction Registration, default | ||
src/ProductsList.tsx @org/team false - - ProductDetail - | ||
``` | ||
$ npx knip --reporter json | mlr --ijson --opprint --no-auto-flatten cat | ||
file owners files unlisted exports types duplicates | ||
src/Registration.tsx @org/owner true react lowercaseFirstLetter, RegistrationBox RegistrationServices, RegistrationAction Registration, default | ||
src/ProductsList.tsx @org/team false - - ProductDetail - | ||
##### Markdown Table | ||
``` | ||
$ npx knip --reporter json | mlr --ijson --omd --no-auto-flatten cat | ||
| file | owners | files | duplicates | | ||
| --- | --- | --- | --- | | ||
| src/Registration.tsx | @org/owner | true | Registration, default | | ||
| src/ProductsList.tsx | @org/team | false | | | ||
``` | ||
$ npx knip --reporter json | mlr --ijson --omd --no-auto-flatten cat | ||
| file | owners | files | duplicates | | ||
| --- | --- | --- | --- | | ||
| src/Registration.tsx | @org/owner | true | Registration, default | | ||
| src/ProductsList.tsx | @org/team | false | | | ||
Include specific issue types and/or replace the `cat` command with `put` for clean output: | ||
``` | ||
npx knip --include files,duplicates --reporter json | mlr --ijson --opprint --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }' | ||
npx knip --reporter json | mlr --ijson --omd --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }' | ||
``` | ||
npx knip --include files,duplicates --reporter json | mlr --ijson --opprint --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }' | ||
npx knip --reporter json | mlr --ijson --omd --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }' | ||
@@ -482,16 +524,18 @@ ### More Output Examples | ||
| Feature | **knip** | [depcheck][7] | [unimported][8] | [ts-unused-exports][9] | [ts-prune][10] | [find-unused-exports][11] | | ||
| --------------------------------- | :------: | :-----------: | :-------------: | :--------------------: | :------------: | :-----------------------: | | ||
| Unused files | β | - | β | - | - | - | | ||
| Unused dependencies | β | β | β | - | - | - | | ||
| Unlisted dependencies | β | β | β | - | - | - | | ||
| [Custom dependency resolvers][12] | β | β | β | - | - | - | | ||
| Unused exports | β | - | - | β | β | β | | ||
| Duplicate exports | β | - | - | β | β | β | | ||
| Search namespaces | β | - | - | β | β | β | | ||
| Custom reporters | β | - | - | - | - | - | | ||
| Pure JavaScript/ESM | β | β | β | - | - | β | | ||
| Configure entry files | β | β | β | β | β | β | | ||
| [Support monorepos][13] | π | - | - | - | - | - | | ||
| ESLint plugin available | - | - | - | β | - | - | | ||
| Feature | **knip** | [depcheck][16] | [unimported][17] | [ts-unused-exports][18] | [ts-prune][19] | [find-unused-exports][20] | | ||
| :-------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: | :-----------------------: | | ||
| Unused files | β | - | β | - | - | - | | ||
| Unused dependencies | β | β | β | - | - | - | | ||
| Unlisted dependencies | β | β | β | - | - | - | | ||
| [CustomΒ dependencyΒ resolvers][21] | β | β | β | - | - | - | | ||
| Unused exports | β | - | - | β | β | β | | ||
| UnusedΒ classΒ members | β | - | - | - | - | - | | ||
| UnusedΒ enumΒ members | β | - | - | - | - | - | | ||
| Duplicate exports | β | - | - | β | β | β | | ||
| Search namespaces | β | - | - | β | β | β | | ||
| Custom reporters | β | - | - | - | - | - | | ||
| JavaScript support | β | β | β | - | - | β | | ||
| Configure entry files | β | β | β | β | β | β | | ||
| [Support monorepos][22] | π | - | - | - | - | - | | ||
| ESLint plugin available | - | - | - | β | - | - | | ||
@@ -507,7 +551,8 @@ β = Supported, β = Not supported, - = Out of scope | ||
Using a string like `"plugin:cypress/recommended"` in the `extends` property of a `.eslintrc.json` in a package | ||
directory of a monorepo is nice for DX. But Knip will need some help to find it and to understand this _resolves to_ the | ||
`eslint-plugin-cypress` _dependency_. Or see it is not listed in `package.json`. Or that the dependency is still listed, | ||
directory of a monorepo is nice for DX. But Knip will need some help to find it and to understand this resolves to the | ||
`eslint-plugin-cypress` dependency. Or see it is not listed in `package.json`. Or that the dependency is still listed, | ||
but no longer in use. Many popular projects reference plugins in similar ways, such as Babel, Webpack and Storybook. | ||
Big compliments to [depcheck][15] which already does this! They call this "specials". [Knip has this ambition][16], too. | ||
Big compliments to [depcheck][23] which already does this! They call this "specials". This is on [Knip's roadmap][24], | ||
as well, with the additional ambition to also find used dependencies that are not listed in `package.json`. | ||
@@ -534,12 +579,20 @@ unimported is strict in this regard and works based on production files and `dependencies`, so does not have custom | ||
[5]: ./assets/cow-with-orange-scissors-van-gogh-style.webp | ||
[6]: ./assets/how-it-works.drawio.svg | ||
[7]: https://github.com/depcheck/depcheck | ||
[8]: https://github.com/smeijer/unimported | ||
[9]: https://github.com/pzavolinsky/ts-unused-exports | ||
[10]: https://github.com/nadeesha/ts-prune | ||
[11]: https://github.com/jaydenseric/find-unused-exports | ||
[12]: #custom-dependency-resolvers | ||
[13]: #monorepos-1 | ||
[14]: #monorepos | ||
[15]: https://github.com/depcheck/depcheck#special | ||
[16]: https://github.com/webpro/knip/issues/7 | ||
[6]: https://github.com/webpro/knip/issues | ||
[7]: #monorepos | ||
[8]: ./assets/how-it-works.drawio.svg | ||
[9]: #json | ||
[10]: #symbol-default | ||
[11]: #compact | ||
[12]: #code-owners | ||
[13]: #reading-the-report | ||
[14]: https://github.com/johnkerl/miller | ||
[15]: https://github.com/kellyjonbrazil/jtbl | ||
[16]: https://github.com/depcheck/depcheck | ||
[17]: https://github.com/smeijer/unimported | ||
[18]: https://github.com/pzavolinsky/ts-unused-exports | ||
[19]: https://github.com/nadeesha/ts-prune | ||
[20]: https://github.com/jaydenseric/find-unused-exports | ||
[21]: #custom-dependency-resolvers | ||
[22]: #monorepos-1 | ||
[23]: https://github.com/depcheck/depcheck#special | ||
[24]: #roadmap |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86719
53
581
10
1302