clear_node_modules 1.4.3 → 1.5.0
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/package.json +3 -3
- package/src/lib.js +34 -65
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clear_node_modules",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Recursively remove node_modules folders from current directory and subdirectories",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/mooniitt/clear_node_modules#readme",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"ora": "^
|
|
35
|
-
"rimraf": "^
|
|
34
|
+
"ora": "^5.4.1",
|
|
35
|
+
"rimraf": "^5.0.0"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/lib.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const rimraf = require("rimraf");
|
|
3
|
+
const { rimraf } = require("rimraf");
|
|
4
4
|
const ora = require("ora");
|
|
5
|
-
const { promisify } = require("util");
|
|
6
|
-
|
|
7
|
-
const rimrafAsync = promisify(rimraf);
|
|
8
5
|
|
|
9
6
|
// 格式化文件大小
|
|
10
7
|
function formatSize(bytes) {
|
|
@@ -40,11 +37,9 @@ function getDirSize(dir) {
|
|
|
40
37
|
|
|
41
38
|
function wrap(LIMIT_SIZE, NODE_MODULES) {
|
|
42
39
|
return async function clearDir(dirPath) {
|
|
43
|
-
const
|
|
44
|
-
let totalCount = 0;
|
|
45
|
-
let doneCount = 0;
|
|
40
|
+
const foldersToDelete = [];
|
|
46
41
|
let totalFreed = 0;
|
|
47
|
-
let
|
|
42
|
+
let skippedCount = 0;
|
|
48
43
|
|
|
49
44
|
// 扫描阶段
|
|
50
45
|
const scanSpinner = ora("🔍 Scanning for node_modules...").start();
|
|
@@ -61,7 +56,8 @@ function wrap(LIMIT_SIZE, NODE_MODULES) {
|
|
|
61
56
|
try {
|
|
62
57
|
if (entry.isSymbolicLink()) continue;
|
|
63
58
|
if (entry.name === NODE_MODULES && entry.isDirectory()) {
|
|
64
|
-
|
|
59
|
+
const size = getDirSize(subPath);
|
|
60
|
+
foldersToDelete.push({ path: subPath, size });
|
|
65
61
|
} else if (entry.isDirectory()) {
|
|
66
62
|
scan(subPath);
|
|
67
63
|
}
|
|
@@ -76,77 +72,50 @@ function wrap(LIMIT_SIZE, NODE_MODULES) {
|
|
|
76
72
|
|
|
77
73
|
scan(dirPath);
|
|
78
74
|
|
|
79
|
-
if (
|
|
75
|
+
if (foldersToDelete.length === 0) {
|
|
80
76
|
scanSpinner.info("No node_modules found.");
|
|
81
77
|
return;
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
scanSpinner.succeed(`Found ${
|
|
80
|
+
scanSpinner.succeed(`Found ${foldersToDelete.length} node_modules folder(s)`);
|
|
85
81
|
console.log("");
|
|
86
82
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (entry.isSymbolicLink()) continue;
|
|
100
|
-
|
|
101
|
-
if (entry.name === NODE_MODULES && entry.isDirectory()) {
|
|
102
|
-
const dirSize = getDirSize(subPath);
|
|
103
|
-
const sizeMB = dirSize / 1024 / 1024;
|
|
104
|
-
|
|
105
|
-
if (sizeMB < LIMIT_SIZE) {
|
|
106
|
-
doneCount++;
|
|
107
|
-
console.log(` ⏭️ [${doneCount}/${totalCount}] Skipped (${formatSize(dirSize)}) ${subPath}`);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
83
|
+
// 串行删除,避免进度混乱
|
|
84
|
+
const total = foldersToDelete.length;
|
|
85
|
+
for (let i = 0; i < foldersToDelete.length; i++) {
|
|
86
|
+
const { path: folderPath, size } = foldersToDelete[i];
|
|
87
|
+
const sizeMB = size / 1024 / 1024;
|
|
88
|
+
const progress = `[${i + 1}/${total}]`;
|
|
89
|
+
|
|
90
|
+
if (sizeMB < LIMIT_SIZE) {
|
|
91
|
+
skippedCount++;
|
|
92
|
+
console.log(` ⏭️ ${progress} Skipped (${formatSize(size)}) ${folderPath}`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
110
95
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
failedCount++;
|
|
123
|
-
spinner.fail(`[${doneCount}/${totalCount}] ✗ Failed - ${subPath}: ${err.message}`);
|
|
124
|
-
});
|
|
125
|
-
tasks.push(task);
|
|
126
|
-
} else if (entry.isDirectory()) {
|
|
127
|
-
await recurse(subPath);
|
|
128
|
-
}
|
|
129
|
-
} catch (e) {
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
} catch (e) {
|
|
134
|
-
// 忽略
|
|
96
|
+
const spinner = ora({
|
|
97
|
+
text: `${progress} Removing ${formatSize(size)} - ${folderPath}`,
|
|
98
|
+
prefixText: " "
|
|
99
|
+
}).start();
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
await rimraf(folderPath);
|
|
103
|
+
totalFreed += size;
|
|
104
|
+
spinner.succeed(`${progress} Freed ${formatSize(size)} - ${folderPath}`);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
spinner.fail(`${progress} Failed - ${folderPath}: ${err.message}`);
|
|
135
107
|
}
|
|
136
108
|
}
|
|
137
|
-
|
|
138
|
-
await recurse(dirPath);
|
|
139
|
-
await Promise.all(tasks);
|
|
140
109
|
|
|
141
110
|
// 汇总信息
|
|
142
111
|
console.log("");
|
|
143
112
|
console.log("─".repeat(50));
|
|
144
113
|
console.log(` ✨ Completed!`);
|
|
145
|
-
console.log(` 📁
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
console.log(` ⚠️ Failed: ${failedCount}`);
|
|
114
|
+
console.log(` 📁 Total: ${total} folder(s)`);
|
|
115
|
+
if (skippedCount > 0) {
|
|
116
|
+
console.log(` ⏭️ Skipped: ${skippedCount}`);
|
|
149
117
|
}
|
|
118
|
+
console.log(` 💾 Freed: ${formatSize(totalFreed)}`);
|
|
150
119
|
console.log("─".repeat(50));
|
|
151
120
|
};
|
|
152
121
|
}
|