javascript
const fs = require("fs");
const path = require("path");
const archiver = require("archiver");
const moment = require("moment");
const ProgressBar = require("progress");
const packageJSON = require("./package.json");
// 格式化文件大小
function formatFileSize(bytes, targetUnit) {
bytes = parseFloat(bytes);
if (!bytes || bytes < 0) return "--";
const units = ["B", "KB", "MB", "GB", "T"];
let unitIndex;
let size;
if (targetUnit) {
unitIndex = units.indexOf(targetUnit.toUpperCase());
size = bytes / 1024 ** unitIndex;
} else {
unitIndex = 0;
size = bytes;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
}
return `${size.toFixed(2)} ${units[unitIndex]}`;
}
// 递归计算目录总大小
function getDirectorySize(dirPath) {
let totalSize = 0;
const files = fs.readdirSync(dirPath);
for (const file of files) {
const filePath = path.join(dirPath, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
totalSize += getDirectorySize(filePath);
} else {
totalSize += stats.size;
}
}
return totalSize;
}
// 删除旧的压缩包
function deleteOldCompressedFiles() {
const compressedExtensions = [".zip", ".rar", ".7z"];
const files = fs.readdirSync(__dirname);
for (const file of files) {
const ext = path.extname(file).toLowerCase();
if (compressedExtensions.includes(ext)) {
const filePath = path.join(__dirname, file);
try {
fs.unlinkSync(filePath);
console.log(`✅ 已删除旧压缩包: ${filePath}`);
} catch (err) {
console.error(`❌ 删除压缩包失败: ${filePath}`, err);
}
}
}
}
// 主流程
function main() {
const distPath = path.join(__dirname, "dist");
const fileName = `${moment().format("YYYY-MM-DD-HHmmss")}-${packageJSON.version}.zip`;
const outputPath = path.join(__dirname, fileName);
if (!fs.existsSync(distPath)) {
console.error("❌ 错误: dist 目录不存在");
process.exit(1);
}
// 删除旧压缩包
deleteOldCompressedFiles();
// 计算 dist 目录总大小
const totalSize = getDirectorySize(distPath);
if (totalSize === 0) {
console.error("❌ 错误: dist 目录为空");
process.exit(1);
}
// 初始化输出流和压缩器
const output = fs.createWriteStream(outputPath);
const archive = archiver("zip", { zlib: { level: 9 } });
// 创建进度条
const bar = new ProgressBar("📦 打包进度 [:bar] 进度 [:percent] 剩余时间 [:etas]", {
total: totalSize,
width: 40,
complete: "=",
incomplete: "-",
});
// 事件监听
archive.on("entry", (entry) => {
bar.tick(entry.stats.size); // 更新进度
});
archive.on("error", (err) => {
console.error("❌ 压缩失败:", err);
process.exit(1);
});
output.on("close", () => {
const finalSize = formatFileSize(archive.pointer());
console.log(`✅ 压缩完成: ${fileName},总大小: ${finalSize}`);
});
// 管道连接
archive.pipe(output);
archive.directory(distPath, "dist");
archive.finalize();
}
// 执行主流程
main();
package.json文件修改
javascript
"name": "xxx",
"version": "0.1.0", // 此处是版本号,每次打包只需修改这里
"private": true,
"scripts": {
"build": "vue-cli-service build --mode production && npm run zip",
"zip": "node zip.js"
},
直接npm run build 就可以了,至此,打包后,直接生成zip压缩包,恭喜。