Skip to content

[Feature]: Support .mts files being passed to --config for CJS projects with node type stripping #15780

@ashleybartlett

Description

@ashleybartlett

🚀 Feature Proposal

I ask that Jest adds support for passing in a .mts file being passed to --config and parsed as ESM during node type stripped importing

Motivation

I have a project (internal) that is currently configured to CommonJS, but we write all our code in ESM format and rely on Typescript to compile (more of an oversight than a conscious choice).

With the recent change in node 22.18 (LTS) that enables type stripping by default this caused us some headaches, as it broke our existing flow due to config not being native ESM compatible (just lacking extension on relative import).

The issue I have is that because our project does not have ESM enabled, as I use config imports to have some shared base config, and different CI config, node gives a warning parsing as they are parsed by node as CJS first. I does successfully then try ESM parsing and works. This is all due to how node module lookups work. It's possible to override this default CJS behaviour by using the .mts extension on the config files.

Unfortunately jest --config=<configFile> does not accept a .mts file. I ended up creating shim .ts config files that import the .mts versions, as a workaround, but it doubles the number of config files.

Example

Running with .ts. files that
Imaging a basic config setup like:

// ./test-config/jest.config.ts
import type { Config } from 'jest';
import { createDefaultPreset } from 'ts-jest';

const defaultPreset = createDefaultPreset();

/** All configs inherit these base settings */
const config: Config = {
  ...defaultPreset,
  rootDir: '../',
  testEnvironment: 'node',
  testMatch: ['<rootDir>/src/**/*.test.ts'],
};

export default config;

//  ./test-config/jest.config.ci.ts
import type { Config } from 'jest';

// this is the relative import that throws a warning
import defaultConfig from './jest.config.ts';

const config: Config = {
  ...defaultConfig,
  collectCoverage: true,
  coverageDirectory: '<rootDir>/test-reports',
  reporters: ['default', ['jest-junit', { outputDirectory: '<rootDir>/test-reports', outputName: 'unit-test.xml' }]],
  ci: true,
};

export default config;

Then I call jest with this config with type stripping enabled:

$ jest -c ./test-config/jest.config.ci.ts
(node:91) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///opt/atlassian/pipelines/agent/build/test-config/jest.config.ts is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to /opt/atlassian/pipelines/agent/build/package.json.
(Use `node --trace-warnings ...` to show where the warning was created)

Ideally I can just rename the config files to `.mts

$ jest -c ./test-config/jest.config.ci.mts

Pitch

Adding support for .mts files would make it easier to use, should be trivial to implement, and make it easier to use native type stripping in existing CommonJS projects.

When I looked at the code flow, it looks like it would be natively supported pretty easily with minimal changes, where similar code was written recently on #15720 and #15682

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions