I recently experienced a memory leak in my jest with ts-node tests in my Nestjs project. After debugging, all evidence pointed towards jest being the issue so I started to migrate to vitest, following the guide here: https://docs.nestjs.com/recipes/swc#vitest. I also migrated my build step to SWC for consistency.
I'm currently experiencing an issue EXCLUSIVLEY when running tests, getting the error SyntaxError: Cannot use import statement outside a module for each of my TypeOrm entitles. I do not have this issue when building and running the dev server.
I'm currently using a glob to point to my entities directory. When I manually import each of my entities and add them to the entities array in my datasource, the tests run fine.
Here's my vitest.config.ts for context (located in test dir, hence strange paths):
import { defineConfig } from 'vitest/config';
import swc from 'unplugin-swc';
import { config } from 'dotenv';
const env = config({ path: '../.env.test' }).parsed;
export default defineConfig({
test: {
globals: true,
testTimeout: 0,
pool: 'threads',
poolOptions: {
threads: {
maxThreads: 1,
minThreads: 1,
},
},
include: ['**/*.e2e-spec.ts'],
root: './..',
env,
},
plugins: [
swc.vite({
sourceMaps: true,
minify: false,
jsc: {
parser: {
syntax: 'typescript',
decorators: true,
dynamicImport: true,
},
transform: {
legacyDecorator: true,
decoratorMetadata: true,
},
baseUrl: './..',
},
}),
],
});
And here's my datasource config:
import { ConfigService } from '@nestjs/config';
import { DataSourceOptions } from 'typeorm';
import { NamingStrategy } from './naming-strategy';
import {
AUTOMIGRATE,
DB_HOST,
DB_NAME,
DB_PASS,
DB_PORT,
DB_USER,
DYNO,
} from '../config/config.constants';
import { HEROKU_PRIMARY_DYNO_NAME } from '../../constants/common-constants';
const IS_TEST_ENVIRONMENT = process.env.NODE_ENV === 'test';
export function typeormConfigFactory(
configService: ConfigService,
): DataSourceOptions {
const migrationsRun =
!global.cli &&
(configService.get(AUTOMIGRATE) ||
configService.get(DYNO) === HEROKU_PRIMARY_DYNO_NAME);
return {
type: 'mysql',
host: configService.get(DB_HOST),
port: configService.get(DB_PORT),
username: configService.get(DB_USER),
password: configService.get(DB_PASS),
database: configService.get(DB_NAME),
timezone: 'Z',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
namingStrategy: new NamingStrategy(),
synchronize: false,
charset: 'utf8mb4',
// Run migrations automatically,
// you can disable this if you prefer running migration manually.
migrationsRun,
logging: IS_TEST_ENVIRONMENT ? [] : ['schema', 'error', 'warn'],
migrations: [__dirname + '/../../migrations/**/*{.ts,.js}'],
};
}