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

相关推荐
小陈工1 小时前
2026年4月2日技术资讯洞察:数据库融合革命、端侧AI突破与脑机接口产业化
开发语言·前端·数据库·人工智能·python·安全
IT_陈寒1 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
HIT_Weston1 小时前
41、【Agent】【OpenCode】本地代理分析(五)
javascript·人工智能·opencode
C澒1 小时前
AI 生码:A 类生码方案架构升级
前端·ai编程
前端Hardy2 小时前
前端必看!LocalStorage这么用,再也不踩坑(多框架通用,直接复制)
前端·javascript·面试
前端Hardy2 小时前
前端必看!前端路由守卫这么写,再也不担心权限混乱(Vue/React通用)
前端·javascript·面试
Lee川2 小时前
从零构建现代化登录界面:React + Tailwind CSS 前端工程实践
前端·react.js
Awu12272 小时前
⚡精通 Claude 第 1 课:掌握 Slash Commands
前端·人工智能·ai编程
竹林8182 小时前
从ethers.js迁移到Viem:我在重构DeFi前端时踩过的那些坑
前端·javascript
码云之上2 小时前
上下文工程实战:解决多轮对话中的"上下文腐烂"问题
前端·node.js·agent