AlipayEventSourceFixPlugin.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const fs = require('fs');
  2. const path = require('path');
  3. class AlipayEventSourceFixPlugin {
  4. apply(compiler) {
  5. compiler.hooks.afterEmit.tapAsync('AlipayEventSourceFixPlugin', (compilation, callback) => {
  6. this.fixEventSource();
  7. callback();
  8. });
  9. }
  10. fixEventSource() {
  11. const taroJsPath = path.join(process.cwd(), 'dist', 'taro.js');
  12. if (!fs.existsSync(taroJsPath)) {
  13. console.log('AlipayEventSourceFixPlugin: dist/taro.js not found');
  14. return;
  15. }
  16. console.log('AlipayEventSourceFixPlugin: Fixing EventSource in dist/taro.js...');
  17. let content = fs.readFileSync(taroJsPath, 'utf8');
  18. let replaced = false;
  19. // 新策略: Taro 4.x 压缩后的 EventSource (class X extends Map with removeNode)
  20. if (content.includes('extends Map{removeNode(')) {
  21. console.log('AlipayEventSourceFixPlugin: Found minified EventSource (extends Map with removeNode)');
  22. const minifiedPattern =
  23. /class \w+ extends Map\{removeNode\([\s\S]*?removeNodeTree\([\s\S]*?\}\}const r=new \w+/g;
  24. if (minifiedPattern.test(content)) {
  25. const replacement =
  26. 'class EventSource{data={};get(e){return this.data[e]};set(e,t){this.data[e]=t};delete(e){delete this.data[e]};has(e){return e in this.data};removeNode(e){const{sid:t,uid:n}=e;this.delete(t);n!==t&&n&&this.delete(n)};removeNodeTree(e){this.removeNode(e);const{childNodes:t}=e;t.forEach(e=>this.removeNodeTree(e))}}const r=new EventSource';
  27. content = content.replace(minifiedPattern, replacement);
  28. fs.writeFileSync(taroJsPath, content, 'utf8');
  29. console.log('AlipayEventSourceFixPlugin: Success: Minified EventSource replaced');
  30. replaced = true;
  31. }
  32. }
  33. // 原有策略: 处理未压缩的 EventSource
  34. if (!replaced && content.includes('EventSource')) {
  35. console.log('AlipayEventSourceFixPlugin: Found EventSource in dist/taro.js');
  36. const newEventSource =
  37. '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}';
  38. // 方式1:查找并替换event-source.js模块
  39. const eventSourceModulePattern =
  40. /\/\*\*\*\.\/node_modules\/@tarojs\/runtime\/dist\/dom\/event-source\.js[\s\S]*?class EventSource[\s\S]*?\/\*\*\*\/\s*\}\);/g;
  41. if (eventSourceModulePattern.test(content)) {
  42. console.log('AlipayEventSourceFixPlugin: Found event-source.js module');
  43. const matches = content.match(eventSourceModulePattern);
  44. if (matches && matches.length > 0) {
  45. const oldModule = matches[0];
  46. const moduleStart = oldModule.substring(0, oldModule.indexOf('class EventSource'));
  47. const moduleEnd = oldModule.substring(oldModule.lastIndexOf('*/') + 2);
  48. const newModule = moduleStart + newEventSource + moduleEnd;
  49. content = content.replace(oldModule, newModule);
  50. fs.writeFileSync(taroJsPath, content, 'utf8');
  51. console.log('AlipayEventSourceFixPlugin: Success: EventSource module replaced');
  52. replaced = true;
  53. }
  54. }
  55. // 方式2:直接查找EventSource类定义
  56. if (!replaced) {
  57. const eventSourceStart = content.indexOf('class EventSource');
  58. if (eventSourceStart !== -1) {
  59. console.log('AlipayEventSourceFixPlugin: Found EventSource class');
  60. let braceCount = 0;
  61. let eventSourceEnd = eventSourceStart;
  62. let foundOpeningBrace = false;
  63. for (let i = eventSourceStart; i < content.length; i++) {
  64. if (content[i] === '{') {
  65. braceCount++;
  66. foundOpeningBrace = true;
  67. } else if (content[i] === '}') {
  68. braceCount--;
  69. if (foundOpeningBrace && braceCount === 0) {
  70. eventSourceEnd = i + 1;
  71. break;
  72. }
  73. }
  74. }
  75. if (eventSourceEnd > eventSourceStart) {
  76. const oldEventSource = content.substring(eventSourceStart, eventSourceEnd);
  77. content = content.replace(oldEventSource, newEventSource);
  78. fs.writeFileSync(taroJsPath, content, 'utf8');
  79. console.log('AlipayEventSourceFixPlugin: Success: EventSource class replaced');
  80. replaced = true;
  81. }
  82. }
  83. }
  84. if (!replaced) {
  85. console.log('AlipayEventSourceFixPlugin: Info: EventSource not found or could not be replaced');
  86. }
  87. }
  88. if (!replaced) {
  89. console.log('AlipayEventSourceFixPlugin: Info: No EventSource pattern found in dist/taro.js');
  90. }
  91. }
  92. }
  93. module.exports = AlipayEventSourceFixPlugin;