const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); // 定义项目根目录 const rootDir = __dirname; // 定义输出目录 const distDir = path.join(rootDir, 'dist'); // 定义要排除的目录和文件 const excludeDirs = ['node_modules', '.git', 'dist', '.vscode', 'scripts']; const excludeFiles = ['.gitignore', 'package-lock.json', 'yarn.lock', 'release.js', 'README.md']; // 获取当前日期,用于生成zip文件名(格式:YYYY-MM-DD) function getCurrentDate() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } // 定义wxml压缩函数 function compressWxml(content) { // 移除HTML注释 content = content.replace(//g, ''); // 移除多余的空白字符(空格、换行、制表符) // 保留标签内的必要空格 content = content.replace(/\s+/g, ' '); // 移除标签前后的空格 content = content.replace(/\s*\s*/g, '>'); return content; } // 定义js压缩函数 - 安全处理已压缩文件,去除真正多余的内容 function compressJs(content) { let result = content; return result; } // 定义css压缩函数 function compressCss(content) { // 移除单行注释 content = content.replace(/\/\/.*$/gm, ''); // 移除多行注释 content = content.replace(/\/\*[\s\S]*?\*\//g, ''); // 移除多余的空白字符 content = content.replace(/\s+/g, ' '); // 移除CSS属性前后的空格 content = content.replace(/\s*([{:;}])\s*/g, '$1'); // 移除行首和行尾的空格 content = content.replace(/^\s+|\s+$/gm, ''); return content; } // 定义json压缩函数 function compressJson(content) { try { // 使用JSON.parse和JSON.stringify进行压缩 // 确保中文等非ASCII字符不会被转义 const jsonObj = JSON.parse(content); return JSON.stringify(jsonObj, null, 0); } catch (error) { // 如果JSON解析失败,返回原始内容 console.warn('Failed to compress JSON, using original content:', error.message); return content; } } // 递归复制目录并压缩文件(wxml, js, css, json) function copyAndCompressDir(sourceDir, targetDir) { // 创建目标目录 if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true }); } const files = fs.readdirSync(sourceDir); files.forEach(file => { const sourcePath = path.join(sourceDir, file); const targetPath = path.join(targetDir, file); const stats = fs.statSync(sourcePath); // 跳过排除的目录和文件 if (excludeDirs.includes(file) || excludeFiles.includes(file)) { return; } if (stats.isDirectory()) { // 递归处理子目录 copyAndCompressDir(sourcePath, targetPath); } else { const extname = path.extname(file); let compressedContent; let content; try { // 根据文件类型选择不同的处理方式 if (extname === '.wxml') { // 压缩wxml文件 content = fs.readFileSync(sourcePath, { encoding: 'utf8' }); compressedContent = compressWxml(content); fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' }); console.log(`Compressed and copied: ${sourcePath}`); } else if (extname === '.js') { // 压缩js文件 content = fs.readFileSync(sourcePath, { encoding: 'utf8' }); compressedContent = compressJs(content); fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' }); console.log(`Compressed and copied: ${sourcePath}`); } else if (extname === '.css') { // 压缩css文件 content = fs.readFileSync(sourcePath, { encoding: 'utf8' }); compressedContent = compressCss(content); fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' }); console.log(`Compressed and copied: ${sourcePath}`); } else if (extname === '.json') { // 压缩json文件 content = fs.readFileSync(sourcePath, { encoding: 'utf8' }); compressedContent = compressJson(content); fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' }); console.log(`Compressed and copied: ${sourcePath}`); } else { // 直接复制其他文件 fs.copyFileSync(sourcePath, targetPath); console.log(`Copied: ${sourcePath}`); } } catch (error) { console.error(`Error processing file ${sourcePath}:`, error.message); // 发生错误时,直接复制原始文件 fs.copyFileSync(sourcePath, targetPath); console.log(`Fallback: Copied original file ${sourcePath}`); } } }); } // 使用系统命令创建zip压缩包 function createZipArchive(sourceDir, outputPath) { try { // 根据操作系统选择命令 if (process.platform === 'win32') { // Windows系统使用PowerShell命令,排除文件名后缀为 -mp-weixin.zip 的文件 // 使用PowerShell的管道功能和Where-Object来排除特定文件 const command = `PowerShell.exe -Command "Get-ChildItem -Path \"${sourceDir}\" | Where-Object { $_.Name -notlike '*\-mp\-weixin\.zip' } | Compress-Archive -DestinationPath \"${outputPath}\" -Force"`; execSync(command, { shell: 'cmd.exe' }); } else { // Linux/Mac系统使用zip命令,排除文件名后缀为 -mp-weixin.zip 的文件 const command = `zip -r \"${outputPath}\" * -x \"*-mp-weixin.zip\"`; execSync(command, { cwd: sourceDir }); } console.log(`Zip archive created: ${outputPath}`); } catch (error) { console.error('Error creating zip archive:', error.message); throw error; } } function cleanDistDir(distDir) { if (fs.existsSync(distDir)) { // 清理dist目录下除**-mp-weixin.zip文件外的所有内容 const files = fs.readdirSync(distDir); files.forEach(file => { const filePath = path.join(distDir, file); const stats = fs.statSync(filePath); // 只保留符合特定命名模式的zip文件(**-mp-weixin.zip) if (stats.isFile() && path.extname(file) === '.zip' && file.endsWith('-mp-weixin.zip')) { console.log(`Keeping zip file: ${file}`); } else { if (stats.isDirectory()) { fs.rmSync(filePath, { recursive: true, force: true }); console.log(`Removed directory: ${file}`); } else { fs.unlinkSync(filePath); console.log(`Removed file: ${file}`); } } }); console.log('Cleaned dist directory (excluding -mp-weixin.zip files)'); } } // 主函数 function main() { try { // 解析命令行参数 const args = process.argv.slice(2); const keepDist = args.includes('--keep-dist') || args.includes('-k'); // 清理dist目录(如果存在且不保留) if (fs.existsSync(distDir)) { cleanDistDir(distDir); } else { // 创建dist目录 fs.mkdirSync(distDir, { recursive: true }); console.log('Created dist directory'); } // 复制并压缩文件到dist目录 console.log('Start copying and compressing files...'); copyAndCompressDir(rootDir, distDir); console.log('Files copied and compressed successfully!'); // 生成zip文件名(格式:POCT检测分析平台-定制化-YYYY-MM-DD-mp-weixin.zip) const currentDate = getCurrentDate(); const zipFileName = `POCT检测分析平台-定制化-${currentDate}-mp-weixin.zip`; const zipPath = path.join(distDir, zipFileName); // 创建zip压缩包 console.log('Creating zip archive...'); createZipArchive(distDir, zipPath); // 清理dist目录(如果不保留) if (!keepDist) { cleanDistDir(distDir); } console.log('\nAll tasks completed successfully!'); console.log(`Dist directory: ${distDir}`); console.log(`Zip file: ${zipPath}`); } catch (error) { console.error('Error occurred:', error); process.exit(1); } } // 执行主函数 main(); // 输出帮助信息 if (process.argv.includes('--help') || process.argv.includes('-h')) { console.log('Usage: node release.js [options]'); console.log('Options:'); console.log(' --keep-dist, -k Keep existing dist directory contents'); console.log(' --help, -h Show this help message'); }