This repository has been archived by the owner on Sep 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 42
Proposal: CommonJS named exports defined in package.json #324
Labels
Comments
GeoffreyBooth
added
modules-agenda
To be discussed in a meeting
interoperability
cjs
esm
features
proposal
labels
Apr 28, 2019
why not import C from './index.cjs';
export const compile = C.compile;
... i assume you're thinking of something like: "exportNamesBikeshed": [
"compile",
...
] but if the first solution already exists.... i really really dislike having the export bindings out of band from the file that provides them. oh this is proposed because we haven't figured out dual mode nvm... i still really dislike out of band export declarations |
does this need to be an agenda item before we solve dual mode? i wouldn't expect this to be an issue unless we determine that dual mode won't happen. |
Extension resolution would address this, ftr, and is quite viable. |
@GeoffreyBooth can we close this? |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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: