Skip to content

Output is not compatible with ESM with esModule: true #476

@tichopad

Description

@tichopad

Hey folks! 👋

First off, I really appreciate the work you've put into this - making it super easy to build cross-compatible packages! ❤️

Issue description:

Now, I'm migrating a Node.js + NPM package to Deno + JSR & NPM.

The transform correctly outputs source files in an ESM format, however the output package.json doesn't use "type": "module", which causes Node to not recognize the module format and error out.

I can easily add "type": "module" to the build config, which then propagates to the output package.json file and produces a working ESM-compatible package.
But this then makes the dnt's generated test runner fail.

Cause:

The issue's caused by the generated test_runner.js using CJS even with esModule: true. Once I switch to "type": "module", Node expects all the output code to be ESM and the test step during the transform fails.

Steps to reproduce:

  1. Clone https://github.com/tichopad/alacritty-theme-switch/tree/mt-version-3.x
  2. Change test to true in https://github.com/tichopad/alacritty-theme-switch/blob/mt-version-3.x/scripts/build-npm.ts
  3. Run deno install && deno task build-npm
  4. Get an error
The error
[dnt] Transforming...
[dnt] Running npm install...

added 25 packages, and audited 26 packages in 1s

3 packages are looking for funding
run npm fund for details

found 0 vulnerabilities
[dnt] Building project...
[dnt] Type checking ESM...
[dnt] Emitting ESM package...
[dnt] Running post build action...
Added shebang to ./npm/esm/src/main.js
[dnt] Running tests...

alacritty-theme-switch@3.0.0-beta.9 test
node test_runner.js

file:///home/pernik/Projects/alacritty-theme-switch-v3/npm/test_runner.js:1
const pc = require("picocolors");
^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/home/pernik/Projects/alacritty-theme-switch-v3/npm/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///home/pernik/Projects/alacritty-theme-switch-v3/npm/test_runner.js:1:12
at ModuleJob.run (node:internal/modules/esm/module_job:303:25)
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:663:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:99:5)

Node.js v24.0.2
error: Uncaught (in promise) Error: npm run test failed with exit code 1
throw new Error(
^
at runCommand (https://jsr.io/@deno/dnt/0.42.3/lib/utils.ts:56:13)
at eventLoopTick (ext:core/01_core.js:179:7)
at async build (https://jsr.io/@deno/dnt/0.42.3/mod.ts:431:5)
at async file:///home/pernik/Projects/alacritty-theme-switch-v3/scripts/build-npm.ts:6:1

Temporary fix:

Disable tests by setting test: false or revert to CJS.

Actual fix:

The output test_runner.js would have to be ESM-compatible when esModule is set to true.

Additionally, I'd expect the output package.json to automatically set "type": "module" when esModule is set to true, but that could be considered a breaking change and it's not directly related to the error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions