exports-cleanup 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # exports-cleanup
2
+
3
+ > Find unused exports in your codebase - clean up dead code and reduce bundle size
4
+
5
+ [![npm version](https://img.shields.io/npm/v/exports-cleanup.svg)](https://www.npmjs.com/package/exports-cleanup)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Problem
9
+
10
+ You export 100 functions. Only 20 are actually used. Dead code bloats your bundle.
11
+
12
+ ## Solution
13
+
14
+ `exports-cleanup` scans your codebase, tracks all imports, and finds exports that are never used anywhere.
15
+
16
+ ## Features
17
+
18
+ - **Fast scanning** - Uses regex-based parsing for speed
19
+ - **Bundle size estimation** - Shows potential savings in KB
20
+ - **TypeScript + JavaScript** - Works with .ts, .tsx, .js, .jsx, .mjs
21
+ - **Type-aware** - Optionally include/exclude type exports
22
+ - **CI/CD ready** - Exit code 1 when unused exports found
23
+ - **Zero config** - Just run it
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ # Run directly with npx (recommended)
29
+ npx exports-cleanup
30
+
31
+ # Or install globally
32
+ npm install -g exports-cleanup
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ### Basic Scan
38
+
39
+ ```bash
40
+ # Scan current directory
41
+ npx exports-cleanup
42
+
43
+ # Scan specific directory
44
+ npx exports-cleanup ./src
45
+
46
+ # Compact output
47
+ npx exports-cleanup --compact
48
+ ```
49
+
50
+ ### Include Types
51
+
52
+ ```bash
53
+ # Also check type and interface exports
54
+ npx exports-cleanup --include-types
55
+ ```
56
+
57
+ ### Show All Exports
58
+
59
+ ```bash
60
+ # Show used exports too
61
+ npx exports-cleanup --show-used
62
+ ```
63
+
64
+ ## Example Output
65
+
66
+ ```
67
+ 🔍 Unused Exports (47 found):
68
+
69
+ Summary:
70
+ Total exports: 120
71
+ Unused: 47
72
+ Used: 73
73
+ Potential savings: 23.4 KB
74
+
75
+ 📁 src/utils/helpers.ts
76
+ ❌ formatDate() [function]
77
+ Line 12 - exported but never imported
78
+ ❌ calculateTax() [function]
79
+ Line 45 - exported but never imported
80
+ ❌ DEPRECATED_CONSTANT [const]
81
+ Line 78 - exported but never imported
82
+
83
+ 📁 src/utils/validation.ts
84
+ ❌ validateEmail() [function]
85
+ Line 5 - exported but never imported
86
+ ❌ validatePhone() [function]
87
+ Line 23 - exported but never imported
88
+
89
+ ──────────────────────────────────────────────────
90
+ Potential bundle reduction: 23.4 KB
91
+
92
+ 💡 Tips:
93
+ • Remove unused exports to reduce bundle size
94
+ • Some exports may be used dynamically (check manually)
95
+ • Entry points and public APIs may show as "unused"
96
+
97
+ ──────────────────────────────────────────────────
98
+ Cleaned up dead code? Consider supporting:
99
+ ☕ https://buymeacoffee.com/willzhangfly
100
+ ```
101
+
102
+ ### Compact Output
103
+
104
+ ```
105
+ 🔍 Found 47 unused exports:
106
+
107
+ src/utils/helpers.ts
108
+ formatDate, calculateTax, DEPRECATED_CONSTANT
109
+ src/utils/validation.ts
110
+ validateEmail, validatePhone
111
+ src/components/OldButton.tsx
112
+ OldButton, OldButtonProps
113
+
114
+ Potential savings: 23.4 KB
115
+ ```
116
+
117
+ ## Comparison with Alternatives
118
+
119
+ | Feature | exports-cleanup | TypeScript | ESLint | ts-prune | knip |
120
+ |---------|---------------|------------|--------|----------|------|
121
+ | Find unused exports | ✅ | ❌ | ❌ | ✅ | ✅ |
122
+ | Bundle size estimate | ✅ | ❌ | ❌ | ❌ | ❌ |
123
+ | Zero config | ✅ | ❌ | ❌ | ⚠️ | ❌ |
124
+ | Fast | ✅ | ✅ | ✅ | ❌ | ⚠️ |
125
+ | CI/CD exit codes | ✅ | ✅ | ✅ | ⚠️ | ✅ |
126
+ | Actively maintained | ✅ | ✅ | ✅ | ❌ (2021) | ✅ |
127
+
128
+ ## CLI Options
129
+
130
+ ```
131
+ Usage: exports-cleanup [options] [path]
132
+
133
+ Arguments:
134
+ path Directory to scan (default: ".")
135
+
136
+ Options:
137
+ --json Output results as JSON
138
+ --compact Compact output format
139
+ --include-types Include type and interface exports
140
+ --show-used Also show used exports
141
+ --ignore <patterns> Additional patterns to ignore (comma-separated)
142
+ -V, --version Output version number
143
+ -h, --help Display help
144
+ ```
145
+
146
+ ## CI/CD Integration
147
+
148
+ ```yaml
149
+ # GitHub Actions
150
+ - name: Check for unused exports
151
+ run: npx exports-cleanup
152
+ # Exits with code 1 if unused exports found
153
+
154
+ # With threshold (using jq)
155
+ - name: Check unused exports count
156
+ run: |
157
+ npx exports-cleanup --json > unused.json
158
+ COUNT=$(cat unused.json | jq '.unusedExports')
159
+ if [ "$COUNT" -gt 10 ]; then
160
+ echo "Too many unused exports: $COUNT"
161
+ exit 1
162
+ fi
163
+ ```
164
+
165
+ ## Programmatic Usage
166
+
167
+ ```typescript
168
+ import { analyzeExports } from 'exports-cleanup';
169
+
170
+ const result = await analyzeExports('./src', {
171
+ includeTypes: false,
172
+ exclude: ['**/*.test.ts'],
173
+ });
174
+
175
+ console.log(`Found ${result.unusedExports} unused exports`);
176
+ console.log(`Potential savings: ${result.estimatedSavings} bytes`);
177
+
178
+ // Get unused export names
179
+ for (const file of result.files) {
180
+ for (const exp of file.exports) {
181
+ if (exp.isUnused) {
182
+ console.log(`${exp.export.name} in ${file.file}`);
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ ## False Positives
189
+
190
+ Some exports may appear unused but are actually used:
191
+
192
+ 1. **Entry points** - Main exports used by consumers of your package
193
+ 2. **Dynamic imports** - `import()` expressions aren't always detected
194
+ 3. **Re-exports** - `export * from './module'`
195
+ 4. **Framework conventions** - Next.js pages, React components loaded by name
196
+ 5. **Public APIs** - Exports meant for external use
197
+
198
+ Review results manually before removing exports.
199
+
200
+ ## Ignored by Default
201
+
202
+ - `node_modules/`
203
+ - `dist/`, `build/`
204
+ - `.next/`
205
+ - `coverage/`
206
+ - `*.d.ts` (declaration files)
207
+ - `*.test.*`, `*.spec.*`
208
+ - `__tests__/`
209
+
210
+ ## Requirements
211
+
212
+ - Node.js 18.0.0 or higher
213
+
214
+ ## Support
215
+
216
+ This project is maintained in my free time. If it helped clean up your codebase, I'd really appreciate your support:
217
+
218
+ - ⭐ Star the repo—it helps others discover this tool
219
+ - 📢 Share with your team or on social media
220
+ - 🐛 [Report bugs or suggest features](https://github.com/willzhangfly/exports-cleanup/issues)
221
+ - ☕ [Buy me a coffee](https://buymeacoffee.com/willzhangfly) if you'd like to support development
222
+
223
+ Thank you to everyone who has contributed, shared feedback, or helped spread the word!
224
+
225
+ ## License
226
+
227
+ MIT
228
+
229
+ ---
230
+
231
+ **Made with ❤️ for cleaner codebases**
@@ -0,0 +1,9 @@
1
+ import type { ScanResult } from '../types/index.js';
2
+ /**
3
+ * Analyze exports in a directory
4
+ */
5
+ export declare function analyzeExports(rootDir: string, options?: {
6
+ includeTypes?: boolean;
7
+ exclude?: string[];
8
+ }): Promise<ScanResult>;
9
+ //# sourceMappingURL=export-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/export-analyzer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAMV,UAAU,EACX,MAAM,mBAAmB,CAAC;AAyN3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACf,GACL,OAAO,CAAC,UAAU,CAAC,CAyGrB"}
@@ -0,0 +1,292 @@
1
+ import { readFileSync } from 'fs';
2
+ import { resolve, dirname } from 'path';
3
+ import glob from 'fast-glob';
4
+ /**
5
+ * Default patterns
6
+ */
7
+ const DEFAULT_INCLUDE = ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.mjs'];
8
+ const DEFAULT_EXCLUDE = [
9
+ '**/node_modules/**',
10
+ '**/dist/**',
11
+ '**/build/**',
12
+ '**/.next/**',
13
+ '**/coverage/**',
14
+ '**/*.d.ts',
15
+ '**/*.test.*',
16
+ '**/*.spec.*',
17
+ '**/__tests__/**',
18
+ ];
19
+ /**
20
+ * Estimate size of a code block in bytes
21
+ */
22
+ function estimateSize(code) {
23
+ // Rough estimate: minified code is ~60% of original
24
+ return Math.round(code.length * 0.6);
25
+ }
26
+ /**
27
+ * Extract exports from a file
28
+ */
29
+ function extractExports(content, filePath) {
30
+ const exports = [];
31
+ const lines = content.split('\n');
32
+ // Regex patterns for different export types
33
+ const patterns = [
34
+ // export function name()
35
+ { regex: /^export\s+function\s+(\w+)/gm, type: 'function' },
36
+ // export async function name()
37
+ { regex: /^export\s+async\s+function\s+(\w+)/gm, type: 'function' },
38
+ // export class Name
39
+ { regex: /^export\s+class\s+(\w+)/gm, type: 'class' },
40
+ // export const name =
41
+ { regex: /^export\s+const\s+(\w+)\s*[=:]/gm, type: 'const' },
42
+ // export let name =
43
+ { regex: /^export\s+let\s+(\w+)\s*[=:]/gm, type: 'variable' },
44
+ // export var name =
45
+ { regex: /^export\s+var\s+(\w+)\s*[=:]/gm, type: 'variable' },
46
+ // export type Name =
47
+ { regex: /^export\s+type\s+(\w+)/gm, type: 'type' },
48
+ // export interface Name
49
+ { regex: /^export\s+interface\s+(\w+)/gm, type: 'interface' },
50
+ // export enum Name
51
+ { regex: /^export\s+enum\s+(\w+)/gm, type: 'enum' },
52
+ // export default function/class/etc
53
+ { regex: /^export\s+default\s+(?:function|class)\s+(\w+)?/gm, type: 'default' },
54
+ // export default name
55
+ { regex: /^export\s+default\s+(\w+)\s*;?$/gm, type: 'default' },
56
+ ];
57
+ // Find line numbers
58
+ const getLineNumber = (index) => {
59
+ let line = 1;
60
+ for (let i = 0; i < index && i < content.length; i++) {
61
+ if (content[i] === '\n')
62
+ line++;
63
+ }
64
+ return line;
65
+ };
66
+ for (const { regex, type } of patterns) {
67
+ let match;
68
+ while ((match = regex.exec(content)) !== null) {
69
+ const name = match[1] || 'default';
70
+ const line = getLineNumber(match.index);
71
+ // Estimate size of the export
72
+ let endIndex = content.indexOf('\n\n', match.index);
73
+ if (endIndex === -1)
74
+ endIndex = content.length;
75
+ const code = content.slice(match.index, endIndex);
76
+ exports.push({
77
+ name,
78
+ type,
79
+ file: filePath,
80
+ line,
81
+ isDefault: type === 'default',
82
+ estimatedSize: estimateSize(code),
83
+ });
84
+ }
85
+ }
86
+ // Handle export { name1, name2 }
87
+ const namedExportRegex = /^export\s*\{([^}]+)\}/gm;
88
+ let match;
89
+ while ((match = namedExportRegex.exec(content)) !== null) {
90
+ const names = match[1].split(',').map(n => {
91
+ const parts = n.trim().split(/\s+as\s+/);
92
+ return parts[parts.length - 1].trim();
93
+ });
94
+ const line = getLineNumber(match.index);
95
+ for (const name of names) {
96
+ if (name && !exports.some(e => e.name === name)) {
97
+ exports.push({
98
+ name,
99
+ type: 'const',
100
+ file: filePath,
101
+ line,
102
+ isDefault: false,
103
+ estimatedSize: 100, // Rough estimate for re-exports
104
+ });
105
+ }
106
+ }
107
+ }
108
+ return exports;
109
+ }
110
+ /**
111
+ * Extract imports from a file
112
+ */
113
+ function extractImports(content, filePath, rootDir) {
114
+ const imports = [];
115
+ const lines = content.split('\n');
116
+ // Patterns for imports
117
+ const importPatterns = [
118
+ // import { name } from './file'
119
+ /import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/g,
120
+ // import name from './file'
121
+ /import\s+(\w+)\s+from\s*['"]([^'"]+)['"]/g,
122
+ // import * as name from './file'
123
+ /import\s*\*\s*as\s+(\w+)\s+from\s*['"]([^'"]+)['"]/g,
124
+ ];
125
+ const getLineNumber = (index) => {
126
+ let line = 1;
127
+ for (let i = 0; i < index && i < content.length; i++) {
128
+ if (content[i] === '\n')
129
+ line++;
130
+ }
131
+ return line;
132
+ };
133
+ // Named imports
134
+ const namedImportRegex = /import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/g;
135
+ let match;
136
+ while ((match = namedImportRegex.exec(content)) !== null) {
137
+ const names = match[1].split(',').map(n => {
138
+ const parts = n.trim().split(/\s+as\s+/);
139
+ return parts[0].trim();
140
+ });
141
+ const fromPath = match[2];
142
+ const line = getLineNumber(match.index);
143
+ // Skip external packages
144
+ if (!fromPath.startsWith('.') && !fromPath.startsWith('/'))
145
+ continue;
146
+ const resolvedPath = resolveImportPath(fromPath, filePath, rootDir);
147
+ for (const name of names) {
148
+ if (name) {
149
+ imports.push({
150
+ name,
151
+ fromFile: resolvedPath,
152
+ toFile: filePath,
153
+ line,
154
+ isDefault: false,
155
+ });
156
+ }
157
+ }
158
+ }
159
+ // Default imports
160
+ const defaultImportRegex = /import\s+(\w+)(?:\s*,\s*\{[^}]*\})?\s+from\s*['"]([^'"]+)['"]/g;
161
+ while ((match = defaultImportRegex.exec(content)) !== null) {
162
+ const name = match[1];
163
+ const fromPath = match[2];
164
+ const line = getLineNumber(match.index);
165
+ if (!fromPath.startsWith('.') && !fromPath.startsWith('/'))
166
+ continue;
167
+ const resolvedPath = resolveImportPath(fromPath, filePath, rootDir);
168
+ imports.push({
169
+ name: 'default',
170
+ fromFile: resolvedPath,
171
+ toFile: filePath,
172
+ line,
173
+ isDefault: true,
174
+ });
175
+ }
176
+ return imports;
177
+ }
178
+ /**
179
+ * Resolve import path to absolute path
180
+ */
181
+ function resolveImportPath(importPath, fromFile, rootDir) {
182
+ const dir = dirname(fromFile);
183
+ let resolved = resolve(dir, importPath);
184
+ // Try adding extensions
185
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '/index.ts', '/index.tsx', '/index.js'];
186
+ for (const ext of extensions) {
187
+ const withExt = resolved + ext;
188
+ try {
189
+ readFileSync(withExt);
190
+ return withExt;
191
+ }
192
+ catch {
193
+ continue;
194
+ }
195
+ }
196
+ return resolved;
197
+ }
198
+ /**
199
+ * Analyze exports in a directory
200
+ */
201
+ export async function analyzeExports(rootDir, options = {}) {
202
+ const { includeTypes = false, exclude = [] } = options;
203
+ const allExcludes = [...DEFAULT_EXCLUDE, ...exclude];
204
+ // Get all files
205
+ const files = await glob(DEFAULT_INCLUDE, {
206
+ cwd: rootDir,
207
+ absolute: true,
208
+ ignore: allExcludes,
209
+ onlyFiles: true,
210
+ });
211
+ // Extract all exports and imports
212
+ const allExports = [];
213
+ const allImports = [];
214
+ for (const file of files) {
215
+ try {
216
+ const content = readFileSync(file, 'utf-8');
217
+ const exports = extractExports(content, file);
218
+ const imports = extractImports(content, file, rootDir);
219
+ allExports.push(...exports);
220
+ allImports.push(...imports);
221
+ }
222
+ catch {
223
+ continue;
224
+ }
225
+ }
226
+ // Filter out type exports if not including them
227
+ const filteredExports = includeTypes
228
+ ? allExports
229
+ : allExports.filter(e => e.type !== 'type' && e.type !== 'interface');
230
+ // Analyze usage
231
+ const fileAnalysisMap = new Map();
232
+ for (const exp of filteredExports) {
233
+ // Find imports of this export
234
+ const usages = allImports.filter(imp => {
235
+ const isSameFile = imp.fromFile === exp.file ||
236
+ imp.fromFile.replace(/\.(ts|tsx|js|jsx|mjs)$/, '') === exp.file.replace(/\.(ts|tsx|js|jsx|mjs)$/, '');
237
+ if (!isSameFile)
238
+ return false;
239
+ if (exp.isDefault) {
240
+ return imp.isDefault;
241
+ }
242
+ return imp.name === exp.name;
243
+ });
244
+ const usedIn = [...new Set(usages.map(u => u.toFile))];
245
+ const isUnused = usedIn.length === 0;
246
+ const analysis = {
247
+ export: exp,
248
+ usageCount: usedIn.length,
249
+ usedIn,
250
+ isUnused,
251
+ };
252
+ // Add to file analysis
253
+ if (!fileAnalysisMap.has(exp.file)) {
254
+ fileAnalysisMap.set(exp.file, {
255
+ file: exp.file,
256
+ exports: [],
257
+ unusedCount: 0,
258
+ usedCount: 0,
259
+ });
260
+ }
261
+ const fileAnalysis = fileAnalysisMap.get(exp.file);
262
+ fileAnalysis.exports.push(analysis);
263
+ if (isUnused) {
264
+ fileAnalysis.unusedCount++;
265
+ }
266
+ else {
267
+ fileAnalysis.usedCount++;
268
+ }
269
+ }
270
+ // Calculate totals
271
+ const fileAnalyses = Array.from(fileAnalysisMap.values())
272
+ .filter(f => f.exports.length > 0)
273
+ .sort((a, b) => b.unusedCount - a.unusedCount);
274
+ let totalExports = 0;
275
+ let unusedExports = 0;
276
+ let estimatedSavings = 0;
277
+ for (const fa of fileAnalyses) {
278
+ totalExports += fa.exports.length;
279
+ unusedExports += fa.unusedCount;
280
+ estimatedSavings += fa.exports
281
+ .filter(e => e.isUnused)
282
+ .reduce((sum, e) => sum + e.export.estimatedSize, 0);
283
+ }
284
+ return {
285
+ files: fileAnalyses,
286
+ totalExports,
287
+ unusedExports,
288
+ usedExports: totalExports - unusedExports,
289
+ estimatedSavings,
290
+ };
291
+ }
292
+ //# sourceMappingURL=export-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/export-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { resolve } from 'path';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { analyzeExports } from '../analyzer/export-analyzer.js';
7
+ import { printScanResult, printCompactResult, printJsonResult, printSupportMessage } from './output.js';
8
+ const program = new Command();
9
+ program
10
+ .name('exports-cleanup')
11
+ .description('Find unused exports in your codebase')
12
+ .version('0.0.1');
13
+ program
14
+ .argument('[path]', 'Directory to scan', '.')
15
+ .option('--json', 'Output results as JSON', false)
16
+ .option('--compact', 'Compact output format', false)
17
+ .option('--include-types', 'Include type and interface exports', false)
18
+ .option('--show-used', 'Also show used exports', false)
19
+ .option('--ignore <patterns>', 'Additional patterns to ignore (comma-separated)', '')
20
+ .action(async (pathArg, options) => {
21
+ try {
22
+ const projectPath = resolve(pathArg);
23
+ // Parse ignore patterns
24
+ const ignorePatterns = options.ignore
25
+ ? options.ignore.split(',').map(p => p.trim())
26
+ : [];
27
+ // Scan
28
+ const spinner = ora('Scanning for exports...').start();
29
+ let result;
30
+ try {
31
+ result = await analyzeExports(projectPath, {
32
+ includeTypes: options.includeTypes,
33
+ exclude: ignorePatterns,
34
+ });
35
+ spinner.stop();
36
+ }
37
+ catch (error) {
38
+ spinner.fail('Scan failed');
39
+ throw error;
40
+ }
41
+ // Output
42
+ if (options.json) {
43
+ printJsonResult(result, projectPath);
44
+ return;
45
+ }
46
+ if (options.compact) {
47
+ printCompactResult(result, projectPath);
48
+ }
49
+ else {
50
+ printScanResult(result, projectPath, options.showUsed);
51
+ }
52
+ printSupportMessage();
53
+ // Exit with code 1 if unused exports found (useful for CI)
54
+ if (result.unusedExports > 0) {
55
+ process.exit(1);
56
+ }
57
+ }
58
+ catch (error) {
59
+ if (error instanceof Error) {
60
+ console.error(chalk.red(`\n❌ Error: ${error.message}`));
61
+ }
62
+ else {
63
+ console.error(chalk.red('\n❌ An unexpected error occurred'));
64
+ }
65
+ process.exit(1);
66
+ }
67
+ });
68
+ program.parse();
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ScanResult } from '../types/index.js';
2
+ /**
3
+ * Print scan results
4
+ */
5
+ export declare function printScanResult(result: ScanResult, cwd: string, showUsed?: boolean): void;
6
+ /**
7
+ * Print compact results
8
+ */
9
+ export declare function printCompactResult(result: ScanResult, cwd: string): void;
10
+ /**
11
+ * Print JSON result
12
+ */
13
+ export declare function printJsonResult(result: ScanResult, cwd: string): void;
14
+ /**
15
+ * Print support message
16
+ */
17
+ export declare function printSupportMessage(): void;
18
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAgC,MAAM,mBAAmB,CAAC;AAmClF;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAe,GAAG,IAAI,CAqDhG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA2BxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAmBrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
@@ -0,0 +1,145 @@
1
+ import chalk from 'chalk';
2
+ import { relative } from 'path';
3
+ /**
4
+ * Format bytes to human readable
5
+ */
6
+ function formatBytes(bytes) {
7
+ if (bytes < 1024)
8
+ return `${bytes} B`;
9
+ if (bytes < 1024 * 1024)
10
+ return `${(bytes / 1024).toFixed(1)} KB`;
11
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
12
+ }
13
+ /**
14
+ * Get color for export type
15
+ */
16
+ function getTypeColor(type) {
17
+ switch (type) {
18
+ case 'function':
19
+ return chalk.blue;
20
+ case 'class':
21
+ return chalk.magenta;
22
+ case 'const':
23
+ case 'variable':
24
+ return chalk.cyan;
25
+ case 'type':
26
+ case 'interface':
27
+ return chalk.gray;
28
+ case 'enum':
29
+ return chalk.yellow;
30
+ case 'default':
31
+ return chalk.green;
32
+ default:
33
+ return chalk.white;
34
+ }
35
+ }
36
+ /**
37
+ * Print scan results
38
+ */
39
+ export function printScanResult(result, cwd, showUsed = false) {
40
+ console.log();
41
+ if (result.unusedExports === 0) {
42
+ console.log(chalk.green('✅ No unused exports found!'));
43
+ console.log(chalk.gray(` Scanned ${result.totalExports} exports across ${result.files.length} files.`));
44
+ console.log();
45
+ return;
46
+ }
47
+ console.log(chalk.bold.yellow(`🔍 Unused Exports (${result.unusedExports} found):`));
48
+ console.log();
49
+ // Summary
50
+ console.log(chalk.gray('Summary:'));
51
+ console.log(` Total exports: ${result.totalExports}`);
52
+ console.log(` ${chalk.red(`Unused:`)} ${result.unusedExports}`);
53
+ console.log(` ${chalk.green(`Used:`)} ${result.usedExports}`);
54
+ console.log(` Potential savings: ${chalk.cyan(formatBytes(result.estimatedSavings))}`);
55
+ console.log();
56
+ // Files with unused exports
57
+ for (const fileAnalysis of result.files) {
58
+ if (fileAnalysis.unusedCount === 0 && !showUsed)
59
+ continue;
60
+ const relativePath = relative(cwd, fileAnalysis.file);
61
+ console.log(chalk.bold.white(`📁 ${relativePath}`));
62
+ for (const exp of fileAnalysis.exports) {
63
+ if (exp.isUnused) {
64
+ const typeColor = getTypeColor(exp.export.type);
65
+ const typeLabel = typeColor(`[${exp.export.type}]`);
66
+ console.log(` ${chalk.red('❌')} ${exp.export.name}() ${typeLabel}`);
67
+ console.log(chalk.gray(` Line ${exp.export.line} - exported but never imported`));
68
+ }
69
+ else if (showUsed) {
70
+ const typeColor = getTypeColor(exp.export.type);
71
+ const typeLabel = typeColor(`[${exp.export.type}]`);
72
+ console.log(` ${chalk.green('✅')} ${exp.export.name}() ${typeLabel}`);
73
+ console.log(chalk.gray(` Used in ${exp.usageCount} file(s)`));
74
+ }
75
+ }
76
+ console.log();
77
+ }
78
+ // Tips
79
+ console.log(chalk.gray('─'.repeat(50)));
80
+ console.log(chalk.bold('Potential bundle reduction:'), chalk.cyan(formatBytes(result.estimatedSavings)));
81
+ console.log();
82
+ console.log(chalk.gray('💡 Tips:'));
83
+ console.log(chalk.gray(' • Remove unused exports to reduce bundle size'));
84
+ console.log(chalk.gray(' • Some exports may be used dynamically (check manually)'));
85
+ console.log(chalk.gray(' • Entry points and public APIs may show as "unused"'));
86
+ console.log();
87
+ }
88
+ /**
89
+ * Print compact results
90
+ */
91
+ export function printCompactResult(result, cwd) {
92
+ console.log();
93
+ if (result.unusedExports === 0) {
94
+ console.log(chalk.green('✅ No unused exports found!'));
95
+ return;
96
+ }
97
+ console.log(chalk.bold.yellow(`🔍 Found ${result.unusedExports} unused exports:`));
98
+ console.log();
99
+ for (const fileAnalysis of result.files) {
100
+ if (fileAnalysis.unusedCount === 0)
101
+ continue;
102
+ const relativePath = relative(cwd, fileAnalysis.file);
103
+ const unusedNames = fileAnalysis.exports
104
+ .filter(e => e.isUnused)
105
+ .map(e => e.export.name)
106
+ .join(', ');
107
+ console.log(` ${chalk.gray(relativePath)}`);
108
+ console.log(` ${chalk.red(unusedNames)}`);
109
+ }
110
+ console.log();
111
+ console.log(chalk.gray(`Potential savings: ${formatBytes(result.estimatedSavings)}`));
112
+ console.log();
113
+ }
114
+ /**
115
+ * Print JSON result
116
+ */
117
+ export function printJsonResult(result, cwd) {
118
+ // Convert to relative paths for cleaner output
119
+ const output = {
120
+ ...result,
121
+ files: result.files.map(f => ({
122
+ ...f,
123
+ file: relative(cwd, f.file),
124
+ exports: f.exports.map(e => ({
125
+ ...e,
126
+ export: {
127
+ ...e.export,
128
+ file: relative(cwd, e.export.file),
129
+ },
130
+ usedIn: e.usedIn.map(u => relative(cwd, u)),
131
+ })),
132
+ })),
133
+ };
134
+ console.log(JSON.stringify(output, null, 2));
135
+ }
136
+ /**
137
+ * Print support message
138
+ */
139
+ export function printSupportMessage() {
140
+ console.log(chalk.gray('─'.repeat(50)));
141
+ console.log(chalk.gray('Cleaned up dead code? Consider supporting:'));
142
+ console.log(chalk.cyan('☕ https://buymeacoffee.com/willzhangfly'));
143
+ console.log();
144
+ }
145
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * unused-exports
3
+ * Find and remove unused exports from your codebase
4
+ */
5
+ export type { ExportType, ExportedItem, ImportReference, ExportAnalysis, FileAnalysis, ScanResult, CliOptions, } from './types/index.js';
6
+ export { analyzeExports } from './analyzer/export-analyzer.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,UAAU,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * unused-exports
3
+ * Find and remove unused exports from your codebase
4
+ */
5
+ // Analyzer
6
+ export { analyzeExports } from './analyzer/export-analyzer.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Type of export
3
+ */
4
+ export type ExportType = 'function' | 'class' | 'const' | 'type' | 'interface' | 'enum' | 'default' | 'variable';
5
+ /**
6
+ * Represents an exported item
7
+ */
8
+ export interface ExportedItem {
9
+ name: string;
10
+ type: ExportType;
11
+ file: string;
12
+ line: number;
13
+ isDefault: boolean;
14
+ estimatedSize: number;
15
+ }
16
+ /**
17
+ * Import reference
18
+ */
19
+ export interface ImportReference {
20
+ name: string;
21
+ fromFile: string;
22
+ toFile: string;
23
+ line: number;
24
+ isDefault: boolean;
25
+ }
26
+ /**
27
+ * Analysis result for an export
28
+ */
29
+ export interface ExportAnalysis {
30
+ export: ExportedItem;
31
+ usageCount: number;
32
+ usedIn: string[];
33
+ isUnused: boolean;
34
+ }
35
+ /**
36
+ * File analysis result
37
+ */
38
+ export interface FileAnalysis {
39
+ file: string;
40
+ exports: ExportAnalysis[];
41
+ unusedCount: number;
42
+ usedCount: number;
43
+ }
44
+ /**
45
+ * Overall scan result
46
+ */
47
+ export interface ScanResult {
48
+ files: FileAnalysis[];
49
+ totalExports: number;
50
+ unusedExports: number;
51
+ usedExports: number;
52
+ estimatedSavings: number;
53
+ }
54
+ /**
55
+ * CLI options
56
+ */
57
+ export interface CliOptions {
58
+ path: string;
59
+ json: boolean;
60
+ includeTypes: boolean;
61
+ ignore: string[];
62
+ }
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;AAEjH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "exports-cleanup",
3
+ "version": "0.0.1",
4
+ "description": "Find and remove unused exports - clean up dead code from your codebase",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "exports-cleanup": "./dist/cli/index.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsx src/cli/index.ts",
19
+ "prepublishOnly": "npm run build",
20
+ "clean": "rm -rf dist"
21
+ },
22
+ "keywords": [
23
+ "unused",
24
+ "exports",
25
+ "dead-code",
26
+ "cleanup",
27
+ "refactor",
28
+ "typescript",
29
+ "bundle",
30
+ "size",
31
+ "lint",
32
+ "analyzer"
33
+ ],
34
+ "author": "",
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/willzhangfly/unused-exports.git"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/willzhangfly/unused-exports/issues"
42
+ },
43
+ "homepage": "https://github.com/willzhangfly/unused-exports#readme",
44
+ "funding": {
45
+ "type": "buymeacoffee",
46
+ "url": "https://buymeacoffee.com/willzhangfly"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.0.0"
50
+ },
51
+ "dependencies": {
52
+ "commander": "^12.0.0",
53
+ "chalk": "^5.3.0",
54
+ "fast-glob": "^3.3.2",
55
+ "ora": "^8.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "typescript": "^5.3.0",
59
+ "@types/node": "^20.11.0",
60
+ "tsx": "^4.7.0"
61
+ }
62
+ }