Files
2025-12-28 08:13:13 +08:00

192 lines
5.9 KiB
JavaScript
Raw Permalink 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 { parentPort, workerData } = require('worker_threads');
const fs = require('fs');
// 检查是否在 Worker 环境中
const isWorker = typeof parentPort !== 'undefined' && workerData;
if (!isWorker) {
console.log('⚠️ Worker script must be run with worker threads');
process.exit(0);
}
const { inputPath, useOllama, OLLAMA_CONFIG } = workerData;
// 本地备用方法
function removeConsoleLocally(jsCode) {
return jsCode
.replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, '')
.replace(/\/\*[\s\S]*?\*\//g, '')
.replace(/\/\/.*$/gm, '');
}
// 简单的fetch polyfill当node-fetch不可用时
async function simpleFetch(url, options) {
const https = require('https');
const http = require('http');
const urlObj = new URL(url);
return new Promise((resolve, reject) => {
const lib = urlObj.protocol === 'https:' ? https : http;
const req = lib.request(url, options, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
resolve({
ok: res.statusCode >= 200 && res.statusCode < 300,
json: async () => JSON.parse(data),
text: async () => data,
status: res.statusCode,
statusText: res.statusMessage
});
});
});
req.on('error', reject);
if (options.body) {
req.write(options.body);
}
req.end();
});
}
async function removeConsoleWithOllama(jsCode) {
const prompt = `Please remove all console statements from this JavaScript code while preserving the code structure and functionality. Only remove console.log, console.error, console.warn, console.info, console.debug, console.assert, console.trace, console.table, console.group, console.groupEnd, console.time, console.timeEnd calls. Return only the cleaned code without any explanations.
JavaScript code:
\`\`\`javascript
${jsCode}
\`\`\`
`;
try {
const response = await simpleFetch(`${OLLAMA_CONFIG.baseUrl}/api/generate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: OLLAMA_CONFIG.model,
prompt: prompt,
stream: false,
options: {
temperature: 0.1,
top_p: 0.9,
max_tokens: 8000
}
})
});
if (!response.ok) {
throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
if (!data.response) {
throw new Error('No response from Ollama');
}
let cleanedCode = data.response.trim();
if (cleanedCode.startsWith('```')) {
const lines = cleanedCode.split('\n');
if (lines[0].includes('javascript')) {
lines.shift();
} else {
lines.shift();
}
if (lines[lines.length - 1] === '```') {
lines.pop();
}
cleanedCode = lines.join('\n');
}
return cleanedCode;
} catch (error) {
throw error;
}
}
// 检查语法错误避免Worker线程崩溃
function hasSyntaxErrors(code) {
const lines = code.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
// 检查常见的webpack打包错误模式
if (line.includes('p[s][0]') && !line.includes('p[s][0];')) {
return true;
}
// 检查未闭合的正则表达式
if (line.match(/\/[^\/\*]*$/)) {
return true;
}
}
return false;
}
async function processFile() {
try {
const originalCode = fs.readFileSync(inputPath, 'utf8');
// 检查语法错误
if (hasSyntaxErrors(originalCode)) {
return {
success: false,
error: 'Syntax errors detected in original code, skipping processing',
skipped: true
};
}
let cleanedCode;
let processingMethod;
if (useOllama) {
// 尝试使用Ollama
try {
cleanedCode = await removeConsoleWithOllama(originalCode);
processingMethod = 'ollama';
} catch (ollamaError) {
// Ollama失败使用本地方法
console.log('Ollama failed, using local method:', ollamaError.message);
cleanedCode = removeConsoleLocally(originalCode);
processingMethod = 'local-fallback';
}
} else {
// 直接使用本地方法
cleanedCode = removeConsoleLocally(originalCode);
processingMethod = 'local';
}
// 计算压缩效果
const sizeReduction = originalCode.length - cleanedCode.length;
const compressionRatio = originalCode.length > 0 ?
((sizeReduction / originalCode.length) * 100).toFixed(2) : 0;
return {
success: true,
cleanedCode,
processingMethod,
stats: {
originalSize: originalCode.length,
processedSize: cleanedCode.length,
sizeReduction,
compressionRatio: parseFloat(compressionRatio)
}
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
// Worker消息处理
processFile().then(result => {
parentPort.postMessage(result);
}).catch(error => {
parentPort.postMessage({ success: false, error: error.message });
});