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

相关推荐
m0_6470579623 分钟前
uniapp使用rich-text流式 Markdown 换行问题与解决方案
前端·javascript·uni-app
We་ct36 分钟前
LeetCode 49. 字母异位词分组:经典哈希解法解析+易错点规避
前端·算法·leetcode·typescript·哈希算法
CHU72903538 分钟前
废品回收小程序前端功能设计逻辑与实践
前端·小程序
lzhdim39 分钟前
微星首款全白设计的M-ATX小板! MPG B850M EDGE TIMAX WIF刀锋 钛评测:性能媲美顶级X870E主板
前端·edge
恋猫de小郭43 分钟前
小米 HyperOS 4 大变样?核心应用以 Rust / Flutter 重写,不兼容老系统
android·前端·人工智能·flutter·ios
摘星编程44 分钟前
OpenHarmony环境下React Native:Loading全屏加载遮罩
javascript·react native·react.js
李火火的安全圈1 小时前
基于Yakit、Wavely实现CVE-2025-55182(React Server Components(RSC)) 反序列化漏洞挖掘和POC编写
前端·react.js
Orange_sparkle1 小时前
dify的web页面如何传入user用户信息进行对话,而不是uuid
前端·人工智能
Amumu121381 小时前
Vue Router 和 常用组件库
前端·javascript·vue.js
霍理迪1 小时前
CSS移动端开发及less使用方法
前端·css