简体   繁体   中英

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

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)

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 

--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",
  },
});

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

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

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"
  }
}

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

在 Mac 上

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

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"
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM