打包选择环境并压缩
实现以下功能
- 当运行 pnpm build 时,脚本会:
- 自动扫描根目录下所有的 .env.xxx 文件
- 从每个环境文件中读取 VUE_APP_TITLE 的值
- 以 "环境名 (VUE_APP_TITLE)" 的格式显示选项列表
- 选择环境后:
- 会执行对应的 npm run build:xxx 命令
- 打包完成后会询问是否需要打包成 zip
- 如果选择打包成 zip,可以:
- 自定义要打包的文件夹路径(默认是 ./dist)
- 自定义 zip 文件名(默认是 dist-环境名.zip)
输出示例:
sh
? 选择打包环境: (Use arrow keys)
❯ test (测试环境)
dev (开发环境)
pro (pro环境)
添加 npm 命令
json
"scripts": {
"build": "node build/build.js",
}
添加打包命令
js
// ./build/build.js
const inquirer = require("inquirer")
const { spawn } = require("child_process")
const { createZipFromFolder } = require("./compress.js")
const fs = require("fs")
const path = require("path")
const prompt = inquirer.createPromptModule()
// 读取根目录下所有的.env文件
const getEnvFiles = () => {
const files = fs.readdirSync(process.cwd())
return files.filter(file => file.startsWith(".env."))
}
// 获取当前git分支名称
const getCurrentBranch = () => {
try {
return execSync("git rev-parse --abbrev-ref HEAD", {
encoding: "utf8",
}).trim();
} catch (error) {
console.error("获取分支名称失败:", error)
return null
}
}
// 从.env文件中读取VUE_APP_TITLE
const getEnvTitle = envFile => {
const content = fs.readFileSync(path.join(process.cwd(), envFile), "utf-8")
const titleMatch = content.match(/VUE_APP_TITLE\s*=\s*['"]?([^'"\n]+)['"]?/)
return titleMatch ? titleMatch[1].trim() : envFile.replace(".env.", "")
}
// 获取所有环境选项
const getEnvChoices = () => {
const envFiles = getEnvFiles()
return envFiles.map(file => {
const envName = file.replace(".env.", "")
const title = getEnvTitle(file)
return {
name: `${envName} (${title})`,
value: envName,
}
})
}
const run = async () => {
const { env } = await prompt([
{
type: "list",
name: "env",
message: "选择打包环境:",
choices: getEnvChoices(),
},
])
console.log(`开始打包环境: ${env}`)
const buildProcess = spawn(`npm run build:${env}`, {
shell: true,
stdio: "inherit",
})
buildProcess.on("exit", async code => {
if (code !== 0) {
console.error(`打包失败,退出代码: ${code}`)
return
}
console.log("打包完成!")
const { shouldZip } = await prompt([
{
type: "confirm",
name: "shouldZip",
message: "是否打包为zip?",
default: true,
},
])
if (shouldZip) {
const { zipFolder, zipName } = await prompt([
{
type: "input",
name: "zipFolder",
message: "请输入要打包的文件夹路径:",
default: "./dist",
},
{
type: "input",
name: "zipName",
message: "请输入zip文件名:",
default: `dist.zip`,
},
])
createZipFromFolder(zipFolder, zipName)
}
})
}
run()
添加压缩命令
js
// ./build/compress.js
const JSZip = require("jszip")
const path = require("path")
const fs = require("fs")
const { promisify } = require("util")
const zip = new JSZip()
// 将 fs 的回调方法转为 Promise 形式
const readdir = promisify(fs.readdir)
const stat = promisify(fs.stat)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const unlink = promisify(fs.unlink)
const access = promisify(fs.access)
// 递归添加文件夹内容到 zip
const addFolderToZip = async (zip, folderPath, zipFolderPath = "") => {
const files = await readdir(folderPath)
for (const fileName of files) {
const fullPath = path.join(folderPath, fileName)
const fileStat = await stat(fullPath)
if (fileStat.isDirectory()) {
// 如果是文件夹,递归添加
const folderZip = zip.folder(zipFolderPath + fileName + "/")
await addFolderToZip(folderZip, fullPath)
} else {
// 如果是文件,添加到 zip
const fileData = await readFile(fullPath)
zip.file(zipFolderPath + fileName, fileData)
}
}
}
// 创建 ZIP 文件
module.exports.createZipFromFolder = async (folderPath, outputZipPath) => {
try {
// 检查文件夹是否存在
await access(folderPath, fs.constants.F_OK)
} catch (err) {
console.error("错误: 文件夹路径不存在:", folderPath)
return
}
try {
// 如果 ZIP 文件已存在,先删除它
await access(outputZipPath, fs.constants.F_OK)
await unlink(outputZipPath)
console.log("覆盖已有的 ZIP 文件:", outputZipPath)
} catch (err) {
// 如果文件不存在,忽略错误
}
// 获取文件夹名称并将其作为 zipFolderPath
const folderName = path.basename(folderPath)
// 创建一个顶层文件夹
const folderZip = zip.folder(folderName)
// 递归添加文件夹内容
await addFolderToZip(folderZip, folderPath)
// 生成 ZIP 文件内容并保存
const zipContent = await zip.generateAsync({ type: "nodebuffer" })
await writeFile(outputZipPath, zipContent)
console.log("ZIP 文件创建成功:", outputZipPath)
}
// 使用示例
// const folderPath = '../dist';
// const outputZipPath = '../dist.zip';
// module.exports.createZipFromFolder(folderPath, outputZipPath).catch(err => {
// console.error('发生错误:', err);
// });