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-jest not configured to match tsc options #59

Closed
kmturley opened this issue May 7, 2024 · 3 comments
Closed

ts-jest not configured to match tsc options #59

kmturley opened this issue May 7, 2024 · 3 comments

Comments

@kmturley
Copy link

kmturley commented May 7, 2024

Some code works fine via npm run build && npm start but not by npm test.
My assumption is that ts-jest is not configured to work in the same way as tsconfig.

How to replicate

git clone https://github.com/jsynowiec/node-typescript-boilerplate.git
cd node-typescript-boilerplate
npm install

1) No top-level 'await' expressions

Add to bottom of main.ts

console.log(await greeter('Bob'));

Then run:

npm run build && npm start
npm test

Notice how start works fine, but test outputs this error:

 FAIL  __tests__/main.test.ts
  ● Test suite failed to run
    src/main.ts:36:13 - error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
    console.log(await greeter('Bob'));

1) No native node.js modules

Add these lines to the bottom of main.ts

import path from 'path';
async function init() {
  console.log(path.basename('test/path/filename.json'));
  console.log(await greeter('Bob'));
}
init();

Then run:

npm run build && npm start
npm test

Notice how start works fine, but test outputs this error:

 RUNS  __tests__/main.test.ts
/Users/kimturley/Sites/node-typescript-boilerplate/src/main.ts:497
  console.log(path_1.default.basename('test/path/filename.json'));
TypeError: Cannot read properties of undefined (reading 'basename')
@jsynowiec
Copy link
Owner

Hi @kmturley, thanks for asking. I believe these are outside the scope of this base template, as these are specific problems with jest and ts-jest. These are not “issues” with the template repository itself.

As you noticed yourself, simply compiling the modified main.ts works, and if you want to get the jest transformer to also handle the ESM module like this, then you can add and enable esModuleInterop in the tsconfig. However, please understand the side effects.

As for the top-level await, this is one of many known challenges when using ts-jest, jest, ESM and TypeScript. People are using different combinations of settings to work around the challenges, with mixed success. If you really need this behavior, please read this and this.

One, example, way to work around this, after reading and understanding the side effects of changed options, is to:

  • Run jest using Node with experimental-vm-modules, like so node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js
  • Ensure that jest is available at runtime in globals using a setup files
  • Set allowJS to true in tsconfig.json.

Here's the diff:

diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts
index 9aaca6e..5d505a0 100644
--- a/__tests__/main.test.ts
+++ b/__tests__/main.test.ts
@@ -40,3 +40,5 @@ describe('greeter function', () => {
     expect(hello).toBe(`Hello, ${name}`);
   });
 });
+
+console.log(await greeter('Bob'));
\ No newline at end of file
diff --git a/jest.config.js b/jest.config.js
index 10696f4..b290a41 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -9,6 +9,9 @@ export default {
   },
   testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(m)?ts$',
   coverageDirectory: 'coverage',
+  setupFiles: [
+    "<rootDir>/test-setup.js"
+  ],
   collectCoverageFrom: [
     'src/**/*.ts',
     'src/**/*.mts',
diff --git a/package.json b/package.json
index e310426..c590855 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "build:watch": "tsc -w -p tsconfig.json",
     "build:release": "npm run clean && tsc -p tsconfig.release.json",
     "lint": "eslint . --ext .ts --ext .mts",
-    "test": "jest --coverage",
+    "test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
     "prettier": "prettier --config .prettierrc --write .",
     "test:watch": "jest --watch"
   },
diff --git a/tsconfig.json b/tsconfig.json
index 4a94f7f..9b122df 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -17,7 +17,8 @@
     "noUnusedParameters": true,
     "noImplicitAny": false,
     "noImplicitThis": false,
-    "strictNullChecks": false
+    "strictNullChecks": false,
+    "allowJs": true
   },
   "include": ["src/**/*", "__tests__/**/*"]
 }

and it will output

╰─ ➜ npm run test

> node-typescript-boilerplate@0.0.0 test
> node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js --coverage

  console.log
    Hello, Bob

      at __tests__/main.test.ts:44:9

 PASS  __tests__/main.test.ts (5.987 s)
 ...

Lastly, because of such challenges with jest, and the overall poor DX around ESM and TypeScript, I'm going to switch this repo to vitest. Please see #56 for more details and further explanation. Your code should work without any additional modifications with vitest.

@kmturley
Copy link
Author

kmturley commented May 9, 2024

Thanks for the quick response and resolution.
Its crazy that in 2024, it is still this difficult to configure tools to use the same language options.
Not heard of vitest but will check it out. Thanks!

@kmturley
Copy link
Author

vitest looks great.

I was interested to see what would happen if I follow the latest guides for each tool:

This was the result:
https://github.com/kmturley/node-typescript-eslint-prettier-vitest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants