Skip to content

Commit

Permalink
Improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Oct 5, 2022
1 parent f8e7efd commit 65d93ca
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 45 deletions.
96 changes: 52 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ This is where Exportman comes in:
- [x] Resolves all (unused) files in your project and reports **unused files and exports**.
- [x] Verifies that exported symbols are actually used in other files, even when part of an imported namespace.
- [x] Finds duplicate exports of the same symbol.
- [ ] Supports JavaScript projects with CommonJS and ES Modules (TODO).
- [x] Supports JavaScript inside TypeScript projects (`"allowJs": true`)
- [ ] Supports JavaScript-only projects with CommonJS and ESM (no `tsconfig.json`) - TODO

Exportman really shines in larger projects where you have much more files (such as `/docs`, `/tools` and `/scripts`)
than only production code. The `includes` setting in `tsconfig.json` is often too broad, resulting in too many false
negatives. Similar projects either detect only unimported files, or only unused exports. Most of them don't work by
configuring entry files, an essential feature to produce good results. This also allows to unleash Exportman on a
specific part of your project, and scan/handle these separately.
specific part of your project, and work these separately.

Exportman is another fresh take on keeping your projects clean & tidy.

Expand All @@ -37,13 +38,13 @@ Create a configuration file, let's name it `.exportman.json` with these contents

```json
{
"entryFiles": ["src/index.tsx"],
"filePatterns": ["src/**/*.{ts,tsx}", "!**/*.spec.{ts,tsx}"]
"entryFiles": ["src/index.ts"],
"filePatterns": ["src/**/*.ts", "!**/*.spec.ts"]
}
```

The `entryFiles` target the starting point(s) to resolve dependencies. The `filePatterns` should contain all files it
should match them against (including potentially unused files).
The `entryFiles` target the starting point(s) to resolve production code dependencies. The `filePatterns` should contain
all files it should match them against, including potentially unused files.

Then run the checks:

Expand All @@ -53,6 +54,22 @@ npx exportman --config .exportman

This will analyze the project and output unused files, exports, types and duplicate exports.

Use `--onlyFiles` when configuring Exportman for faster initial results.

## How It Works

Exportman works by creating two sets of files:

1. Production code is the set of files resolved from the `entryFiles`.
2. Project files are the full set of files matching the `filePatterns`.
3. The subset of project files that are not production code will be reported as unused files (in red).
4. Then the production code (in blue) will be scanned for unused exports.

![How it works](./assets/how-it-works.drawio.svg)

Clean and actionable reports are achieved when non-production code such as tests are excluded from the `filePatterns`
(using negation patterns such as `!**/*.test.ts`).

## Options

```
Expand Down Expand Up @@ -81,12 +98,32 @@ More info: https://github.com/webpro/exportman

## More configuration examples

### Test files

For best results, it is recommended to exclude files such as tests from the project files. When including tests and
other non-production files, they may prevent production files from being reported as unused. Not including them will
make it clear what production files can be removed (including dependent files!).

The same goes for any type of non-production files, such as Storybook stories or end-to-end tests.

To report dangling files and exports that are not used by any of the production or test files, include both to the set
of `entryFiles`:

```json
{
"entryFiles": ["src/index.ts", "src/**/*.spec.ts"],
"filePatterns": ["src/**/*.ts", "!**/*.e2e.ts"]
}
```

In theory this idea could be extended to report some kind of test coverage.

### Monorepos

#### Separate packages

In repos with multiple packages, the `--cwd` option comes in handy. With similar package structures, the packages can be
configured conveniently using globs:
configured using globs:

```json
{
Expand All @@ -97,18 +134,20 @@ configured conveniently using globs:
}
```

Packages can also be explicitly configured per package directory. To scan the packages separately, using the first match
from the configuration file:
Packages can also be explicitly configured per package directory.

To scan the packages separately, using the first match from the configuration file:

```
exportman --cwd packages/client --config exportman.json
exportman --cwd packages/services --config exportman.json
```

#### Connected projects (e.g. using Nx)
#### Connected projects

A good example of a large project setup is a monorepo, such as created with Nx. Let's take an example project
configuration for an Nx project using Next.js, Jest and Storybook:
configuration for an Nx project using Next.js, Jest and Storybook. This can also be a JavaScript file, which allows to
add logic and/or comments:

```js
const entryFiles = ['apps/**/pages/**/*.{js,ts,tsx}'];
Expand All @@ -130,39 +169,8 @@ const filePatterns = [
module.exports = { entryFiles, filePatterns };
```

This should give good results about unused files and exports. After the first run, the configuration can be tweaked
further to the project structure.

### Test Coverage

This can also be turned around: which source files are not covered by tests? Here's an example configuration based on
the previous one:

```js
const entryFiles = ['{apps,libs}/**/*.spec.{ts,tsx}'];

const filePatterns = [
'{apps,libs}/**/*.{ts,tsx}',
'!apps/**/pages/**/*.{ts,tsx}',
// Next.js
'!**/next.config.js',
'!**/apps/**/public/**',
'!**/apps/**/next-env.d.ts'
// Jest
'!**/jest.config.ts',
// Storybook
'!**/.storybook/**',
'!**/*.stories.tsx',
];

module.exports = { entryFiles, filePatterns };
```

```
npx exportman --config exportman.config --onlyFiles
```

This will output the production files that are not imported from test files or their dependencies, etc.
This should give good results about unused files and exports for the monorepo. After the first run, the configuration
can be tweaked further to the project structure.

## Example Output

Expand Down
53 changes: 53 additions & 0 deletions assets/how-it-works.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@
"name": "exportman",
"version": "0.0.3",
"description": "Find unused files and exports in your TypeScript project",
"keywords": [
"find",
"detect",
"unused",
"files",
"exports",
"types",
"duplicates",
"typescript",
"maintenance",
"unimported"
],
"main": "dist/index.js",
"bin": {
"exportman": "dist/cli.js"
Expand All @@ -16,7 +28,6 @@
"files": [
"dist"
],
"keywords": [],
"author": {
"name": "Lars Kappert",
"email": "[email protected]"
Expand Down

0 comments on commit 65d93ca

Please sign in to comment.