Skip to content

esm: Moving exports['.'] to an "index" field#30239

Closed
guybedford wants to merge 8 commits intonodejs:masterfrom
guybedford:exports-conditions-entry
Closed

esm: Moving exports['.'] to an "index" field#30239
guybedford wants to merge 8 commits intonodejs:masterfrom
guybedford:exports-conditions-entry

Conversation

@guybedford
Copy link
Copy Markdown
Contributor

@guybedford guybedford commented Nov 3, 2019

This PR moves the exports['.'] main field to its own field as "index". Modules group discussion issue at nodejs/modules#422.

We previously added sugar for the exports['.'] as just setting exports: String directly. This way "exports" can be thought of as the new main for modules.

When setting this main, users get encapsulated packages by default, then when they want to add exports they can upgrade the String to an object with a dot property and other exports, which is a sensible upgrade step to make, and the dot export makes complete sense in this context as another export.

When considering conditional exports though, we have the problem that this same sugaring cannot apply because when exports is an object we cannot know if it is an object of export paths, or whether it is an object of conditions for the main.

The problem here is a user might start out with a package.json like:

{
  "exports": "./main.js"
}

then decide to upgrade their package to support conditional exports with dual-resolution. They cannot simply change exports to an object at this point, but rather have to change it to an object with a dot property as well (a two-step process as opposed to a single step adjustment):

{
  "exports": {
    ".": {
      "require": "./main.cjs",
      "default": "./main.mjs"
    }
  }
}

The idea of the "index" field is to replace the "exports" sugar with its own field such that this simplifies the definition to just:

{
  "index": {
    "require": "./main.cjs",
    "default": "./main.mjs"
  }
}

@GeoffreyBooth tested against his data set and there were less than 50 cases of index in the wild I believe, with most of those already pointing to a main string.

We've previously been very cautious to get caught up on the definition of a new package.json field here if we could avoid it - which so far we have been able to by using "exports" for both. But I believe the above usability scenario is enough of a concern to warrant reconsideration here, especially considering this is the field most users will set first for many Node.js development experiences, and small frictions matter at this scale.

This PR is a follow-up to the conditional exports PR at #29978, and is based to that branch. The actual diff is only the last commit.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Nov 3, 2019
@guybedford
Copy link
Copy Markdown
Contributor Author

For discussion that is not direct PR review, please use the modules group issue at nodejs/modules#422.

@guybedford guybedford force-pushed the exports-conditions-entry branch from 378a666 to 646cb3f Compare November 3, 2019 19:49
@hybrist
Copy link
Copy Markdown
Contributor

hybrist commented Nov 4, 2019

For completeness sake, one potential alternative syntax for this would also be:

{
  "exports": [{
    "require": "./main.cjs",
    "default": "./main.mjs"
  }]
}

This is using the fallback syntax (array) which means that it also supports a short-hand for default:

{
  "exports": [{
    "require": "./main.cjs"
  }, "./main.mjs"]
}

The downside is that we'd end up with a noisy array wrapper in this case that usually (which using the verbose nested syntax) isn't required around conditionals.

@guybedford guybedford mentioned this pull request Nov 5, 2019
14 tasks
@guybedford
Copy link
Copy Markdown
Contributor Author

As per discussion at today's meeting, we have decided not to implement this proposal for now, and instead will be looking to explore a conditional exports main sugar instead for this case.

@guybedford guybedford closed this Nov 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants