Overriding `tsconfig.json` for ts-node in mocha
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
Solution 1:
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:
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:
--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:
-
Create a file
test/tshook.js
. It contains:require("ts-node").register({ project: "test/tsconfig.json", });
-
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:
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