vue自动打包工程为压缩包

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压缩包,恭喜。

相关推荐
QQ1__8115175158 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态8 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子8 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室8 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI8 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing8 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者8 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册8 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李8 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢8 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web