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 CHANGED
@@ -1 +1,133 @@
1
- # react-cleaner
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
- const program = new Command();
6
+ async function loadChalk() {
7
+ return (await import("chalk")).default;
8
+ }
6
9
 
7
- program
8
- .name("qleaner")
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.command("qlean-scan")
26
- .description("Scan the project for unused files")
27
- .argument("<path>", "The path to the directory to scan for unused files")
28
- .option("-e, --exclude-dir <dir...>", "Exclude directories from the scan")
29
- .option("-f, --exclude-file <file...>", "Exclude files from the scan")
30
- .option("-F, --exclude-file-print <files...>", "Do not Print the excluded files")
31
- .action(async (path, options) => {
32
- const unusedFiles = await unUsedFiles(path, options);
33
- // console.clear()
34
- unusedFiles.forEach((file) => {
35
- console.log(file);
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
- program.parse(process.argv);
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 path = require("path");
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
- async function getFiles(directory = "src", options) {
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.listFiles) {
54
- console.log('***************** Files *****************');
55
- files.forEach((file) => {
56
- console.log(file);
57
- })
58
- }
59
- if (options.listImports) {
60
- console.log('***************** Imports *****************');
61
- imports.forEach((importStatement) => {
62
- console.log(`${importStatement.file}:${importStatement.line}:${importStatement.column} ${importStatement.from}`);
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.9",
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
  }