I am trying to enable Jest to work in my NestJS application, which I have configured to work in an ESModules package. However, when I run the tests, I get an error:
<path>/server/src/common/http-exception/http-exception.filter.spec.ts:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { HttpExceptionFilter } from './http-exception.filter.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1495:14)
How to get it to work? I want to continue using ESModules since it works fine in the non-test files.
Here’s my setup (briefly):
-
package.json
{ "name": "server", "type": "module", "scripts": { "test": "jest" } }
-
tsconfig.json (some of the shown options are derived from a parent tsconfig; an effective result is shown below)
{ "compilerOptions": { "noEmit": true, // this is set to 'false' in tsconfig.build.json "target": "es2020", "module": "esnext", "moduleResolution": "NodeNext", "sourceMap": true, "strict": true, "allowImportingTsExtensions": false, // this seems to be important; see the note below 👇 "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true } }
- A note about
allowImportingTsExtensions
. The project is a monorepo, and what’s shown in this question is itsserver
part/package. There’s also aclient
package. In theclient/tsconfig.json
, theallowImportingTsExtensions
option is set totrue
. And it works fine: if a component is defined incomponent.tsx
, then the test canimport { Component } from './component.tsx'
just fine (note: using.tsx
extension). Moreover, if I changeimport … from '….tsx'
toimport … from '….js'
(which should be allowed), it doesn’t work anymore ("the filecomponent.js
is not found"). I am perfectly fine with importing.tsx
but this behavior requires"moduleResolution": "bundler"
and"noEmit": true
, which isn’t compatible with how NestJS works (it seems to work withdist/**/*.js
files; if there are no files indist
, it’ll fail). Therefore, I setallowImportingTsExtensions
tofalse
and use.js
extensions in test files. But (I think) if I could setallowImportingTsExtensions
totrue
somehow, and use.ts
extensions in imports in test files, this might fix the whole thing. So far, I’m not sure how to do it, and whether this is possible at all with NestJS (and whether it would be the fix).
- A note about
-
jest.config.ts
export default { preset: 'ts-jest', rootDir: '.', projects: [ { displayName: 'unit', testMatch: ['<rootDir>/src/**/*.spec.ts'], }, ], }
-
src/common/http-exception/http-exception.filter.ts
import { BaseExceptionFilter } from '@nestjs/core' @Catch() export class HttpExceptionFilter extends BaseExceptionFilter { // implementation }
-
src/common/http-exception/http-exception.filter.spec.ts
import { HttpExceptionFilter } from './http-exception.filter.js' describe('HttpExceptionFilter', () => { // tests })