Skip to content

Commit

Permalink
Merge branch 'release/1.0' into feat/benchmark-vue-core
Browse files Browse the repository at this point in the history
  • Loading branch information
kazushisan authored Dec 10, 2024
2 parents 859baf6 + 3154bcd commit 771fcff
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 105 deletions.
200 changes: 108 additions & 92 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
<h1 align="center">tsr</h1>
# tsr

[![npm version](https://badge.fury.io/js/tsr.svg)](https://badge.fury.io/js/tsr)
[![install size](https://packagephobia.com/badge?p=tsr)](https://packagephobia.com/result?p=tsr)
[![CI](https://github.com/line/tsr/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/line/tsr/actions/workflows/ci.yml)

TypeScript Remove (tsr) is a utility that removes unused code from TypeScript projects – It's like tree shaking, but for source files

## Features

<div align="center">
<br />
<img width="600" src="./media/cover.gif" />
<br />
<br />
<p>TypeScript Remove (tsr) is a utility that removes unused code from TypeScript projects – It's like tree shaking, but for source files</p>
</div>

[![npm version](https://badge.fury.io/js/@line%2Fts-remove-unused.svg)](https://badge.fury.io/js/@line%2Fts-remove-unused)
[![install size](https://packagephobia.com/badge?p=ts-remove-unused)](https://packagephobia.com/result?p=ts-remove-unused)
[![CI](https://github.com/line/ts-remove-unused/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/line/ts-remove-unused/actions/workflows/ci.yml)
### 🕵️ Find unused code

## Features
tsr statically analyses your TypeScript project like how tree-shaking is implemented in bundlers. Run tsr to get a list of unused exports and files (modules) in your TypeScript project. Use tsr in your CI pipeline to detect unused code from being added.

### 🧹 Remove unused code automatically

tsr is built for automatic code removal. Not only does tsr remove the `export` keyword from unused declarations, it will remove the whole declaration if the declaration not used within the file. tsr will also remove imports and other local declarations that became unnecessary after removing the declaration. [Check out the examples of how tsr edits your files.](#examples)

- 🛠️ Auto-fix unused exports — removes the `export` keyword from the declaration or the whole declaration based on its usage
- 🧹 Deletes TypeScript modules that have no referenced exports
- 🕵️ Check – Use the command without `--write` to detect unused code without making changes
### 📦 Works out of the box

tsr uses the TypeScript compiler to detect files in your project and resolve imports. The only requirement is a valid `tsconfig.json`. There's no need to setup another config file to get tsr running. Specify your entrypoint file and start using tsr in seconds.

## Install

Expand All @@ -27,88 +34,19 @@ TypeScript is a peer dependency.

## Quick Start

1. 🔍 Check your `tsconfig.json` – Make sure `include` and `exclude` is configured thoroughly so that we can correctly detect what's "unused" in your project.
1. **🔍 Check your `tsconfig.json`** – Make sure `include` and `exclude` are configured thoroughly so that tsr can correctly detect unused code.

2. 🔍 Check your entrypoint files – What's the file that is the starting point for your code? Without this information, all files will be recognized as unnecessary. Usually it is some file like `src/main.ts` or maybe a group of files like `src/pages/*`.
2. **🔍 Check your entrypoint files** – Without entrypoint files, all files are unnecessary. Usually it is some file like `src/main.ts` or maybe a group of files like `src/pages/*`.

3. 🚀 Execute – Pass a regex (or multiple regex patterns) that match the entrypoints. Use `--write` to change the files in place.
3. **🚀 Execute** – Pass regex patterns that match the entrypoints. Use `--write` to change the files in place.

```bash
npx tsr 'src/main\.ts$'
```

## Examples

Here are some examples of how this tool will auto-fix unused code.

<!-- prettier-ignore-start -->

When `a2` is not used within the project:

```diff
--- src/a.ts
+++ src/a.ts
@@ -1,3 +1 @@
export const a = 'a';
-
-export const a2 = 'a2';
```

When `b` is not used within the project but `f()` is used within the project:

```diff
--- src/b.ts
+++ src/b.ts
@@ -1,5 +1,5 @@
-export const b = 'b';
+const b = 'b';

export function f() {
return b;
}
```

When `f()` is not used within the project and when deleting it will result in `import` being unnecessary:

```diff
--- src/c.ts
+++ src/c.ts
@@ -1,7 +1 @@
-import { cwd } from "node:process";
-
export const c = 'c';
-
-export function f() {
- return cwd();
-}
```

When `f()` and `exported` are not used within the project and when deleting `f()` will result in `exported` and `local` being unnecessary:

```diff
--- src/d.ts
+++ src/d.ts
@@ -1,8 +1 @@
-export const exported = "exported";
-const local = "local";
-
export const d = "d";
-
-export function f() {
- return { exported, local };
-}

```

<!-- prettier-ignore-end -->

In addition to the behavior shown in the examples above, tsr will delete files that have no used exports.

tsr works with all kinds of code: variables, functions, interfaces, classes, type aliases and more!

## Usage

### Options
### CLI

<!-- prettier-ignore-start -->

Expand Down Expand Up @@ -140,7 +78,7 @@ npx tsr 'src/main\.ts$'
Specifies the `tsconfig.json` that is used to analyze your codebase. Defaults to `tsconfig.json` in your project root.

```bash
npx tsr --project tsconfig.client.json
npx tsr --project tsconfig.client.json 'src/main\.ts$'
```

#### `-w`, `--write`
Expand All @@ -152,15 +90,15 @@ Writes fixable changes in place.
#### `-r`, `--recursive`

The default behavior of the CLI is to process all files once. Some issues may not be detected if the unused code is a result of the modification of another file in the project. When this option is enabled, tsr will recursively re-edit/re-check files that may be affected by a file edit.
The default behavior of the CLI is to process all files once. Some issues may not be detected if the unused code is a result of the modification of another file in the project. When this option is enabled, tsr will recursively look into files that may be affected by a file edit.

This will take longer but is helpful when you want to edit in one pass.

#### `--include-d-ts`

By default, exported types in `.d.ts` files are not detected. Use the `--include-d-ts` option if you want to include types in `.d.ts` files

### Use the JavaScript API
### JavaScript API

Alternatively, you can use the JavaScript API to execute tsr.

Expand All @@ -173,7 +111,20 @@ await tsr({
});
```

### Skip
The project path and/or the custom `tsconfig.json` can be manually specified.

```typescript
await tsr({
entrypoints: [/main\.ts/],
mode: 'check',
configFile: 'tsconfig.sample.json',
projectRoot: '/path/to/project',
});
```

Check the type definition `import('tsr').Config` for all of the available options.

## Skip

When you add a comment `// tsr-skip` to your export declaration, it will be skipped from being removed

Expand All @@ -182,7 +133,7 @@ When you add a comment `// tsr-skip` to your export declaration, it will be skip
export const hello = 'world';
```

## Handling test files
## Test files

If you have a separate tsconfig for tests using [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html), that would be great! tsr will remove exports/files that exist for the sake of testing.

Expand Down Expand Up @@ -224,14 +175,79 @@ export const a = 'a';

tsr's main goal is to remove unused exports and delete unused modules, but it will also delete unused imports that are a result of removing an export declaration.

## Author
## Examples

Kazushi Konosu (https://github.com/kazushisan)
Here are some examples of how tsr edits your files when it finds unused code.

<!-- prettier-ignore-start -->

When `a2` is not used within the project:

```diff
--- src/a.ts
+++ src/a.ts
@@ -1,3 +1 @@
export const a = 'a';
-
-export const a2 = 'a2';
```

When `b` is not used within the project but `f()` is used within the project:

```diff
--- src/b.ts
+++ src/b.ts
@@ -1,5 +1,5 @@
-export const b = 'b';
+const b = 'b';

export function f() {
return b;
}
```

When `f()` is not used within the project and when deleting it will result in `import` being unnecessary:

```diff
--- src/c.ts
+++ src/c.ts
@@ -1,7 +1 @@
-import { cwd } from "node:process";
-
export const c = 'c';
-
-export function f() {
- return cwd();
-}
```

When `f()` and `exported` are not used within the project and when deleting `f()` will result in `exported` and `local` being unnecessary:

```diff
--- src/d.ts
+++ src/d.ts
@@ -1,8 +1 @@
-export const exported = "exported";
-const local = "local";
-
export const d = "d";
-
-export function f() {
- return { exported, local };
-}

```

<!-- prettier-ignore-end -->

## Contributing

Contributions are welcomed!

## Author

Kazushi Konosu (https://github.com/kazushisan)

## License

```
Expand Down
39 changes: 39 additions & 0 deletions doc/MIGRATING_TO_V1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Migrating to v1

This document will cover the migration process from v0 to v1.

## `@line/ts-remove-unused` is renamed to `tsr`

The unnecessary parts from the name `@line/ts-remove-unused` is removed, renaming the tool to `tsr` 😉

```
npm i tsr
```

## `--check` is the default behavior

In v0, the default behavior of the CLI was to apply the edits. This was reasonable because the command was long `npx @line/ts-remove-unused`. `--check` will be the default behavior, and the editing feature will be provided with `--write` in order to prevent accidental code edits when executing `npx tsx`.

```bash
npx tsr --write 'src/main\.ts$' ## use --write to edit files
```

## `--skip` is removed with variadic arguments

The `--skip` option has been removed with variadic arguments to simplify the command line interface.

```bash
npx @line/ts-remove-unused --skip 'src/main\.ts$' ## v0
npx tsx 'src/main\.ts$' ## v1
```

## JavaScript API has changed

The name has changed.

```typescript
import { remove } from '@line/ts-remove-unused'; // before
import { tsr } from 'tsr'; // after
```

Checkout `import('tsr').Config` for more available options.
8 changes: 4 additions & 4 deletions lib/tsr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const tsr = async ({
if (entrypoints.length === 0) {
logger.write(
chalk.bold.red(
'At least one pattern must be specified for the skip option\n',
'At least one pattern must be specified for entrypoints\n',
),
);

Expand All @@ -80,7 +80,7 @@ export const tsr = async ({
}

if (entrypointFiles.length === 0) {
logger.write(chalk.bold.red('No files matched the skip pattern\n'));
logger.write(chalk.bold.red('No files matched the entrypoints pattern\n'));

system.exit(1);
return;
Expand All @@ -96,9 +96,9 @@ export const tsr = async ({

logger.write(
chalk.gray(
`Project has ${formatCount(fileNames.length, 'file')}, skipping ${formatCount(
`Project has ${formatCount(fileNames.length, 'file')}. Found ${formatCount(
entrypointFiles.length,
'file',
'entrypoint file',
)}\n`,
),
);
Expand Down
4 changes: 2 additions & 2 deletions test/include_dts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('project: include_dts', () => {
assert.equal(
stripedOutput,
`tsconfig using default options
Project has 2 files, skipping 1 file
Project has 2 files. Found 1 entrypoint file
export types.d.ts:2:0 'B'
✖ remove 1 export
`,
Expand Down Expand Up @@ -80,7 +80,7 @@ export types.d.ts:2:0 'B'
assert.equal(
stripedOutput,
`tsconfig using default options
Project has 2 files, skipping 2 files
Project has 2 files. Found 2 entrypoint files
✔ all good!
`,
);
Expand Down
6 changes: 3 additions & 3 deletions test/load_tsconfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('project: load_tsconfig', () => {
assert.equal(
stripedOutput,
`tsconfig using default options
Project has 1 file, skipping 1 file
Project has 1 file. Found 1 entrypoint file
✔ all good!
`,
);
Expand Down Expand Up @@ -78,7 +78,7 @@ Project has 1 file, skipping 1 file
assert.equal(
stripedOutput,
`tsconfig using default options
Project has 1 file, skipping 1 file
Project has 1 file. Found 1 entrypoint file
✔ all good!
`,
);
Expand Down Expand Up @@ -113,7 +113,7 @@ Project has 1 file, skipping 1 file
assert.equal(
stripedOutput,
`tsconfig test/fixtures/load_tsconfig/tsconfig.sample.json
Project has 1 file, skipping 1 file
Project has 1 file. Found 1 entrypoint file
✔ all good!
`,
);
Expand Down
2 changes: 1 addition & 1 deletion test/reexport_delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test('reexport_delete', async () => {
assert.equal(
stripedOutput,
`tsconfig test/fixtures/reexport_delete/tsconfig.json
Project has 3 files, skipping 1 file
Project has 3 files. Found 1 entrypoint file
export b.ts:0:0 'export * from './a';'
file a.ts
✖ delete 1 file, remove 1 export
Expand Down
Loading

0 comments on commit 771fcff

Please # to comment.