qleaner 1.0.9 โ 1.0.10
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 +133 -1
- package/bin/cli.js +66 -30
- package/command.js +41 -14
- package/package.json +2 -1
- package/.pnp.cjs +0 -7954
- package/.pnp.loader.mjs +0 -2126
- package/.yarn/install-state.gz +0 -0
package/README.md
CHANGED
|
@@ -1 +1,133 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Qleaner
|
|
2
|
+
|
|
3
|
+
A powerful CLI tool to analyze and clean up your React codebase by finding unused files and listing all imports. Built with Node.js and Babel AST parsing.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ๐ **Scan for unused files**: Identify files that are not imported anywhere in your project
|
|
8
|
+
- ๐ **List all imports**: Get a complete list of all import statements in your codebase
|
|
9
|
+
- ๐ฏ **File listing**: List all files in your project
|
|
10
|
+
- โ๏ธ **Flexible configuration**: Exclude directories and files from scanning
|
|
11
|
+
- ๐ **Fast performance**: Uses fast-glob for efficient file scanning
|
|
12
|
+
- ๐ช **TypeScript support**: Works with TypeScript, JavaScript, JSX, and TSX files
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Install globally
|
|
18
|
+
npm install -g qleaner
|
|
19
|
+
|
|
20
|
+
# Or use with npx
|
|
21
|
+
npx qleaner
|
|
22
|
+
|
|
23
|
+
# Or install locally
|
|
24
|
+
yarn add qleaner
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### List Imports and Files
|
|
30
|
+
|
|
31
|
+
List all imports and files in your project:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
qleaner qlean-list <path> [options]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Options:**
|
|
38
|
+
- `-l, --list-files` - List all the files in the project
|
|
39
|
+
- `-i, --list-imports` - List all the imports in the project
|
|
40
|
+
- `-e, --exclude-dir <dir...>` - Exclude directories from the scan
|
|
41
|
+
- `-f, --exclude-file <file...>` - Exclude files from the scan
|
|
42
|
+
- `-F, --exclude-file-print <file...>` - Do not print the excluded files
|
|
43
|
+
|
|
44
|
+
**Examples:**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# List all files in src directory
|
|
48
|
+
qleaner qlean-list src --list-files
|
|
49
|
+
|
|
50
|
+
# List all imports in src directory
|
|
51
|
+
qleaner qlean-list src --list-imports
|
|
52
|
+
|
|
53
|
+
# List files excluding node_modules and dist
|
|
54
|
+
qleaner qlean-list src --list-files -e node_modules dist
|
|
55
|
+
|
|
56
|
+
# List imports excluding specific files
|
|
57
|
+
qleaner qlean-list src --list-imports -f "**/*.test.js" "**/*.spec.js"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Scan for Unused Files
|
|
61
|
+
|
|
62
|
+
Find files that are not imported anywhere in your project:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
qleaner qlean-scan <path> [options]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Options:**
|
|
69
|
+
- `-e, --exclude-dir <dir...>` - Exclude directories from the scan
|
|
70
|
+
- `-f, --exclude-file <file...>` - Exclude files from the scan
|
|
71
|
+
- `-F, --exclude-file-print <files...>` - Do not print the excluded files
|
|
72
|
+
|
|
73
|
+
**Examples:**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Scan src directory for unused files
|
|
77
|
+
qleaner qlean-scan src
|
|
78
|
+
|
|
79
|
+
# Scan excluding test directories
|
|
80
|
+
qleaner qlean-scan src -e __tests__ __mocks__ test
|
|
81
|
+
|
|
82
|
+
# Scan excluding specific file patterns
|
|
83
|
+
qleaner qlean-scan src -f "**/*.test.js" "**/*.stories.js"
|
|
84
|
+
|
|
85
|
+
# Scan with multiple exclusions
|
|
86
|
+
qleaner qlean-scan src -e node_modules dist -f "**/*.config.js"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## How It Works
|
|
90
|
+
|
|
91
|
+
1. **File Discovery**: Uses `fast-glob` to recursively find all `.tsx`, `.ts`, `.js`, and `.jsx` files in the specified directory
|
|
92
|
+
2. **AST Parsing**: Uses Babel parser to parse files and extract import statements
|
|
93
|
+
3. **Analysis**: Compares file paths with import paths to identify unused files
|
|
94
|
+
4. **Reporting**: Outputs the results based on the selected command and options
|
|
95
|
+
|
|
96
|
+
## Supported File Types
|
|
97
|
+
|
|
98
|
+
- `.js` - JavaScript files
|
|
99
|
+
- `.jsx` - JavaScript React files
|
|
100
|
+
- `.ts` - TypeScript files
|
|
101
|
+
- `.tsx` - TypeScript React files
|
|
102
|
+
|
|
103
|
+
## Use Cases
|
|
104
|
+
|
|
105
|
+
- ๐งน **Code cleanup**: Remove dead code and unused files from your React projects
|
|
106
|
+
- ๐ **Code analysis**: Understand import patterns and dependencies in your codebase
|
|
107
|
+
- ๐ **Project audit**: Identify orphaned files that may have been forgotten
|
|
108
|
+
- ๐ฆ **Bundle optimization**: Find files that can be removed to reduce bundle size
|
|
109
|
+
|
|
110
|
+
## Configuration
|
|
111
|
+
|
|
112
|
+
You can exclude directories and files from scanning using the command-line options. This is useful for:
|
|
113
|
+
- Excluding test files
|
|
114
|
+
- Excluding build outputs
|
|
115
|
+
- Excluding third-party libraries
|
|
116
|
+
- Excluding configuration files
|
|
117
|
+
|
|
118
|
+
## Requirements
|
|
119
|
+
|
|
120
|
+
- Node.js 14+
|
|
121
|
+
- Yarn or npm
|
|
122
|
+
|
|
123
|
+
## Contributing
|
|
124
|
+
|
|
125
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
|
130
|
+
|
|
131
|
+
## Version
|
|
132
|
+
|
|
133
|
+
Current version: 1.0.9
|
package/bin/cli.js
CHANGED
|
@@ -1,38 +1,74 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const { Command } = require("commander");
|
|
3
3
|
const { getFiles, unUsedFiles } = require("../command");
|
|
4
|
+
const Table = require('cli-table3')
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
async function loadChalk() {
|
|
7
|
+
return (await import("chalk")).default;
|
|
8
|
+
}
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.description("A tool to clean up your React code")
|
|
10
|
-
.version("1.0.0");
|
|
10
|
+
(async () => {
|
|
11
|
+
const chalk = await loadChalk();
|
|
11
12
|
|
|
12
|
-
program
|
|
13
|
-
.command("qlean-list")
|
|
14
|
-
.description("List all the imports in the project")
|
|
15
|
-
.argument("<path>", "The path to the directory to scan for imports")
|
|
16
|
-
.option("-l, --list-files", "List all the files in the project")
|
|
17
|
-
.option("-i, --list-imports", "List all the imports in the project")
|
|
18
|
-
.option("-e, --exclude-dir <dir...>", "Exclude directories from the scan")
|
|
19
|
-
.option("-f, --exclude-file <file...>", "Exclude files from the scan")
|
|
20
|
-
.option("-F, --exclude-file-print <file...>", "Do not Print the excluded files")
|
|
21
|
-
.action(async (path, options) => {
|
|
22
|
-
const imports = await getFiles(path, options);
|
|
23
|
-
});
|
|
13
|
+
const program = new Command();
|
|
24
14
|
|
|
25
|
-
program
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
15
|
+
program
|
|
16
|
+
.name("qleaner")
|
|
17
|
+
.description("A tool to clean up your React code")
|
|
18
|
+
.version("1.0.0");
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.command("qlean-list")
|
|
22
|
+
.description("List all the imports in the project")
|
|
23
|
+
.argument("<path>", "The path to the directory to scan for imports")
|
|
24
|
+
.option("-l, --list-files", "List all the files in the project")
|
|
25
|
+
.option("-i, --list-imports", "List all the imports in the project")
|
|
26
|
+
.option("-e, --exclude-dir <dir...>", "Exclude directories from the scan")
|
|
27
|
+
.option("-f, --exclude-file <file...>", "Exclude files from the scan")
|
|
28
|
+
.option(
|
|
29
|
+
"-F, --exclude-file-print <file...>",
|
|
30
|
+
"Do not Print the excluded files"
|
|
31
|
+
)
|
|
32
|
+
.option("-t, --table", "Print the results in a table")
|
|
33
|
+
.action(async (path, options) => {
|
|
34
|
+
const { tableImports, tableFiles } = await getFiles(path, options, chalk);
|
|
35
|
+
if(options.table){
|
|
36
|
+
console.log(chalk.yellow('***************** Imported Files *****************'));
|
|
37
|
+
console.log(tableImports.toString());
|
|
38
|
+
console.log(chalk.green('***************** List Files *****************'));
|
|
39
|
+
console.log(tableFiles.toString());
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
program
|
|
44
|
+
.command("qlean-scan")
|
|
45
|
+
.description("Scan the project for unused files")
|
|
46
|
+
.argument("<path>", "The path to the directory to scan for unused files")
|
|
47
|
+
.option("-e, --exclude-dir <dir...>", "Exclude directories from the scan")
|
|
48
|
+
.option("-f, --exclude-file <file...>", "Exclude files from the scan")
|
|
49
|
+
.option(
|
|
50
|
+
"-F, --exclude-file-print <files...>",
|
|
51
|
+
"Do not Print the excluded files"
|
|
52
|
+
)
|
|
53
|
+
.option("-t, --table", "Print the results in a table")
|
|
54
|
+
.action(async (path, options) => {
|
|
55
|
+
const unusedFiles = await unUsedFiles(path, options);
|
|
56
|
+
// console.clear()
|
|
57
|
+
if(options.table){
|
|
58
|
+
const table = new Table({
|
|
59
|
+
head: ['Unused Files'],
|
|
60
|
+
colWidths: [50]
|
|
61
|
+
})
|
|
62
|
+
unusedFiles.forEach(file => {
|
|
63
|
+
table.push([file])
|
|
64
|
+
})
|
|
65
|
+
console.log(table.toString())
|
|
66
|
+
|
|
67
|
+
}else {
|
|
68
|
+
unusedFiles.forEach((file) => {
|
|
69
|
+
console.log(chalk.red(file));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
36
72
|
});
|
|
37
|
-
|
|
38
|
-
|
|
73
|
+
program.parse(process.argv);
|
|
74
|
+
})();
|
package/command.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const fg = require("fast-glob");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
-
const
|
|
3
|
+
const Table = require('cli-table3');
|
|
4
4
|
const parser = require("@babel/parser");
|
|
5
5
|
const traverse = require("@babel/traverse").default;
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async function getFiles(directory = "src", options, chalk) {
|
|
9
11
|
const contentPaths = [`${directory}/**/*.{tsx,ts,js,jsx}`];
|
|
10
12
|
if (options.excludeDir && options.excludeDir.length > 0) {
|
|
11
13
|
options.excludeDir.forEach(dir => {
|
|
@@ -49,18 +51,42 @@ async function getFiles(directory = "src", options) {
|
|
|
49
51
|
// },
|
|
50
52
|
// });
|
|
51
53
|
}
|
|
52
|
-
|
|
53
|
-
if (options.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
|
|
55
|
+
if (options.table) {
|
|
56
|
+
const tableImports = new Table({
|
|
57
|
+
head: ['File', 'Line', 'Column', 'Import'],
|
|
58
|
+
colWidths: [20, 10, 10, 20],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const tableFiles = new Table({
|
|
62
|
+
head: ['File'],
|
|
63
|
+
colWidths: [20],
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (options.listFiles) {
|
|
67
|
+
files.forEach((file) => {
|
|
68
|
+
tableFiles.push([file]);
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
if (options.listImports) {
|
|
72
|
+
imports.forEach((importStatement) => {
|
|
73
|
+
tableImports.push([importStatement.file, importStatement.line, importStatement.column, importStatement.from]);
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
return { tableImports, tableFiles };
|
|
77
|
+
}else{
|
|
78
|
+
if (options.listFiles) {
|
|
79
|
+
console.log(chalk.green('***************** Files *****************'));
|
|
80
|
+
files.forEach((file) => {
|
|
81
|
+
console.log(chalk.green(file));
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
if (options.listImports) {
|
|
85
|
+
console.log(chalk.yellow('***************** Imports *****************'));
|
|
86
|
+
imports.forEach((importStatement) => {
|
|
87
|
+
console.log(chalk.yellow(`${importStatement.file}:${importStatement.line}:${importStatement.column} ${importStatement.from}`));
|
|
88
|
+
})
|
|
89
|
+
}
|
|
64
90
|
}
|
|
65
91
|
}
|
|
66
92
|
|
|
@@ -76,6 +102,7 @@ async function unUsedFiles(directory = "src", options) {
|
|
|
76
102
|
contentPaths.push(`!${directory}/**/${file}`);
|
|
77
103
|
});
|
|
78
104
|
}
|
|
105
|
+
|
|
79
106
|
const files = await fg(contentPaths);
|
|
80
107
|
const imports = [];
|
|
81
108
|
const unusedFiles = [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qleaner",
|
|
3
3
|
"packageManager": "yarn@4.6.0",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.10",
|
|
5
5
|
"main": "command.js",
|
|
6
6
|
"bin": "./bin/cli.js",
|
|
7
7
|
"scripts": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"@babel/parser": "^7.28.5",
|
|
16
16
|
"@babel/traverse": "^7.28.5",
|
|
17
17
|
"chalk": "^5.6.2",
|
|
18
|
+
"cli-table3": "^0.6.5",
|
|
18
19
|
"commander": "^14.0.2",
|
|
19
20
|
"fast-glob": "^3.3.3"
|
|
20
21
|
}
|