I am trying to figure out how to setup VS Code to debug mocha tests in a TypeScript module npm project.
When I combined these solutions I hit a wall:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for C:\Users\peter\Projects\TEMP\node_modules\mocha\bin\_mocha
at new NodeError (node:internal/errors:400:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:74:9)
at defaultGetFormat (node:internal/modules/esm/get_format:114:38)
at defaultLoad (node:internal/modules/esm/load:81:20)
at nextLoad (node:internal/modules/esm/loader:161:28)
at C:\Users\peter\Projects\TEMP\node_modules\ts-node\src\esm.ts:255:45
at async addShortCircuitFlag (C:\Users\peter\Projects\TEMP\node_modules\ts-node\src\esm.ts:409:15)
at async nextLoad (node:internal/modules/esm/loader:161:22)
at async ESMLoader.load (node:internal/modules/esm/loader:596:20)
at async ESMLoader.moduleProvider (node:internal/modules/esm/loader:448:11) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
It reads like it can't load the \node_modules\mocha\bin\_mocha
extensionless binary when the experimental-specifier-resolution=node
option is set.
A workaround would be to remove the --experimental-specifier-resolution=node
runtimeArgs
from launch.json
and add the .js
extension to all imports but it's a rather hacky solution I would rather not do.
My Environment
- node: v19.3.0
- npm: 9.2.0
Files
https://github.com/pariesz/vscode-debug-issue
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Mocha",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [
"--no-timeouts",
"--colors",
"--inspect-brk",
"*.test.ts"
],
"runtimeArgs": [
"--experimental-specifier-resolution=node",
"--loader", "ts-node/esm"
]
}
]
}
package.json
{
"type": "module",
"scripts": {
"test": "mocha --node-option loader=ts-node/esm --node-option experimental-specifier-resolution=node *.test.ts"
},
"devDependencies": {
"@types/chai": "^4.3.5",
"@types/mocha": "^10.0.1",
"chai": "^4.3.7",
"mocha": "^10.2.0",
"ts-node": "^10.9.1",
"tslib": "^2.5.0",
"typescript": "^5.0.4"
}
}
tsconfig.json
{
"compilerOptions": {
"types": ["mocha", "node" ],
"typeRoots": [ "./node_modules/@types" ],
"module": "ESNext",
"moduleResolution": "node"
},
"exclude": [
"node_modules",
]
}
project.ts
export const TRUE = true;
project.test.ts
import { assert } from "chai"
import { TRUE } from "./project"
describe("project", () => {
it("TRUE === true", () => {
assert.isTrue(TRUE);
})
})
UPDATE 1
Some googling led me to make experimental-specifier-resolution=node support extension-less files
I have tried adding a custom loader (loader.mjs) and commited to the repo:
let is_main = true;
export const load = (url, context, loadNext) => {
if (is_main) {
is_main = false;
if (!context.format) {
context.format = "commonjs";
}
}
return loadNext(url, context, loadNext);
};
Now I have a new error:
Error: Failed to load raw source: Format was 'null' and url was 'file:///C:/Users/peter/Projects/TEMP/node_modules/mocha/bin/_mocha''.
at C:\Users\peter\Projects\TEMP\node_modules\ts-node\src\esm.ts:265:17
at async addShortCircuitFlag (C:\Users\peter\Projects\TEMP\node_modules\ts-node\src\esm.ts:409:15)
at async nextLoad (node:internal/modules/esm/loader:161:22)
at async ESMLoader.load (node:internal/modules/esm/loader:596:20)
at async ESMLoader.moduleProvider (node:internal/modules/esm/loader:448:11)
at async link (node:internal/modules/esm/module_job:68:21)
I have use console.log
to verify that ./loader.js
is run and format
is set for node_modules/mocha/bin/_mocha
and had a look at esm.ts but I still don't understand how it gets to this state.