nodejs zip 批量压缩文件夹 按需过滤文件 批量迁徙mv备份 shell bash 命令

  

安装依赖

$ npm i jszip os shelljs -S

 

app.js

// $ npm i jszip os shelljs -S
const fs = require('fs')
const { join, sep } = require('path')

const os = require('os')
const JSZIP = require('jszip')
const shell = require('shelljs')

const homedir = os.homedir()
const desktop = join(homedir, '/Desktop/')

// 调试神器
const debug = (...args) => (console.log(...args), args[args.length - 1])

// fixbug:shell 执行不支持 window \ 的格式。强制修复为 Linux / 格式
const exec = command => shell.exec(debug("—— DEBUG ——:", command.replace(/\\/g, '/')))

// 获取文件大小
const readSize = target => {
    const size = fs.statSync(target).size
    if (size < 1024) {
        return size + ' kb'
    } else {
        return Math.floor(size / 1024) + ' mb'
    }
}

// 我的压缩列表(TODO:抽离到独立的配置文件)
const zipList = [ 
    join(desktop, 'dls-visual-12345'),
    join(desktop, 'dls-micro-app'),
    join(desktop, '我的ahk'),
    join(desktop, 'pandora-cli'),
]

// 编译临时存储地址
const template_address = join(__dirname, 'template')

// fixbug: 还是这样最安全,毕竟要用 shell 执行地址
const allzip_address = join(template_address, '*.zip')

// 迁移地址
const migrate_address = join(desktop, '同步项目')

// 创建临时文件夹和同步专用文件夹
exec(`mkdir -p ${template_address} && mkdir -p ${migrate_address}`)

// 排除部分文件或文件夹
const exclude = name => !['.git', 'node_modules'].includes(name)

// zip 递归读取文件夹下的文件流
function readDir(zip, nowPath) {
    // 读取目录中的所有文件及文件夹(同步操作)
    let files = fs.readdirSync(nowPath) 

    //遍历检测目录中的文件
    files.filter(exclude).forEach((fileName, index) => {
        // 打印当前读取的文件名
        false && console.log(fileName, index) 

        // 当前文件的全路径
        let fillPath = join(nowPath, fileName)

        // 获取一个文件的属性
        let file = fs.statSync(fillPath) 

        // 如果是目录的话,继续查询
        if (file.isDirectory()) {
            // 压缩对象中生成该目录
            let dirlist = zip.folder(fileName) 
            // (递归)重新检索目录文件
            readDir(dirlist, fillPath) 
        } else {
            // 压缩目录添加文件
            zip.file(fileName, fs.readFileSync(fillPath)) 
        }
    })
}

// 开始压缩文件
function zipFolder({ target = __dirname, output = __dirname + '/result.zip' }) {
    // 创建 zip 实例
    const zip = new JSZIP()

    // zip 递归读取文件夹下的文件流
    readDir(zip, target)

    // 设置压缩格式,开始打包
    return zip.generateAsync({
        // nodejs 专用
        type: 'nodebuffer', 
        // 压缩算法
        compression: 'DEFLATE', 
        // 压缩级别
        compressionOptions: { level: 9, },
    }).then(content => {
        // 将打包的内容写入 当前目录下的 result.zip中
        fs.writeFileSync(output, content, 'utf-8') 
    })
}

// demo
false && zipFolder({ 
    // 目标文件夹
    target: join(__dirname, 'test'), 
    // 输出 zip 
    output: __dirname + '/result.zip' 
})

// 删除所有的 .zip 
exec(`rm -rf ${allzip_address}`)

// 开始压缩
const workers = zipList.map(async target => {
    // 获取文件名
    const [name] = target.split(sep).reverse()

    // zip 输出路径和文件名
    const output = join(template_address, `${name}-${Date.now()}.zip`)

    // 压缩目标文件夹
    await zipFolder({ target, output })

    // 获取压缩体积
    const size = readSize(output)

    // 打印成功信息
    console.log(`☀️ ${name} 已压缩完成:`, output, ` (${size})`)
})

;(async () => {
    // 等待任务完成
    await Promise.all(workers)
    // 开始批量迁徙
    exec(`mv ${allzip_address} -t ${migrate_address}`)
})();

 

posted @ 2021-12-04 10:33  贝尔塔猫  阅读(160)  评论(0编辑  收藏  举报