conventional-changelog / commitlint

📓 Lint commit messages
https://commitlint.js.org
MIT License
16.81k stars 905 forks source link

TypeError: format is not a function #645

Open reintroducing opened 5 years ago

reintroducing commented 5 years ago

Expected Behavior

I'm trying to commit in a new repository that uses husky and my commit should work and pass husky checks as expected.

Current Behavior

When I try to commit, I see the following:

husky > commit-msg (node v10.3.0)
/Users/mprzybylski/Work/Livongo/fe-utils/node_modules/@commitlint/cli/lib/cli.js:113
    throw err;
    ^

TypeError: format is not a function
    at /Users/mprzybylski/Work/Livongo/fe-utils/node_modules/@commitlint/cli/lib/cli.js:193:18
    at run (/Users/mprzybylski/Work/Livongo/fe-utils/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:75:22)
    at /Users/mprzybylski/Work/Livongo/fe-utils/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:92:30
    at flush (/Users/mprzybylski/Work/Livongo/fe-utils/node_modules/babel-polyfill/node_modules/core-js/modules/_microtask.js:18:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)
husky > commit-msg hook failed (add --no-verify to bypass)

Affected packages

Possible Solution

I'm not sure, and the odd thing is this works in my pre-existing repos, but it fails in this new one.

Steps to Reproduce (for bugs)

  1. Make changes to files.
  2. Commit changes. Error.

I've created a small repo that reproduces the problem here: https://github.com/reintroducing/commit-test

commitlint.config.js ```js module.exports = { extends: ['@spothero/commitlint-config'] }; ```

Context

I can't commit to the new repo unless i bypass husky checks. I'm using a custom commitlint config which can be found here: https://github.com/spothero/commitlint-config

Your Environment

Executable Version
commitlint --version 7.5.2
git --version 2.20.1 (Apple Git-117)
node --version 10.3.0
aaryn101 commented 5 years ago

I am seeing the same thing. It only appeared after upgrading to husky@2.2.0.

reintroducing commented 5 years ago

for what its worth, my commitlint setup is pinned to husky@1.3.1.

reintroducing commented 5 years ago

I went ahead and added a link to a repo I just created which reproduces the problem: https://github.com/reintroducing/commit-test

mattwills8 commented 5 years ago

Also seeing it, started today after package updates!

Using VSCode with prettier and eslint

marionebl commented 5 years ago

Thanks for reporting, I'll look into this.

marionebl commented 5 years ago

Could reproduce - this is caused by a mismatch between the @commitlint/format (7.6.0) and @commitlint/cli (7.5.1) package versions. Could you install the latest cli and check if this fixes the issue for you?

npm install @commitlint/cli@latest
keenwon commented 5 years ago

@marionebl @commitlint/core exported the wrong format?

mattwills8 commented 5 years ago

@marionebl worked for me, thanks!!

reintroducing commented 5 years ago

@marionebl that did indeed fix it, thank you, appreciate the quick turn around on this.

varl commented 5 years ago

I'm importing from @commitlint/format and I have the same problem.

The docs for @commitlint/format are no longer correct.

Test code for @commitlint/format:

const format = require('@commitlint/format')
console.log('format', typeof format)
format({})

Result: 7.5.0

format function

Result: 7.6.0

format object
// { default: [Function: format],
//  formatResult: [Function: formatResult] }
[ERROR] TypeError: format is not a function

Test code for @commitlint/core:

const { read, load, lint, format } = require('@commitlint/core')

console.log('format', typeof format)
console.log('load', typeof load)
console.log('read', typeof read)
console.log('lint', typeof lint)

Result: 7.5.0

format function
load function
read function
lint function

Result: 7.6.0

format object
load function
read function
lint function
[ERROR] TypeError: format is not a function

To me this is actually a breaking change for @commitlint/format and @commitlint/core since the API has changed in a non-backwards compatible way.

Is this intentional and going forward we should import from require('@commitlint/format').default?

marionebl commented 5 years ago

To me this is actually a breaking change for @commitlint/format and @commitlint/core since the API has changed in a non-backwards compatible way.

Thanks for the analysis - you are right about the accidental breaking change. I'm in the process of creating a patch release that addresses this.

Is this intentional and going forward we should import from require('@commitlint/format').default?

No, when 7.6.1 and (later) 8.0.0 are released you'll be able to require the default export of @commitlint/format directly.

varl commented 5 years ago

@marionebl thanks for your response, and effort in fixing it. 👍

marionebl commented 5 years ago

Fixed via @commitlint/format@7.6.1

varl commented 5 years ago

Hi @marionebl

This is broken again in 8.0.0 with no mention in the changelog.

const format = require('@commitlint/format')
console.log(format)
/* result =>

{ __esModule: true,
  default: [Function: format],
  format: [Function: format],
  formatResult: [Function: formatResult] }

*/

The imports for read, load, lint all have the default export exposed. Is the plan to change those as well?

Either way, I didn't see the breaking change for format in the changelog so I am unsure if this is intentional.

This change solves it, but is is inconsistent with the sibling packages:

@@ -1,7 +1,7 @@
 const read = require('@commitlint/read')
 const load = require('@commitlint/load')
 const lint = require('@commitlint/lint')
-const format = require('@commitlint/format')
+const { format } = require('@commitlint/format')
 const config = require('@commitlint/config-conventional')
skeggse commented 4 years ago

I'm currently working around this in a (hopefully) forward-compatible way like:

import * as commitlint from '@commitlint/core';

import interopRequireDefault from '@babel/runtime/helpers/interopRequireDefault';
const format = interopRequireDefault(commitlint.format),
  lint = interopRequireDefault(commitlint.lint),
  load = interopRequireDefault(commitlint.load);

// format is not a function

Since this is an error again (per @varl) and as recent as 8.3.2, can we re-open this issue?

elliotleelewis commented 4 years ago

This is also broken in 9.1.1 with @commitlint/lint. 😢

Get the same error: TypeError: lint is not a function

salolivares commented 4 years ago

Yep, 9.1.1 @commitlint/lint and @commitlint/load are broken.

const load = require('@commitlint/load')
console.log(load)
/* =>

{ default: [AsyncFunction: load] } 
*/

The fix is just add .default: const load = require('@commitlint/load').default. The API docs need to be updated if this was intended.

escapedcat commented 4 years ago

@salolivares thanks for the info!
Does this solve the issue?
If yes, would you mind updating the docs?

elliotleelewis commented 4 years ago

@escapedcat I dont think that's a long-term solution. This seems like a workaround?

escapedcat commented 4 years ago

Not sure what to do with this.
If .default works I feel it's good solution.
Or anyone has a suggestion what might need to be changed here to create a better solution?

elliotleelewis commented 4 years ago

I think the problem is with your tsconfig.shared.json. Your target is set to es2017 instead of es5, so the default method being exported is an async method, and I'm not sure if the require(...) syntax stumbles over that?

Any particular reason why we're targeting es2017 vs es5?

EDIT: Here's what I see when inspecting a couple of packages' contents...

@commitlint/resolve-extends works perfectly fine, and here is its default export (lines 23 and 35):

image

@commitlint/lint doesn't work, and here is its default export (lines 12 and 117):

image

The only difference that I can see between them is the async tag on the method declaration in @commitlint/lint? Using target: "es5" should fix that? 😃

escapedcat commented 4 years ago

@elliotleelewis thanks for the info.
Someone just mentioned that the babel preset ist still targeting node v6.
Might be good to clean this up. Instead of targeting es5 maybe we should just target node 12 because that's the currently supported node version.

armano2 commented 3 years ago

@elliotleelewis thanks for the info. Someone just mentioned that the babel preset ist still targeting node v6. Might be good to clean this up. Instead of targeting es5 maybe we should just target node 12 because that's the currently supported node version.

this is unrelated, as babel is not used to compile code anymore

The only difference that I can see between them is the async tag on the method declaration in @commitlint/lint? Using target: "es5" should fix that? 😃

in theory yes, but this is really bad idea, as code is going to be way slower (due to transforms)


personally i will recommend adding non default export to load like it has been done to format, and let ppl import as

const { load } = require('@commitlint/load')
marklai1998 commented 7 months ago

give it a push, I'm getting this in 19.0.3

ezeamin commented 7 months ago

Hi! Got this error on 19.0.3 (Node 21.2.0). It's on @commitlint/cli:

(...)/node_modules/@commitlint/cli/lib/cli.js:129
        throw err;
        ^

TypeError: format is not a function
    at main (file://(...)/node_modules/.pnpm/@commitlint+cli@19.0.3_@types+node@20.11.24_typescript@5.3.3/node_modules/@commitlint/cli/lib/cli.js:280:20)
robweiss22 commented 7 months ago

Also seeing this error as of a today:

node_modules/@commitlint/cli/lib/cli.js:129
        throw err;
        ^

TypeError: format is not a function
JounQin commented 7 months ago

@ezeamin @robweiss22 Please provide online reproduction instead of only error messages.

robweiss22 commented 7 months ago

@JounQin Please see this example: https://github.com/Vunovati/pino-opentelemetry-transport/actions/runs/8142947695/job/22339436738?pr=147#step:7:9

JounQin commented 7 months ago
image

@robweiss22 I can't reproduce it on GitPod, you need to provide an online and runnable reproduction with steps.

robweiss22 commented 7 months ago

Our issue is from a private repo, so I can't share our exact case. For now we have downgraded to version 18 which worked for us. Hopefully @ezeamin can share some more information.

ezeamin commented 7 months ago

@robweiss22 Will see if tomorrow morning I can get a reproduction.

ezeamin commented 7 months ago

@robweiss22 @JounQin reinstalling node_modules did it for me. I tried with many different commits, with different options, but after deleting node_modules and installing them again (@commitlint/cli v19.0.3), everything worked ok, and I wasn't able to reproduce the issue. For what it's worth, this error happened to me only when using pnpm instead of npm.

marklai1998 commented 7 months ago

removing node_module with pnpm did help

jaklan commented 6 months ago

Also faced the same issue when using commitlint as pre-commit:

repos:
  # commitlint
  - repo: local
    hooks:
      - id: commitlint
        name: commitlint
        language: node
        additional_dependencies:
          [commitlint@~19, "@commitlint/config-conventional@~19"]
        entry: commitlint
        args: [--edit]
        stages: [commit-msg]

The output:

commitlint...............................................................Failed
- hook id: commitlint
- exit code: 1

file:///Users/<user>/.cache/pre-commit/repoptynl_vl/node_env-system/lib/node_modules/commitlint/node_modules/@commitlint/cli/lib/cli.js:127
        throw err;
        ^

TypeError: format is not a function
    at main (file:///Users/<user>/.cache/pre-commit/repoptynl_vl/node_env-system/lib/node_modules/commitlint/node_modules/@commitlint/cli/lib/cli.js:272:20)

Node.js v21.7.1

Running pre-commit clean to do the fresh install (== remove the whole /Users/<user>/.cache/pre-commit directory) didn't resolve the issue.

[commitlint@~18, "@commitlint/config-conventional@~18"] works with no issues.

HARISHSENTHIL commented 6 months ago

Format test › works if Format works

TypeError: covenantsql.format is not a function

   8 | describe("Format test", () => {
   9 |   it("works if Format works", () => {
> 10 |     const formatted = covenantsql.format('select * from ?? limit ?', ['test_table', 1])
     |                                   ^
  11 |     expect(formatted === 'select * from `test_table` limit 1').toBeTruthy()
  12 |   })
  13 | })

i am getting this error . i have installed everything perfectly please help me to resolve this issue

sgammon commented 6 months ago

I ran into this today, and adding:

public-hoist-pattern[]=@commitlint*
public-hoist-pattern[]=commitlint

... to .npmrc, then running pnpm install, fixed it for me, with pnpm@9.0.5.