用node写一个压缩文件(zip格式)的脚本
缘起日常的发包没有运维自动化,本着不要
DRY的原则,重复的流程应该写成自动化或半自动化的方式。
- 安装依赖
npm i --global archiver - 实现逻辑思路:从路径读取文件(或目录),交给
archiver处理压缩,输出结果
const fs = require('fs')
const path = require('path')
const archiver = require('archiver')
/**
*
* @param {String} source 打包文件路径
* @param {String} target 输出文件路径
*/
function archivePackage(source, target, ignoreFile = []) {
return new Promise((resolve, reject) => {
const sourcePath = normalizePath(source)
try {
fs.accessSync(sourcePath, fs.constants.R_OK)
} catch (error) {
return reject(error)
}
// create a file to stream archive data to.
const output = fs.createWriteStream(normalizePath(target))
const archive = archiver('zip', {
zlib: { level: 9 }, // Sets the compression level.
})
// listen for all archive data to be written
// 'close' event is fired only when a file descriptor is involved
output.on('close', function () {
console.log(archive.pointer() + ' total bytes')
console.log(
'archiver has been finalized and the output file descriptor has closed.'
)
resolve()
})
// This event is fired when the data source is drained no matter what was the data source.
// It is not part of this library but rather from the NodeJS Stream API.
// @see: https://nodejs.org/api/stream.html#stream_event_end
output.on('end', function () {
console.log('Data has been drained')
})
// good practice to catch warnings (ie stat failures and other non-blocking errors)
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
// log warning
} else {
// throw error
throw err
}
})
// good practice to catch this error explicitly
archive.on('error', function (err) {
reject()
throw err
})
// pipe archive data to the file
archive.pipe(output)
// append files from a sub-directory and naming it `new-subdir` within the archive
// archive.directory('subdir/', 'new-subdir');
// append files from a sub-directory, putting its contents at the root of archive
// archive.directory(normalizePath(source), false)
// append files from a glob pattern
//? sometheing suggestion ref: https://stackoverflow.com/questions/65960979/node-js-archiver-need-syntax-for-excluding-file-types-via-glob
//? 目前ignore 选项不能忽略文件夹
archive.glob('**/*', { cwd: normalizePath(source), ignore: ignoreFile })
// finalize the archive (ie we are done appending files but streams have to finish yet)
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
archive.finalize()
})
}
function normalizePath(pathStr) {
return path.resolve(pathStr.replace(/^[A-Z]{1}:/gi, '').replace(/\\/g, '/'))
}
function cleanFile(pathStr) {
if (fs.existsSync(pathStr)) {
const stat = fs.statSync(pathStr)
if (stat.isDirectory()) {
fs.rmSync(pathStr, { recursive: true })
} else if (stat.isFile()) {
fs.unlinkSync(pathStr)
}
}
}
function cleanPrepareDir(pathStr) {
cleanFile(pathStr)
fs.mkdirSync(pathStr)
}
function copyFile(sourcePath, targetPath) {
fs.copyFileSync(sourcePath, targetPath)
console.log(`copy ${sourcePath} to ${targetPath} successed.`)
}
function main() {
// 根目录只能是当前执行的盘符 此处 / = D:
let today = new Date().toISOString().split(/T/)[0].replace(/-/g, '')
const packagePath = `/前端包/前端包${today}`
const packagePathZip = `${packagePath}.zip`
cleanPrepareDir(packagePath)
cleanFile(packagePathZip)
// 根据实际需要 copy 文件到目标目录
copyFile('./readme.md', `${packagePath}/readme.md`)
const p1 = archivePackage(
'/work/git_project/dist',
`${packagePath}/dist.zip`,
['**/.vscode/**/*', '**/.env*']
)
const p2 = archivePackage(
'/work/svn_project/public',
`${packagePath}/public.zip`,
['**/.vscode/**/*', '**/.env*']
)
Promise.all([p1, p2])
.then(() => {
archivePackage(packagePath, packagePathZip)
})
.catch((err) => {
console.error('打包出错:', err)
throw err
})
}
main()
这个脚本是放到项目中打包使用,没有过多做配置。有实际需求可以使用 minimist 库解析参数,路径作为参数输入。
注意
注意: 在windows下,如果输入路径和输出路径不在同一个根盘符路径下,需要在执行过程中切换当前脚本工作路径。用到 process.chdir()。例如,输入文件为:D:\\app, 输出路径为:E:\\output ,需要在
D盘下执行,执行打包内容后 ,process.chdir("E:\\") 切换盘符再输出 压缩后的文件。同理,可以在任何盘符下执行,对应切换盘符找到文件路径即可。
推荐 tar
node 的压缩工具包还有一个 tar 的包,是 node 实现 linux 下的 tar 功能更丰富、压缩率更高,不过不支持 zip 格式文件,因此没有使用。没有格式要求,强烈建议使用 tar 。

本文介绍了如何使用Node.js通过archiver模块创建zip压缩文件,并提供了使用示例。同时,作者推荐了在某些场景下使用tar工具,因其在Linux下功能更为丰富。
1386

被折叠的 条评论
为什么被折叠?



