Skip to content

Commit

Permalink
Start a vote on require(esm) markers (#1621)
Browse files Browse the repository at this point in the history
* Start a vote on require(esm) markers

This is a follow-up to the naming bikeshed in nodejs/loaders#221
which is for the implementation in nodejs/node#54563
A summary can be found in nodejs/node#54563 (review)
  • Loading branch information
joyeecheung authored Sep 20, 2024
1 parent b6aea31 commit e502c16
Showing 1 changed file with 58 additions and 4 deletions.
62 changes: 58 additions & 4 deletions votes/initiateNewVote/_EDIT_ME.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# 1. Select a subject for the vote. This can be a question addressed to the TSC
# voting members.
subject: REPLACEME
subject: Choosing a marker to customize default exports returned by `require(esm)`

# 2. You can leave the header instructions as is, or modify them if you see fit.
headerInstructions: |
Expand All @@ -24,8 +24,8 @@ headerInstructions: |
# voters express their preference for each candidates, no matter how many
# there are.
candidates:
- TODO
- TODO
- '`export { foo as "module.exports" };`'
- '`export const __cjsUnwrapDefault = true;`'

# 4. Pass the following to false if it's important to keep the candidates in the
# order you define above. Presenting candidates in a fixed order tends to
Expand All @@ -35,10 +35,64 @@ canShuffleCandidates: true
# 5. Insert here a short description of the vote objectives and link to the
# issue it was discussed on to give the full context.
footerInstructions: |
TBD
This is a follow-up to the naming bikeshed in https://github.com/nodejs/loaders/issues/221
which is for the implementation in https://github.com/nodejs/node/pull/54563
and the follow-on issue in https://github.com/nodejs/node/pull/53848
A short summary can be found in https://github.com/nodejs/node/pull/54563#pullrequestreview-2288424604
# 6. Optionally, insert a brief introduction for the vote PR, in the markdown format.
prBody: |
When a user have an existing CommonJS package like this:
```js
// foo package:
module.exports = function foo () { };
// ESM users get...
import foo from 'foo';
// CommmonJS users get..
const foo = require('foo');
```
Now that `require(esm)` is possible and they can ship ESM to their CommonJS users without breaking them, they would try something like this:
```js
// foo package
export default function foo () { };
// ESM users get...
import foo from 'foo';
// CommmonJS users get..
const foo = require('foo').default; // <--- This is now different!
```
As you can see, for CommonJS consumers this will not be exactly equivalent. Since in ESM the default exports is a property of the name space, they need to access `.default` from the result returned by
`require(esm)`. So the idea is that Node.js can take a marker from package authors to directly customize what `require(esm)` returns in this case.
To keep `const foo = require('foo')` working, the two proposed markers are:
```js
export default function foo () { };
export const __cjsUnwrapDefault = true;
```
or
```js
export default function foo () { };
export { foo as "module.exports" };
```
Further to this vote, there is [a follow-on proposal](https://github.com/nodejs/node/pull/53848) to reuse this marker on namespaces representing CJS modules imported into ESM, where attaching this marker would effectively define a scheme for converting CJS into ESM that would retain full transitive interop semantics allowing arbitrary CJS to be converted into ESM as a non-breaking change.
Under this follow-on marking, when importing some CJS module `bar` into ESM:
```js
module.exports = 'bar';
```
Users importing with `console.log(await import('bar'))` would obtain a namespace object either of the form `ModuleNamespace { __cjsUnwrapDefault: true, default: 'bar' }` or `ModuleNamespace { default: 'bar', 'module.exports': 'bar' }` depending on which option is chosen for this first PR.
The vote should stay open for 7 days, or until all TSC voting members have cast a ballot.
# 7. Optionally, choose an id that will be used for the branch name as well as
# the vote folder name. If not supplied, a UUID will be used.
Expand Down

0 comments on commit e502c16

Please sign in to comment.