chore: 优化发布微信小程序的脚本配置
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release-mp-weixin": "node scripts/mp-weixin.patch.js"
|
"mp-weixin": "node scripts/mp-weixin.patch.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"terser-webpack-plugin": "^5.3.10"
|
"terser-webpack-plugin": "^5.3.10"
|
||||||
|
|||||||
58
scripts/create-zip.js
Normal file
58
scripts/create-zip.js
Normal 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
|
||||||
|
}
|
||||||
@@ -20,9 +20,8 @@ const fs = require('fs');
|
|||||||
const fsp = fs.promises;
|
const fsp = fs.promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const { exec } = require('child_process');
|
const { openFileDirectory } = require('./open-directory');
|
||||||
const { promisify } = require('util');
|
const { createZipWithSystemCommand } = require('./create-zip');
|
||||||
const execAsync = promisify(exec);
|
|
||||||
|
|
||||||
async function commonPatch(mode = 'production') {
|
async function commonPatch(mode = 'production') {
|
||||||
try {
|
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() {
|
async function main() {
|
||||||
// 1) 打补丁
|
// 1) 打补丁
|
||||||
@@ -155,6 +109,9 @@ async function main() {
|
|||||||
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
|
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
|
||||||
const zipFilePath = await createZipWithSystemCommand(sourceDir, destDir);
|
const zipFilePath = await createZipWithSystemCommand(sourceDir, destDir);
|
||||||
console.log(`ZIP 文件路径: ${zipFilePath}`);
|
console.log(`ZIP 文件路径: ${zipFilePath}`);
|
||||||
|
|
||||||
|
// 3) 自动打开zip所在的目录
|
||||||
|
await openFileDirectory(zipFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exists(p) {
|
async function exists(p) {
|
||||||
|
|||||||
337
scripts/open-directory.js
Normal file
337
scripts/open-directory.js
Normal 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
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user