Skip to content

module: implement logical conditional exports ordering

This updates the ordering of matching for conditional exports to apply in logical order, as opposed to an invisible priority order of the conditions set by the resolver itself. This effectively makes the logic line up with the intuitive model that @sokra proposed in https://github.com/nodejs/modules/issues/452#issuecomment-562442188.

The main reason is that with many conditions, making sense of what will match becomes almost impossible. Consider for example:

{
  "exports": {
    "browser": "./main-browser.js",
    "production": "./main-production.js",
    "development": "./main-dev.js",
    "node": "./main-node.js",
    "default": "./main.js"
  }
}

Strictly speaking, the resolver order of the above would be (assuming either core support for production / development, or through a custom flag): 1. production/development 2. browser/node 3. default.

Yet as a user setting the browser + production condition, there is no clear indication at all that "browser" will never be used, and "production" will always take priority. With this change, "browser" is chosen first whenever browser is enabled.

By moving to object order, the user is in full control of the matching, and can be sure their preferred target condition will be selected first.

The other change is with nesting, for example in:

{
  "exports": {
    "production": {
      "browser": "./asdf.js"
    },
    "default": "./x.js"
  }
}

Currently if in the "node" + "production" environment, trying to load the package will throw entirely because we greedily match the "production" condition, and then fail to match the browser condition and then bail.

With this PR, the failure on the "production" condition will still fall back to trying the "default" condition, providing a nicer fallback workflow.

The examples of production / browser are all hypothetical to explain the semantics - the conditions supported remain the same under this PR.

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