Overriding `tsconfig.json` for ts-node in mocha
Asked Answered
B

9

85

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
Beetner answered 16/11, 2016 at 15:29 Comment(0)
M
87

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)
Milissamilissent answered 3/6, 2017 at 12:8 Comment(3)
bummer that there doesn't seem to be a nice way of doing this in a way that works for both Windows and *nix.Berky
Take a look at @Louis answer for a cross-platform supportMilissamilissent
Windows: cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha -r ts-node/register test/**/*.spec.ts --reporter=dotKnuth
W
51

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 
Wiebmer answered 25/5, 2019 at 18:2 Comment(5)
For Windows a small adjustment were needed: SET TS_NODE_PROJECT=./tsconfig.commonjs.json&& mocha -r ts-node/register test/**/*.spec.tsPappose
You can use cross-env (npmjs.com/package/cross-env) to make the command platform independent.Stator
In @PerThomasson's comment, the space between .json and && is not a typo, it is needed. Might save you some time :DFascicule
Nice example. It worked. Now I have another problem, My code is for browser then I have some document.getElementById, when I run the test I get the error ReferenceError: document is not defined Any idea? Thanks.Kuhns
If document is not defined, you are not running in a browser, or you built for the wrong target, or you need to include a browser environment in your node runtime.Wiebmer
K
22

--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",
  },
});
Kelila answered 3/3, 2017 at 21:14 Comment(3)
This breaks breakpoints in Webstorm debug. Probably something wrong in maps file. Note that breakpoints break under in ./src/ files while under ./test they work fine. Anything can be done about it? I mean if I don't do this --require test/tshook.js - breakpoints work as expected.Hyperthyroidism
Here's how it looks: I tried to stepInto but it skipped a lot of functions, and stopped somewhere in random place. Without tshooks this works as expected . static.pychat.org/photo/WLdZb0pO_Mon_Jul_31_170826_2017.gifHyperthyroidism
In case anyone else is wondering how mocha finds "test/mocha.opts", that path is the default path for this file. In my case I had a different folder name for tests, which was causing problems.Cale
A
7

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

Acrimonious answered 29/6, 2017 at 8:40 Comment(1)
I have to specify path to the tsconfig.json file i.e. <root>/test/tsconfig.json to make it workSteep
A
6

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';

Aslant answered 10/4, 2019 at 9:54 Comment(0)
C
4

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"
  }
}
Clarey answered 1/10, 2019 at 13:37 Comment(1)
ts-mocha seems deprecatedDispassionate
M
3

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

Morea answered 9/1, 2020 at 2:59 Comment(0)
S
1

On mac

"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --require ts-node/register test/**/*.ts",
Steep answered 25/6, 2019 at 4:36 Comment(0)
H
0

This doesn't address the core original question, but goes to the heart of getting mocha with typescript working, so I'll post it here in case it helps others.

We found that some ridiculous backslash escaping was needed to make this work on Windows. It works fine on Mac too, even though Mac doesn't need the same escaping.

Then, additional ts-node require directives were critical.

File package.json:

{
  "scripts": {
    ...
    "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha"
  },

  ...

  "mocha": {
    "require": [
      "ts-node/register",
      "tsconfig-paths/register"
    ],
    "watch-files": [
      "./src/**/*.ts",
      "./tests/**/*.spec.ts"
    ],
    "spec": "./tests/**/*.spec.ts"
  }
Halloran answered 17/7, 2022 at 2:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.