Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Apr 19, 2023
1 parent cfebc6b commit 9f924ce
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 37 deletions.
16 changes: 10 additions & 6 deletions README.md
Expand Up @@ -44,12 +44,17 @@ Knip has good defaults and you can run it without any configuration. Here's the

```json
{
"entry": ["index.{js,ts}", "src/index.{js,ts}"],
"project": ["**/*.{js,ts}"]
"entry": ["index.js", "src/index.js"],
"project": ["**/*.js"]
}
```

Well, almost, this is the full list of default extensions: `js`, `mjs`, `cjs`, `jsx`, `ts`, `mts`, `cts` and `tsx`.
In addition to `index.js`, the following file names and extensions are also considered entry files:

- `index`, `main` and `cli`
- `js`, `mjs`, `cjs`, `jsx`, `ts`, `mts`, `cts` and `tsx`

This means files like `main.cjs` and `src/cli.ts` are automatically added as entry files.

### Entry Files

Expand All @@ -58,10 +63,9 @@ Knip looks for entry files at those default locations, but also in other places:
- The `main`, `bin` and `exports` fields of `package.json`.
- [Plugins][2] such as for Next.js, Remix, Gatsby or Svelte add entry files.
- The `scripts` in package.json or other scripts may provide entry files.
- Knip does this for each [workspace][1] it finds.

In other words, Knip looks in many places and you may not need much configuration. In a perfectly boring world where
everything is according to defaults you don't even need a `knip.json` file.
Knip does this for each [workspace][1] it finds, trying to minimize the configuration to suit your project. In a
perfectly boring world where everything is according to defaults you wouldn't even need a `knip.json` file at all.

Larger projects tend to have more things customized, and therefore probably get more out of Knip with a configuration
file. Let's say you are using `.ts` files exclusively and have all source files only in the `src` directory:
Expand Down
84 changes: 53 additions & 31 deletions docs/handling-issues.md
@@ -1,49 +1,66 @@
# Handling Issues

How to handle a long list of reported issues with false positives? The following sections describe potential causes for
false positives, and how to handle them.
How to handle reported issues? A long list of reported issues with many false positives may be caused by several things.
This document aims to help out with handling all of that.

## Unused files

Here are a few solutions you might want to consider when Knip reports too many unused files:
Here are a few things to consider when Knip reports unused files:

- Files may be reported as unused because they are not part of the (default) `entry` file patterns. When added to the
`entry` file patterns, they will no longer be reported as unused.
- Files may be reported as unused because they are not part of the dependency graph calculated from the (default)
`entry` file patterns. When added to the `entry` file patterns, they will no longer be reported as unused.

- Files may be reported as unused because they are not part of the default file patterns and there's no plugin for that
type of file yet. This usually happens when a tool or framework has its own standards regarding entry files. For
example, Next.js has `pages/**/*.js` and Remix has `app/routes/**/*.ts`. Such file patterns can be added manually to
the `entry` patterns of any workspace, or [override existing plugin configuration][1]. Even better: open an issue to
report this or [create the plugin][2].
- Files may be reported as unused because existing plugins do not include that type of entry file yet. This usually
happens when a tool or framework has its own locations regarding entry files. For example, Next.js has `pages/**/*.js`
and Remix has `app/routes/**/*.ts`. Potential solutions:

- [Override plugin configuration][1] to customize default patterns for existing plugins.
- [Create a new plugin][2] for tools or frameworks that are not [in the list][3] yet (or open an issue to request it).
- In the meantime, such file patterns can be added manually to the `entry` patterns of any workspace

- When working in a repository that is not a package-based monorepo and contains many configuration files across the
repository, see [multi-project repositories][3] for a potential solution.
repository, see [multi-project repositories][4] to also match those files.

- Ignore specific files and/or directories. Files and/or directories should be ignored when they are not used by other
source code and configuration files. Or when they are magically imported by other tooling, such as fixtures, mocks or
templates. Here are a few examples of common ignore patterns:
- Files and/or directories should be ignored when they are not used by other source code and configuration files. Or
when they are magically imported by other tooling, such as fixtures, mocks or templates. Here are a few examples of
common ignore patterns:

```json
{
"ignore": ["**/*.d.ts", "**/__mocks__", "**/__fixtures__"]
}
```

- Source files are reported as unused, when only their build artifact is imported. For instance, a `src/module.ts` file
is compiled to `dist/core.js`. When another source file (or package) imports `dist/core.js`, then `src/module.ts` is
not referenced from anywhere. The solution is to add `src/module.ts` to the entry file patterns.

- When a file in the dependency graph is ignored (caused by `.gitignore`) and that is the only one that imports a source
file, then the latter is reported as unused. For instance, for a dependency graph like `src/index.ts`
`ignored/file.ts``src/module.ts`, the ignored file is not part of the dependency graph and causes `src/module.ts`
to be reported as unused. In this case, potential solutions include:

- Add `src/module.ts` to the `entry` file patterns.
- Add `ignored/file.ts` to the `entry` file patterns.
- Add `src/module.ts` to the `ignore` file patterns.
- Make sure `ignored/file.ts` is not ignored by `.gitignore` anymore.
- Use `--no-gitignore` to ignore `.gitignore` files (so `ignored/file.ts` is added to the dependency graph).

## Unused dependencies

Dependencies imported in unused files are reported as unused dependencies. So it's good to remedy too many unused files
first.

- If unused dependencies are related to dependencies having a Knip [plugin][4], maybe the `config` and/or `entry` files
for that dependency are at custom locations? The default values are in the plugin's documentation and can be
overridden to match the custom location(s).
- If unused dependencies are related to dependencies having a Knip [plugin][3], the `config` and/or `entry` files for
that dependency may be at custom locations. The default values are in the plugin's documentation and can be overridden
to match the custom path(s).

- If a dependency doesn't have a Knip plugin yet, this might result in false positives. For instance, when an unknown
`tool.config.js` refers to `@tool/plugin` then this plugin will be reported as an unused dependency. Please file an
issue or [create a new plugin][2].
- If a dependency doesn't have a Knip plugin yet, this might result in false positives. For instance, when
`tool.config.js` refers to `@tool/package` then this dependency will be reported as an unused. Please file an issue or
[create a new plugin][2].

- Dependencies might be used only in files with non-default extensions like `.mdx`, `.vue` or `.svelte`, etc. See
[compilers][5] for more details.
- Dependencies might be imported only from files with extensions like `.mdx`, `.vue` or `.svelte`. See [compilers][5]
for more details on how to include them.

- Problematic dependencies can be ignored:

Expand All @@ -55,23 +72,28 @@ first.

## Unlisted dependencies

Unlisted dependencies are used, but not listed in `package.json`.
This means that a dependency is used, but not listed in `package.json`.

Often the reason for a dependency reported as unlisted is that it's a transitive dependency that can be imported
directly. For instance, Knip uses `fast-glob` which in turn has `micromatch` as a transitive dependency. When Knip
imports or uses `micromatch` directly somewhere, `micromatch` will be reported as unlisted, unless it's added as a
direct dependency of Knip itself in `package.json`.
An unlisted dependency might be a transitive dependency that's imported directly. For instance, Knip uses `fast-glob`
which in turn has `micromatch` as a (transitive) dependency. Knip uses both `fast-glob` and `micromatch`, resulting in
`micromatch` being reported as unlisted. The solution is to make sure `micromatch` itself is also listed in
`package.json`.

## Unused exports

Unused exports of `entry` files are not reported. Exports of other files are might be reported as unused, while they are
meant to be used by consumers of the library. There are a few options to consider for those exported values and types:
Unused exports of `entry` files are not reported.

Sometimes exports of non-entry files are meant to be imported by consumers of the library. There are a few options to
consider in this case:

- Move the export(s) to an entry file.
- Add the containing file to the `entry` array in the configuration.
- Re-export the export(s) from an existing entry file.
- Mark the export(s) [using the JSDoc `@public` tag][6].

Note that entries in the `exports` map in `package.json` are automatically added as entry files by Knip (except when
they are ignored by a `.gitignore` entry).

## Start using Knip in CI with too many reported issues

Eventually, this type of QA only really works when it's tied to an automated workflow. But with too many issues to
Expand All @@ -86,8 +108,8 @@ help in the meantime:

[1]: ../README.md#override-plugin-configuration
[2]: ./writing-a-plugin.md
[3]: ../README.md#multi-project-repositories
[4]: ../README.md#plugins
[3]: ../README.md#plugins
[4]: ../README.md#multi-project-repositories
[5]: ./compilers.md
[6]: ../README.md#public-exports
[7]: ../README.md#filters
Expand Down

0 comments on commit 9f924ce

Please sign in to comment.