You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Sep 2, 2023. It is now read-only.
I’m the publisher of the coffeescript package, which is written using CommonJS and has a Node API that includes exports compile and VERSION. Currently dependents can use my package in CoffeeScript via CommonJS code like:
const{ compile }=require('coffeescript');
I would like to be able to provide named exports for dependents that are using ESM syntax, for example:
because the --experimental-modules implementation doesn’t currently support named exports from CommonJS.
Alternatively, I could create a proxy ESM file, like this at the root of my package:
// module.mjs at package rootimportCoffeeScriptfrom'./lib/coffeescript/coffeescript.js';// CommonJS mainexportdefaultCoffeeScript;const{VERSION, compile }=CoffeeScript;export{VERSION,compile};
but then users would have to reference it as from 'coffeescript/module.mjs', not from 'coffeescript'. That’s not terrible, but it’s not as intuitive and familiar (and equivalent to CommonJS) as just from 'coffeescript'.
Efforts So Far
We’ve been blocked on a solution for named exports from CommonJS for a long time. I won’t get into the details, but at the moment none of the solutions currently on the table seem like they will likely be viable.
Package authors want to provide equivalent, and equally good, user experiences for both CommonJS and ESM consumers of their packages. This applies whether the packages themselves are originally written in CommonJS or ESM. Personally, I wouldn’t feel the need for a better dual packages solution if we had a way to provide named exports from the package root (the import { compile } from 'coffeescript' example above). And under the dual CommonJS/ESM package approach, the same specifier (e.g. 'coffeescript') would produce two separate instances, causing potentially unwanted results.
What all the CommonJS named exports solutions proposed so far have in common is that they dynamically attempt to figure out what the named exports from a CommonJS package should be. What if, instead, we rely on the package author to define their CommonJS named exports?
Potential Solution: Named Exports in package.json
Rather than a separate entry point for ESM, what if the package.json simply declared what the named exports are for my package? Then import { compile } from 'coffeescript' could work, because the resolver would know that compile was available as a named export for the package root.
This would nicely complement the package path maps feature we’re also working on. As paths are defined in package.json, the CommonJS named exports could be defined along with them.
If we really want to be ambitious, the named exports could be added to the package.json automatically by the package manager during installation or by npm (the company) via a scan through their registry. The named exports could be determined by running Node in a locked-down sandbox environment and using Reflect.ownKeys on the path, e.g. Reflect.ownKeys(require('coffeescript')). The resulting array could be added to package.json as the named exports for the root path of the package.
The text was updated successfully, but these errors were encountered:
User Story
I’m the publisher of the
coffeescript
package, which is written using CommonJS and has a Node API that includes exportscompile
andVERSION
. Currently dependents can use my package in CoffeeScript via CommonJS code like:I would like to be able to provide named exports for dependents that are using ESM syntax, for example:
Currently, the best I can offer my dependents is:
because the
--experimental-modules
implementation doesn’t currently support named exports from CommonJS.Alternatively, I could create a proxy ESM file, like this at the root of my package:
but then users would have to reference it as
from 'coffeescript/module.mjs'
, notfrom 'coffeescript'
. That’s not terrible, but it’s not as intuitive and familiar (and equivalent to CommonJS) as justfrom 'coffeescript'
.Efforts So Far
We’ve been blocked on a solution for named exports from CommonJS for a long time. I won’t get into the details, but at the moment none of the solutions currently on the table seem like they will likely be viable.
Package authors want to provide equivalent, and equally good, user experiences for both CommonJS and ESM consumers of their packages. This applies whether the packages themselves are originally written in CommonJS or ESM. Personally, I wouldn’t feel the need for a better dual packages solution if we had a way to provide named exports from the package root (the
import { compile } from 'coffeescript'
example above). And under the dual CommonJS/ESM package approach, the same specifier (e.g.'coffeescript'
) would produce two separate instances, causing potentially unwanted results.What all the CommonJS named exports solutions proposed so far have in common is that they dynamically attempt to figure out what the named exports from a CommonJS package should be. What if, instead, we rely on the package author to define their CommonJS named exports?
Potential Solution: Named Exports in
package.json
Rather than a separate entry point for ESM, what if the
package.json
simply declared what the named exports are for my package? Thenimport { compile } from 'coffeescript'
could work, because the resolver would know thatcompile
was available as a named export for the package root.This would nicely complement the package path maps feature we’re also working on. As paths are defined in
package.json
, the CommonJS named exports could be defined along with them.If we really want to be ambitious, the named exports could be added to the
package.json
automatically by the package manager during installation or by npm (the company) via a scan through their registry. The named exports could be determined by running Node in a locked-down sandbox environment and usingReflect.ownKeys
on the path, e.g.Reflect.ownKeys(require('coffeescript'))
. The resulting array could be added topackage.json
as the named exports for the root path of the package.The text was updated successfully, but these errors were encountered: