// https://github.com/vbenjs/vue-vben-admin/blob/03ceb2aac5a47d7127562f2855d41da5c58b81bf/internal/vite-config/src/plugins/archiver.ts import type { Plugin } from 'vite'; import archiver from 'archiver'; import fs from 'node:fs'; import path from 'node:path'; interface ArchiverOptions { /** * 输出目录 * @default '' */ outputDir?: string; /** * 输出的zip文件名(不含扩展名) * @default 'dist' */ outputFileName?: string; /** * 要打包的源目录 * @default 'dist' */ sourceDir?: string; } /** * 用于将构建输出打包成zip文件的Vite插件 */ export function viteArchiverPlugin(options: ArchiverOptions = {}): Plugin { const { outputDir = '', outputFileName = 'dist', sourceDir = 'dist' } = options; return { apply: 'build', closeBundle: async () => { const sourcePath = path.resolve(process.cwd(), sourceDir); // 检查源目录是否存在 if (!fs.existsSync(sourcePath)) { console.error(`Source directory '${sourceDir}' does not exist.`); return; } // 如果输出目录不存在,则创建它 const outputPath = path.resolve(process.cwd(), outputDir); if (outputDir && !fs.existsSync(outputPath)) { fs.mkdirSync(outputPath, { recursive: true }); } const outputFilePath = path.join(outputPath, `${outputFileName}.zip`); const output = fs.createWriteStream(outputFilePath); const archive = archiver('zip', { zlib: { level: 9 }, // 设置压缩级别 }); // 监听所有归档数据写入完成 output.on('close', () => { console.log(`Archive created: ${outputFilePath}`); console.log(`Total bytes: ${archive.pointer()}`); }); // 良好实践:捕获警告(例如stat失败和其他非阻塞错误) archive.on('warning', (err) => { if (err.code === 'ENOENT') { console.warn(err); } else { throw err; } }); // 良好实践:明确捕获此错误 archive.on('error', (err) => { throw err; }); // 将归档数据通过管道传输到文件 archive.pipe(output); // 从目录添加文件到归档 archive.directory(sourcePath, false); // 完成归档(即我们已完成添加文件,但流尚未结束) await archive.finalize(); }, name: 'vite-plugin-archiver', }; }