Skip to content

ERR_REQUIRE_ESM when using Node.js ESM in tandem with TypeScript config (commitlint.config.ts) #3251

Closed
@shian15810

Description

@shian15810
// package.json
{
  "type": "module"
}
// tsconfig.json
{
  "compilerOptions": {
    "module": "node16"
  }
}

Expected Behavior

With the given setup above, executing npx commitlint --to HEAD should not result in ERR_REQUIRE_ESM error.

Current Behavior

Currently, the above setup is giving the following output:

./node_modules/ts-node/dist-raw/node-internal-errors.js:46
  const err = new Error(getErrRequireEsmMessage(filename, parentPath, packageJsonPath))
              ^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./commitlint.config.ts
require() of ES modules is not supported.
require() of ./commitlint.config.ts from ./node_modules/cosmiconfig-typescript-loader/dist/loader.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from ./package.json.

    at createErrRequireEsm (./node_modules/ts-node/dist-raw/node-internal-errors.js:46:15)
    at assertScriptCanLoadAsCJSImpl (./node_modules/ts-node/dist-raw/node-internal-modules-cjs-loader.js:584:11)
    at Object.require.extensions.<computed> [as .ts] (./node_modules/ts-node/src/index.ts:1589:5)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Function.Module._load (node:internal/modules/cjs/loader:834:12)
    at Module.require (node:internal/modules/cjs/loader:1012:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at loader (./node_modules/cosmiconfig-typescript-loader/dist/loader.js:12:28)
    at Explorer.loadFileContent (./node_modules/cosmiconfig/src/Explorer.ts:81:32)
    at Explorer.createCosmiconfigResult (./node_modules/cosmiconfig/src/Explorer.ts:89:36) {
  name: 'TypeScriptCompileError'
}

Affected packages

  • cli
  • core
  • prompt
  • config-angular

Possible Solution

  1. Support commitlint.config.cts, or
  2. Use import() to load config

Steps to Reproduce (for bugs)

  1. First step: Minimal setup of commitlint according to the official documentation with package.json and tsconfig.json supplied above.
  2. Second step: Run npx commitlint --to HEAD.
commitlint.config.ts
import type { UserConfig } from "@commitlint/types";

const config: UserConfig = {
  extends: ["@commitlint/config-conventional"],
};

export default config;

Context

Without touching tsconfig.json, if I remove "type": "module" from package.json, npx commitlint --to HEAD can be executed successfully.

But this is not plausible since I have migrated the whole repository to Node.js ESM since the release of TypeScript 4.7 officially supporting it.

Raising this issue as people with similar setup will encounter this as well.

Currently resorted to using commitlint.config.cjs, but still prefer to have commitlint.config.ts in the long run.

Your Environment

Executable Version
commitlint --version 17.0.2
git --version 2.36.1
node --version 18.4.0

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