Skip to content

🐛 Bug - Fails to compile in TypeScript CommonJS project with moduleResolution: node16/nodenext #42

Closed
@tylerbutler

Description

@tylerbutler

🐛 Describe the bug

microdiff doesn't export types correctly for Node16+'s ESM module resolution. This means that using microdiff with a project using moduleResolution: Node16 or NodeNext, which is what TypeScript recommends for Node projects, fails to compile because of missing types.

🧑‍🏫 To Reproduce

When compiling a CommonJS TypeScript project with moduleResolution: node16 or nodenext, importing microdiff results in the following error:

error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("microdiff")' call instead.

To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field `"type": "module"` to ...

See https://arethetypeswrong.github.io/?p=microdiff%401.4.0 and you'll see that microdiff has an ESM types file but none for CJS, so TypeScript ultimately "can't find" the CJS types, so it thinks the package is ESM-only. arethetypeswrong is a great tool to investigate and validate your export map.

🧑‍💻 Code

I can provide a test project if needed.

✅ Expected behavior

No compilation error.

Possible fix

A possible fix would be to create a rolled-up declaration for ESM and CJS using rollup and rollup-plugin-dts. This has worked well in some other projects I've seen, but might not be appropriate here.

Another option might be to use https://github.com/isaacs/tshy to use TypeScript to produce both ESM and CJS output.

Options that are tempting but don't work

You might be tempted to make the exports map look like this and use the same declaration files for all exports. I.e.

"exports": {
  "require": {
    "types": "./dist/index.d.ts",
    "default": "./dist/index.cjs"
  },
  "import": {
    "types": "./dist/index.d.ts",
    "default": "./dist/index.js"
  },
  "default": {
    "types": "./dist/index.d.ts",
    "default": "./dist/index.js"
  }
},

This setup creates the following problems:

🖥️ Runtime Version

Node 18, mac OS ARM

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions