commitizen / cz-cli

The commitizen command line utility. #BlackLivesMatter
http://commitizen.github.io/cz-cli/
MIT License
16.77k stars 552 forks source link

Error [ERR_REQUIRE_ESM]: require() of ES Module #916

Open alisonailea opened 2 years ago

alisonailea commented 2 years ago

when trying to build custom commitizen prompt configs in node >14 where

{
  "type": "module",
 }

it throws an error

require() of ES Module /custom-cz.js from /node_modules/commitizen/dist/commitizen/adapter.js not supported.
Instead change the require of index.js in /node_modules/commitizen/dist/commitizen/adapter.js to a dynamic import() which is available in all CommonJS modules.
import { configLoader } from 'commitizen';
const config = configLoader.load();
alisonailea commented 2 years ago

the easiest fix here seems to be to publish the /src directory so as to allow esmodule users to import directly.

tal-rofe commented 1 year ago

As the source code currently requires the adapter main file, assume index.js, this file cannot be ESM-like. This enforces us to use CommonJS in our index.js file - which means: We CANNOT use 3rd party libraries written in ESM

Nowadays packages maintainers going to support ESM only. For example, this inquirer plugin: inquirer-autocomplete-prompt is (as for now) major version 3, and this version enforces ESM only. That means, any adapter using this inquirer-autocomplete-prompt@3 will fail.

Resolution: Replace this line: https://github.com/commitizen/cz-cli/blob/master/src/commitizen/adapter.js#L142 From let adapter = require(resolvedAdapterPath); to let adapter = await import(resolvedAdapterPath)

you-hengh commented 1 year ago

Does cz-cli now support ES modules? I am using the Vitepress framework to write my blog, and their latest version has migrated to ES module mode. I am using cz-cli, but it does not support esmodule, and I do not want to modify the source code myself to solve this problem.

So can you help me? @tal-rofe

tal-rofe commented 1 year ago

Does cz-cli now support ES modules? I am using the Vitepress framework to write my blog, and their latest version has migrated to ES module mode. I am using cz-cli, but it does not support esmodule, and I do not want to modify the source code myself to solve this problem.

So can you help me? @tal-rofe

It is hard to understand the issue you have. Why would you need to modify your source code to use cz-cli? It does not seem like you try to create a new custom commitizen adapter..

I have an example of a package written in ESM, https://github.com/Exlint/cz-vinyl, where I also use cz-cli along.

you-hengh commented 1 year ago

Does cz-cli now support ES modules? I am using the Vitepress framework to write my blog, and their latest version has migrated to ES module mode. I am using cz-cli, but it does not support esmodule, and I do not want to modify the source code myself to solve this problem. So can you help me? @tal-rofe

It is hard to understand the issue you have. Why would you need to modify your source code to use cz-cli? It does not seem like you try to create a new custom commitizen adapter..

I have an example of a package written in ESM, https://github.com/Exlint/cz-vinyl, where I also use cz-cli along.

Thank you very much for your reply. The problem has been solved. As for mentioning modifying the source code, it is because I saw that you wrote about it on April 21st, 2023.

Resolution: Replace this line: https://github.com/commitizen/cz-cli/blob/master/src/commitizen/adapter.js#L142 From let adapter = require(resolvedAdapterPath); to let adapter = await import(resolvedAdapterPath)

jimthedev commented 9 months ago

@tal-rofe I expect that the only way to deal with this is something like commitizen looking at an adapter path to try to determine if the adapter is esm or commonjs and then using await import() if it can positively determine that it is using esm, otherwise it will fall back to the current default require? Does that sound right?

tal-rofe commented 8 months ago

@tal-rofe I expect that the only way to deal with this is something like commitizen looking at an adapter path to try to determine if the adapter is esm or commonjs and then using await import() if it can positively determine that it is using esm, otherwise it will fall back to the current default require? Does that sound right?

Code should only use await import(...) without a condition. When you use import you can import both CommonJS and ESM files. This is the difference. Using require means you must "require" CommonJS file.

@jimthedev

danny-does-stuff commented 6 months ago

I was able to fix this issue by upgrading @commitlint/cz-commitlint. https://github.com/conventional-changelog/commitlint/issues/3949