chore(release.js): 当前发布程序
This commit is contained in:
168
release.js
168
release.js
@@ -49,24 +49,79 @@ function compressWxml(content) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 定义js压缩函数 - 使用Terser去除console语句
|
||||
// 检测代码是否已被压缩
|
||||
function isCodeCompressed(content) {
|
||||
// 如果代码没有换行符或换行符很少,很可能是已压缩的
|
||||
const lineBreaks = (content.match(/\n/g) || []).length;
|
||||
const hasManyLineBreaks = lineBreaks > content.length / 50; // 平均每50个字符至少有一个换行
|
||||
|
||||
// 如果代码有很多连续的分号或逗号,很可能是已压缩的
|
||||
const hasManyConsecutiveSemicolons = /;{2,}/.test(content);
|
||||
const hasManyConsecutiveCommas = /,{2,}/.test(content);
|
||||
|
||||
// 如果代码没有注释,很可能是已压缩的
|
||||
const hasComments = /\/\/|\/\*/.test(content);
|
||||
|
||||
return !hasManyLineBreaks || hasManyConsecutiveSemicolons || hasManyConsecutiveCommas || !hasComments;
|
||||
}
|
||||
|
||||
// 定义js压缩函数 - 使用Terser去除console语句、未使用变量和注释
|
||||
function compressJs(content, filePath) {
|
||||
return content;
|
||||
try {
|
||||
// 使用Terser进行压缩
|
||||
const result = minify(content, {
|
||||
// 检测代码是否已被压缩
|
||||
const isCompressed = isCodeCompressed(content);
|
||||
|
||||
// 先尝试使用正则表达式直接去除console语句
|
||||
let processedContent = content;
|
||||
|
||||
// 匹配完整的console函数调用,支持嵌套括号
|
||||
const consoleRegex = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd|assert|clear|count|countReset|group|groupCollapsed|groupEnd|memory|profile|profileEnd|timeStamp)\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*;/gi;
|
||||
processedContent = processedContent.replace(consoleRegex, '');
|
||||
|
||||
// 配置基础压缩选项
|
||||
const baseOptions = {
|
||||
compress: {
|
||||
drop_console: true, // 去除所有console语句
|
||||
drop_debugger: true, // 去除debugger语句
|
||||
dead_code: true,
|
||||
passes: 3 // 增加压缩次数
|
||||
dead_code: true, // 移除死代码
|
||||
unused: true, // 移除未使用的变量
|
||||
toplevel: true, // 清理顶层作用域未使用的变量
|
||||
passes: isCompressed ? 15 : 10, // 大幅增加压缩次数
|
||||
reduce_funcs: true, // 合并或移除未使用的函数
|
||||
collapse_vars: true, // 折叠定义后不再修改的变量
|
||||
sequences: true, // 合并连续的变量声明
|
||||
evaluate: true, // 提前计算常量表达式
|
||||
unsafe: true, // 已压缩代码启用更激进的压缩策略
|
||||
unsafe_comps: true, // 优化比较操作
|
||||
reduce_vars: true, // 合并或移除变量
|
||||
join_vars: true, // 合并变量声明
|
||||
side_effects: false, // 假设函数调用没有副作用
|
||||
pure_funcs: ['console.log', 'console.warn', 'console.error', 'console.info', 'console.debug'], // 标记这些函数为纯函数,可以安全移除
|
||||
pure_getters: true, // 假设getter函数没有副作用
|
||||
unsafe_math: true, // 允许不安全的数学优化
|
||||
unsafe_proto: true, // 允许不安全的原型优化
|
||||
unsafe_regexp: true, // 允许不安全的正则表达式优化
|
||||
conditionals: true, // 优化条件表达式
|
||||
comparisons: true, // 优化比较操作
|
||||
booleans: true, // 优化布尔表达式
|
||||
typeofs: true // 优化typeof操作
|
||||
},
|
||||
mangle: false, // 不混淆变量名,保持代码可读性
|
||||
output: {
|
||||
format: {
|
||||
ascii_only: true, // 确保输出ASCII字符
|
||||
comments: false // 去除所有注释
|
||||
comments: false, // 去除所有注释
|
||||
beautify: false // 不美化输出
|
||||
},
|
||||
// 为已压缩代码启用更严格的处理
|
||||
parse: {
|
||||
bare_returns: true, // 允许顶级return语句
|
||||
expression: false // 禁用表达式模式
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 使用Terser进行压缩
|
||||
const result = minify(processedContent, baseOptions);
|
||||
|
||||
if (result.error) {
|
||||
console.warn('Terser compression failed for', filePath, ':', result.error.message);
|
||||
@@ -153,6 +208,87 @@ function outputJsCompressionStats() {
|
||||
console.log('=====================================');
|
||||
}
|
||||
|
||||
// 递归处理dist目录下已有的JS文件,再次压缩以去除console语句、未使用变量和注释
|
||||
function processExistingJsFiles(distDir) {
|
||||
console.log(`Processing directory: ${distDir}`);
|
||||
const files = fs.readdirSync(distDir);
|
||||
console.log(`Found files: ${files.join(', ')}`);
|
||||
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(distDir, file);
|
||||
const stats = fs.statSync(filePath);
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
// 递归处理子目录
|
||||
processExistingJsFiles(filePath);
|
||||
} else if (path.extname(file) === '.js') {
|
||||
// 处理JS文件
|
||||
console.log(`Found JS file: ${filePath}`);
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, { encoding: 'utf8' });
|
||||
|
||||
// 检测是否包含console语句
|
||||
const hasConsole = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd)/i.test(content);
|
||||
if (hasConsole) {
|
||||
filesWithConsole.push(filePath);
|
||||
}
|
||||
|
||||
// 直接使用正则表达式去除console语句(优化版本,减少复杂度)
|
||||
let processedContent = content;
|
||||
|
||||
// 匹配完整的console函数调用,支持嵌套括号
|
||||
const consoleRegex = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd|assert|clear|count|countReset|group|groupCollapsed|groupEnd|memory|profile|profileEnd|timeStamp)\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*;/gi;
|
||||
processedContent = processedContent.replace(consoleRegex, '');
|
||||
|
||||
// 去除单行注释
|
||||
processedContent = processedContent.replace(/\/\/.*$/gm, '');
|
||||
|
||||
// 去除多行注释(优化版本,避免过度匹配)
|
||||
processedContent = processedContent.replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
|
||||
// 然后再使用terser进行压缩
|
||||
const compressedContent = compressJs(processedContent, filePath);
|
||||
|
||||
// 检测压缩后是否仍包含console语句
|
||||
const hasConsoleAfterCompression = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd)/i.test(compressedContent);
|
||||
if (hasConsoleAfterCompression) {
|
||||
filesWithConsoleAfterCompression.push({ sourcePath: filePath, targetPath: filePath });
|
||||
}
|
||||
|
||||
// 确保即使内容变化很小也要写入文件
|
||||
const finalContent = compressedContent;
|
||||
|
||||
// 写入文件(无论是否有变化)
|
||||
fs.writeFileSync(filePath, finalContent, { encoding: 'utf8' });
|
||||
console.log(`Processed: ${filePath}`);
|
||||
|
||||
// 更新统计信息
|
||||
const originalSize = Buffer.from(content).length;
|
||||
const compressedSize = Buffer.from(finalContent).length;
|
||||
const sizeDiff = originalSize - compressedSize;
|
||||
const compressionRatio = originalSize > 0 ? (sizeDiff / originalSize * 100).toFixed(2) : '0.00';
|
||||
|
||||
totalJsOriginalSize += originalSize;
|
||||
totalJsCompressedSize += compressedSize;
|
||||
jsFileCount++;
|
||||
jsSizeDetails.push({
|
||||
path: filePath,
|
||||
originalSize,
|
||||
compressedSize,
|
||||
sizeDiff,
|
||||
compressionRatio
|
||||
});
|
||||
|
||||
console.log(` Original: ${originalSize} bytes`);
|
||||
console.log(` Compressed: ${compressedSize} bytes`);
|
||||
console.log(` Saved: ${sizeDiff} bytes (-${compressionRatio}%)`);
|
||||
} catch (error) {
|
||||
console.error(`Error processing file ${filePath}:`, error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 递归复制目录并压缩文件(wxml, js, css, json)
|
||||
function copyAndCompressDir(sourceDir, targetDir) {
|
||||
// 创建目标目录
|
||||
@@ -306,20 +442,31 @@ function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const keepDist = args.includes('--keep-dist') || args.includes('-k');
|
||||
const noZip = args.includes('--no-zip') || args.includes('-n');
|
||||
const onlyProcessDist = args.includes('--only-process-dist') || args.includes('-p'); // 只处理dist目录下已有的JS文件
|
||||
|
||||
// 清理dist目录(如果存在且不保留)
|
||||
if (fs.existsSync(distDir)) {
|
||||
if (!keepDist && !onlyProcessDist) {
|
||||
cleanDistDir(distDir);
|
||||
}
|
||||
} else {
|
||||
// 创建dist目录
|
||||
fs.mkdirSync(distDir, { recursive: true });
|
||||
console.log('Created dist directory');
|
||||
}
|
||||
|
||||
// 根据参数决定执行哪种流程
|
||||
if (onlyProcessDist) {
|
||||
// 只处理dist目录下已有的JS文件
|
||||
console.log('Start processing existing JS files in dist directory...');
|
||||
processExistingJsFiles(distDir);
|
||||
console.log('Processing existing JS files completed!');
|
||||
} else {
|
||||
// 复制并压缩文件到dist目录
|
||||
console.log('Start copying and compressing files...');
|
||||
copyAndCompressDir(rootDir, distDir);
|
||||
console.log('Files copied and compressed successfully!');
|
||||
}
|
||||
|
||||
// 输出JS文件压缩统计结果
|
||||
outputJsCompressionStats();
|
||||
@@ -337,8 +484,8 @@ function main() {
|
||||
console.log('Skipping zip archive creation (--no-zip specified)');
|
||||
}
|
||||
|
||||
// 清理dist目录(如果不保留)
|
||||
if (!keepDist) {
|
||||
// 清理dist目录(如果不保留且不是只处理dist目录)
|
||||
if (!keepDist && !onlyProcessDist) {
|
||||
cleanDistDir(distDir);
|
||||
}
|
||||
|
||||
@@ -396,5 +543,6 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
||||
console.log('Options:');
|
||||
console.log(' --keep-dist, -k Keep existing dist directory contents');
|
||||
console.log(' --no-zip, -n Skip zip archive creation');
|
||||
console.log(' --only-process-dist, -p Only process existing JS files in dist directory');
|
||||
console.log(' --help, -h Show this help message');
|
||||
}
|
||||
Reference in New Issue
Block a user