ForbesLindesay/atdatabases

Dynamic import returns double-nested `default` for `@databases/split-sql-query`

geelen opened this issue · 1 comments

Using "@databases/split-sql-query": "^1.0.3",:

❯ node
Welcome to Node.js v18.3.0.
Type ".help" for more information.
> splitExports = await import('@databases/split-sql-query')
[Module: null prototype] {
  __esModule: true,
  default: {
    hasValues: [Function: hasValues],
    hasSemicolonBeforeEnd: [Function: hasSemicolonBeforeEnd],
    default: [Function: splitSqlQuery]
  },
  hasSemicolonBeforeEnd: [Function: hasSemicolonBeforeEnd],
  hasValues: [Function: hasValues]
}

I've been working on https://github.com/geelen/npx-import and experimenting with dynamically installing & loading modules like this, but never seen a doubly nested default export like this. I know this kind of CJS/ESM interop can be kinda weird to debug, so this issue is more of an FYI more than anything. But thought you might want to know...

This happens because the module is compiled to CommonJS for maximum backwards compatibility, but node.js (& some other environments) screwed this up when they added support for ESM. The result is that every early adopter of ESM is now forced to update every package and painstakingly adjust it to work with both. It's a massive pain.

Most of the packages in this repo actually work around it by doing:

module.exports = Object.assign(
  DefaultExport,
  {
    default: DefaultExport,
    NamedExportA,
    NamedExportB
  }
)

This works pretty well in most, but not all environments, but it's extra effort so I haven't historically bothered on packages that I expect will only really be used internally, like split-sql-query.