Next: , Up: Node Packages   [Index]


3.1.1 Package Entry Points

In a package’s package.json file, two fields can define entry points for a package:

"main"

The "main" field is supported in all versions of Node.js; thus, it can be used as a fallback for legacy versions of Node.js that do not support the "exports" field.

To set the ‘main’ entry point for a package, it is advisable to define both "exports" and "main" in the package’s package.json file:

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

When the "exports" field is defined, all subpaths of the package are encapsulated and no longer available to importers. This encapsulation of exports provides more reliable guarantees about package interfaces for tools and when handling semver upgrades for a package. It is not a strong encapsulation since a direct require of any absolute subpath of the package such as require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.

"exports"

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". 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". It is best to explicitly specify entry points so that the package’s public API is well-defined.

subpath exports

When using the "exports" field, custom subpaths can be defined along with the ‘main’ entry point by treating the ‘main’ entry point as the "." subpath:

{
  "main": "./main.js",
  "exports": {
    ".": "./main.js",
    "./submodule": "./src/submodule.js"
  }
}

Now only the defined subpath in "exports" can be imported by a consumer:

import submodule from 'es-module-package/submodule';
// Loads ./node_modules/es-module-package/src/submodule.js

While other subpaths will error.


Next: , Up: Node Packages   [Index]