gullerya / object-observer

Object Observer functionality of JavaScript objects/arrays via native Proxy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exported CommonJS package

seidelmartin opened this issue · comments

Hi @gullerya, first of all, thanks for this nice library I'm very happy that I found it but there's an issue that basically restricts me from using it.
Unfortunately, I'm not able to import that package into my codebase because I'm using CommonJS module resolution and your package is only compatible with ES modules.
Would it be possible to extend you build script so it also produces .cjs file that uses module.exports = ... rather than rely on ES export ...?
I've found an article that can be useful in achieving this https://www.sensedeep.com/blog/posts/2021/how-to-create-single-source-npm-module.html

I've created PR that generates also commonjs module #122

Hi @seidelmartin, thanks for kudos, my pleasure!

Sorry for the delay too, has things on the table, work stuff :)

As per CJS here - I do have a couple of concerns about this one, let's talk through couple of them and see if we can find some common ground for this.

I'm generally quite opinionated advocating to leave the CJS behind, actually once I had that support and deliberately dropped it, so it brings few points that I'd like to work along:

  • the current default flavor of the ESM including the relevant parts of package.json and folders structure to be kept as it is, it is also must to preserve the backward compatibility with the current consumers so that they do not required to change anything in the import paths or alike
  • I'd like to keep the dependencies at low as possible, and babel (with its dependencies of course) looks to me too bloated comparatively to other tools (probably unbuild), adding a dev times and maintenance much more than the worth it brings

I've found another article talking on this topic, this one and would like to see WDYT on this:

  • building additional cjs distro files (one basic and one minified), namespaced under their own folder (with min.js and js extensions)
  • adding the exports entry to package.json to resolve the default stuff (the concern expressed in the article you've cited is not relevant to object-observer)
  • replacing the export statement of the code with module.exports which I'd do myself, without bringing any further dependency

Would that work for you?

After reading a bit more in the formal docs, I think that what I'm suggesting maps well to what described as an Isolate State approach in NodeJS documentation.

Hi, so if I understand it correctly you wouldn't mind to include it back but I need to

  • Keep the structure of the dist directory the same and on top of that build the CJS module
  • Build the module with unbuild rather than babel

Sounds good to me, I'll change it in my PR. :)

Yes, in general I'm okay this this.
And just as a suggestion - even before going for unbuild can you please check if kind of snippet below can solve it without any tooling at all:

cjsCode = srcCode.replace(/^export/, 'module.exports =');

Replacing export by module.exports would in general work. The concern I have is that I would have to move the export statement as very last line of file otherwise Observable is not initialized. It's also not very scalable if you decide to split index to multiple files.

So I've updated my PR and refactored the build-utils.js module so it uses mkdir instead of babel. The mkdir is internally used by unbuild.
You can find the structure of dist folder below. I think it matches what you've had before with the difference of ESModule build file has mjs extension.
On top of that, I've also generated source maps since they're useful when debugging from minified file. But I can remove them if you find them useless.

Screenshot from 2022-09-05 10-23-38

Hi @seidelmartin sorry to bother post factum, but I'd like to make sure I'm not missing anything:

  • I've pulled the code
  • entered node and just did a simple require('object-observer') thing
  • it is trying correctly to bring dist/cjs/object-observer.min.js BUT

For this use case node complains with ERR_REQUIRE_ESM since:

  • the extension is js
  • the module's type is module

So I think that given that I'd not like to give up on the module type, we need to make the extensions .cjs for this to work.
WDYT?

And another, minor issue - I'd like to change the main property of package json from pointing to dist/cjs/.. to the ESM's dist/.., I can't see it poses any issues for the CJM support, do you?

Interesting, I've been testing it by copying those newly built files to my project's node_modules and it was working just fine. I'm using typescript so maybe it does some magic...
I've created a PR where I address those issues #124

Perfect, thanks!

@seidelmartin I've released 5.1.0 version that includes the CJS porting, also added a relevant portion about this in the readme (Install section) - let me know what you think and if anything is missing we can do a patch release round.

And if all is well from your side - please close this item!
Huge thanks for help!

@seidelmartin any feedback on this one?

Hi, yeah sorry I've been off for some time. It looks fine. I can confirm that latest version works in node with CJS module resolution. Thanks for help.

Sure thing and thanks to you actually, great contribution!!!
🚀