启用--loader ts-node/esm时异常堆栈追踪行号错误问题求助
使用
ts-node/esm加载器时TypeScript测试堆栈追踪行号错误问题 问题现象
执行测试脚本ts-mocha test.ts --loader=ts-node/esm时,异常堆栈追踪显示的代码行号与实际错误行不符(例如错误指向第17行,但实际错误代码在第9行);关闭--loader=ts-node/esm选项后,行号恢复正确。
复现代码
test.ts
import chai, { expect } from 'chai'; it('throws error but shows the wrong line', async () => { const a = 2; const b = 4; const c = a + b; expect(c).to.be.eq(7); }) // 错误堆栈示例: // AssertionError: expected 6 to equal 7 // + expected - actual // -6 // +7 // at /home/delta/dev/bug-ts-mocha/test.ts:17:33 <--- 实际应为第9行 // at Generator.next (<anonymous>) // at /home/delta/dev/bug-ts-mocha/test.ts:8:71 // at new Promise (<anonymous>) // at __awaiter (test.ts:4:12) // at Context.<anonymous> (test.ts:13:51) // at processImmediate (node:internal/timers:466:21)
package.json
{ "name": "bug-ts-loader", "version": "1.0.0", "main": "index.js", "scripts": { "test": "ts-mocha test.ts --loader=ts-node/esm" }, "dependencies": { "@types/chai": "^4.3.4", "@types/mocha": "^10.0.1", "chai": "^4.3.7", "ts-mocha": "^10.0.0", "ts-node": "^10.9.1", "typescript": "^4.9.5" } }
tsconfig.json
{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "paths": { "*": ["./src/*", "./@types/*", "./test/*"] }, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": false, "noImplicitAny": false, "typeRoots": [ "@types/*", "node_modules/@types/*" ], "types": ["node", "mocha"] }, "exclude": ["dist"] }
问题原因
- source map关联失效:
ts-node/esm加载器在实时转译ES模块时,没有正确生成或传递source map信息,导致Node.js无法将转译后的JS代码行映射回原始TS文件的对应行。 - 模块配置不匹配:
tsconfig.json中module设置为CommonJS,但使用--loader=ts-node/esm强制启用ES模块加载器,模块系统的不匹配进一步干扰了source map的生成逻辑。
解决方案
方案1:使用ts-node原生ESM模式替代loader选项
修改npm测试脚本,使用ts-mocha的--esm参数启用ES模块支持,无需手动指定--loader:
{ "scripts": { "test": "ts-mocha --esm test.ts" } }
该方式会让ts-node自动处理ES模块的source map生成与关联,确保堆栈行号准确。
方案2:调整tsconfig适配ES模块
修改tsconfig.json的模块配置,与ES加载器兼容,并确保开启sourceMap:
{ "compilerOptions": { "target": "ES6", "module": "ESNext", "moduleResolution": "node16", "paths": { "*": ["./src/*", "./@types/*", "./test/*"] }, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": false, "noImplicitAny": false, "typeRoots": [ "@types/*", "node_modules/@types/*" ], "types": ["node", "mocha"], "sourceMap": true }, "exclude": ["dist"] }
方案3:预编译TypeScript后执行测试
先编译TS文件并生成source map,再用mocha执行编译后的JS文件,完全依赖TypeScript官方编译流程保证source map正确性:
- 在
tsconfig.json中开启sourceMap: true - 修改package.json脚本:
{ "scripts": { "build": "tsc", "test": "mocha dist/test.js" } }
内容的提问来源于stack exchange,提问作者Delta Boukensha
相关产品推荐
相关产品推荐

