Debugging "TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"" with ts-node and Mocha
The Problem:
You're using ts-node
with Mocha to run your TypeScript tests, but you encounter the error "TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"". This error happens when Mocha tries to load your TypeScript files directly without proper configuration.
Simplified Explanation:
Imagine trying to play a song on a CD player without knowing the format. Mocha is the CD player, TypeScript files are the songs, and ts-node
is the translator that makes the songs playable. Without the translator, Mocha can't understand your TypeScript code.
The Scenario:
Let's say you have a simple TypeScript file called myTest.ts
:
// myTest.ts
import { expect } from 'chai';
describe('My Test Suite', () => {
it('should pass', () => {
expect(true).to.be.true;
});
});
And your Mocha test script (test.js
):
// test.js
require('ts-node/register');
const mocha = require('mocha');
mocha.run();
You've included ts-node/register
to tell Mocha to use ts-node
to load your TypeScript files. However, you still get the error.
The Root Cause:
The issue lies in the way ts-node
handles CommonJS modules. By default, ts-node/register
uses a loader that's designed for ES Modules. While this works well for ES Modules, CommonJS modules require a different approach.
The Solution:
To fix the error, you need to use the dedicated ts-node/esm
loader for CommonJS modules. Replace ts-node/register
with ts-node/esm
in your Mocha test script:
// test.js
require('ts-node/esm');
const mocha = require('mocha');
mocha.run();
Explanation:
ts-node/esm
specifically instructs ts-node
to treat your TypeScript files as CommonJS modules. This allows Mocha to understand and execute your tests correctly.
Additional Insights:
-
Using
require
: Whilerequire
is suitable for CommonJS, you can useimport
for ES Modules in your TypeScript files. However, ensure that your Mocha configuration correctly handles the module system. -
tsconfig.json: Consider using a
tsconfig.json
file to manage TypeScript compilation options. You can configuremodule
andmoduleResolution
to align with your project's needs.
Example:
Let's modify the myTest.ts
file to use require
:
// myTest.ts
const { expect } = require('chai');
describe('My Test Suite', () => {
it('should pass', () => {
expect(true).to.be.true;
});
});
Now, running the test.js
script with ts-node/esm
will execute the tests successfully.
Conclusion:
The "TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"" error arises from a mismatch between Mocha's expectations and ts-node
's module handling. Using ts-node/esm
ensures proper loading of CommonJS modules in your TypeScript tests, allowing Mocha to run them smoothly.
References and Resources: