Overriding `tsconfig.json` for ts-node in mocha

node.jsmocha.jsTsconfig

node.js Problem Overview


Is it possible to override which tsconfig.json ts-node uses when called from mocha?

My main tsconfig.json contains "module": "es2015", but I want to use "module": "commonjs" for ts-node only.

I tried this

mocha --compilers ts:ts-node/register,tsx:ts-node/register \
    --compilerOptions '{"module":"commonjs"}' \
    --require ts-node/register test/**/*.spec.ts*

but it did not work:

SyntaxError: Unexpected token import
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:387:25)
    at Module.m._compile (/usr/lib/node_modules/ts-node/src/index.ts:406:23)
    at Module._extensions..js (module.js:422:10)
    at Object.require.extensions.(anonymous function) [as .tsx] (/usr/lib/node_modules/ts-node/src/index.ts:409:12)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at /usr/lib/node_modules/mocha/lib/mocha.js:222:27
    at Array.forEach (native)
    at Mocha.loadFiles (/usr/lib/node_modules/mocha/lib/mocha.js:219:14)
    at Mocha.run (/usr/lib/node_modules/mocha/lib/mocha.js:487:10)
    at Object.<anonymous> (/usr/lib/node_modules/mocha/bin/_mocha:458:18)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:146:18)
    at node.js:404:3

node.js Solutions


Solution 1 - node.js

You need to set the configuration through the TS_NODE_COMPILER_OPTIONS environment variable

Example code on an unix machine:

TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}' \
mocha --require ts-node/register 'test/**/*.spec.{ts,tsx}'

Explanation extracted from the repository documentation


CLI and Programmatic Options

Environment variable denoted in parentheses.

  • -T, --transpile-only Use TypeScript's faster transpileModule (TS_NODE_TRANSPILE_ONLY, default: false)

  • -I, --ignore [pattern] Override the path patterns to skip compilation (TS_NODE_IGNORE, default: /node_modules/)

  • -P, --project [path] Path to TypeScript JSON project file (TS_NODE_PROJECT)

  • -C, --compiler [name] Specify a custom TypeScript compiler (TS_NODE_COMPILER, default: typescript)

  • -D, --ignore-diagnostics [code] Ignore TypeScript warnings by diagnostic code (TS_NODE_IGNORE_DIAGNOSTICS)

  • -O, --compiler-options [opts] JSON object to merge with compiler options (TS_NODE_COMPILER_OPTIONS)

  • --files Load files from tsconfig.json on startup (TS_NODE_FILES, default: false)

  • --pretty Use pretty diagnostic formatter (TS_NODE_PRETTY, default: false)

  • --skip-project Skip project config resolution and loading (TS_NODE_SKIP_PROJECT, default: false)

  • --skip-ignore Skip ignore checks (TS_NODE_SKIP_IGNORE, default: false)

  • --log-error Logs errors of types instead of exit the process (TS_NODE_LOG_ERROR, default: false)

  • --prefer-ts-exts Re-order file extensions so that TypeScript imports are preferred (TS_NODE_PREFER_TS_EXTS, default: false)

Solution 2 - node.js

TypeScript allows you to override a configuration file. Rather than hard-code JSON in an environment variable as mentioned in the other solutions, specify the overridden configuration path in the environment. The TS_NODE_PROJECT environment variable can be used for this.

TS_NODE_PROJECT='./tsconfig.commonjs.json'

So if your main config is:

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   }
}

You can create another configuration that overrides the module setting.

tsconfig.commonjs.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs"
  }
}

When you run mocha, specify the overridden configuration to use:

"test": "TS_NODE_PROJECT='./tsconfig.commonjs.json' mocha -r ts-node/register test/**/*.spec.ts*"

This makes it very easy to further customize your tsconfig just for mocha testing. You can even run ts-node (outside of mocha) directly specifying that path:

ts-node -P tsconfig.commonjs.json -r myFile.ts 

Solution 3 - node.js

--compilerOptions wont' work.

What you need to do is customize how you register ts-node. My case was a little bit different from yours, I wanted it to use test/tsconfig.json, which contained settings needed by my test code. If I just used --require ts-node/register, it was using a default configuration that did not contain the settings needed to run my tests.

What I did was:

  1. Create a file test/tshook.js. It contains:

     require("ts-node").register({
       project: "test/tsconfig.json",
     });
    
  2. I edited my test/mocha.opts to have:

     --require test/tshook.js
     test/**/*.ts
    

This should will pass the desired setting to ts-node:

require("ts-node").register({
  compilerOptions: {
    module: "commonjs",
  },
});

Solution 4 - node.js

In package.json - scripts section:

"test": "TS_NODE_PROJECT=src mocha"

picks up my tsconfig.json in the src directory of my project, overriding the default tsconfig.json.

OP can achieve same by using test instead of src

Solution 5 - node.js

This worked for me on windows

set TS_NODE_COMPILER_OPTIONS={\"module\":\"commonjs\"} && mocha -r ts-node/register test/unit/*.test.ts 

This was the error that prompted me to use that solution

(function (exports, require, module, __filename, __dirname) { import 'mocha';

Solution 6 - node.js

You can also use ts-mocha (https://www.npmjs.com/package/ts-mocha)

Example

package.json

"test": "ts-mocha -p test/tsconfig.cjs.json test/**/*.test.ts"

test/tsconfig.cjs.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "module": "commonjs"
  }
}

Solution 7 - node.js

While there doesn't seem to be a unified linux/windows command line phrasing that works, you can set the compiler-options from the command line. In my case, much like the OP, I have a tsconfig.json with a module: esnext. I was able to override on the command line:

Ran on Windows, w/ts-node installed globally, but in different shell types:

bash/mingw64:
ts-node --compiler-options={"module":"commonJS"} xxx.ts

cmd:
ts-node --compiler-options={\"module\":\"commonJS\"} xxx.ts

Solution 8 - node.js

On mac

"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --require ts-node/register test/**/*.ts",

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRalphView Question on Stackoverflow
Solution 1 - node.jslleonView Answer on Stackoverflow
Solution 2 - node.jsSteven SpunginView Answer on Stackoverflow
Solution 3 - node.jsLouisView Answer on Stackoverflow
Solution 4 - node.jsSamir SethView Answer on Stackoverflow
Solution 5 - node.jsWakeelView Answer on Stackoverflow
Solution 6 - node.jsGrafluxeView Answer on Stackoverflow
Solution 7 - node.jsRandy LarsonView Answer on Stackoverflow
Solution 8 - node.jsbarathView Answer on Stackoverflow