dnt icon indicating copy to clipboard operation
dnt copied to clipboard

Allow CJS to expose the default export with `require(...)` instead of `require(...).default`

Open bgrins opened this issue 3 years ago • 4 comments

Hi, I've been trying to migrate the TinyColor library to use Deno and cross compile to Node (CJS and ESM). It's all working fine (https://github.com/bgrins/TinyColor/pull/241), except for one problem:

The generated CJS exports the object on default when requiring (https://github.com/bgrins/TinyColor/blob/bcfcd1d49181a45fab2dd1858ef22890adba1809/npm/script/mod.js#L50) such that to access it I need to do var tinycolor = require("tinycolor2").default whereas the current behavior and external API works like var tinycolor = require("tinycolor2");. I don't want to change the existing API as the library is used by a lot of people - is there a way to change the output from dnt to match the current behavior?

My best guess was that it's the esModuleInterop option at https://github.com/denoland/dnt/blob/main/mod.ts#L348 which is causing this behavior, but the generated test output also expects to pull the object out of .default so maybe there would need to be more changes as well.

bgrins avatar Dec 20 '22 17:12 bgrins

I checked with unsetting esModuleInterop but no luck. I guess as per the UMD at https://github.com/bgrins/TinyColor/blob/e3b7bdde11e05fe520f0ba63059d4b929a227279/npm/script/mod.js#L6 if the factory function returns an object it will set module.exports to that, which would work. Maybe there's a way to make that happen based on how things get exported in the module or some configuration in the build?

bgrins avatar Dec 20 '22 18:12 bgrins

I'm wondering why this is still an issue a year later! Forcing CJS imports to use the default property is a major drawback and unexpected for users.

uncenter avatar Sep 16 '23 01:09 uncenter

I'm wondering why this is still an issue a year later!

@uncenter it's a much harder problem than you might expect. TypeScript does not provide a way (to my knowledge) to transform an esm default export to a module.exports = ... so that people can do const mod = require(...). Please open a PR if you know a solution and have the time. Thanks!

dsherret avatar Sep 16 '23 03:09 dsherret

I'm wondering why this is still an issue a year later!

@uncenter it's a much harder problem than you might expect. TypeScript does not provide a way (to my knowledge) to transform an esm default export to a module.exports = ... so that people can do const mod = require(...). Please open a PR if you know a solution and have the time. Thanks!

Sorry I didn't mean to come off rudely. I was just surprised that there wasn't any activity on the issue :)

I don't know an exact solution but this isn't a problem in every bundler so I'm guessing there must be a workaround.

uncenter avatar Sep 16 '23 14:09 uncenter