You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用--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"]
}

问题原因

  1. source map关联失效:ts-node/esm加载器在实时转译ES模块时,没有正确生成或传递source map信息,导致Node.js无法将转译后的JS代码行映射回原始TS文件的对应行。
  2. 模块配置不匹配: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正确性:

  1. 在tsconfig.json中开启sourceMap: true
  2. 修改package.json脚本:
{
  "scripts": {
    "build": "tsc",
    "test": "mocha dist/test.js"
  }
}

内容的提问来源于stack exchange,提问作者Delta Boukensha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:45:13