156 lines
5.1 KiB
JavaScript
156 lines
5.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 文件的路径
|
|
let nodeModulesCollectorPath = path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'app-builder-lib',
|
|
'out',
|
|
'node-module-collector',
|
|
'nodeModulesCollector.js'
|
|
)
|
|
|
|
// 检查文件是否存在
|
|
console.log(`正在检查文件: ${nodeModulesCollectorPath}`)
|
|
if (!fs.existsSync(nodeModulesCollectorPath)) {
|
|
console.error('找不到 nodeModulesCollector.js 文件,请确保已安装 electron-builder')
|
|
|
|
// 尝试查找其他可能的路径
|
|
const possiblePaths = [
|
|
path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'electron-builder',
|
|
'node_modules',
|
|
'app-builder-lib',
|
|
'out',
|
|
'node-module-collector',
|
|
'nodeModulesCollector.js'
|
|
),
|
|
path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'app-builder-lib',
|
|
'lib',
|
|
'node-module-collector',
|
|
'nodeModulesCollector.js'
|
|
),
|
|
path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'app-builder-lib',
|
|
'dist',
|
|
'node-module-collector',
|
|
'nodeModulesCollector.js'
|
|
)
|
|
]
|
|
|
|
for (const possiblePath of possiblePaths) {
|
|
console.log(`尝试查找: ${possiblePath}`)
|
|
if (fs.existsSync(possiblePath)) {
|
|
console.log(`找到文件: ${possiblePath}`)
|
|
nodeModulesCollectorPath = possiblePath
|
|
break
|
|
}
|
|
}
|
|
|
|
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 堆栈溢出修复补丁!')
|