Skip to content

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

This PR moves the exports['.'] main field to its own field as "index". Modules group discussion issue at https://github.com/nodejs/modules/issues/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 https://github.com/nodejs/node/pull/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

Merge request reports

Loading