101arrowz / fflate

High performance (de)compression in an 8kB package
https://101arrowz.github.io/fflate
MIT License
2.21k stars 77 forks source link

Fix types ESM module resolution #170

Closed Methuselah96 closed 1 year ago

Methuselah96 commented 1 year ago

"Are the types wrong?" reveals that the ESM modules in this package are masquerading as CJS from a type perspective (https://arethetypeswrong.github.io/?p=fflate%400.8.0):

image

This PR fixes the situation by creating a separate declaration file per module as recommended in the TypeScript documentation:

It’s important to note that the CommonJS entrypoint and the ES module entrypoint each needs its own declaration file, even if the contents are the same between them. Every declaration file is interpreted either as a CommonJS module or as an ES module, based on its file extension and the "type" field of the package.json, and this detected module kind must match the module kind that Node will detect for the corresponding JavaScript file for type checking to be correct. Attempting to use a single .d.ts file to type both an ES module entrypoint and a CommonJS entrypoint will cause TypeScript to think only one of those entrypoints exists, causing compiler errors for users of the package.

Creating a declaration file per module fixes the type module resolution and fixes the "Are the types wrong?" tests:

image

The resulting built files now all specify whether they are CJS or MJS with the corresponding file extension and each module now has a corresponding declaration file which absolves the need to explicitly list them in package.json#exports:

image

101arrowz commented 1 year ago

This PR seems good but I remember avoiding the .mjs file extension for a reason - I'll have to look into why before merging.

101arrowz commented 1 year ago

I think I made this change to avoid errors when directly importing something like fflate/esm/browser without an extension in some environments. That was probably more necessary a few years ago than today, but I'd still like to support that behavior for backwards compat. Also, .mjs gives a bad MIME type in some static file servers, which could be an issue for people who serve fflate manually.

I think it's possible to fix the types here without switching the file extensions; I'll try to modify this PR to do so.