npmshit
Version:
自动清理node_modules中无用的文件
212 lines • 7.2 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const promises_1 = __importDefault(require("rd/promises"));
const rd_1 = __importDefault(require("rd"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const util_1 = require("util");
const BLACK_LIST_FILE = [
"license",
"license.txt",
"license-mit.txt",
"author",
"authors",
"changelog",
"changelogs",
"history",
"codeowners",
"gulpfile.js",
"bower.json",
"tsconfig.json",
"tslint.json",
"tslint.yaml",
"package-lock.json",
"npm-shrinkwrap.json",
"yarn.lock",
];
const BLACK_LIST_EXT = [".md", ".markdown", ".map"];
const BLACK_LIST_ADVJS_EXT = [".min.js", ".test.js", ".spec.js", ".debug.js"];
const BLACK_LIST_DIR = [
"example",
"examples",
"test",
"tests",
".idea",
".vscode",
"docs",
"doc",
"wiki",
"__test__",
"__mock__",
];
const BLACK_LIST_PACKAGE = {
handlebars: {
dirs: ["dist"],
files: [],
},
typescript: {
dirs: [],
files: ["CopyrightNotice.txt", "ThirdPartyNoticeText.txt"],
},
};
const WHITE_LIST_PACKAGE_FIELD = ["name", "version", "main", "scripts", "typings", "bin", "dependencies"];
exports.unlinkAsync = util_1.promisify(fs_1.default.unlink);
exports.rmdirAsync = util_1.promisify(fs_1.default.rmdir);
exports.statAsync = util_1.promisify(fs_1.default.stat);
function rmdir(dir) {
return __awaiter(this, void 0, void 0, function* () {
const list = yield promises_1.default.readDir(dir);
list.sort((a, b) => b.length - a.length);
for (const n of list) {
try {
yield exports.rmdirAsync(n);
}
catch (err) { }
}
try {
yield exports.rmdirAsync(dir);
}
catch (err) { }
});
}
exports.rmdir = rmdir;
function humanFileSize(size) {
if (size < 1)
return "0 B";
var i = Math.floor(Math.log(size) / Math.log(1024));
return (size / Math.pow(1024, i)).toFixed(2) + " " + ["B", "kB", "MB", "GB", "TB"][i];
}
exports.humanFileSize = humanFileSize;
function listFiles(base) {
return __awaiter(this, void 0, void 0, function* () {
const res = {
totalSize: 0,
size: 0,
packageFreeSize: 0,
packageCount: 0,
fileCount: 0,
fileList: [],
dirList: [],
packageFileList: [],
removeFiles: [],
};
function fileFiltter(name) {
const file = path_1.default.basename(name).toLocaleLowerCase();
if (file === "package.json") {
res.packageCount += 1;
res.packageFileList.push(name);
}
if (file[0] === ".")
return true;
if (BLACK_LIST_FILE.indexOf(file) !== -1)
return true;
const ext = path_1.default.extname(name).toLocaleLowerCase();
if (BLACK_LIST_EXT.indexOf(ext) !== -1)
return true;
if (ext === ".js") {
for (const advExt of BLACK_LIST_ADVJS_EXT) {
if (file.slice(-advExt.length) === advExt)
return true;
}
}
}
function dirFiltter(name) {
const dir = path_1.default.basename(name).toLocaleLowerCase();
if (BLACK_LIST_DIR.indexOf(dir) !== -1)
res.dirList.push(name);
}
function process(name, stats) {
const file = path_1.default.basename(name).toLocaleLowerCase();
if (file === "package.json") {
const { size: newSize, removeFiles } = reducePackageJson(name);
const size = stats.size - newSize;
res.size += size;
res.packageFreeSize += size;
res.removeFiles = res.removeFiles.concat(removeFiles);
}
}
function findOne(filename, stats, next) {
res.totalSize += stats.size;
process(filename, stats);
if (stats.isFile() && !fileFiltter(filename)) {
return next();
}
if (stats.isDirectory()) {
dirFiltter(filename);
return next();
}
res.size += stats.size;
res.fileCount += 1;
res.fileList.push(filename);
next();
}
yield promises_1.default.each(base, findOne);
for (const dir of res.dirList) {
const { size, files } = yield getDirTotalSize(dir);
res.fileList = res.fileList.concat(files);
res.size += size;
}
res.removeFiles.forEach(f => {
if (res.fileList.indexOf(f) !== -1)
return;
const s = fs_1.default.statSync(f);
res.fileList.push(f);
res.size += s.size;
});
return res;
});
}
exports.listFiles = listFiles;
function getDirTotalSize(dir) {
return __awaiter(this, void 0, void 0, function* () {
let size = 0;
const files = [];
yield promises_1.default.eachFile(dir, (f, s, next) => {
size += s.size;
files.push(f);
next();
});
return { size, files };
});
}
function reducePackageJson(name, write = false) {
const origin = fs_1.default.readFileSync(name);
const pkg = JSON.parse(origin.toString());
let removeFiles = [];
if (pkg.name in BLACK_LIST_PACKAGE) {
const { dirs, files } = BLACK_LIST_PACKAGE[pkg.name];
const dir = path_1.default.dirname(name);
files.forEach(n => {
const f = path_1.default.resolve(dir, n);
if (fs_1.default.existsSync(f)) {
removeFiles.push(f);
}
});
dirs.forEach(n => {
const files = rd_1.default.readFileSync(path_1.default.resolve(dir, n));
removeFiles = removeFiles.concat(files);
});
}
const newPkg = {};
for (const n of WHITE_LIST_PACKAGE_FIELD) {
newPkg[n] = pkg[n];
}
const data = Buffer.from(JSON.stringify(newPkg));
if (write) {
fs_1.default.writeFileSync(name, data);
}
return { size: data.length, removeFiles };
}
exports.reducePackageJson = reducePackageJson;
//# sourceMappingURL=index.js.map