Files
mp-weixin-2811-xcx.aigc-qui…/release.js

308 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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'];
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(/<!--[\s\S]*?-->/g, '');
// 移除多余的空白字符(空格、换行、制表符)
// 保留标签内的必要空格
content = content.replace(/\s+/g, ' ');
// 移除标签前后的空格
content = content.replace(/\s*</g, '<');
content = content.replace(/>\s*/g, '>');
return content;
}
// 定义js压缩函数 - 采用更安全的压缩策略,接近微信小程序开发工具的压缩方式
function compressJs(content) {
// 移除单行注释
content = content.replace(/\/\/.*$/gm, '');
// 移除多行注释
content = content.replace(/\/\*[\s\S]*?\*\//g, '');
// 移除行尾多余的空白字符
content = content.replace(/\s+$/gm, '');
// 移除多余的空行,只保留必要的换行
content = content.replace(/\n{2,}/g, '\n');
// 保存所有require语句避免压缩时破坏模块路径
const requireStatements = [];
let requireIndex = 0;
content = content.replace(/require\s*\([^)]+\)/g, (match) => {
const placeholder = `__REQUIRE_PLACEHOLDER_${requireIndex}__`;
requireStatements.push({ placeholder, content: match });
requireIndex++;
return placeholder;
});
// 在适当的位置添加分号,避免语法错误
// 只在特定情况下添加分号
// 1. 处理return、break、continue、throw等语句
content = content.replace(/(return|break|continue|throw)\s*(.*?)\n/g, '$1 $2;\n');
// 2. 处理变量声明和赋值(简单情况)
content = content.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*\s*=\s*[^;\n]+)\n/g, '$1;\n');
// 3. 处理函数调用
content = content.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*\s*\([^;\n]+\))\n/g, '$1;\n');
// 移除语句之间多余的空白字符,但保留必要的空格
content = content.replace(/\s*\{\s*/g, '{');
content = content.replace(/\s*\}\s*/g, '}');
content = content.replace(/\s*;\s*/g, ';');
content = content.replace(/\s*,\s*/g, ',');
content = content.replace(/\s*=\s*/g, '=');
content = content.replace(/\s*\+\s*/g, '+');
content = content.replace(/\s*-\s*/g, '-');
content = content.replace(/\s*\*\s*/g, '*');
content = content.replace(/\s*\/\s*/g, '/');
content = content.replace(/\s*\[\s*/g, '[');
content = content.replace(/\s*\]\s*/g, ']');
// 移除多余的分号
content = content.replace(/;;+/g, ';');
// 移除多余的空白字符(连续的空格只保留一个)
content = content.replace(/\s+/g, ' ');
// 恢复之前保存的require语句
requireStatements.forEach(({ placeholder, content: requireContent }) => {
content = content.replace(placeholder, requireContent + ';');
});
// 移除文件开头和结尾的分号
content = content.replace(/^;|;$/g, '');
// 移除所有多余的空格
content = content.replace(/\s+/g, '');
// 确保最后一个require语句也有分号
content = content.replace(/require\([^)]+\)$/, '$&;');
return content;
}
// 定义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, content, { 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文件名格式数码喷墨墨水-定制化-YYYY-MM-DD-mp-weixin.zip
const currentDate = getCurrentDate();
const zipFileName = `数码喷墨墨水-定制化-${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');
}