const fs = require('fs'); const path = require('path'); class AlipayEventSourceFixPlugin { apply(compiler) { // 在构建完成后执行 compiler.hooks.afterEmit.tapAsync('AlipayEventSourceFixPlugin', (compilation, callback) => { this.fixEventSource(); callback(); }); } fixEventSource() { const taroJsPath = path.join(process.cwd(), 'dist', 'taro.js'); if (!fs.existsSync(taroJsPath)) { console.log('AlipayEventSourceFixPlugin: dist/taro.js not found'); return; } console.log('AlipayEventSourceFixPlugin: Fixing EventSource in dist/taro.js...'); let content = fs.readFileSync(taroJsPath, 'utf8'); // 检查是否存在EventSource相关的代码 if (content.includes('EventSource')) { console.log('AlipayEventSourceFixPlugin: Found EventSource in dist/taro.js'); // 新的EventSource实现(使用标准格式,确保语法正确) const newEventSource = 'class EventSource {\n data = {};\n\n get(id) {\n return this.data[id];\n }\n\n set(id, value) {\n this.data[id] = value;\n }\n\n delete(id) {\n delete this.data[id];\n }\n\n has(id) {\n return id in this.data;\n }\n\n removeNode(child) {\n const { sid, uid } = child;\n this.delete(sid);\n if (uid !== sid && uid) this.delete(uid);\n }\n\n removeNodeTree(child) {\n this.removeNode(child);\n const { childNodes } = child;\n childNodes.forEach((node) => this.removeNodeTree(node));\n }\n}'; let replaced = false; // 方式1:查找并替换event-source.js模块 const eventSourceModulePattern = /\/\*\*\*\.\/node_modules\/@tarojs\/runtime\/dist\/dom\/event-source\.js[\s\S]*?class EventSource[\s\S]*?\/\*\*\*\/\s*\}\);/g; if (eventSourceModulePattern.test(content)) { console.log('AlipayEventSourceFixPlugin: Found event-source.js module'); const matches = content.match(eventSourceModulePattern); if (matches && matches.length > 0) { const oldModule = matches[0]; // 提取模块的开头部分 const moduleStart = oldModule.substring(0, oldModule.indexOf('class EventSource')); // 提取模块的结尾部分 const moduleEnd = oldModule.substring(oldModule.lastIndexOf('*/') + 2); // 构建新的模块内容 const newModule = moduleStart + newEventSource + moduleEnd; // 替换整个模块 content = content.replace(oldModule, newModule); fs.writeFileSync(taroJsPath, content, 'utf8'); console.log('AlipayEventSourceFixPlugin: Success: EventSource module replaced'); replaced = true; } } // 方式2:直接查找EventSource类定义 if (!replaced) { const eventSourceStart = content.indexOf('class EventSource'); if (eventSourceStart !== -1) { console.log('AlipayEventSourceFixPlugin: Found EventSource class'); // 查找类的结束位置 let braceCount = 0; let eventSourceEnd = eventSourceStart; let foundOpeningBrace = false; for (let i = eventSourceStart; i < content.length; i++) { if (content[i] === '{') { braceCount++; foundOpeningBrace = true; } else if (content[i] === '}') { braceCount--; if (foundOpeningBrace && braceCount === 0) { eventSourceEnd = i + 1; // 包含结束大括号 break; } } } if (eventSourceEnd > eventSourceStart) { const oldEventSource = content.substring(eventSourceStart, eventSourceEnd); // 替换为新的实现 content = content.replace(oldEventSource, newEventSource); fs.writeFileSync(taroJsPath, content, 'utf8'); console.log('AlipayEventSourceFixPlugin: Success: EventSource class replaced'); replaced = true; } } } // 方式3:处理压缩后的EventSource类 if (!replaced) { const compressedPattern = /class EventSource[^{]*\{[^}]*\{[^}]*\{[^}]*\}[^}]*\}[^}]*\}/g; if (compressedPattern.test(content)) { console.log('AlipayEventSourceFixPlugin: Found compressed EventSource'); const matches = content.match(compressedPattern); if (matches && matches.length > 0) { content = content.replace(matches[0], newEventSource); fs.writeFileSync(taroJsPath, content, 'utf8'); console.log('AlipayEventSourceFixPlugin: Success: Compressed EventSource replaced'); replaced = true; } } } // 方式4:处理语法错误的情况 if (!replaced && content.includes('class EventSource') && (content.includes('sid, uid') || content.includes('childNodes'))) { console.log('AlipayEventSourceFixPlugin: Found EventSource with potential syntax errors'); // 查找EventSource开始位置 const eventSourceStart = content.indexOf('class EventSource'); if (eventSourceStart !== -1) { // 查找一个合理的结束位置 const eventSourceEnd = content.indexOf('eventSource', eventSourceStart); if (eventSourceEnd > eventSourceStart) { // 提取从EventSource开始到eventSource变量定义之间的内容 const oldEventSource = content.substring(eventSourceStart, eventSourceEnd); // 替换为新的实现 content = content.replace(oldEventSource, newEventSource); fs.writeFileSync(taroJsPath, content, 'utf8'); console.log('AlipayEventSourceFixPlugin: Success: EventSource with syntax errors fixed'); replaced = true; } } } if (!replaced) { console.log('AlipayEventSourceFixPlugin: Info: EventSource not found or could not be replaced'); } } else { console.log('AlipayEventSourceFixPlugin: Info: No EventSource found in dist/taro.js'); } } } module.exports = AlipayEventSourceFixPlugin;