planetscale/database-js

Add support for CJS imports

miketromba opened this issue · 9 comments

See issue: #100
Specifically, my comment here: #100 (comment)

For many typescript users, especially those using ts-node in their environment, a CJS export of this package would be a huge improvement to the DX.

Here is a great article from a maintainer who solved the same problem within his package (supporting both ESM and CJS since most users are still using CJS). He includes specifics of how to implement this setup: https://evertpot.com/universal-commonjs-esm-typescript-packages/

TLDR: Within package.json, you can specify both a CJS export and an ESM export so that users automatically get the right version of this library for their environment when they import it.

E.g.

{
  "type": "module",
  "exports": {
    "require": "./cjs/index.js",
    "import": "./esm/index.js"
  },
  "main": "cjs/index.js"
}

When specifying your package.json this way, Node will automatically load the correct (cjs/esm) directory depending on what the user needs. This all happens automatically. Neat!

Created PR #123

for the love of god yes. Im categorically blocked with my app until this is sorted. I have a barely instantiated nrwl/nx monorepo with a nestjs application and a nodejs library that builds a drizzle schema and exports a planetscale connection. Everything i do to fix it leads back to this ->

F:\...\product-suite\node_modules\.pnpm\@nx+js@16.5.2_@swc-node+register@1.4.2_@swc+core@1.3.69_nx@16.5.2_typescript@5.1.6\node_modules\@nx\js\src\executors\node\node-with-require-overrides.js:18
        return originalLoader.apply(this, arguments);
                              ^
Error [ERR_REQUIRE_ESM]: require() of ES Module F:\...\product-suite\node_modules\.pnpm\@planetscale+database@1.8.0\node_modules\@planetscale\database\dist\index.js from F:\...\haven-world-tours\product-suite\dist\apps\web-server\main.js not supported.
Instead change the require of index.js in F:\client-projects\haven-world-tours\product-suite\dist\apps\web-server\main.js to a dynamic import() which is available in all CommonJS modules.

@binaryartifex For now, the temporary solution I'm using is to build the package locally and store it in my codebase. You can do the same by cloning this cjs fork (https://github.com/miketromba/database-js-cjs/tree/main) and running npm install && npm build Then, grab the built dist folder, rename it to e.g. planetscale-database-js, add it to your codebase, and import the library from there. Not a good long-term solution because you have to do this each time the library updates, but it works for now.

Hey y'all! Sorry for the delay in replying to this one. I'm hoping to get some time this week to review and come to a decision on CommonJS.

For my own understanding, what's preventing the use of ESM in certain projects? Looking at ts-node, I see they have support (although it's marked as experimental) for ESM modules, so I don't know why our driver won't work as-is today. I would love some additional context here about how it's being used to better understand, thanks!

@miketromba is there any reason why #123 came to a grinding halt? seems like a no brainer merge?

EDIT: yeah with your temp fix, bit too hard of a sell for the powers that be i think im just gonna have to use a mysql2 connection instead moving forward until this lib plays nice with commonjs

@iheanyi at present im having a good ol time screaming at my nrwl/nx monorepo because it shits the bed whenever i try to import between node libs that export anything remotely resembling an esm module that doesn't have a commonjs build. something to do with their node builder or something im already in over my head with tasks to trouble shoot any further. basically if it doesn't have commonjs support im up a creek atm

@iheanyi Hi Iheanyi, thanks for the consideration. It's mostly a problem of inertia.

ESM is great for greenfield projects if you're willing to deal with a few peculiarities here and there. If I were starting a project today, I would attempt to go with ESM. The problem is that a substantial portion of large, existing codebases operate in CommonJS environments, and are incompatible with ESM-only modules. Trying to launch your project with this module will throw confusing console errors at you.

In theory, most codebases could probably be migrated to ESM, but that means getting buy-in, spending time researching and learning about the differences, and spending valuable dev cycles on the upgrade. IMO that's asking a lot just to be able to use one module.

It's also very confusing for newer JS devs when they import a module expecting it to work and they start getting strange errors / their app won't launch. In my own experience, before learning more about the JS modules ecosystem, this set me off on multiple many-hour sessions of pulling my hair out trying to get the modules I want to use to work in my codebase, only to rip them out and replace with other CJS-friendly modules instead.

That being said, I don't advocate for staying stuck in the past and throwing out ESM / reverting to CJS. Instead, I suggest a hybrid approach - support both ESM and CJS so that all developers, not just 50% (no clue what the actual number is) have a great experience when using this module regardless of which ecosystem they're operating in. Then, once the node.js world comes around and 95%+ of projects are / have upgraded to ESM, simply bump the major version of the repo and cut out CJS support. I created a PR, and as you'll see, it's just a small one-line tweak to how the project is built.

Also, to my understanding, ESM projects are backwards-compatible with CJS, but not vice-versa.

Finally, for some more voices on the topic, here's an interesting reddit thread from 14 days ago that got a lot of attention, where devs share their experiences / debate about CJS vs ESM: https://www.reddit.com/r/node/comments/14rg9ym/esm_not_gaining_traction_in_backend_node/

Hope that helps.

so are we merging #123? i think there's plenty enough argument to support it

Hey y'all, as a heads up, a new release has been cut!