miktam / sizeof

Get size of a JavaScript object
MIT License
300 stars 45 forks source link

ESModules? #90

Open jack3898 opened 1 year ago

jack3898 commented 1 year ago

Hey, I found your tool really useful for my project that utilises an LRU cache! Thanks 😄

But, my project uses ESM, and the default export in your package does not work (my solution so far was to copy the indexv2.js locally into my project and adapt it for ESM). What are your thoughts on ESM, is there something you would be open for me to contribute that helps with ESM support? :)

Jack

miktam commented 1 year ago

@jack3898, it would be great if you could contribute with ESM support!

jack3898 commented 1 year ago

The only question I have is, for backwards compatibility sake I think the best potential way we could go about it is to create an indexv2.mjs (mjs is important) file with the module in it which may mean duplicated code. Or the export in indexv2.js can be changed to a named export (amending the declaration file as well). 😔 Well that's from my experience anyway.

Maybe you might (or might not!) want to go the hard direction that the popular package "chalk" did where they deprecated cjs modules and made their next major release esm only. Same with superjson I think. But more and more packages seem to be pushing for it but lots of projects still rely on cjs.

What do you think about all of this? Any direction you want to take? There's a few ways to go about it, all with their pros and cons.

miktam commented 1 year ago

@jack3898 thank you for the proposal.

Let's add GPT-4 into our loop. Here is what has been produced based on your comment, adding for our discussion:

Here are the potential solutions that you've also touched upon:

    Creating a separate file with .mjs extension: This approach involves maintaining a separate file for the ES Module version of the code. This means that we would have duplicate code but it allows users to explicitly opt-in to ESM if they are ready.

    Switching to named exports: This involves refactoring the code to support named exports which can work with both CommonJS and ESM. However, this might require the consumers of this library to update how they import the module.

    Following the path of packages like 'chalk': Essentially dropping support for CommonJS in the next major release and fully adopting ESM. This is cleaner in the long term but requires consumers to update their code and might not be suitable for those who are not ready to move to ESM.

Each of these options has its own pros and cons as you've mentioned. I'm personally leaning towards creating a separate .mjs file as it offers flexibility for the consumers. However, I am open to suggestions and would love to hear what the community prefers.

Creating a separate file with a .mjs extension for supporting ES Modules alongside the CommonJS module has its pros and cons:

Pros:

    Backward Compatibility: By creating a separate file with .mjs extension, you are not modifying the existing CommonJS module. This ensures backward compatibility for existing users who are using the CommonJS version.

    Explicit Choice for Users: With separate files for CommonJS and ES Modules, users have an explicit choice in selecting which module system they want to use based on their project requirements.

    Adherence to Standards: Using the .mjs extension aligns with the standard for distinguishing between CommonJS and ES Modules in Node.js, which can be beneficial in terms of conforming to community standards.

    Incremental Migration: For projects looking to migrate from CommonJS to ES Modules, having a separate .mjs file can facilitate an incremental migration path.

Cons:

    Code Duplication: Since you need to maintain two versions of the code (CommonJS and ES Modules), there is a possibility of code duplication which can lead to maintenance overhead.

    Keeping in Sync: Whenever you update one version of the code, you'll need to make sure the changes are reflected in the other version as well. This can sometimes lead to inconsistencies if not managed carefully.

    Increased Complexity for Users: Some users might find it confusing to have two separate files for different module systems. They may not be sure which one to use or might use them inconsistently.

    Testing Overhead: Having two versions of the code means that you need to ensure that tests are run against both versions, potentially doubling the testing effort.

Overall, creating a separate .mjs file can be a good interim solution for supporting both CommonJS and ES Modules without breaking existing functionality. However, it does come with maintenance overhead and complexity, which should be considered.