Vite项目打包生成dist.zip方法

使用自定义插件(推荐)

步骤1:安装依赖

bash

复制

复制代码
npm install jszip -D

步骤2:创建插件文件

在项目根目录新建zip.js(或createZip.ts,若使用TypeScript),写入以下代码:

javascript

复制

ini 复制代码
const path = require('path');
const fs = require('fs');
const JSZip = require('jszip');

const plugin = (fileName = 'dist', outputPath) => {
  const output = outputPath || path.resolve(__dirname, './dist');
  fileName += '.zip';

  const makeZip = () => {
    const zip = new JSZip();
    const distPath = path.resolve(output);

    // 递归读取文件夹并添加到Zip
    const readDir = (zipInstance, dirPath) => {
      const files = fs.readdirSync(dirPath);
      files.forEach(file => {
        const filePath = path.join(dirPath, file);
        const stats = fs.statSync(filePath);
        if (stats.isDirectory()) {
          const folder = zipInstance.folder(file);
          readDir(folder, filePath);
        } else {
          zipInstance.file(file, fs.readFileSync(filePath));
        }
      });
    };

    // 删除已存在的Zip文件
    const removeExistingZip = () => {
      const zipPath = path.join(distPath, '../', fileName);
      if (fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
    };

    // 生成Zip内容并写入文件
    readDir(zip, distPath);
    zip.generateAsync({
      type: 'nodebuffer',
      compression: 'DEFLATE',
      compressionOptions: { level: 9 }
    }).then(content => {
      const destPath = path.join(distPath, '../', fileName);
      removeExistingZip();
      fs.writeFileSync(destPath, content);
    });
  };

  return {
    name: 'vite-plugin-auto-zip',
    apply: 'build',
    closeBundle: makeZip
  };
};

module.exports = plugin;

步骤3:在Vite配置中引入插件

修改vite.config.js(或vite.config.ts):

javascript

复制

javascript 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import zipPlugin from './zip';

export default defineConfig({
  plugins: [
    vue(),
    zipPlugin() // 可传参自定义文件名,如 zipPlugin('myapp', './custom-dist')
  ],
  build: {
    outDir: 'dist', // 可选:修改输出目录名:cite[3]:cite[8]
  }
});

步骤4:执行打包

bash

复制

arduino 复制代码
npm run build

如果只想在开发环境development)下启用 ZIP 打包功能,而在生产环境production)下禁用,可以修改 Vite 插件逻辑,使其仅在 vite devvite build --mode development 时生效。以下是具体实现方法:


方法 1:基于 mode 动态启用插件

1. 修改插件逻辑(createZip.js

javascript

复制

ini 复制代码
import path from 'path';
import fs from 'fs';
import JSZip from 'jszip';

export default function createZipPlugin(options = {}) {
  const {
    fileName = 'dist',
    outputPath,
    enabled = process.env.NODE_ENV === 'development' // 默认开发环境启用
  } = options;

  if (!enabled) {
    // 如果禁用,返回一个空插件
    return {
      name: 'vite-plugin-auto-zip',
      apply: 'build',
      closeBundle: () => {} // 空函数
    };
  }

  const output = outputPath || path.resolve(process.cwd(), './dist');
  const zipFileName = `${fileName}.zip`;

  const makeZip = () => {
    const zip = new JSZip();
    const distPath = path.resolve(output);

    // 递归读取文件夹
    const readDir = (zipInstance, dirPath) => {
      const files = fs.readdirSync(dirPath);
      files.forEach(file => {
        const filePath = path.join(dirPath, file);
        const stats = fs.statSync(filePath);
        if (stats.isDirectory()) {
          const folder = zipInstance.folder(file);
          readDir(folder, filePath);
        } else {
          zipInstance.file(file, fs.readFileSync(filePath));
        }
      });
    };

    // 生成 ZIP
    readDir(zip, distPath);
    zip.generateAsync({
      type: 'nodebuffer',
      compression: 'DEFLATE',
      compressionOptions: { level: 9 }
    }).then(content => {
      const destPath = path.join(distPath, '../', zipFileName);
      if (fs.existsSync(destPath)) fs.unlinkSync(destPath);
      fs.writeFileSync(destPath, content);
    });
  };

  return {
    name: 'vite-plugin-auto-zip',
    apply: 'build',
    closeBundle: makeZip
  };
}

2. 在 vite.config.js 中动态配置

javascript

复制

javascript 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import createZipPlugin from './createZip';

export default defineConfig(({ mode }) => ({
  plugins: [
    vue(),
    createZipPlugin({
      enabled: mode === 'development' // 仅开发模式启用
    })
  ],
  build: {
    outDir: 'dist'
  }
}));
相关推荐
wordbaby14 分钟前
Flutter Form Builder 完全指南:告别 Controller 地狱
前端·flutter
A***071727 分钟前
React数据可视化应用
前端·react.js·信息可视化
泉城老铁1 小时前
Vue2实现语音报警
前端·vue.js·架构
临江仙4551 小时前
前端骚操作:用户还在摸鱼,新版本已悄悄上线!一招实现无感知版本更新通知
前端·vue.js
想个什么名好呢1 小时前
解决uniapp的H5项目uni-popup页面滚动穿透bug
前端
用户93816912553602 小时前
Vue3项目--mock数据
前端
前端加油站2 小时前
一种新HTML 页面转换成 PDF 技术方案
前端·javascript·vue.js
w***Q3502 小时前
Vue打包
前端·javascript·vue.js
有事没事实验室2 小时前
router-link的custom模式
前端·javascript·vue.js
常乐我净6162 小时前
十、路由和导航
前端