archiver.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import type { PluginOption } from 'vite';
  2. import type { ArchiverPluginOptions } from '../typing';
  3. import fs from 'node:fs';
  4. import fsp from 'node:fs/promises';
  5. import { join } from 'node:path';
  6. import archiver from 'archiver';
  7. export const viteArchiverPlugin = (
  8. options: ArchiverPluginOptions = {},
  9. ): PluginOption => {
  10. return {
  11. apply: 'build',
  12. closeBundle: {
  13. handler() {
  14. const { name = 'dist', outputDir = '.' } = options;
  15. setTimeout(async () => {
  16. const folderToZip = 'dist';
  17. const zipOutputDir = join(process.cwd(), outputDir);
  18. const zipOutputPath = join(zipOutputDir, `${name}.zip`);
  19. try {
  20. await fsp.mkdir(zipOutputDir, { recursive: true });
  21. } catch {
  22. // ignore
  23. }
  24. try {
  25. await zipFolder(folderToZip, zipOutputPath);
  26. console.log(`Folder has been zipped to: ${zipOutputPath}`);
  27. } catch (error) {
  28. console.error('Error zipping folder:', error);
  29. }
  30. }, 0);
  31. },
  32. order: 'post',
  33. },
  34. enforce: 'post',
  35. name: 'vite:archiver',
  36. };
  37. };
  38. async function zipFolder(
  39. folderPath: string,
  40. outputPath: string,
  41. ): Promise<void> {
  42. return new Promise((resolve, reject) => {
  43. const output = fs.createWriteStream(outputPath);
  44. const archive = archiver('zip', {
  45. zlib: { level: 9 }, // 设置压缩级别为 9 以实现最高压缩率
  46. });
  47. output.on('close', () => {
  48. console.log(
  49. `ZIP file created: ${outputPath} (${archive.pointer()} total bytes)`,
  50. );
  51. resolve();
  52. });
  53. archive.on('error', (err) => {
  54. reject(err);
  55. });
  56. archive.pipe(output);
  57. // 使用 directory 方法以流的方式压缩文件夹,减少内存消耗
  58. archive.directory(folderPath, false);
  59. // 流式处理完成
  60. archive.finalize();
  61. });
  62. }