Skip to content

feat!: change root package.json type to module#6034

Draft
JoshuaKGoldberg wants to merge 4 commits into
mochajs:mainfrom
JoshuaKGoldberg:root-package-type-module
Draft

feat!: change root package.json type to module#6034
JoshuaKGoldberg wants to merge 4 commits into
mochajs:mainfrom
JoshuaKGoldberg:root-package-type-module

Conversation

@JoshuaKGoldberg

Copy link
Copy Markdown
Member

PR Checklist

Overview

At long last:

  • package.json's type is switched from "commonjs" to "module"
  • Files are renamed from (.js, .mjs) to (.cjs, .js)

The only "backwards" change here is lib/cli/options.mjs -> lib/cli/options.cjs. It's used in requiremock tests and we haven't migrated to a mocker that supports ESM yet.

💖

@JoshuaKGoldberg

Copy link
Copy Markdown
Member Author

Build failures seem to just be codecov/codecov-action#1876.

@mark-wiemer

Copy link
Copy Markdown
Member

Tests are passing on my Windows machine, Node 20.19.0, with the patched #6040 (ref mark-wiemer@08f921b), no unusual output aside from expected EBADENGINE when installing docs dependencies :)

@mark-wiemer

Copy link
Copy Markdown
Member

Build failures seem to just be codecov/codecov-action#1876.

That bug is old and about random failures, which matches #6036 . I've created a new bug for consistent failures today: #6042 .

@mark-wiemer

Copy link
Copy Markdown
Member

Test failed on my Windows machine with Node v22.12.0:

  346 passing (3m)
  2 pending
  1 failing

  1) FIFO support
       should accept a test passed as a FIFO:
     Error: Couldn't parse JSON: Unexpected token '(', "(node:3652"... is not valid JSON

Original result output: (node:3652) ExperimentalWarning: CommonJS module C:\Users\markw\my-stuff\hello-hello\packages\mocha\packages\mocha\lib\cli\options.cjs is loading ES Module C:\Users\markw\my-stuff\hello-hello\packages\mocha\packages\mocha\lib\cli\one-and-dones.js using require().    
Support for loading ES Module in require() is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
{
  "stats": {
    "suites": 1,
    "tests": 1,
    "passes": 1,
    "pending": 0,
    "failures": 0,
    "start": "2026-06-07T03:12:02.281Z",
    "end": "2026-06-07T03:12:02.282Z",
    "duration": 1
  },
  "tests": [
    {
      "title": "should pass",
      "fullTitle": "suite from FIFO should pass",
      "file": "C:\\Users\\markw\\AppData\\Local\\Temp\\mocha-test-fifo-CH1ftF\\fifo-1",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    }
  ],
  "pending": [],
  "failures": [],
  "passes": [
    {
      "title": "should pass",
      "fullTitle": "suite from FIFO should pass",
      "file": "C:\\Users\\markw\\AppData\\Local\\Temp\\mocha-test-fifo-CH1ftF\\fifo-1",
      "duration": 0,
      "currentRetry": 0,
      "speed": "fast",
      "err": {}
    }
  ]
}
      at toJSONResult (test\integration\helpers.cjs:185:11)
      at invokeMocha.stdio (test\integration\fifo.spec.cjs:44:26)
      at ChildProcess.<anonymous> (test\integration\helpers.cjs:355:5)
      at ChildProcess.emit (node:events:524:28)
      at maybeClose (node:internal/child_process:1101:16)
      at ChildProcess._handle.onexit (node:internal/child_process:304:5)



ERROR: "test-node:integration" exited with 1.
ERROR: "test-node" exited with 1.

I'm going to pause my review now given this is in draft state and you're probably aware of some of these issues :) Happy to continue running Windows- or Linux-specific checks as needed, of course :) thanks for leading this one!

@mark-wiemer mark-wiemer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review given draft state, matches what I want though! Mostly! ;)

Comment thread .github/ISSUE_TEMPLATE/01-bug.yml
```

`mocha.run()` returns a `Runner` instance which emits many [events](https://github.com/mochajs/mocha/blob/9a7053349589344236b20301de965030eaabfea9/lib/runner.js#L52) of interest.
`mocha.run()` returns a `Runner` instance which emits many [events](https://github.com/mochajs/mocha/blob/9a7053349589344236b20301de965030eaabfea9/lib/runner.cjs#L52) of interest.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`mocha.run()` returns a `Runner` instance which emits many [events](https://github.com/mochajs/mocha/blob/9a7053349589344236b20301de965030eaabfea9/lib/runner.cjs#L52) of interest.
`mocha.run()` returns a `Runner` instance which emits many [events](https://github.com/mochajs/mocha/blob/9a7053349589344236b20301de965030eaabfea9/lib/runner.js#L52) of interest.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in my PR (along with the changes in main to change blob/9a7.../lib to blob/main/lib


```js
// test/setup.js
// test/setup.cjs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the fence about changing docs to recommend .cjs extensions for projects that others are creating. It might seem that Mocha only supports CJS files but of course we also support ESM. I think we should keep all examples of user code using the generic .js, both for simplifying this PR and for clarity.

Suggested change
// test/setup.cjs
// test/setup.js

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the change to setup.js in my PR


```bash
mocha --file "./test/setup.js" "./test/**/*.spec.js"
mocha --file "./test/setup.cjs" "./test/**/*.spec.js"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mocha --file "./test/setup.cjs" "./test/**/*.spec.js"
mocha --file "./test/setup.js" "./test/**/*.spec.js"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied this change in my PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I thought we agreed to keep mjs and cjs extensions and avoid js if at all possible. Maybe this is a premature review, nbd if you're already planning on reverting this change.

#5400 (comment)

If we are going to keep some files as CJS and some as ESM in v12 (which I'm OK with), we should always use .cjs and .mjs file extensions, never .js and ideally even add a lint rule for that. Just for absolute clarity :)

  • Me, with a like from Josh

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applies to multiple files

@JoshuaKGoldberg

Copy link
Copy Markdown
Member Author

Ha yeah, I figured I'd come back to this after the Codecov issues were done.

@mark-wiemer

Copy link
Copy Markdown
Member

See also my PR: #6078

Comment thread test/integration/options/ui.spec.cjs
return resolved;
}

if (path.extname(fixture) === ".js") {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we even keep this safety-check? Or should we just remove it and manually fix failing tests?

(I will remove it and see if any tests fail... if none fail, I will be scared of false negatives though!)

? fixture
: path.resolve(__dirname, "fixtures", fixture);

for (const extension of [".cjs", ".js", ".mjs", ".ts"]) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "find a fixture with a matching name and non-matching extension" seems like a significantly new behavior :/

},
"to throw",
"Unable to read /something/wherever: bad file message",
"Unable to read /something/wherever: bad file message: Sinon-provided bad file message",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a change we want to keep?

Comment thread eslint.config.cjs
sourceType: "module",
ecmaVersion: 2025,
},
rules: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?

'" "' +
path.join("bin", "mocha") +
'" -R json --require test/compiler-fixtures/js.fixture "test/compiler-cjs/*.js"',
'" -R json --require test/setup.cjs --require test/compiler-fixtures/js.fixture.cjs "test/compiler-cjs/*.js"',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the new require in these few files?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🛠️ Repo: Switch from CJS to ESM internally

2 participants