chore: 优化发布微信小程序的脚本配置

This commit is contained in:
2025-10-31 11:25:52 +08:00
parent 6673a494cf
commit ed4b969fd1
4 changed files with 401 additions and 49 deletions

View File

@@ -1,6 +1,6 @@
{
"scripts": {
"release-mp-weixin": "node scripts/mp-weixin.patch.js"
"mp-weixin": "node scripts/mp-weixin.patch.js"
},
"devDependencies": {
"terser-webpack-plugin": "^5.3.10"

58
scripts/create-zip.js Normal file
View File

@@ -0,0 +1,58 @@
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
/**
* 使用系统命令创建ZIP跨平台
* @param {string} sourceDir - 要压缩的目录路径
* @param {string} outputDir - 压缩文件输出目录
* @returns {Promise<string>} - 压缩文件的路径
*/
async function createZipWithSystemCommand(sourceDir, outputDir) {
// 检查源目录
if (!fs.existsSync(sourceDir)) {
throw new Error(`源目录不存在: ${sourceDir}`);
}
// 生成文件名
const dateString = new Date().toISOString().split('T')[0];
const zipFileName = `mp-weixin-${dateString}-${new Date().getTime()}.zip`;
const zipFilePath = path.join(outputDir, zipFileName);
let command;
// 根据操作系统选择命令
if (process.platform === 'win32') {
// Windows: 使用PowerShell的Compress-Archive
const sourcePath = sourceDir.replace(/'/g, "''");
const destPath = zipFilePath.replace(/'/g, "''");
command = `powershell -Command "Compress-Archive -Path '${sourcePath}\\*' -DestinationPath '${destPath}' -Force"`;
} else {
// Linux/Mac: 使用zip命令
const sourceBase = path.dirname(sourceDir);
const sourceName = path.basename(sourceDir);
command = `cd '${sourceBase}' && zip -r '${zipFilePath}' '${sourceName}' -x '*/node_modules/*' '*.git/*' '*.DS_Store' '*.log'`;
}
try {
console.log(`执行命令: ${command}`);
const { stdout, stderr } = await execAsync(command);
if (stderr) {
console.warn('警告:', stderr);
}
console.log(`✅ ZIP文件创建完成: ${zipFileName}`);
return zipFilePath;
} catch (error) {
throw new Error(`系统命令执行失败: ${error.message}`);
}
}
module.exports = {
createZipWithSystemCommand
}

View File

@@ -20,9 +20,8 @@ const fs = require('fs');
const fsp = fs.promises;
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
const { openFileDirectory } = require('./open-directory');
const { createZipWithSystemCommand } = require('./create-zip');
async function commonPatch(mode = 'production') {
try {
@@ -97,52 +96,7 @@ async function commonPatch(mode = 'production') {
}
}
/**
* 使用系统命令创建ZIP跨平台
* @param {string} sourceDir - 要压缩的目录路径
* @param {string} outputDir - 压缩文件输出目录
* @returns {Promise<string>} - 压缩文件的路径
*/
async function createZipWithSystemCommand(sourceDir, outputDir) {
// 检查源目录
if (!fs.existsSync(sourceDir)) {
throw new Error(`源目录不存在: ${sourceDir}`);
}
// 生成文件名
const dateString = new Date().toISOString().split('T')[0];
const zipFileName = `mp-weixin-${dateString}-${new Date().getTime()}.zip`;
const zipFilePath = path.join(outputDir, zipFileName);
let command;
// 根据操作系统选择命令
if (process.platform === 'win32') {
// Windows: 使用PowerShell的Compress-Archive
const sourcePath = sourceDir.replace(/'/g, "''");
const destPath = zipFilePath.replace(/'/g, "''");
command = `powershell -Command "Compress-Archive -Path '${sourcePath}\\*' -DestinationPath '${destPath}' -Force"`;
} else {
// Linux/Mac: 使用zip命令
const sourceBase = path.dirname(sourceDir);
const sourceName = path.basename(sourceDir);
command = `cd '${sourceBase}' && zip -r '${zipFilePath}' '${sourceName}' -x '*/node_modules/*' '*.git/*' '*.DS_Store' '*.log'`;
}
try {
console.log(`执行命令: ${command}`);
const { stdout, stderr } = await execAsync(command);
if (stderr) {
console.warn('警告:', stderr);
}
console.log(`✅ ZIP文件创建完成: ${zipFileName}`);
return zipFilePath;
} catch (error) {
throw new Error(`系统命令执行失败: ${error.message}`);
}
}
async function main() {
// 1) 打补丁
@@ -155,6 +109,9 @@ async function main() {
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
const zipFilePath = await createZipWithSystemCommand(sourceDir, destDir);
console.log(`ZIP 文件路径: ${zipFilePath}`);
// 3) 自动打开zip所在的目录
await openFileDirectory(zipFilePath);
}
async function exists(p) {

337
scripts/open-directory.js Normal file
View File

@@ -0,0 +1,337 @@
const { exec, spawn } = require('child_process');
const { promisify } = require('util');
const path = require('path');
const fs = require('fs');
const execAsync = promisify(exec);
/**
* 检测当前操作系统
*/
function getOSPlatform() {
const platform = process.platform;
if (platform === 'win32') return 'windows';
if (platform === 'darwin') return 'macos';
if (platform === 'linux') return 'linux';
return 'unknown';
}
/**
* 检查文件或目录是否存在
*/
function checkPathExists(targetPath) {
try {
fs.accessSync(targetPath);
return true;
} catch (error) {
return false;
}
}
/**
* 获取目录路径(如果是文件则返回所在目录)
*/
function getDirectoryPath(targetPath) {
try {
const stats = fs.statSync(targetPath);
if (stats.isFile()) {
return path.dirname(targetPath);
}
if (stats.isDirectory()) {
return targetPath;
}
} catch (error) {
throw new Error(`路径不存在或无法访问: ${targetPath}`);
}
return targetPath;
}
/**
* 在 Windows 系统打开目录
*/
async function openDirectoryWindows(directoryPath) {
// 确保路径使用反斜杠
const normalizedPath = directoryPath.replace(/\//g, '\\');
console.log(`📁 在文件资源管理器中打开: ${normalizedPath}`);
// 方法1: 使用 explorer 命令
try {
const command = `explorer "${normalizedPath}"`;
await execAsync(command);
console.log('✅ 已启动文件资源管理器');
return true;
} catch (error) {
console.warn('方法1失败:', error.message);
}
// 方法2: 使用 start 命令
try {
const command = `start "" "${normalizedPath}"`;
await execAsync(command);
console.log('✅ 已使用 start 命令打开');
return true;
} catch (error) {
console.warn('方法2失败:', error.message);
}
throw new Error('无法在Windows系统中打开目录');
}
/**
* 在 macOS 系统打开目录
*/
async function openDirectoryMacOS(directoryPath) {
console.log(`📁 在访达中打开: ${directoryPath}`);
// 方法1: 使用 open 命令
try {
const command = `open "${directoryPath}"`;
await execAsync(command);
console.log('✅ 已启动访达');
return true;
} catch (error) {
console.warn('方法1失败:', error.message);
}
// 方法2: 使用 open -R 命令(打开包含指定文件的文件夹)
try {
const command = `open -R "${directoryPath}"`;
await execAsync(command);
console.log('✅ 已使用 open -R 命令打开');
return true;
} catch (error) {
console.warn('方法2失败:', error.message);
}
throw new Error('无法在macOS系统中打开目录');
}
/**
* 在 Linux 系统打开目录
*/
async function openDirectoryLinux(directoryPath) {
console.log(`📁 在文件管理器中打开: ${directoryPath}`);
// 尝试不同的文件管理器
const fileManagers = [
'xdg-open', // 标准Linux桌面打开方式
'nautilus', // GNOME
'dolphin', // KDE
'thunar', // XFCE
'pcmanfm', // LXDE
'nemo', // Cinnamon
'caja' // MATE
];
for (const manager of fileManagers) {
try {
// 检查文件管理器是否可用
await execAsync(`which ${manager}`);
const command = `${manager} "${directoryPath}"`;
const child = spawn(manager, [directoryPath], {
stdio: 'ignore',
detached: true
});
child.unref();
console.log(`✅ 已使用 ${manager} 打开目录`);
return true;
} catch (error) {
// 继续尝试下一个文件管理器
continue;
}
}
// 最后尝试 xdg-open最通用的方式
try {
const command = `xdg-open "${directoryPath}"`;
const child = spawn('xdg-open', [directoryPath], {
stdio: 'ignore',
detached: true
});
child.unref();
console.log('✅ 已使用 xdg-open 打开目录');
return true;
} catch (error) {
throw new Error('无法在Linux系统中打开目录请确保已安装文件管理器');
}
}
/**
* 在终端中打开目录(跨平台)
*/
async function openDirectoryInTerminal(directoryPath) {
const os = getOSPlatform();
const dirPath = getDirectoryPath(directoryPath);
console.log(`💻 操作系统: ${os}`);
console.log(`📂 目标目录: ${dirPath}`);
if (!checkPathExists(dirPath)) {
throw new Error(`路径不存在: ${dirPath}`);
}
switch (os) {
case 'windows':
return await openDirectoryWindows(dirPath);
case 'macos':
return await openDirectoryMacOS(dirPath);
case 'linux':
return await openDirectoryLinux(dirPath);
default:
throw new Error(`不支持的操作系统: ${process.platform}`);
}
}
/**
* 在系统默认终端中打开并切换到目录
*/
async function openTerminalInDirectory(directoryPath) {
const os = getOSPlatform();
const dirPath = getDirectoryPath(directoryPath);
console.log(`🖥️ 在终端中打开目录: ${dirPath}`);
if (!checkPathExists(dirPath)) {
throw new Error(`路径不存在: ${dirPath}`);
}
const commands = {
windows: `start cmd /K "cd /d "${dirPath}" && echo 当前目录: %cd%"`,
macos: `osascript -e 'tell application "Terminal" to do script "cd \\\"${dirPath}\\\" && pwd"'`,
linux: `gnome-terminal --working-directory="${dirPath}" || konsole --workdir "${dirPath}" || xterm -e "cd \\"${dirPath}\\" && bash"`
};
try {
let command;
switch (os) {
case 'windows':
command = commands.windows;
break;
case 'macos':
command = commands.macos;
break;
case 'linux':
command = commands.linux;
break;
default:
throw new Error('不支持的操作系统');
}
// 使用 spawn 避免命令注入漏洞
const shell = os === 'windows' ? 'cmd.exe' : '/bin/bash';
const args = os === 'windows' ? ['/c', command] : ['-c', command];
const child = spawn(shell, args, {
stdio: 'ignore',
detached: true
});
child.unref();
console.log('✅ 已启动终端并切换到目录');
return true;
} catch (error) {
console.warn('无法在终端中打开目录:', error.message);
return false;
}
}
/**
* 主函数 - 打开文件所在目录
*/
async function openFileDirectory(filePath, options = {}) {
const {
openInTerminal = false, // 是否在终端中打开
createIfNotExists = false, // 目录不存在时是否创建
wait = false // 是否等待进程结束
} = options;
try {
// 检查路径是否存在
if (!checkPathExists(filePath)) {
if (createIfNotExists) {
const dirPath = path.dirname(filePath);
fs.mkdirSync(dirPath, { recursive: true });
console.log(`📁 创建目录: ${dirPath}`);
} else {
throw new Error(`路径不存在: ${filePath}`);
}
}
const directoryPath = getDirectoryPath(filePath);
if (openInTerminal) {
await openTerminalInDirectory(directoryPath);
} else {
await openDirectoryInTerminal(directoryPath);
}
return true;
} catch (error) {
console.error('❌ 打开目录失败:', error.message);
return false;
}
}
/**
* 使用示例
*/
async function main() {
// 示例1: 打开当前脚本所在目录
const currentFile = __filename;
console.log('当前文件:', currentFile);
// 方法1: 在文件管理器中打开
console.log('\n--- 在文件管理器中打开 ---');
await openFileDirectory(currentFile);
// 等待2秒
await new Promise(resolve => setTimeout(resolve, 2000));
// 方法2: 在终端中打开(可选)
console.log('\n--- 在终端中打开 ---');
await openFileDirectory(currentFile, { openInTerminal: true });
}
// 命令行使用方式
if (require.main === module) {
const args = process.argv.slice(2);
if (args.length === 0) {
// 没有参数,打开当前目录
openFileDirectory(process.cwd())
.then(success => {
if (!success) process.exit(1);
})
.catch(error => {
console.error('错误:', error.message);
process.exit(1);
});
} else {
const filePath = path.resolve(args[0]);
const options = {
openInTerminal: args.includes('--terminal') || args.includes('-t'),
createIfNotExists: args.includes('--create') || args.includes('-c')
};
openFileDirectory(filePath, options)
.then(success => {
if (!success) process.exit(1);
})
.catch(error => {
console.error('错误:', error.message);
process.exit(1);
});
}
}
// 导出函数
module.exports = {
openFileDirectory,
openDirectoryInTerminal,
openTerminalInDirectory,
getOSPlatform
};