61

Setup: I have a Node project (pure Node, no browser bits) written in TypeScript. I can use the TypeScript compiler (tsc) from the typescript module to compile the code. So far so good.

However, I want to write tests using Mocha, and that's where I'm having trouble. I tried --compilers ts:typescript, but I keep getting errors like:

error TS5023: Unknown compiler option 'compilers'.

It looks like the command line to mocha ends up being passed to tsc, which is obviously not good.

Thomas
  • 174,939
  • 50
  • 355
  • 478

4 Answers4

95

For anybody who has tried and had problems with typescript-require you may want to try ts-node.

$ npm install -g ts-node
$ mocha --require ts-node/register src/**/*.spec.ts

It also appears that there has been some ongoing discussion about deprecating typescript-require in favor of ts-node.

Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
jpierson
  • 16,435
  • 14
  • 105
  • 149
  • Using ts-node, I have difficulties doing code coverage for the tests using Istanbul (after running the mocha tests in gulp). Istanbul doesn't seem to be able to remap to the original TS files (using Istanbul remapper). Any possible solutions for this? – calclavia Jun 22 '16 at 03:26
  • 4
    To avoid a lot of complications I've resorted to compiling my tests which are written in TypeScript with tsc as a precursor to running tests and making sure to generate source maps. This allows me to debug my tests in VS Code and doesn't rely on typescript-require or ts-node. – jpierson Jun 23 '16 at 03:44
  • 3
    `typescript-require` is already deprecated https://github.com/theblacksmith/typescript-require/issues/34#issuecomment-230915434 – martin Oct 28 '16 at 14:31
  • 7
    What is test.ts in relation to 'src/**/*.spec.ts'? – Jamel Toms Oct 28 '16 at 19:01
  • 4
    @jpierson can you make your process a full answer? – Bob Dec 16 '16 at 08:49
  • For people getting **unable to compile TypeScript**: Try including `"include": ["**/*.ts"]` on tsconfig.json https://github.com/TypeStrong/ts-node/issues/168#issuecomment-257009461 – BrunoLM Jan 12 '17 at 00:50
  • @Bob I'll try to expound on what I arrived at when I get a chance but I haven't worked in that TypeScript project for a few months now and I'm not sure when I'll get a chance to get back into it. – jpierson Jan 12 '17 at 02:34
  • 3
    @JamelToms it seems like `test.ts` is not required, and the last part is the pattern to find all tests in project. this worked for me: `mocha --require ts-node/register src/**/*.spec.ts` – dark_ruby Jan 29 '17 at 20:08
  • 1
    If you are looking at this now, take a gander at https://github.com/piotrwitek/ts-mocha. Makes this even easier. – JRadness May 01 '19 at 17:39
  • 3
    This seems to no longer work with mocha, it gives me the error `Unknown file extension ".ts"` with the latest version. – justin.m.chase Aug 31 '21 at 15:06
  • 1
    @justin.m.chase [New "loader"](https://github.com/mochajs/mocha/issues/4726#issuecomment-903213780). Set "`"loader": "ts-node/esm"` in `.mocharc.json` instead of `"require"`". – Cameron Tacklind Jan 02 '22 at 05:55
  • @JamelToms, many people use .test.ts instead of .spec.ts as the convention for test files, especially Jest users. – Joshua Richardson Jul 09 '23 at 23:21
9

Don't use this answer. typescript-require is unmaintained, and ts-node is its replacement. Leaving this answer here for posterity.

Found it. The typescript module is actually like a "main" function; it runs the compiler as soon as the module is loaded. Not very nice design.

I poked at Mocha's acceptance tests, which show how to use a custom compiler for foo files. They wire it up via the require.extensions mechanism. I was halfway through writing a module that just calls tsc on the command line when I realized that somebody must have done this before. So it's very simple:

$ npm install typescript-require --save-dev
$ mocha --compilers ts:typescript-require
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • I don't really think this works well. You can see [my related question](http://stackoverflow.com/questions/32996110/combine-mocha-typescript-and-watch) to understand why. – Michael Tiller Nov 13 '15 at 19:36
  • 1
    Don't look at this one. The project is deprecated. – Dmitrii Sorin Jun 28 '17 at 03:27
  • 1
    Thanks @DmitriiSorin. I've edited my answer, and submitted a PR to the typescript-require README to announce this more clearly. Also I just noticed that I originally asked the question, so I could move the green check mark :D – Thomas Jun 29 '17 at 06:09
  • 1
    `--compilers` is also deprecated ... >< aaahhh use `--require ts-node/register` they say.. and/or with `--require source-map-support/register` – Melroy van den Berg May 15 '18 at 19:42
5

Using the latest version of Mocha and ts-node I was getting an Unexpected token import issue. Using the below settings with ts-mocha worked for me:

tsconfig.json

{
    "files": [
        "src/main.ts"
    ],
    "compilerOptions": {
        "noImplicitAny": true,
        "target": "es2015",
        "types": ["mocha"],
        "module": "commonjs"
    }
}

package.json

"scripts": {
    "mocha": "ts-mocha -p library/tsconfig.json library/test/**/*.ts"
  },

launch.json

{
    "type": "node",
    "request": "launch",
    "name": "Mocha Tests",
    "runtimeArgs": [
        "${workspaceFolder}/node_modules/ts-mocha/bin/ts-mocha",
        "--timeout", "999999",
        "-p",
        "${workspaceFolder}/library/tsconfig.json",
        "${workspaceFolder}/library/test/**/*.ts"
    ],
    "internalConsoleOptions": "openOnSessionStart"
}

and gulp.js just incase you want to use gulp too

const gulp = require('gulp');
const ts = require('gulp-typescript');
const mocha = require('gulp-mocha');

const tsProject = ts.createProject('tsconfig.json');

gulp.task('build', () => tsProject.src()
  .pipe(tsProject())
  .js.pipe(gulp.dest('dist')));

gulp.task('test', () => gulp.src('test/*.spec.ts')
  .pipe(mocha({
    reporter: 'nyan',
    require: ['ts-node/register'],
  })));
/* single command to hook into VS Code */
gulp.task('default', gulp.series('build', 'test'));
ToDevAndBeyond
  • 1,120
  • 16
  • 24
  • Using ts-mocha worked for me as well. I added my solution to https://stackoverflow.com/a/58186015/7322030 – Grafluxe Oct 01 '19 at 13:48
1

Configure ts-node as your loader.

Add .mocharc.js to project root:

module.exports = {
  loader: 'ts-node/esm',
};

Ensure you have ts-node installed: npm install ts-node -D. Source here.

Matt Jensen
  • 1,495
  • 17
  • 21
  • Cannot parse the mocharc.js unless renamed to mocharc.cjs and then cannot import anything in a project with typescript and javascript. – HMR Nov 03 '22 at 10:45
  • If you can't parse .mocharc.js file then that may be a separate issue that I'd resolve first. – Matt Jensen Aug 11 '23 at 08:52