最近看着公司项目打包太过混乱 因为协同开发 需要随时更新代码到测试环境 虽然有git的自动化部署脚本 但是上了正式的内网环境(政府项目无互联网环境) 打包还是要手动部署的 所以想写个简单的备份脚本 发包的时候能知道最后发包人及发包时间和版本 话不多说 上代码
项目结构:
添加tsconfig.run.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es2018",
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"moduleResolution": "node"
},
"include": ["build/index.ts"]
}
添加build下index.ts
注意安装 npm install ts-node
archiver @types/archiver -D
import * as fs from "fs";
import path from "path";
import moment from "moment";
import { exec } from "child_process";
import archiver from "archiver";
// 文件数
let files = 0;
// 获取文件路径
const getPath = (dir: string) => path.resolve(__dirname, "../", dir),
archive = archiver("zip", {
zlib: { level: 6 },
}),
// 获取git用户名
getGitUser = () => {
return new Promise((resolve, reject) => {
exec("git config user.name", (err, stdout) => {
if (err) {
console.log("未获取到当前打包人:", err);
return reject("未知");
}
console.log("当前打包人:", stdout.slice(0, -1));
resolve(stdout.slice(0, -1));
});
});
},
// 获取文件数
dirLen = (srcPath: string) => {
fs.readdirSync(srcPath).forEach((dir) => {
const filePath = path.join(srcPath, dir);
if (fs.lstatSync(filePath).isDirectory()) {
dirLen(filePath);
} else files += 1;
});
},
// 遍历读取文件
readDirErgodic = async (
srcPath: string,
toPath: string,
callback: () => void
) => {
try {
const dirList = fs.readdirSync(srcPath);
for await (const file of dirList) {
//拼接路径
const curPath = path.join(srcPath, file),
toCopyPath = path.join(toPath, file);
if (fs.lstatSync(curPath).isDirectory()) {
fs.mkdirSync(toCopyPath);
readDirErgodic(curPath, toCopyPath, callback);
} else {
const readable = fs.createReadStream(curPath),
writable = fs.createWriteStream(toCopyPath);
readable.pipe(writable);
writable.on("finish", () => {
files--;
// files === 0 && console.log("finish", callback);
files === 0 && callback && callback();
});
}
}
} catch (err) {
console.log("------------读取dist文件失败------------", err);
throw new Error(err + "");
}
},
// 读取dist下所有文件
readDistDir = async (srcPath: string, toPath: string) => {
try {
// 计算多少文件数
dirLen(srcPath);
// 创建复制过去准备打包的文件夹
fs.mkdirSync(toPath);
console.log("打包文件个数:", files);
return new Promise((resolve) => {
readDirErgodic(srcPath, toPath, () => resolve(true));
});
} catch (err) {
return Promise.resolve(false);
}
},
// 删除指定文件夹下所有文件并删除该文件夹
deleteFolderErgodic = async (folderPath: string) => {
const files = fs.readdirSync(folderPath);
for await (const filePath of files) {
//拼接路径
const curPath = path.join(folderPath, filePath);
if (fs.lstatSync(curPath).isDirectory()) {
await deleteFolderErgodic(curPath);
isEmptyDir(curPath) && fs.rmdirSync(curPath);
} else {
fs.unlinkSync(curPath);
}
}
return Promise.resolve(true);
},
// 是否为空文件夹
isEmptyDir = (folderPath: string) => {
try {
const list = fs.readdirSync(folderPath);
return list && Array.isArray(list) && list.length === 0 ? true : false;
} catch (e) {
return true;
}
},
// 删除指定文件夹
deleteFolder = async (folderPath: string) => {
await deleteFolderErgodic(folderPath);
// 删除现在为空的文件夹
// console.log("isEmptyDir(folderPath)", isEmptyDir(folderPath));
isEmptyDir(folderPath) && fs.rmdirSync(folderPath);
},
// 打包文件
compressFolder = async (fileName: string) => {
if (fs.existsSync(fileName)) {
console.log("------------打包压缩开始------------");
const output = fs.createWriteStream(`${fileName}.zip`);
// 监听archive对象的错误事件
archive.on("error", (err: any) => {
console.log("打包错误", err);
throw err;
});
output.on("close", () => {
let times = 3;
console.log("------------删除打包文件中....------------");
const timer: NodeJS.Timer = setInterval(() => {
console.log(`${times}秒`);
if (times == 1) {
if (fs.existsSync(fileName)) {
deleteFolder(fileName);
console.log("------------打包压缩流程完成!------------");
return clearInterval(timer);
} else
console.log(
"------------删除打包文件失败,请根据情况手动删除------------"
);
}
times--;
}, 1000);
});
// 将archive流导向输出文件
archive.pipe(output);
// 添加要打包的文件
archive.directory(fileName, false);
// 完成archive
archive.finalize();
}
};
// 将打包的dist文件存入文件备份中
(async function copyFileToBackFiles(srcFile: string, distFile: string) {
console.log("------------打包压缩流程开始!------------");
!fs.existsSync(distFile) && fs.mkdirSync(distFile);
const fileName = `${distFile}/${path.basename(process.cwd())}-${moment(
new Date()
).format("YYYY-MM-DD HH:mm:ss")}-${await getGitUser()}`;
//
// console.log("fileName", path.basename(process.cwd()));
// 读取dist文件夹下所有文件并拷贝到fileName文件夹下
if (!(await readDistDir(srcFile, fileName)))
return console.log("------------打包压缩意外终止------------");
// 压缩文件
compressFolder(fileName);
})(getPath("dist"), getPath("dist_back_files"));
package.json添加运行脚本
{
"build-only": "vite build && ts-node",
"ts-node": "ts-node --project tsconfig.run.json build/index",
}
脚本将在构建完成后 创建一个
压缩文件名组成: 项目名-日期-git最后一次提交人
暂时性满足了我的需求 后期准备把他封装成一个插件包发上去 等着再说叭~
评论 (0)