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

相关推荐
深念Y4 分钟前
stable-diffusion.cpp 的 FLUX.2 Klein 9B 分步
java·前端·数据库
小帅不太帅8 分钟前
1.5M 参数的 OCR 模型,我把它跑进了浏览器
前端·javascript·ai编程
风骏时光牛马16 分钟前
AI编程场景下故障根因分析与复盘总结
前端
Sterting36 分钟前
Element-Plus 入门与整体布局
前端·vue.js·elementui
程序员黑豆8 小时前
Java 注释详解:单行、多行与文档注释的完整指南
java·前端·ai编程
剪刀石头布啊8 小时前
antd中可编辑表格中巧用useWatch实现联动高性能效果,以及定制延伸学习
前端
油丶酸萝卜别吃9 小时前
前端转全栈学习路线
前端·学习
浮生望9 小时前
前端路由进阶:History API原理与手写HistoryRouter
前端
陆枫Larry9 小时前
JavaScript 中的竞态是什么,为啥会有竟态?
前端
上海安当技术11 小时前
半天接入:USBKey RESTful API + C 动态库,Web 和 C/S 两套集成路径实战
前端·后端·restful·集成·usbkey