Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: update to package.exports docs #33074

Closed
wants to merge 24 commits into from
Closed
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 42 additions & 15 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,25 +183,52 @@ versions of Node.js, but its capabilities are limited: it only defines the main
entry point of the package.

The `"exports"` field provides an alternative to `"main"` where the package
main entry point can be defined while also encapsulating the package, preventing
any other entry points besides those defined in `"exports"`. If package entry
points are defined in both `"main"` and `"exports"`, the latter takes precedence
in versions of Node.js that support `"exports"`. [Conditional Exports][] can
also be used within `"exports"` to define different package entry points per
environment, including whether the package is referenced via `require` or via
`import`.
main entry point can be defined while also encapsulating the package,
**preventing any other entry points besides those defined in `"exports"`**.
This encapsulation allows module authors to define a public interface for
their package.

If both `"exports"` and `"main"` are defined, the `"exports"` field takes
precedence over `"main"`.
precedence over `"main"`. It is important to note that `"exports"` are not
specific to ES modules or CommonJS; `"main"` will be overridden by `"exports"`
if it exists. As such `"main"` cannot be used as a fallback for CommonJS
but it can be used as a fallback for legacy versions of Node.js that do not
support the exports field.
MylesBorins marked this conversation as resolved.
Show resolved Hide resolved

[Conditional Exports][] can be used within `"exports"` to define different
package entry points per environment, including whether the package is
referenced via `require` or via `import`. For more information about supporting
both Common.js and ES Modules in a single package please consult
MylesBorins marked this conversation as resolved.
Show resolved Hide resolved
[the dual CommonJS/ES module packages section][].

**Warning**: Introducing the `"exports"` field prevents consumers of a package
from using any entry points that are not defined, including the `package.json`
(e.g. `require('your-package/package.json')`. **This will likely be a breaking
change.**

To make the introduction of `"exports"` non-breaking, ensure that every
previously supported entry point is exported. It is best to explicitly specify
entry points so that the package’s public API is well-defined. For example,
a project that previous exported `main`, `lib`,
`feature`, and the `package.json` could use the following `package.exports`:

Both `"main"` and `"exports"` entry points are not specific to ES modules or
CommonJS; `"main"` will be overridden by `"exports"` in a `require` so it is
not a CommonJS fallback.
```json
{
"exports": {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/index.js": "./lib/index.js",
MylesBorins marked this conversation as resolved.
Show resolved Hide resolved
"./feature": "./feature/index.js",
"./feature/index.js": "./feature/index.js",
"./package.json": "./package.json"
}
}
```

This is important with regard to `require`, since `require` of ES module files
throws an error in all versions of Node.js. To create a package that works both
in modern Node.js via `import` and `require` and also legacy Node.js versions,
see [the dual CommonJS/ES module packages section][].
As a last resort, package encapsulation can be disabled entirely by creating an
export for the root of the package `"./": "./"`. This will expose every file in
jkrems marked this conversation as resolved.
Show resolved Hide resolved
the package at the cost of disabling encapsulation and the tooling and optimization
benefits that come with it.
MylesBorins marked this conversation as resolved.
Show resolved Hide resolved

#### Main Entry Point Export

Expand Down