Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ts-node using with mocha and tsconfig.json #521

Closed
courteous opened this issue Jan 22, 2018 · 11 comments
Closed

ts-node using with mocha and tsconfig.json #521

courteous opened this issue Jan 22, 2018 · 11 comments
Labels
question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.

Comments

@courteous
Copy link

courteous commented Jan 22, 2018

Hello and first thank you for creating this project. I bumped is a problem that seems to be discussed before but it is not clear to me what the solution is:

Here is the problem:

I was following yesterday this unit testing manual that describe one of the ways how to do unit testing with mocha and chai. It is all working as presented there but i found out that if i add my tsconfig.json to the project then the test stop working and fail with the error

It all is working if the file tsconfig.json is not in the main directory

npm run test


> [email protected] test /home/tito/Projects/test
> ./node_modules/mocha/bin/mocha -r ts-node/register  ./tests/example.ts

SyntaxError: Unexpected token ] in JSON at position 475
    at JSON.parse (<anonymous>)
    at parse (/home/tito/Projects/test/node_modules/tsconfig/src/tsconfig.ts:195:15)
    at readFileSync (/home/tito/Projects/test/node_modules/tsconfig/src/tsconfig.ts:181:10)
    at Object.loadSync (/home/tito/Projects/test/node_modules/tsconfig/src/tsconfig.ts:151:18)
    at readConfig (/home/tito/Projects/test/node_modules/ts-node/src/index.ts:455:18)
    at Object.register (/home/tito/Projects/test/node_modules/ts-node/src/index.ts:205:18)
    at Object.<anonymous> (/home/tito/Projects/test/node_modules/ts-node/register/index.js:1:16)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at requires.forEach.mod (/home/tito/Projects/test/node_modules/mocha/bin/_mocha:467:3)
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (/home/tito/Projects/test/node_modules/mocha/bin/_mocha:466:10)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Function.Module.runMain (module.js:701:10)
    at startup (bootstrap_node.js:193:16)
    at bootstrap_node.js:617:3

if I rename or remove the tsconfig.json file my test a running with mocha ok and if i execute
npm run test

then i get:


[  Hello function
    ✓ should return hello world
  1 passing (5ms)

and here is how the test script is being executed in package.json:

  "scripts": {
    "echo": "echo \"Error not test specified \" && exit 1",
    ......
    "server": "webpack-dev-server --watch",
    "test": "./node_modules/mocha/bin/mocha -r ts-node/register  ./tests/example.ts"
    .....
  },

I have tired adding exclude parameter to my tsconfig.json as mentioned in the issue number 4 here, but that does not seems to fix the problem i.e. here is how my tsconfig.json looks like:


{
    "compilerOptions": {
      "outDir": "./dist/",
      "sourceMap": true,
      "noImplicitAny": true,
      "module": "es6",
      "target": "es5",
      "jsx": "react",
      "allowJs": true,
      "removeComments": false

    }
    "exclude": [
        "node_modules",
        "tests",

    ]

  }

I have tired adding the dist folder to the exclude statements but that only changes the exception thrown i..e

> ./node_modules/mocha/bin/mocha -r ts-node/register  ./tests/example.ts

/home/tito/test/tests/example.ts:1
(function (exports, require, module, __filename, __dirname) { import { expect } from '../node_modules/chai';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at new Script (vm.js:51:7)
    at createScript (vm.js:138:10)
    at Object.runInThisContext (vm.js:199:10)
    at Module._compile (module.js:624:28)
    at Module.m._compile (/home/tito/test/node_modules/ts-node/src/index.ts:422:23)
    at Module._extensions..js (module.js:671:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/home/tito/test/node_modules/ts-node/src/index.ts:425:12)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at /home/tito/test/node_modules/mocha/lib/mocha.js:231:27
    at Array.forEach (<anonymous>)
    at Mocha.loadFiles (/home/tito/test/node_modules/mocha/lib/mocha.js:228:14)
    at Mocha.run (/home/tito/test/node_modules/mocha/lib/mocha.js:536:10)
    at Object.<anonymous> (/home/tito/test/node_modules/mocha/bin/_mocha:582:18)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Function.Module.runMain (module.js:701:10)
    at startup (bootstrap_node.js:193:16)
    at bootstrap_node.js:617:3


but that does not seems to solve the problem as well.

In issue number 4 it was mentioned that i should use the "--noProject" directive but how to execute that with mocha? i.e what is the command line to test with i.e.
ts-node --no-project node_modules/mocha/bin/mocha -r ts-node/register ./tests/example.ts``
or
ts-node --no-project node_modules/mocha/bin/_mocha -r ts-node/register ./tests/example.ts
or

i do not quite understand to what should i apply that "--no-project" directive.

basically the question is how to use the ts-node correctly with mocha.

and here are some stats

node_modules/ts-node/dist$ ./bin.js --version
ts-node v4.1.0
node v9.4.0
typescript v2.6.2

any help is really appreciated.

regards,

@gloomybrain
Copy link

gloomybrain commented Jan 23, 2018

Hi @courteous! I've been struggling with a similar issue lately and here's the setup that worked for me:

package.json

{
  "name": "my-project",
  "version": "0.1.0",
  "main": "/out/index.js",
  "scripts": {
    "prestart": "./node_modules/typescript/bin/tsc",
    "start": "node out/index.js",
    "pretest": "./node_modules/.bin/tslint --config tslint.json --project tsconfig.json",
    "test": "./node_modules/mocha/bin/mocha --require ts-node/register test/**/*.spec.ts"
  },
  "devDependencies": {
    "@types/chai": "^4.1.1",
    "@types/express": "^4.11.0",
    "@types/mocha": "^2.2.46",
    "@types/node": "^8.5.8",
    "chai": "^4.1.2",
    "mocha": "^5.0.0",
    "ts-node": "^4.1.0",
    "tslint": "^5.9.1",
    "typescript": "^2.6.2"
  }
}

tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "moduleResolution": "node",
        "outDir": "./out",
        "strict": true,
        "target": "es2016"
    },
    "include": [
        "src/**/*.ts"
    ]
}

So as you can see the npm start command first executes compilation via tsc (see "prestart") and then actually starts the main file. Notice the "include" section in tsconfig.json that implicitly excludes everything other than "src" directory from compilation.
The npm test command in turn runs ts-node internally which compiles your sources on-the-fly AND explicitly includes the "test/**/*.spec.ts" file pattern into compilation. Thus all of the tests under "test" directory are being compiled and run.

Hope that helps =)

@courteous
Copy link
Author

Hello Denis, many thanks for the reply. I have tired exactly what you described and for that proposed i wanted to consolidate all my *.ts file in one folder which i did just not. i.e. currently all *.ts are in folder called ts/ which is on in on level as the package.json and tsconfig.json. However even when putting the "inlude"statement in the tsconfig as you proposed and execution the npm start as in our cases that did not help. What i did is found a a way to replicate the problem on a very simple project that i uploaded here:

https://github.com/courteous/failMinimalProjectUnitTesting

the only difference here is that i removed one of your lines i.e.
// "pretest": "./node_modules/.bin/tslint --config tslint.json ",

since for the replication tslint.conf is not required.

if i rename tsconfig.json to something else then test work, if i rename it back to tsconfig.json then they fail.

any help is really appreciated.

@courteous
Copy link
Author

courteous commented Jan 26, 2018

got it changing node-ts does not support es6 yet, described here:

#212

changing the module parameters from

// "module": "es6",
"module": "commonjs",

worked for me, although es6 support will be nice since that is where the road is going anyway.

@blakeembrey
Copy link
Member

JSON parsing should be a bit better with #536 so the error will be easier to track down. Your issue was with invalid JSON (trailing comma in the exclude array) but it shouldn't be an issue with the next release.

@blakeembrey blakeembrey added the question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead. label Feb 19, 2018
@JakobJingleheimer
Copy link

I have this issue on v7.0.0 (which was released after @blakeembrey's comment on 19 Feb). Mine is definitely caused by a trailing comma, which is usually fine (npm and typescript aren't complaining).

@blakeembrey
Copy link
Member

Can you print version information and confirm? There’s no code parsing JSON in this library anymore so it shouldn’t be possible.

@JakobJingleheimer
Copy link

@blakeembry I did before I posted: yarn why ts-node (tells me 7.0.0). Well then why…

@JakobJingleheimer
Copy link

JakobJingleheimer commented Jul 13, 2018

D'oh, sorry! I didn't look high enough in the stacktrace: ts-node is using tsconfig-paths (via -r), which is actually throwing the error: dividab/tsconfig-paths#48

@AWolf81
Copy link

AWolf81 commented Jan 14, 2021

I got also the import error issue and fixed it with ts-node-test-register.

Then my Mocha is started like mocha --require ts-node-test-register src/**/*.spec.ts and I've added a tsconfig.json in test folder with the following content:

{
   // your other config or extend from rootDir/tsconfig.json
    "compilerOptions": {
        "module": "commonjs"
    }
}

If you don't like to have a new dependency for this, you could also do cross-env TS_NODE_PROJECT=\"test/tsconfig.json\" mocha --require ts-node/register src/**/*.spec.ts with the same tsconfig.json as above.

Note: Cross-env is used to have the env setting working on Windows / Linux etc. - tested on Windows.

@cspotcode
Copy link
Collaborator

cspotcode commented Jan 15, 2021

@AWolf81 for what it's worth, you can also add ts-node-specific compilerOptions to your root tsconfig.json, and ts-node will use them as overrides. This means you can tell tsc to use module: es6 and ts-node to use module: commonjs.

{
  // tsconfig.json
  "compilerOptions": {
    "module": "es6"
  },
  "ts-node": {
    // these overrides are used by ts-node
    "compilerOptions": {
      "module": "commonjs"
    }
  }
}

@KillyMXI
Copy link

KillyMXI commented Nov 1, 2021

This gist did the job for me: https://gist.github.com/jordansexton/2a0c3c360aa700cc9528e89620e82c3d

I can't see "node-option" documented anywhere but it actually works and seems prettier than using node_modules internals or falling back to CommonJS.

Mocha section in package.json:

  "mocha": {
    "extension": [
      "ts"
    ],
    "node-option": [
      "experimental-specifier-resolution=node",
      "loader=ts-node/esm"
    ],
    "spec": "test/**/*.ts"
  }

ts-node section in tsconfig.json:

  "ts-node": {
    "compilerOptions": {
      "module": "ESNext",
      "esModuleInterop": true,
      "moduleResolution": "Node"
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.
Projects
None yet
Development

No branches or pull requests

7 participants