mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 02:20:10 +08:00
110 lines
4.1 KiB
JavaScript
110 lines
4.1 KiB
JavaScript
/**
|
||
* 修复 electron-builder 堆栈溢出问题的补丁脚本
|
||
*
|
||
* 这个脚本修复了 electron-builder 在处理循环依赖时导致的堆栈溢出问题。
|
||
* 主要修改了以下文件:
|
||
* 1. node_modules/app-builder-lib/out/node-module-collector/nodeModulesCollector.js
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
// 获取 nodeModulesCollector.js 文件的路径
|
||
const nodeModulesCollectorPath = path.join(
|
||
process.cwd(),
|
||
'node_modules',
|
||
'app-builder-lib',
|
||
'out',
|
||
'node-module-collector',
|
||
'nodeModulesCollector.js'
|
||
);
|
||
|
||
// 检查文件是否存在
|
||
if (!fs.existsSync(nodeModulesCollectorPath)) {
|
||
console.error('找不到 nodeModulesCollector.js 文件,请确保已安装 electron-builder');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 读取文件内容
|
||
let content = fs.readFileSync(nodeModulesCollectorPath, 'utf8');
|
||
|
||
// 修复 1: 修改 _getNodeModules 方法,添加环路检测
|
||
const oldGetNodeModulesMethod = /(_getNodeModules\(dependencies, result\) \{[\s\S]*?result\.sort\(\(a, b\) => a\.name\.localeCompare\(b\.name\)\);\s*\})/;
|
||
const newGetNodeModulesMethod = `_getNodeModules(dependencies, result, depth = 0, visited = new Set()) {
|
||
// 添加递归深度限制
|
||
if (depth > 10) {
|
||
console.log("递归深度超过10,停止递归");
|
||
return;
|
||
}
|
||
|
||
if (dependencies.size === 0) {
|
||
return;
|
||
}
|
||
|
||
for (const d of dependencies.values()) {
|
||
const reference = [...d.references][0];
|
||
const moduleId = \`\${d.name}@\${reference}\`;
|
||
|
||
// 环路检测:如果已经访问过这个模块,则跳过
|
||
if (visited.has(moduleId)) {
|
||
console.log(\`检测到循环依赖: \${moduleId}\`);
|
||
continue;
|
||
}
|
||
|
||
// 标记为已访问
|
||
visited.add(moduleId);
|
||
|
||
const p = this.dependencyPathMap.get(moduleId);
|
||
if (p === undefined) {
|
||
builder_util_1.log.debug({ name: d.name, reference }, "cannot find path for dependency");
|
||
continue;
|
||
}
|
||
const node = {
|
||
name: d.name,
|
||
version: reference,
|
||
dir: p,
|
||
};
|
||
result.push(node);
|
||
if (d.dependencies.size > 0) {
|
||
node.dependencies = [];
|
||
this._getNodeModules(d.dependencies, node.dependencies, depth + 1, visited);
|
||
}
|
||
|
||
// 处理完成后,从已访问集合中移除,允许在其他路径中再次访问
|
||
visited.delete(moduleId);
|
||
}
|
||
result.sort((a, b) => a.name.localeCompare(b.name));
|
||
}`;
|
||
|
||
content = content.replace(oldGetNodeModulesMethod, newGetNodeModulesMethod);
|
||
|
||
// 修复 2: 修改 getNodeModules 方法,传递 visited 集合
|
||
const oldGetNodeModulesCall = /(this\._getNodeModules\(hoisterResult\.dependencies, this\.nodeModules\);)/;
|
||
const newGetNodeModulesCall = `// 创建一个新的 visited 集合用于环路检测
|
||
const visited = new Set();
|
||
|
||
this._getNodeModules(hoisterResult.dependencies, this.nodeModules, 0, visited);`;
|
||
|
||
content = content.replace(oldGetNodeModulesCall, newGetNodeModulesCall);
|
||
|
||
// 修复 3: 修改 convertToDependencyGraph 方法,跳过路径未定义的依赖
|
||
const oldPathCheck = /(if \(!dependencies\.path\) \{[\s\S]*?throw new Error\("unable to parse `path` during `tree\.dependencies` reduce"\);[\s\S]*?\})/;
|
||
const newPathCheck = `if (!dependencies.path) {
|
||
builder_util_1.log.error({
|
||
packageName,
|
||
data: dependencies,
|
||
parentModule: tree.name,
|
||
parentVersion: tree.version,
|
||
}, "dependency path is undefined");
|
||
// 跳过这个依赖而不是抛出错误
|
||
console.log(\`跳过路径未定义的依赖: \${packageName}\`);
|
||
return acc;
|
||
}`;
|
||
|
||
content = content.replace(oldPathCheck, newPathCheck);
|
||
|
||
// 写入修改后的内容
|
||
fs.writeFileSync(nodeModulesCollectorPath, content, 'utf8');
|
||
|
||
console.log('成功应用 electron-builder 堆栈溢出修复补丁!');
|