detail | 详细描述
问题描述
在 Unity PuerTS 的 CommonJS 模块加载链路中,ILoader.ReadFile(string filepath, out string debugpath) 返回的
debugPath 会被一路传递到 puer.evalScript(script, debugPath),但默认的 puer.evalScript 实现没有使用这个
debugPath。
这会导致 CommonJS 模块最终以普通 eval(script) 的形式出现在 V8 Inspector / VSCode 调试器中,调试器无法稳定识别真实文
件路径,进而影响断点绑定和 sourcemap 定位。
涉及版本
我在以下两个版本/组合中都观察到了类似问题:
-
com.tencent.puerts.core 2.0.4
com.tencent.puerts.commonjs 1.1.0-pre.0
-
com.tencent.puerts.core 3.0.2
com.tencent.puerts.v8 3.0.2
相关代码
以 com.tencent.puerts.core 3.0.2 为例,ILoader 接口本身提供了 debugpath:
public interface ILoader
{
bool FileExists(string filepath);
string ReadFile(string filepath, out string debugpath);
}
模块加载时,puer.loadFile 会从 loader 读取 debugPath:
function loadFile(path) {
let debugPath = [];
var content = loader.ReadFile(path, debugPath);
return { content: content, debugPath: debugPath[0] };
}
puer.loadFile = loadFile;
CommonJS 模块执行时,module.mjs 会把 debugPath 传给 puer.evalScript:
function executeModule(fullPath, script, debugPath) {
if (debugPath === undefined) debugPath = fullPath;
let wrapped = puer.evalScript(
"(function (exports, require, module, __filename, __dirname) { " + script + "\n});",
debugPath
);
wrapped(exports, createLazyRequire(fullPath), module, debugPath, dirname(debugPath));
}
但默认 puer.evalScript 实现没有使用 debugPath:
puer.evalScript = global.__tgjsEvalScript || function (script, debugPath) {
return eval(script);
}
在 com.tencent.puerts.core 2.0.4 + com.tencent.puerts.commonjs 1.1.0-pre.0 中也有类似链路:
let wrapped = puer.evalScript(
"(function (exports, require, module, __filename, __dirname) { " + script + "\n});",
debugPath
)
但默认实现仍是:
puer.evalScript = global.__tgjsEvalScript || function (script, debugPath) {
return eval(script);
}
IL2CPP 初始化路径中甚至是:
puer.evalScript = eval
这也无法消费 debugPath。
### 当前现象
当自定义 loader 返回真实文件路径时,例如:
public string ReadFile(string filepath, out string debugpath)
{
debugpath = fullPath;
return File.ReadAllText(fullPath);
}
debugpath 能正确传递到 CommonJS 模块执行逻辑,但最终因为 puer.evalScript 只是 eval(script),调试器中看到的脚本路径不是
loader 返回的真实路径。
在 VSCode attach V8 Inspector 调试时,可能出现以下问题:
- CommonJS 模块显示为 eval 脚本,而不是实际文件路径
- 断点无法稳定绑定到本地 JS/TS 文件
- sourcemap 定位不稳定或失效
- 需要业务侧手动 patch puer.evalScript 才能恢复调试路径
### 当前 workaround
目前可以通过替换 puer.evalScript 并追加 sourceURL / 修正 sourceMappingURL 来规避:
puer.evalScript = function (script, debugPath) {
if (typeof script !== 'string') {
return eval(script);
}
if (debugPath) {
var normalized = String(debugPath).replace(/\\/g, '/');
if (/^[a-zA-Z]:\//.test(normalized)) {
normalized = 'file:///' + normalized;
} else if (normalized.charAt(0) === '/') {
normalized = 'file://' + normalized;
}
script += '\n//# sourceURL=' + normalized;
}
return eval(script);
};
这样 VSCode / V8 Inspector 能够识别 CommonJS 模块对应的真实文件路径,断点和 sourcemap 也能正常工作。
### 期望行为
希望 PuerTS 默认的 puer.evalScript(script, debugPath) 能消费传入的 debugPath,例如:
1. 在默认实现中根据 debugPath 追加 //# sourceURL=...
2. 或者通过其他官方推荐方式把 debugPath 传递给底层 eval / V8 Inspector
3. 同时避免破坏用户自定义的 global.__tgjsEvalScript
也就是说,对于通过 ILoader.ReadFile(..., out debugpath) 返回的真实路径,CommonJS 模块执行时调试器应能看到对应的脚本路
径。
### 疑问
请问默认 puer.evalScript 忽略 debugPath 是有意设计吗?
如果不是,是否可以在默认实现中基于 debugPath 自动追加 sourceURL,或者提供一个官方推荐的方式来处理 CommonJS 模块调试路
径?
detail | 详细描述
问题描述
在 Unity PuerTS 的 CommonJS 模块加载链路中,
ILoader.ReadFile(string filepath, out string debugpath)返回的debugPath会被一路传递到puer.evalScript(script, debugPath),但默认的puer.evalScript实现没有使用这个debugPath。这会导致 CommonJS 模块最终以普通
eval(script)的形式出现在 V8 Inspector / VSCode 调试器中,调试器无法稳定识别真实文件路径,进而影响断点绑定和 sourcemap 定位。
涉及版本
我在以下两个版本/组合中都观察到了类似问题:
com.tencent.puerts.core2.0.4com.tencent.puerts.commonjs1.1.0-pre.0com.tencent.puerts.core3.0.2com.tencent.puerts.v83.0.2相关代码
以
com.tencent.puerts.core3.0.2为例,ILoader接口本身提供了debugpath: