11cb0ef41Sopenharmony_ci# Modules: Packages
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci<!--introduced_in=v12.20.0-->
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci<!-- type=misc -->
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci<!-- YAML
81cb0ef41Sopenharmony_cichanges:
91cb0ef41Sopenharmony_ci  - version:
101cb0ef41Sopenharmony_ci    - v14.13.0
111cb0ef41Sopenharmony_ci    - v12.20.0
121cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/34718
131cb0ef41Sopenharmony_ci    description: Add support for `"exports"` patterns.
141cb0ef41Sopenharmony_ci  - version:
151cb0ef41Sopenharmony_ci    - v14.6.0
161cb0ef41Sopenharmony_ci    - v12.19.0
171cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/34117
181cb0ef41Sopenharmony_ci    description: Add package `"imports"` field.
191cb0ef41Sopenharmony_ci  - version:
201cb0ef41Sopenharmony_ci    - v13.7.0
211cb0ef41Sopenharmony_ci    - v12.17.0
221cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/29866
231cb0ef41Sopenharmony_ci    description: Unflag conditional exports.
241cb0ef41Sopenharmony_ci  - version:
251cb0ef41Sopenharmony_ci    - v13.7.0
261cb0ef41Sopenharmony_ci    - v12.16.0
271cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31001
281cb0ef41Sopenharmony_ci    description: Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`.
291cb0ef41Sopenharmony_ci  - version:
301cb0ef41Sopenharmony_ci    - v13.6.0
311cb0ef41Sopenharmony_ci    - v12.16.0
321cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31002
331cb0ef41Sopenharmony_ci    description: Unflag self-referencing a package using its name.
341cb0ef41Sopenharmony_ci  - version: v12.7.0
351cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/28568
361cb0ef41Sopenharmony_ci    description:
371cb0ef41Sopenharmony_ci      Introduce `"exports"` `package.json` field as a more powerful alternative
381cb0ef41Sopenharmony_ci      to the classic `"main"` field.
391cb0ef41Sopenharmony_ci  - version: v12.0.0
401cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/26745
411cb0ef41Sopenharmony_ci    description:
421cb0ef41Sopenharmony_ci      Add support for ES modules using `.js` file extension via `package.json`
431cb0ef41Sopenharmony_ci      `"type"` field.
441cb0ef41Sopenharmony_ci-->
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci## Introduction
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciA package is a folder tree described by a `package.json` file. The package
491cb0ef41Sopenharmony_ciconsists of the folder containing the `package.json` file and all subfolders
501cb0ef41Sopenharmony_ciuntil the next folder containing another `package.json` file, or a folder
511cb0ef41Sopenharmony_cinamed `node_modules`.
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciThis page provides guidance for package authors writing `package.json` files
541cb0ef41Sopenharmony_cialong with a reference for the [`package.json`][] fields defined by Node.js.
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci## Determining module system
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci### Introduction
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciNode.js will treat the following as [ES modules][] when passed to `node` as the
611cb0ef41Sopenharmony_ciinitial input, or when referenced by `import` statements or `import()`
621cb0ef41Sopenharmony_ciexpressions:
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci* Files with an `.mjs` extension.
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci* Files with a `.js` extension when the nearest parent `package.json` file
671cb0ef41Sopenharmony_ci  contains a top-level [`"type"`][] field with a value of `"module"`.
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci* Strings passed in as an argument to `--eval`, or piped to `node` via `STDIN`,
701cb0ef41Sopenharmony_ci  with the flag `--input-type=module`.
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciNode.js will treat the following as [CommonJS][] when passed to `node` as the
731cb0ef41Sopenharmony_ciinitial input, or when referenced by `import` statements or `import()`
741cb0ef41Sopenharmony_ciexpressions:
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci* Files with a `.cjs` extension.
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci* Files with a `.js` extension when the nearest parent `package.json` file
791cb0ef41Sopenharmony_ci  contains a top-level field [`"type"`][] with a value of `"commonjs"`.
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci* Strings passed in as an argument to `--eval` or `--print`, or piped to `node`
821cb0ef41Sopenharmony_ci  via `STDIN`, with the flag `--input-type=commonjs`.
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciAside from these explicit cases, there are other cases where Node.js defaults to
851cb0ef41Sopenharmony_cione module system or the other based on the value of the
861cb0ef41Sopenharmony_ci[`--experimental-default-type`][] flag:
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci* Files ending in `.js` or with no extension, if there is no `package.json` file
891cb0ef41Sopenharmony_ci  present in the same folder or any parent folder.
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci* Files ending in `.js` or with no extension, if the nearest parent
921cb0ef41Sopenharmony_ci  `package.json` field lacks a `"type"` field; unless the folder is inside a
931cb0ef41Sopenharmony_ci  `node_modules` folder. (Package scopes under `node_modules` are always treated
941cb0ef41Sopenharmony_ci  as CommonJS when the `package.json` file lacks a `"type"` field, regardless
951cb0ef41Sopenharmony_ci  of `--experimental-default-type`, for backward compatibility.)
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci* Strings passed in as an argument to `--eval` or piped to `node` via `STDIN`,
981cb0ef41Sopenharmony_ci  when `--input-type` is unspecified.
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ciThis flag currently defaults to `"commonjs"`, but it may change in the future to
1011cb0ef41Sopenharmony_cidefault to `"module"`. For this reason it is best to be explicit wherever
1021cb0ef41Sopenharmony_cipossible; in particular, package authors should always include the [`"type"`][]
1031cb0ef41Sopenharmony_cifield in their `package.json` files, even in packages where all sources are
1041cb0ef41Sopenharmony_ciCommonJS. Being explicit about the `type` of the package will future-proof the
1051cb0ef41Sopenharmony_cipackage in case the default type of Node.js ever changes, and it will also make
1061cb0ef41Sopenharmony_cithings easier for build tools and loaders to determine how the files in the
1071cb0ef41Sopenharmony_cipackage should be interpreted.
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci### Modules loaders
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ciNode.js has two systems for resolving a specifier and loading modules.
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciThere is the CommonJS module loader:
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci* It is fully synchronous.
1161cb0ef41Sopenharmony_ci* It is responsible for handling `require()` calls.
1171cb0ef41Sopenharmony_ci* It is monkey patchable.
1181cb0ef41Sopenharmony_ci* It supports [folders as modules][].
1191cb0ef41Sopenharmony_ci* When resolving a specifier, if no exact match is found, it will try to add
1201cb0ef41Sopenharmony_ci  extensions (`.js`, `.json`, and finally `.node`) and then attempt to resolve
1211cb0ef41Sopenharmony_ci  [folders as modules][].
1221cb0ef41Sopenharmony_ci* It treats `.json` as JSON text files.
1231cb0ef41Sopenharmony_ci* `.node` files are interpreted as compiled addon modules loaded with
1241cb0ef41Sopenharmony_ci  `process.dlopen()`.
1251cb0ef41Sopenharmony_ci* It treats all files that lack `.json` or `.node` extensions as JavaScript
1261cb0ef41Sopenharmony_ci  text files.
1271cb0ef41Sopenharmony_ci* It cannot be used to load ECMAScript modules (although it is possible to
1281cb0ef41Sopenharmony_ci  [load ECMASCript modules from CommonJS modules][]). When used to load a
1291cb0ef41Sopenharmony_ci  JavaScript text file that is not an ECMAScript module, it loads it as a
1301cb0ef41Sopenharmony_ci  CommonJS module.
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ciThere is the ECMAScript module loader:
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci* It is asynchronous.
1351cb0ef41Sopenharmony_ci* It is responsible for handling `import` statements and `import()` expressions.
1361cb0ef41Sopenharmony_ci* It is not monkey patchable, can be customized using [loader hooks][].
1371cb0ef41Sopenharmony_ci* It does not support folders as modules, directory indexes (e.g.
1381cb0ef41Sopenharmony_ci  `'./startup/index.js'`) must be fully specified.
1391cb0ef41Sopenharmony_ci* It does no extension searching. A file extension must be provided
1401cb0ef41Sopenharmony_ci  when the specifier is a relative or absolute file URL.
1411cb0ef41Sopenharmony_ci* It can load JSON modules, but an import assertion is required.
1421cb0ef41Sopenharmony_ci* It accepts only `.js`, `.mjs`, and `.cjs` extensions for JavaScript text
1431cb0ef41Sopenharmony_ci  files.
1441cb0ef41Sopenharmony_ci* It can be used to load JavaScript CommonJS modules. Such modules
1451cb0ef41Sopenharmony_ci  are passed through the `cjs-module-lexer` to try to identify named exports,
1461cb0ef41Sopenharmony_ci  which are available if they can be determined through static analysis.
1471cb0ef41Sopenharmony_ci  Imported CommonJS modules have their URLs converted to absolute
1481cb0ef41Sopenharmony_ci  paths and are then loaded via the CommonJS module loader.
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci### `package.json` and file extensions
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ciWithin a package, the [`package.json`][] [`"type"`][] field defines how
1531cb0ef41Sopenharmony_ciNode.js should interpret `.js` files. If a `package.json` file does not have a
1541cb0ef41Sopenharmony_ci`"type"` field, `.js` files are treated as [CommonJS][].
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ciA `package.json` `"type"` value of `"module"` tells Node.js to interpret `.js`
1571cb0ef41Sopenharmony_cifiles within that package as using [ES module][] syntax.
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ciThe `"type"` field applies not only to initial entry points (`node my-app.js`)
1601cb0ef41Sopenharmony_cibut also to files referenced by `import` statements and `import()` expressions.
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci```js
1631cb0ef41Sopenharmony_ci// my-app.js, treated as an ES module because there is a package.json
1641cb0ef41Sopenharmony_ci// file in the same folder with "type": "module".
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ciimport './startup/init.js';
1671cb0ef41Sopenharmony_ci// Loaded as ES module since ./startup contains no package.json file,
1681cb0ef41Sopenharmony_ci// and therefore inherits the "type" value from one level up.
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciimport 'commonjs-package';
1711cb0ef41Sopenharmony_ci// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
1721cb0ef41Sopenharmony_ci// lacks a "type" field or contains "type": "commonjs".
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ciimport './node_modules/commonjs-package/index.js';
1751cb0ef41Sopenharmony_ci// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
1761cb0ef41Sopenharmony_ci// lacks a "type" field or contains "type": "commonjs".
1771cb0ef41Sopenharmony_ci```
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ciFiles ending with `.mjs` are always loaded as [ES modules][] regardless of
1801cb0ef41Sopenharmony_cithe nearest parent `package.json`.
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ciFiles ending with `.cjs` are always loaded as [CommonJS][] regardless of the
1831cb0ef41Sopenharmony_cinearest parent `package.json`.
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci```js
1861cb0ef41Sopenharmony_ciimport './legacy-file.cjs';
1871cb0ef41Sopenharmony_ci// Loaded as CommonJS since .cjs is always loaded as CommonJS.
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ciimport 'commonjs-package/src/index.mjs';
1901cb0ef41Sopenharmony_ci// Loaded as ES module since .mjs is always loaded as ES module.
1911cb0ef41Sopenharmony_ci```
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ciThe `.mjs` and `.cjs` extensions can be used to mix types within the same
1941cb0ef41Sopenharmony_cipackage:
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci* Within a `"type": "module"` package, Node.js can be instructed to
1971cb0ef41Sopenharmony_ci  interpret a particular file as [CommonJS][] by naming it with a `.cjs`
1981cb0ef41Sopenharmony_ci  extension (since both `.js` and `.mjs` files are treated as ES modules within
1991cb0ef41Sopenharmony_ci  a `"module"` package).
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci* Within a `"type": "commonjs"` package, Node.js can be instructed to
2021cb0ef41Sopenharmony_ci  interpret a particular file as an [ES module][] by naming it with an `.mjs`
2031cb0ef41Sopenharmony_ci  extension (since both `.js` and `.cjs` files are treated as CommonJS within a
2041cb0ef41Sopenharmony_ci  `"commonjs"` package).
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci### `--input-type` flag
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci<!-- YAML
2091cb0ef41Sopenharmony_ciadded: v12.0.0
2101cb0ef41Sopenharmony_ci-->
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ciStrings passed in as an argument to `--eval` (or `-e`), or piped to `node` via
2131cb0ef41Sopenharmony_ci`STDIN`, are treated as [ES modules][] when the `--input-type=module` flag
2141cb0ef41Sopenharmony_ciis set.
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci```bash
2171cb0ef41Sopenharmony_cinode --input-type=module --eval "import { sep } from 'node:path'; console.log(sep);"
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ciecho "import { sep } from 'node:path'; console.log(sep);" | node --input-type=module
2201cb0ef41Sopenharmony_ci```
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ciFor completeness there is also `--input-type=commonjs`, for explicitly running
2231cb0ef41Sopenharmony_cistring input as CommonJS. This is the default behavior if `--input-type` is
2241cb0ef41Sopenharmony_ciunspecified.
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci## Determining package manager
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci> Stability: 1 - Experimental
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ciWhile all Node.js projects are expected to be installable by all package
2311cb0ef41Sopenharmony_cimanagers once published, their development teams are often required to use one
2321cb0ef41Sopenharmony_cispecific package manager. To make this process easier, Node.js ships with a
2331cb0ef41Sopenharmony_citool called [Corepack][] that aims to make all package managers transparently
2341cb0ef41Sopenharmony_ciavailable in your environment - provided you have Node.js installed.
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciBy default Corepack won't enforce any specific package manager and will use
2371cb0ef41Sopenharmony_cithe generic "Last Known Good" versions associated with each Node.js release,
2381cb0ef41Sopenharmony_cibut you can improve this experience by setting the [`"packageManager"`][] field
2391cb0ef41Sopenharmony_ciin your project's `package.json`.
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci## Package entry points
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ciIn a package's `package.json` file, two fields can define entry points for a
2441cb0ef41Sopenharmony_cipackage: [`"main"`][] and [`"exports"`][]. Both fields apply to both ES module
2451cb0ef41Sopenharmony_ciand CommonJS module entry points.
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ciThe [`"main"`][] field is supported in all versions of Node.js, but its
2481cb0ef41Sopenharmony_cicapabilities are limited: it only defines the main entry point of the package.
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ciThe [`"exports"`][] provides a modern alternative to [`"main"`][] allowing
2511cb0ef41Sopenharmony_cimultiple entry points to be defined, conditional entry resolution support
2521cb0ef41Sopenharmony_cibetween environments, and **preventing any other entry points besides those
2531cb0ef41Sopenharmony_cidefined in [`"exports"`][]**. This encapsulation allows module authors to
2541cb0ef41Sopenharmony_ciclearly define the public interface for their package.
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ciFor new packages targeting the currently supported versions of Node.js, the
2571cb0ef41Sopenharmony_ci[`"exports"`][] field is recommended. For packages supporting Node.js 10 and
2581cb0ef41Sopenharmony_cibelow, the [`"main"`][] field is required. If both [`"exports"`][] and
2591cb0ef41Sopenharmony_ci[`"main"`][] are defined, the [`"exports"`][] field takes precedence over
2601cb0ef41Sopenharmony_ci[`"main"`][] in supported versions of Node.js.
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci[Conditional exports][] can be used within [`"exports"`][] to define different
2631cb0ef41Sopenharmony_cipackage entry points per environment, including whether the package is
2641cb0ef41Sopenharmony_cireferenced via `require` or via `import`. For more information about supporting
2651cb0ef41Sopenharmony_ciboth CommonJS and ES modules in a single package please consult
2661cb0ef41Sopenharmony_ci[the dual CommonJS/ES module packages section][].
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ciExisting packages introducing the [`"exports"`][] field will prevent consumers
2691cb0ef41Sopenharmony_ciof the package from using any entry points that are not defined, including the
2701cb0ef41Sopenharmony_ci[`package.json`][] (e.g. `require('your-package/package.json')`. **This will
2711cb0ef41Sopenharmony_cilikely be a breaking change.**
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ciTo make the introduction of [`"exports"`][] non-breaking, ensure that every
2741cb0ef41Sopenharmony_cipreviously supported entry point is exported. It is best to explicitly specify
2751cb0ef41Sopenharmony_cientry points so that the package's public API is well-defined. For example,
2761cb0ef41Sopenharmony_cia project that previously exported `main`, `lib`,
2771cb0ef41Sopenharmony_ci`feature`, and the `package.json` could use the following `package.exports`:
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci```json
2801cb0ef41Sopenharmony_ci{
2811cb0ef41Sopenharmony_ci  "name": "my-package",
2821cb0ef41Sopenharmony_ci  "exports": {
2831cb0ef41Sopenharmony_ci    ".": "./lib/index.js",
2841cb0ef41Sopenharmony_ci    "./lib": "./lib/index.js",
2851cb0ef41Sopenharmony_ci    "./lib/index": "./lib/index.js",
2861cb0ef41Sopenharmony_ci    "./lib/index.js": "./lib/index.js",
2871cb0ef41Sopenharmony_ci    "./feature": "./feature/index.js",
2881cb0ef41Sopenharmony_ci    "./feature/index": "./feature/index.js",
2891cb0ef41Sopenharmony_ci    "./feature/index.js": "./feature/index.js",
2901cb0ef41Sopenharmony_ci    "./package.json": "./package.json"
2911cb0ef41Sopenharmony_ci  }
2921cb0ef41Sopenharmony_ci}
2931cb0ef41Sopenharmony_ci```
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ciAlternatively a project could choose to export entire folders both with and
2961cb0ef41Sopenharmony_ciwithout extensioned subpaths using export patterns:
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ci```json
2991cb0ef41Sopenharmony_ci{
3001cb0ef41Sopenharmony_ci  "name": "my-package",
3011cb0ef41Sopenharmony_ci  "exports": {
3021cb0ef41Sopenharmony_ci    ".": "./lib/index.js",
3031cb0ef41Sopenharmony_ci    "./lib": "./lib/index.js",
3041cb0ef41Sopenharmony_ci    "./lib/*": "./lib/*.js",
3051cb0ef41Sopenharmony_ci    "./lib/*.js": "./lib/*.js",
3061cb0ef41Sopenharmony_ci    "./feature": "./feature/index.js",
3071cb0ef41Sopenharmony_ci    "./feature/*": "./feature/*.js",
3081cb0ef41Sopenharmony_ci    "./feature/*.js": "./feature/*.js",
3091cb0ef41Sopenharmony_ci    "./package.json": "./package.json"
3101cb0ef41Sopenharmony_ci  }
3111cb0ef41Sopenharmony_ci}
3121cb0ef41Sopenharmony_ci```
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ciWith the above providing backwards-compatibility for any minor package versions,
3151cb0ef41Sopenharmony_cia future major change for the package can then properly restrict the exports
3161cb0ef41Sopenharmony_cito only the specific feature exports exposed:
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci```json
3191cb0ef41Sopenharmony_ci{
3201cb0ef41Sopenharmony_ci  "name": "my-package",
3211cb0ef41Sopenharmony_ci  "exports": {
3221cb0ef41Sopenharmony_ci    ".": "./lib/index.js",
3231cb0ef41Sopenharmony_ci    "./feature/*.js": "./feature/*.js",
3241cb0ef41Sopenharmony_ci    "./feature/internal/*": null
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci}
3271cb0ef41Sopenharmony_ci```
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci### Main entry point export
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ciWhen writing a new package, it is recommended to use the [`"exports"`][] field:
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ci```json
3341cb0ef41Sopenharmony_ci{
3351cb0ef41Sopenharmony_ci  "exports": "./index.js"
3361cb0ef41Sopenharmony_ci}
3371cb0ef41Sopenharmony_ci```
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ciWhen the [`"exports"`][] field is defined, all subpaths of the package are
3401cb0ef41Sopenharmony_ciencapsulated and no longer available to importers. For example,
3411cb0ef41Sopenharmony_ci`require('pkg/subpath.js')` throws an [`ERR_PACKAGE_PATH_NOT_EXPORTED`][]
3421cb0ef41Sopenharmony_cierror.
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ciThis encapsulation of exports provides more reliable guarantees
3451cb0ef41Sopenharmony_ciabout package interfaces for tools and when handling semver upgrades for a
3461cb0ef41Sopenharmony_cipackage. It is not a strong encapsulation since a direct require of any
3471cb0ef41Sopenharmony_ciabsolute subpath of the package such as
3481cb0ef41Sopenharmony_ci`require('/path/to/node_modules/pkg/subpath.js')` will still load `subpath.js`.
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ciAll currently supported versions of Node.js and modern build tools support the
3511cb0ef41Sopenharmony_ci`"exports"` field. For projects using an older version of Node.js or a related
3521cb0ef41Sopenharmony_cibuild tool, compatibility can be achieved by including the `"main"` field
3531cb0ef41Sopenharmony_cialongside `"exports"` pointing to the same module:
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_ci```json
3561cb0ef41Sopenharmony_ci{
3571cb0ef41Sopenharmony_ci  "main": "./index.js",
3581cb0ef41Sopenharmony_ci  "exports": "./index.js"
3591cb0ef41Sopenharmony_ci}
3601cb0ef41Sopenharmony_ci```
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci### Subpath exports
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci<!-- YAML
3651cb0ef41Sopenharmony_ciadded: v12.7.0
3661cb0ef41Sopenharmony_ci-->
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ciWhen using the [`"exports"`][] field, custom subpaths can be defined along
3691cb0ef41Sopenharmony_ciwith the main entry point by treating the main entry point as the
3701cb0ef41Sopenharmony_ci`"."` subpath:
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci```json
3731cb0ef41Sopenharmony_ci{
3741cb0ef41Sopenharmony_ci  "exports": {
3751cb0ef41Sopenharmony_ci    ".": "./index.js",
3761cb0ef41Sopenharmony_ci    "./submodule.js": "./src/submodule.js"
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci}
3791cb0ef41Sopenharmony_ci```
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ciNow only the defined subpath in [`"exports"`][] can be imported by a consumer:
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci```js
3841cb0ef41Sopenharmony_ciimport submodule from 'es-module-package/submodule.js';
3851cb0ef41Sopenharmony_ci// Loads ./node_modules/es-module-package/src/submodule.js
3861cb0ef41Sopenharmony_ci```
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ciWhile other subpaths will error:
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci```js
3911cb0ef41Sopenharmony_ciimport submodule from 'es-module-package/private-module.js';
3921cb0ef41Sopenharmony_ci// Throws ERR_PACKAGE_PATH_NOT_EXPORTED
3931cb0ef41Sopenharmony_ci```
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci#### Extensions in subpaths
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ciPackage authors should provide either extensioned (`import 'pkg/subpath.js'`) or
3981cb0ef41Sopenharmony_ciextensionless (`import 'pkg/subpath'`) subpaths in their exports. This ensures
3991cb0ef41Sopenharmony_cithat there is only one subpath for each exported module so that all dependents
4001cb0ef41Sopenharmony_ciimport the same consistent specifier, keeping the package contract clear for
4011cb0ef41Sopenharmony_ciconsumers and simplifying package subpath completions.
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_ciTraditionally, packages tended to use the extensionless style, which has the
4041cb0ef41Sopenharmony_cibenefits of readability and of masking the true path of the file within the
4051cb0ef41Sopenharmony_cipackage.
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ciWith [import maps][] now providing a standard for package resolution in browsers
4081cb0ef41Sopenharmony_ciand other JavaScript runtimes, using the extensionless style can result in
4091cb0ef41Sopenharmony_cibloated import map definitions. Explicit file extensions can avoid this issue by
4101cb0ef41Sopenharmony_cienabling the import map to utilize a [packages folder mapping][] to map multiple
4111cb0ef41Sopenharmony_cisubpaths where possible instead of a separate map entry per package subpath
4121cb0ef41Sopenharmony_ciexport. This also mirrors the requirement of using [the full specifier path][]
4131cb0ef41Sopenharmony_ciin relative and absolute import specifiers.
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci### Exports sugar
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci<!-- YAML
4181cb0ef41Sopenharmony_ciadded: v12.11.0
4191cb0ef41Sopenharmony_ci-->
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_ciIf the `"."` export is the only export, the [`"exports"`][] field provides sugar
4221cb0ef41Sopenharmony_cifor this case being the direct [`"exports"`][] field value.
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci```json
4251cb0ef41Sopenharmony_ci{
4261cb0ef41Sopenharmony_ci  "exports": {
4271cb0ef41Sopenharmony_ci    ".": "./index.js"
4281cb0ef41Sopenharmony_ci  }
4291cb0ef41Sopenharmony_ci}
4301cb0ef41Sopenharmony_ci```
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_cican be written:
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci```json
4351cb0ef41Sopenharmony_ci{
4361cb0ef41Sopenharmony_ci  "exports": "./index.js"
4371cb0ef41Sopenharmony_ci}
4381cb0ef41Sopenharmony_ci```
4391cb0ef41Sopenharmony_ci
4401cb0ef41Sopenharmony_ci### Subpath imports
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci<!-- YAML
4431cb0ef41Sopenharmony_ciadded:
4441cb0ef41Sopenharmony_ci  - v14.6.0
4451cb0ef41Sopenharmony_ci  - v12.19.0
4461cb0ef41Sopenharmony_ci-->
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ciIn addition to the [`"exports"`][] field, there is a package `"imports"` field
4491cb0ef41Sopenharmony_cito create private mappings that only apply to import specifiers from within the
4501cb0ef41Sopenharmony_cipackage itself.
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ciEntries in the `"imports"` field must always start with `#` to ensure they are
4531cb0ef41Sopenharmony_cidisambiguated from external package specifiers.
4541cb0ef41Sopenharmony_ci
4551cb0ef41Sopenharmony_ciFor example, the imports field can be used to gain the benefits of conditional
4561cb0ef41Sopenharmony_ciexports for internal modules:
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_ci```json
4591cb0ef41Sopenharmony_ci// package.json
4601cb0ef41Sopenharmony_ci{
4611cb0ef41Sopenharmony_ci  "imports": {
4621cb0ef41Sopenharmony_ci    "#dep": {
4631cb0ef41Sopenharmony_ci      "node": "dep-node-native",
4641cb0ef41Sopenharmony_ci      "default": "./dep-polyfill.js"
4651cb0ef41Sopenharmony_ci    }
4661cb0ef41Sopenharmony_ci  },
4671cb0ef41Sopenharmony_ci  "dependencies": {
4681cb0ef41Sopenharmony_ci    "dep-node-native": "^1.0.0"
4691cb0ef41Sopenharmony_ci  }
4701cb0ef41Sopenharmony_ci}
4711cb0ef41Sopenharmony_ci```
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ciwhere `import '#dep'` does not get the resolution of the external package
4741cb0ef41Sopenharmony_ci`dep-node-native` (including its exports in turn), and instead gets the local
4751cb0ef41Sopenharmony_cifile `./dep-polyfill.js` relative to the package in other environments.
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ciUnlike the `"exports"` field, the `"imports"` field permits mapping to external
4781cb0ef41Sopenharmony_cipackages.
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ciThe resolution rules for the imports field are otherwise analogous to the
4811cb0ef41Sopenharmony_ciexports field.
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci### Subpath patterns
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci<!-- YAML
4861cb0ef41Sopenharmony_ciadded:
4871cb0ef41Sopenharmony_ci  - v14.13.0
4881cb0ef41Sopenharmony_ci  - v12.20.0
4891cb0ef41Sopenharmony_cichanges:
4901cb0ef41Sopenharmony_ci  - version:
4911cb0ef41Sopenharmony_ci    - v16.10.0
4921cb0ef41Sopenharmony_ci    - v14.19.0
4931cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/40041
4941cb0ef41Sopenharmony_ci    description: Support pattern trailers in "imports" field.
4951cb0ef41Sopenharmony_ci  - version:
4961cb0ef41Sopenharmony_ci    - v16.9.0
4971cb0ef41Sopenharmony_ci    - v14.19.0
4981cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/39635
4991cb0ef41Sopenharmony_ci    description: Support pattern trailers.
5001cb0ef41Sopenharmony_ci-->
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ciFor packages with a small number of exports or imports, we recommend
5031cb0ef41Sopenharmony_ciexplicitly listing each exports subpath entry. But for packages that have
5041cb0ef41Sopenharmony_cilarge numbers of subpaths, this might cause `package.json` bloat and
5051cb0ef41Sopenharmony_cimaintenance issues.
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_ciFor these use cases, subpath export patterns can be used instead:
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci```json
5101cb0ef41Sopenharmony_ci// ./node_modules/es-module-package/package.json
5111cb0ef41Sopenharmony_ci{
5121cb0ef41Sopenharmony_ci  "exports": {
5131cb0ef41Sopenharmony_ci    "./features/*.js": "./src/features/*.js"
5141cb0ef41Sopenharmony_ci  },
5151cb0ef41Sopenharmony_ci  "imports": {
5161cb0ef41Sopenharmony_ci    "#internal/*.js": "./src/internal/*.js"
5171cb0ef41Sopenharmony_ci  }
5181cb0ef41Sopenharmony_ci}
5191cb0ef41Sopenharmony_ci```
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci**`*` maps expose nested subpaths as it is a string replacement syntax
5221cb0ef41Sopenharmony_cionly.**
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ciAll instances of `*` on the right hand side will then be replaced with this
5251cb0ef41Sopenharmony_civalue, including if it contains any `/` separators.
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci```js
5281cb0ef41Sopenharmony_ciimport featureX from 'es-module-package/features/x.js';
5291cb0ef41Sopenharmony_ci// Loads ./node_modules/es-module-package/src/features/x.js
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ciimport featureY from 'es-module-package/features/y/y.js';
5321cb0ef41Sopenharmony_ci// Loads ./node_modules/es-module-package/src/features/y/y.js
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ciimport internalZ from '#internal/z.js';
5351cb0ef41Sopenharmony_ci// Loads ./node_modules/es-module-package/src/internal/z.js
5361cb0ef41Sopenharmony_ci```
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ciThis is a direct static matching and replacement without any special handling
5391cb0ef41Sopenharmony_cifor file extensions. Including the `"*.js"` on both sides of the mapping
5401cb0ef41Sopenharmony_cirestricts the exposed package exports to only JS files.
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ciThe property of exports being statically enumerable is maintained with exports
5431cb0ef41Sopenharmony_cipatterns since the individual exports for a package can be determined by
5441cb0ef41Sopenharmony_citreating the right hand side target pattern as a `**` glob against the list of
5451cb0ef41Sopenharmony_cifiles within the package. Because `node_modules` paths are forbidden in exports
5461cb0ef41Sopenharmony_citargets, this expansion is dependent on only the files of the package itself.
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ciTo exclude private subfolders from patterns, `null` targets can be used:
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci```json
5511cb0ef41Sopenharmony_ci// ./node_modules/es-module-package/package.json
5521cb0ef41Sopenharmony_ci{
5531cb0ef41Sopenharmony_ci  "exports": {
5541cb0ef41Sopenharmony_ci    "./features/*.js": "./src/features/*.js",
5551cb0ef41Sopenharmony_ci    "./features/private-internal/*": null
5561cb0ef41Sopenharmony_ci  }
5571cb0ef41Sopenharmony_ci}
5581cb0ef41Sopenharmony_ci```
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci```js
5611cb0ef41Sopenharmony_ciimport featureInternal from 'es-module-package/features/private-internal/m.js';
5621cb0ef41Sopenharmony_ci// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED
5631cb0ef41Sopenharmony_ci
5641cb0ef41Sopenharmony_ciimport featureX from 'es-module-package/features/x.js';
5651cb0ef41Sopenharmony_ci// Loads ./node_modules/es-module-package/src/features/x.js
5661cb0ef41Sopenharmony_ci```
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci### Conditional exports
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci<!-- YAML
5711cb0ef41Sopenharmony_ciadded:
5721cb0ef41Sopenharmony_ci  - v13.2.0
5731cb0ef41Sopenharmony_ci  - v12.16.0
5741cb0ef41Sopenharmony_cichanges:
5751cb0ef41Sopenharmony_ci  - version:
5761cb0ef41Sopenharmony_ci    - v13.7.0
5771cb0ef41Sopenharmony_ci    - v12.16.0
5781cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31001
5791cb0ef41Sopenharmony_ci    description: Unflag conditional exports.
5801cb0ef41Sopenharmony_ci-->
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ciConditional exports provide a way to map to different paths depending on
5831cb0ef41Sopenharmony_cicertain conditions. They are supported for both CommonJS and ES module imports.
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ciFor example, a package that wants to provide different ES module exports for
5861cb0ef41Sopenharmony_ci`require()` and `import` can be written:
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci```json
5891cb0ef41Sopenharmony_ci// package.json
5901cb0ef41Sopenharmony_ci{
5911cb0ef41Sopenharmony_ci  "exports": {
5921cb0ef41Sopenharmony_ci    "import": "./index-module.js",
5931cb0ef41Sopenharmony_ci    "require": "./index-require.cjs"
5941cb0ef41Sopenharmony_ci  },
5951cb0ef41Sopenharmony_ci  "type": "module"
5961cb0ef41Sopenharmony_ci}
5971cb0ef41Sopenharmony_ci```
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ciNode.js implements the following conditions, listed in order from most
6001cb0ef41Sopenharmony_cispecific to least specific as conditions should be defined:
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci* `"node-addons"` - similar to `"node"` and matches for any Node.js environment.
6031cb0ef41Sopenharmony_ci  This condition can be used to provide an entry point which uses native C++
6041cb0ef41Sopenharmony_ci  addons as opposed to an entry point which is more universal and doesn't rely
6051cb0ef41Sopenharmony_ci  on native addons. This condition can be disabled via the
6061cb0ef41Sopenharmony_ci  [`--no-addons` flag][].
6071cb0ef41Sopenharmony_ci* `"node"` - matches for any Node.js environment. Can be a CommonJS or ES
6081cb0ef41Sopenharmony_ci  module file. _In most cases explicitly calling out the Node.js platform is
6091cb0ef41Sopenharmony_ci  not necessary._
6101cb0ef41Sopenharmony_ci* `"import"` - matches when the package is loaded via `import` or
6111cb0ef41Sopenharmony_ci  `import()`, or via any top-level import or resolve operation by the
6121cb0ef41Sopenharmony_ci  ECMAScript module loader. Applies regardless of the module format of the
6131cb0ef41Sopenharmony_ci  target file. _Always mutually exclusive with `"require"`._
6141cb0ef41Sopenharmony_ci* `"require"` - matches when the package is loaded via `require()`. The
6151cb0ef41Sopenharmony_ci  referenced file should be loadable with `require()` although the condition
6161cb0ef41Sopenharmony_ci  matches regardless of the module format of the target file. Expected
6171cb0ef41Sopenharmony_ci  formats include CommonJS, JSON, and native addons but not ES modules as
6181cb0ef41Sopenharmony_ci  `require()` doesn't support them. _Always mutually exclusive with
6191cb0ef41Sopenharmony_ci  `"import"`._
6201cb0ef41Sopenharmony_ci* `"default"` - the generic fallback that always matches. Can be a CommonJS
6211cb0ef41Sopenharmony_ci  or ES module file. _This condition should always come last._
6221cb0ef41Sopenharmony_ci
6231cb0ef41Sopenharmony_ciWithin the [`"exports"`][] object, key order is significant. During condition
6241cb0ef41Sopenharmony_cimatching, earlier entries have higher priority and take precedence over later
6251cb0ef41Sopenharmony_cientries. _The general rule is that conditions should be from most specific to
6261cb0ef41Sopenharmony_cileast specific in object order_.
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_ciUsing the `"import"` and `"require"` conditions can lead to some hazards,
6291cb0ef41Sopenharmony_ciwhich are further explained in [the dual CommonJS/ES module packages section][].
6301cb0ef41Sopenharmony_ci
6311cb0ef41Sopenharmony_ciThe `"node-addons"` condition can be used to provide an entry point which
6321cb0ef41Sopenharmony_ciuses native C++ addons. However, this condition can be disabled via the
6331cb0ef41Sopenharmony_ci[`--no-addons` flag][]. When using `"node-addons"`, it's recommended to treat
6341cb0ef41Sopenharmony_ci`"default"` as an enhancement that provides a more universal entry point, e.g.
6351cb0ef41Sopenharmony_ciusing WebAssembly instead of a native addon.
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ciConditional exports can also be extended to exports subpaths, for example:
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci```json
6401cb0ef41Sopenharmony_ci{
6411cb0ef41Sopenharmony_ci  "exports": {
6421cb0ef41Sopenharmony_ci    ".": "./index.js",
6431cb0ef41Sopenharmony_ci    "./feature.js": {
6441cb0ef41Sopenharmony_ci      "node": "./feature-node.js",
6451cb0ef41Sopenharmony_ci      "default": "./feature.js"
6461cb0ef41Sopenharmony_ci    }
6471cb0ef41Sopenharmony_ci  }
6481cb0ef41Sopenharmony_ci}
6491cb0ef41Sopenharmony_ci```
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ciDefines a package where `require('pkg/feature.js')` and
6521cb0ef41Sopenharmony_ci`import 'pkg/feature.js'` could provide different implementations between
6531cb0ef41Sopenharmony_ciNode.js and other JS environments.
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ciWhen using environment branches, always include a `"default"` condition where
6561cb0ef41Sopenharmony_cipossible. Providing a `"default"` condition ensures that any unknown JS
6571cb0ef41Sopenharmony_cienvironments are able to use this universal implementation, which helps avoid
6581cb0ef41Sopenharmony_cithese JS environments from having to pretend to be existing environments in
6591cb0ef41Sopenharmony_ciorder to support packages with conditional exports. For this reason, using
6601cb0ef41Sopenharmony_ci`"node"` and `"default"` condition branches is usually preferable to using
6611cb0ef41Sopenharmony_ci`"node"` and `"browser"` condition branches.
6621cb0ef41Sopenharmony_ci
6631cb0ef41Sopenharmony_ci### Nested conditions
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ciIn addition to direct mappings, Node.js also supports nested condition objects.
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ciFor example, to define a package that only has dual mode entry points for
6681cb0ef41Sopenharmony_ciuse in Node.js but not the browser:
6691cb0ef41Sopenharmony_ci
6701cb0ef41Sopenharmony_ci```json
6711cb0ef41Sopenharmony_ci{
6721cb0ef41Sopenharmony_ci  "exports": {
6731cb0ef41Sopenharmony_ci    "node": {
6741cb0ef41Sopenharmony_ci      "import": "./feature-node.mjs",
6751cb0ef41Sopenharmony_ci      "require": "./feature-node.cjs"
6761cb0ef41Sopenharmony_ci    },
6771cb0ef41Sopenharmony_ci    "default": "./feature.mjs"
6781cb0ef41Sopenharmony_ci  }
6791cb0ef41Sopenharmony_ci}
6801cb0ef41Sopenharmony_ci```
6811cb0ef41Sopenharmony_ci
6821cb0ef41Sopenharmony_ciConditions continue to be matched in order as with flat conditions. If
6831cb0ef41Sopenharmony_cia nested condition does not have any mapping it will continue checking
6841cb0ef41Sopenharmony_cithe remaining conditions of the parent condition. In this way nested
6851cb0ef41Sopenharmony_ciconditions behave analogously to nested JavaScript `if` statements.
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci### Resolving user conditions
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ci<!-- YAML
6901cb0ef41Sopenharmony_ciadded:
6911cb0ef41Sopenharmony_ci  - v14.9.0
6921cb0ef41Sopenharmony_ci  - v12.19.0
6931cb0ef41Sopenharmony_ci-->
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ciWhen running Node.js, custom user conditions can be added with the
6961cb0ef41Sopenharmony_ci`--conditions` flag:
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci```bash
6991cb0ef41Sopenharmony_cinode --conditions=development index.js
7001cb0ef41Sopenharmony_ci```
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_ciwhich would then resolve the `"development"` condition in package imports and
7031cb0ef41Sopenharmony_ciexports, while resolving the existing `"node"`, `"node-addons"`, `"default"`,
7041cb0ef41Sopenharmony_ci`"import"`, and `"require"` conditions as appropriate.
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ciAny number of custom conditions can be set with repeat flags.
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci### Community Conditions Definitions
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ciCondition strings other than the `"import"`, `"require"`, `"node"`,
7111cb0ef41Sopenharmony_ci`"node-addons"` and `"default"` conditions
7121cb0ef41Sopenharmony_ci[implemented in Node.js core](#conditional-exports) are ignored by default.
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ciOther platforms may implement other conditions and user conditions can be
7151cb0ef41Sopenharmony_cienabled in Node.js via the [`--conditions` / `-C` flag][].
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ciSince custom package conditions require clear definitions to ensure correct
7181cb0ef41Sopenharmony_ciusage, a list of common known package conditions and their strict definitions
7191cb0ef41Sopenharmony_ciis provided below to assist with ecosystem coordination.
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci* `"types"` - can be used by typing systems to resolve the typing file for
7221cb0ef41Sopenharmony_ci  the given export. _This condition should always be included first._
7231cb0ef41Sopenharmony_ci* `"browser"` - any web browser environment.
7241cb0ef41Sopenharmony_ci* `"development"` - can be used to define a development-only environment
7251cb0ef41Sopenharmony_ci  entry point, for example to provide additional debugging context such as
7261cb0ef41Sopenharmony_ci  better error messages when running in a development mode. _Must always be
7271cb0ef41Sopenharmony_ci  mutually exclusive with `"production"`._
7281cb0ef41Sopenharmony_ci* `"production"` - can be used to define a production environment entry
7291cb0ef41Sopenharmony_ci  point. _Must always be mutually exclusive with `"development"`._
7301cb0ef41Sopenharmony_ci
7311cb0ef41Sopenharmony_ciFor other runtimes, platform-specific condition key definitions are maintained
7321cb0ef41Sopenharmony_ciby the [WinterCG][] in the [Runtime Keys][] proposal specification.
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ciNew conditions definitions may be added to this list by creating a pull request
7351cb0ef41Sopenharmony_cito the [Node.js documentation for this section][]. The requirements for listing
7361cb0ef41Sopenharmony_cia new condition definition here are that:
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ci* The definition should be clear and unambiguous for all implementers.
7391cb0ef41Sopenharmony_ci* The use case for why the condition is needed should be clearly justified.
7401cb0ef41Sopenharmony_ci* There should exist sufficient existing implementation usage.
7411cb0ef41Sopenharmony_ci* The condition name should not conflict with another condition definition or
7421cb0ef41Sopenharmony_ci  condition in wide usage.
7431cb0ef41Sopenharmony_ci* The listing of the condition definition should provide a coordination
7441cb0ef41Sopenharmony_ci  benefit to the ecosystem that wouldn't otherwise be possible. For example,
7451cb0ef41Sopenharmony_ci  this would not necessarily be the case for company-specific or
7461cb0ef41Sopenharmony_ci  application-specific conditions.
7471cb0ef41Sopenharmony_ci* The condition should be such that a Node.js user would expect it to be in
7481cb0ef41Sopenharmony_ci  Node.js core documentation. The `"types"` condition is a good example: It
7491cb0ef41Sopenharmony_ci  doesn't really belong in the [Runtime Keys][] proposal but is a good fit
7501cb0ef41Sopenharmony_ci  here in the Node.js docs.
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ciThe above definitions may be moved to a dedicated conditions registry in due
7531cb0ef41Sopenharmony_cicourse.
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_ci### Self-referencing a package using its name
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ci<!-- YAML
7581cb0ef41Sopenharmony_ciadded:
7591cb0ef41Sopenharmony_ci  - v13.1.0
7601cb0ef41Sopenharmony_ci  - v12.16.0
7611cb0ef41Sopenharmony_cichanges:
7621cb0ef41Sopenharmony_ci  - version:
7631cb0ef41Sopenharmony_ci    - v13.6.0
7641cb0ef41Sopenharmony_ci    - v12.16.0
7651cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31002
7661cb0ef41Sopenharmony_ci    description: Unflag self-referencing a package using its name.
7671cb0ef41Sopenharmony_ci-->
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ciWithin a package, the values defined in the package's
7701cb0ef41Sopenharmony_ci`package.json` [`"exports"`][] field can be referenced via the package's name.
7711cb0ef41Sopenharmony_ciFor example, assuming the `package.json` is:
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci```json
7741cb0ef41Sopenharmony_ci// package.json
7751cb0ef41Sopenharmony_ci{
7761cb0ef41Sopenharmony_ci  "name": "a-package",
7771cb0ef41Sopenharmony_ci  "exports": {
7781cb0ef41Sopenharmony_ci    ".": "./index.mjs",
7791cb0ef41Sopenharmony_ci    "./foo.js": "./foo.js"
7801cb0ef41Sopenharmony_ci  }
7811cb0ef41Sopenharmony_ci}
7821cb0ef41Sopenharmony_ci```
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ciThen any module _in that package_ can reference an export in the package itself:
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_ci```js
7871cb0ef41Sopenharmony_ci// ./a-module.mjs
7881cb0ef41Sopenharmony_ciimport { something } from 'a-package'; // Imports "something" from ./index.mjs.
7891cb0ef41Sopenharmony_ci```
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_ciSelf-referencing is available only if `package.json` has [`"exports"`][], and
7921cb0ef41Sopenharmony_ciwill allow importing only what that [`"exports"`][] (in the `package.json`)
7931cb0ef41Sopenharmony_ciallows. So the code below, given the previous package, will generate a runtime
7941cb0ef41Sopenharmony_cierror:
7951cb0ef41Sopenharmony_ci
7961cb0ef41Sopenharmony_ci```js
7971cb0ef41Sopenharmony_ci// ./another-module.mjs
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci// Imports "another" from ./m.mjs. Fails because
8001cb0ef41Sopenharmony_ci// the "package.json" "exports" field
8011cb0ef41Sopenharmony_ci// does not provide an export named "./m.mjs".
8021cb0ef41Sopenharmony_ciimport { another } from 'a-package/m.mjs';
8031cb0ef41Sopenharmony_ci```
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ciSelf-referencing is also available when using `require`, both in an ES module,
8061cb0ef41Sopenharmony_ciand in a CommonJS one. For example, this code will also work:
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci```cjs
8091cb0ef41Sopenharmony_ci// ./a-module.js
8101cb0ef41Sopenharmony_ciconst { something } = require('a-package/foo.js'); // Loads from ./foo.js.
8111cb0ef41Sopenharmony_ci```
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ciFinally, self-referencing also works with scoped packages. For example, this
8141cb0ef41Sopenharmony_cicode will also work:
8151cb0ef41Sopenharmony_ci
8161cb0ef41Sopenharmony_ci```json
8171cb0ef41Sopenharmony_ci// package.json
8181cb0ef41Sopenharmony_ci{
8191cb0ef41Sopenharmony_ci  "name": "@my/package",
8201cb0ef41Sopenharmony_ci  "exports": "./index.js"
8211cb0ef41Sopenharmony_ci}
8221cb0ef41Sopenharmony_ci```
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci```cjs
8251cb0ef41Sopenharmony_ci// ./index.js
8261cb0ef41Sopenharmony_cimodule.exports = 42;
8271cb0ef41Sopenharmony_ci```
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci```cjs
8301cb0ef41Sopenharmony_ci// ./other.js
8311cb0ef41Sopenharmony_ciconsole.log(require('@my/package'));
8321cb0ef41Sopenharmony_ci```
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci```console
8351cb0ef41Sopenharmony_ci$ node other.js
8361cb0ef41Sopenharmony_ci42
8371cb0ef41Sopenharmony_ci```
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci## Dual CommonJS/ES module packages
8401cb0ef41Sopenharmony_ci
8411cb0ef41Sopenharmony_ciPrior to the introduction of support for ES modules in Node.js, it was a common
8421cb0ef41Sopenharmony_cipattern for package authors to include both CommonJS and ES module JavaScript
8431cb0ef41Sopenharmony_cisources in their package, with `package.json` [`"main"`][] specifying the
8441cb0ef41Sopenharmony_ciCommonJS entry point and `package.json` `"module"` specifying the ES module
8451cb0ef41Sopenharmony_cientry point.
8461cb0ef41Sopenharmony_ciThis enabled Node.js to run the CommonJS entry point while build tools such as
8471cb0ef41Sopenharmony_cibundlers used the ES module entry point, since Node.js ignored (and still
8481cb0ef41Sopenharmony_ciignores) the top-level `"module"` field.
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ciNode.js can now run ES module entry points, and a package can contain both
8511cb0ef41Sopenharmony_ciCommonJS and ES module entry points (either via separate specifiers such as
8521cb0ef41Sopenharmony_ci`'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional
8531cb0ef41Sopenharmony_ciexports][]). Unlike in the scenario where `"module"` is only used by bundlers,
8541cb0ef41Sopenharmony_cior ES module files are transpiled into CommonJS on the fly before evaluation by
8551cb0ef41Sopenharmony_ciNode.js, the files referenced by the ES module entry point are evaluated as ES
8561cb0ef41Sopenharmony_cimodules.
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci### Dual package hazard
8591cb0ef41Sopenharmony_ci
8601cb0ef41Sopenharmony_ciWhen an application is using a package that provides both CommonJS and ES module
8611cb0ef41Sopenharmony_cisources, there is a risk of certain bugs if both versions of the package get
8621cb0ef41Sopenharmony_ciloaded. This potential comes from the fact that the `pkgInstance` created by
8631cb0ef41Sopenharmony_ci`const pkgInstance = require('pkg')` is not the same as the `pkgInstance`
8641cb0ef41Sopenharmony_cicreated by `import pkgInstance from 'pkg'` (or an alternative main path like
8651cb0ef41Sopenharmony_ci`'pkg/module'`). This is the “dual package hazard,” where two versions of the
8661cb0ef41Sopenharmony_cisame package can be loaded within the same runtime environment. While it is
8671cb0ef41Sopenharmony_ciunlikely that an application or package would intentionally load both versions
8681cb0ef41Sopenharmony_cidirectly, it is common for an application to load one version while a dependency
8691cb0ef41Sopenharmony_ciof the application loads the other version. This hazard can happen because
8701cb0ef41Sopenharmony_ciNode.js supports intermixing CommonJS and ES modules, and can lead to unexpected
8711cb0ef41Sopenharmony_cibehavior.
8721cb0ef41Sopenharmony_ci
8731cb0ef41Sopenharmony_ciIf the package main export is a constructor, an `instanceof` comparison of
8741cb0ef41Sopenharmony_ciinstances created by the two versions returns `false`, and if the export is an
8751cb0ef41Sopenharmony_ciobject, properties added to one (like `pkgInstance.foo = 3`) are not present on
8761cb0ef41Sopenharmony_cithe other. This differs from how `import` and `require` statements work in
8771cb0ef41Sopenharmony_ciall-CommonJS or all-ES module environments, respectively, and therefore is
8781cb0ef41Sopenharmony_cisurprising to users. It also differs from the behavior users are familiar with
8791cb0ef41Sopenharmony_ciwhen using transpilation via tools like [Babel][] or [`esm`][].
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ci### Writing dual packages while avoiding or minimizing hazards
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_ciFirst, the hazard described in the previous section occurs when a package
8841cb0ef41Sopenharmony_cicontains both CommonJS and ES module sources and both sources are provided for
8851cb0ef41Sopenharmony_ciuse in Node.js, either via separate main entry points or exported paths. A
8861cb0ef41Sopenharmony_cipackage might instead be written where any version of Node.js receives only
8871cb0ef41Sopenharmony_ciCommonJS sources, and any separate ES module sources the package might contain
8881cb0ef41Sopenharmony_ciare intended only for other environments such as browsers. Such a package
8891cb0ef41Sopenharmony_ciwould be usable by any version of Node.js, since `import` can refer to CommonJS
8901cb0ef41Sopenharmony_cifiles; but it would not provide any of the advantages of using ES module syntax.
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ciA package might also switch from CommonJS to ES module syntax in a [breaking
8931cb0ef41Sopenharmony_cichange](https://semver.org/) version bump. This has the disadvantage that the
8941cb0ef41Sopenharmony_cinewest version of the package would only be usable in ES module-supporting
8951cb0ef41Sopenharmony_civersions of Node.js.
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ciEvery pattern has tradeoffs, but there are two broad approaches that satisfy the
8981cb0ef41Sopenharmony_cifollowing conditions:
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ci1. The package is usable via both `require` and `import`.
9011cb0ef41Sopenharmony_ci2. The package is usable in both current Node.js and older versions of Node.js
9021cb0ef41Sopenharmony_ci   that lack support for ES modules.
9031cb0ef41Sopenharmony_ci3. The package main entry point, e.g. `'pkg'` can be used by both `require` to
9041cb0ef41Sopenharmony_ci   resolve to a CommonJS file and by `import` to resolve to an ES module file.
9051cb0ef41Sopenharmony_ci   (And likewise for exported paths, e.g. `'pkg/feature'`.)
9061cb0ef41Sopenharmony_ci4. The package provides named exports, e.g. `import { name } from 'pkg'` rather
9071cb0ef41Sopenharmony_ci   than `import pkg from 'pkg'; pkg.name`.
9081cb0ef41Sopenharmony_ci5. The package is potentially usable in other ES module environments such as
9091cb0ef41Sopenharmony_ci   browsers.
9101cb0ef41Sopenharmony_ci6. The hazards described in the previous section are avoided or minimized.
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ci#### Approach #1: Use an ES module wrapper
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ciWrite the package in CommonJS or transpile ES module sources into CommonJS, and
9151cb0ef41Sopenharmony_cicreate an ES module wrapper file that defines the named exports. Using
9161cb0ef41Sopenharmony_ci[Conditional exports][], the ES module wrapper is used for `import` and the
9171cb0ef41Sopenharmony_ciCommonJS entry point for `require`.
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ci```json
9201cb0ef41Sopenharmony_ci// ./node_modules/pkg/package.json
9211cb0ef41Sopenharmony_ci{
9221cb0ef41Sopenharmony_ci  "type": "module",
9231cb0ef41Sopenharmony_ci  "exports": {
9241cb0ef41Sopenharmony_ci    "import": "./wrapper.mjs",
9251cb0ef41Sopenharmony_ci    "require": "./index.cjs"
9261cb0ef41Sopenharmony_ci  }
9271cb0ef41Sopenharmony_ci}
9281cb0ef41Sopenharmony_ci```
9291cb0ef41Sopenharmony_ci
9301cb0ef41Sopenharmony_ciThe preceding example uses explicit extensions `.mjs` and `.cjs`.
9311cb0ef41Sopenharmony_ciIf your files use the `.js` extension, `"type": "module"` will cause such files
9321cb0ef41Sopenharmony_cito be treated as ES modules, just as `"type": "commonjs"` would cause them
9331cb0ef41Sopenharmony_cito be treated as CommonJS.
9341cb0ef41Sopenharmony_ciSee [Enabling](esm.md#enabling).
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ci```cjs
9371cb0ef41Sopenharmony_ci// ./node_modules/pkg/index.cjs
9381cb0ef41Sopenharmony_ciexports.name = 'value';
9391cb0ef41Sopenharmony_ci```
9401cb0ef41Sopenharmony_ci
9411cb0ef41Sopenharmony_ci```js
9421cb0ef41Sopenharmony_ci// ./node_modules/pkg/wrapper.mjs
9431cb0ef41Sopenharmony_ciimport cjsModule from './index.cjs';
9441cb0ef41Sopenharmony_ciexport const name = cjsModule.name;
9451cb0ef41Sopenharmony_ci```
9461cb0ef41Sopenharmony_ci
9471cb0ef41Sopenharmony_ciIn this example, the `name` from `import { name } from 'pkg'` is the same
9481cb0ef41Sopenharmony_cisingleton as the `name` from `const { name } = require('pkg')`. Therefore `===`
9491cb0ef41Sopenharmony_cireturns `true` when comparing the two `name`s and the divergent specifier hazard
9501cb0ef41Sopenharmony_ciis avoided.
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ciIf the module is not simply a list of named exports, but rather contains a
9531cb0ef41Sopenharmony_ciunique function or object export like `module.exports = function () { ... }`,
9541cb0ef41Sopenharmony_cior if support in the wrapper for the `import pkg from 'pkg'` pattern is desired,
9551cb0ef41Sopenharmony_cithen the wrapper would instead be written to export the default optionally
9561cb0ef41Sopenharmony_cialong with any named exports as well:
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci```js
9591cb0ef41Sopenharmony_ciimport cjsModule from './index.cjs';
9601cb0ef41Sopenharmony_ciexport const name = cjsModule.name;
9611cb0ef41Sopenharmony_ciexport default cjsModule;
9621cb0ef41Sopenharmony_ci```
9631cb0ef41Sopenharmony_ci
9641cb0ef41Sopenharmony_ciThis approach is appropriate for any of the following use cases:
9651cb0ef41Sopenharmony_ci
9661cb0ef41Sopenharmony_ci* The package is currently written in CommonJS and the author would prefer not
9671cb0ef41Sopenharmony_ci  to refactor it into ES module syntax, but wishes to provide named exports for
9681cb0ef41Sopenharmony_ci  ES module consumers.
9691cb0ef41Sopenharmony_ci* The package has other packages that depend on it, and the end user might
9701cb0ef41Sopenharmony_ci  install both this package and those other packages. For example a `utilities`
9711cb0ef41Sopenharmony_ci  package is used directly in an application, and a `utilities-plus` package
9721cb0ef41Sopenharmony_ci  adds a few more functions to `utilities`. Because the wrapper exports
9731cb0ef41Sopenharmony_ci  underlying CommonJS files, it doesn't matter if `utilities-plus` is written in
9741cb0ef41Sopenharmony_ci  CommonJS or ES module syntax; it will work either way.
9751cb0ef41Sopenharmony_ci* The package stores internal state, and the package author would prefer not to
9761cb0ef41Sopenharmony_ci  refactor the package to isolate its state management. See the next section.
9771cb0ef41Sopenharmony_ci
9781cb0ef41Sopenharmony_ciA variant of this approach not requiring conditional exports for consumers could
9791cb0ef41Sopenharmony_cibe to add an export, e.g. `"./module"`, to point to an all-ES module-syntax
9801cb0ef41Sopenharmony_civersion of the package. This could be used via `import 'pkg/module'` by users
9811cb0ef41Sopenharmony_ciwho are certain that the CommonJS version will not be loaded anywhere in the
9821cb0ef41Sopenharmony_ciapplication, such as by dependencies; or if the CommonJS version can be loaded
9831cb0ef41Sopenharmony_cibut doesn't affect the ES module version (for example, because the package is
9841cb0ef41Sopenharmony_cistateless):
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_ci```json
9871cb0ef41Sopenharmony_ci// ./node_modules/pkg/package.json
9881cb0ef41Sopenharmony_ci{
9891cb0ef41Sopenharmony_ci  "type": "module",
9901cb0ef41Sopenharmony_ci  "exports": {
9911cb0ef41Sopenharmony_ci    ".": "./index.cjs",
9921cb0ef41Sopenharmony_ci    "./module": "./wrapper.mjs"
9931cb0ef41Sopenharmony_ci  }
9941cb0ef41Sopenharmony_ci}
9951cb0ef41Sopenharmony_ci```
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ci#### Approach #2: Isolate state
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ciA [`package.json`][] file can define the separate CommonJS and ES module entry
10001cb0ef41Sopenharmony_cipoints directly:
10011cb0ef41Sopenharmony_ci
10021cb0ef41Sopenharmony_ci```json
10031cb0ef41Sopenharmony_ci// ./node_modules/pkg/package.json
10041cb0ef41Sopenharmony_ci{
10051cb0ef41Sopenharmony_ci  "type": "module",
10061cb0ef41Sopenharmony_ci  "exports": {
10071cb0ef41Sopenharmony_ci    "import": "./index.mjs",
10081cb0ef41Sopenharmony_ci    "require": "./index.cjs"
10091cb0ef41Sopenharmony_ci  }
10101cb0ef41Sopenharmony_ci}
10111cb0ef41Sopenharmony_ci```
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_ciThis can be done if both the CommonJS and ES module versions of the package are
10141cb0ef41Sopenharmony_ciequivalent, for example because one is the transpiled output of the other; and
10151cb0ef41Sopenharmony_cithe package's management of state is carefully isolated (or the package is
10161cb0ef41Sopenharmony_cistateless).
10171cb0ef41Sopenharmony_ci
10181cb0ef41Sopenharmony_ciThe reason that state is an issue is because both the CommonJS and ES module
10191cb0ef41Sopenharmony_civersions of the package might get used within an application; for example, the
10201cb0ef41Sopenharmony_ciuser's application code could `import` the ES module version while a dependency
10211cb0ef41Sopenharmony_ci`require`s the CommonJS version. If that were to occur, two copies of the
10221cb0ef41Sopenharmony_cipackage would be loaded in memory and therefore two separate states would be
10231cb0ef41Sopenharmony_cipresent. This would likely cause hard-to-troubleshoot bugs.
10241cb0ef41Sopenharmony_ci
10251cb0ef41Sopenharmony_ciAside from writing a stateless package (if JavaScript's `Math` were a package,
10261cb0ef41Sopenharmony_cifor example, it would be stateless as all of its methods are static), there are
10271cb0ef41Sopenharmony_cisome ways to isolate state so that it's shared between the potentially loaded
10281cb0ef41Sopenharmony_ciCommonJS and ES module instances of the package:
10291cb0ef41Sopenharmony_ci
10301cb0ef41Sopenharmony_ci1. If possible, contain all state within an instantiated object. JavaScript's
10311cb0ef41Sopenharmony_ci   `Date`, for example, needs to be instantiated to contain state; if it were a
10321cb0ef41Sopenharmony_ci   package, it would be used like this:
10331cb0ef41Sopenharmony_ci
10341cb0ef41Sopenharmony_ci   ```js
10351cb0ef41Sopenharmony_ci   import Date from 'date';
10361cb0ef41Sopenharmony_ci   const someDate = new Date();
10371cb0ef41Sopenharmony_ci   // someDate contains state; Date does not
10381cb0ef41Sopenharmony_ci   ```
10391cb0ef41Sopenharmony_ci
10401cb0ef41Sopenharmony_ci   The `new` keyword isn't required; a package's function can return a new
10411cb0ef41Sopenharmony_ci   object, or modify a passed-in object, to keep the state external to the
10421cb0ef41Sopenharmony_ci   package.
10431cb0ef41Sopenharmony_ci
10441cb0ef41Sopenharmony_ci2. Isolate the state in one or more CommonJS files that are shared between the
10451cb0ef41Sopenharmony_ci   CommonJS and ES module versions of the package. For example, if the CommonJS
10461cb0ef41Sopenharmony_ci   and ES module entry points are `index.cjs` and `index.mjs`, respectively:
10471cb0ef41Sopenharmony_ci
10481cb0ef41Sopenharmony_ci   ```cjs
10491cb0ef41Sopenharmony_ci   // ./node_modules/pkg/index.cjs
10501cb0ef41Sopenharmony_ci   const state = require('./state.cjs');
10511cb0ef41Sopenharmony_ci   module.exports.state = state;
10521cb0ef41Sopenharmony_ci   ```
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ci   ```js
10551cb0ef41Sopenharmony_ci   // ./node_modules/pkg/index.mjs
10561cb0ef41Sopenharmony_ci   import state from './state.cjs';
10571cb0ef41Sopenharmony_ci   export {
10581cb0ef41Sopenharmony_ci     state,
10591cb0ef41Sopenharmony_ci   };
10601cb0ef41Sopenharmony_ci   ```
10611cb0ef41Sopenharmony_ci
10621cb0ef41Sopenharmony_ci   Even if `pkg` is used via both `require` and `import` in an application (for
10631cb0ef41Sopenharmony_ci   example, via `import` in application code and via `require` by a dependency)
10641cb0ef41Sopenharmony_ci   each reference of `pkg` will contain the same state; and modifying that
10651cb0ef41Sopenharmony_ci   state from either module system will apply to both.
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ciAny plugins that attach to the package's singleton would need to separately
10681cb0ef41Sopenharmony_ciattach to both the CommonJS and ES module singletons.
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ciThis approach is appropriate for any of the following use cases:
10711cb0ef41Sopenharmony_ci
10721cb0ef41Sopenharmony_ci* The package is currently written in ES module syntax and the package author
10731cb0ef41Sopenharmony_ci  wants that version to be used wherever such syntax is supported.
10741cb0ef41Sopenharmony_ci* The package is stateless or its state can be isolated without too much
10751cb0ef41Sopenharmony_ci  difficulty.
10761cb0ef41Sopenharmony_ci* The package is unlikely to have other public packages that depend on it, or if
10771cb0ef41Sopenharmony_ci  it does, the package is stateless or has state that need not be shared between
10781cb0ef41Sopenharmony_ci  dependencies or with the overall application.
10791cb0ef41Sopenharmony_ci
10801cb0ef41Sopenharmony_ciEven with isolated state, there is still the cost of possible extra code
10811cb0ef41Sopenharmony_ciexecution between the CommonJS and ES module versions of a package.
10821cb0ef41Sopenharmony_ci
10831cb0ef41Sopenharmony_ciAs with the previous approach, a variant of this approach not requiring
10841cb0ef41Sopenharmony_ciconditional exports for consumers could be to add an export, e.g.
10851cb0ef41Sopenharmony_ci`"./module"`, to point to an all-ES module-syntax version of the package:
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ci```json
10881cb0ef41Sopenharmony_ci// ./node_modules/pkg/package.json
10891cb0ef41Sopenharmony_ci{
10901cb0ef41Sopenharmony_ci  "type": "module",
10911cb0ef41Sopenharmony_ci  "exports": {
10921cb0ef41Sopenharmony_ci    ".": "./index.cjs",
10931cb0ef41Sopenharmony_ci    "./module": "./index.mjs"
10941cb0ef41Sopenharmony_ci  }
10951cb0ef41Sopenharmony_ci}
10961cb0ef41Sopenharmony_ci```
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci## Node.js `package.json` field definitions
10991cb0ef41Sopenharmony_ci
11001cb0ef41Sopenharmony_ciThis section describes the fields used by the Node.js runtime. Other tools (such
11011cb0ef41Sopenharmony_cias [npm](https://docs.npmjs.com/cli/v8/configuring-npm/package-json)) use
11021cb0ef41Sopenharmony_ciadditional fields which are ignored by Node.js and not documented here.
11031cb0ef41Sopenharmony_ci
11041cb0ef41Sopenharmony_ciThe following fields in `package.json` files are used in Node.js:
11051cb0ef41Sopenharmony_ci
11061cb0ef41Sopenharmony_ci* [`"name"`][] - Relevant when using named imports within a package. Also used
11071cb0ef41Sopenharmony_ci  by package managers as the name of the package.
11081cb0ef41Sopenharmony_ci* [`"main"`][] - The default module when loading the package, if exports is not
11091cb0ef41Sopenharmony_ci  specified, and in versions of Node.js prior to the introduction of exports.
11101cb0ef41Sopenharmony_ci* [`"packageManager"`][] - The package manager recommended when contributing to
11111cb0ef41Sopenharmony_ci  the package. Leveraged by the [Corepack][] shims.
11121cb0ef41Sopenharmony_ci* [`"type"`][] - The package type determining whether to load `.js` files as
11131cb0ef41Sopenharmony_ci  CommonJS or ES modules.
11141cb0ef41Sopenharmony_ci* [`"exports"`][] - Package exports and conditional exports. When present,
11151cb0ef41Sopenharmony_ci  limits which submodules can be loaded from within the package.
11161cb0ef41Sopenharmony_ci* [`"imports"`][] - Package imports, for use by modules within the package
11171cb0ef41Sopenharmony_ci  itself.
11181cb0ef41Sopenharmony_ci
11191cb0ef41Sopenharmony_ci### `"name"`
11201cb0ef41Sopenharmony_ci
11211cb0ef41Sopenharmony_ci<!-- YAML
11221cb0ef41Sopenharmony_ciadded:
11231cb0ef41Sopenharmony_ci  - v13.1.0
11241cb0ef41Sopenharmony_ci  - v12.16.0
11251cb0ef41Sopenharmony_cichanges:
11261cb0ef41Sopenharmony_ci  - version:
11271cb0ef41Sopenharmony_ci    - v13.6.0
11281cb0ef41Sopenharmony_ci    - v12.16.0
11291cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31002
11301cb0ef41Sopenharmony_ci    description: Remove the `--experimental-resolve-self` option.
11311cb0ef41Sopenharmony_ci-->
11321cb0ef41Sopenharmony_ci
11331cb0ef41Sopenharmony_ci* Type: {string}
11341cb0ef41Sopenharmony_ci
11351cb0ef41Sopenharmony_ci```json
11361cb0ef41Sopenharmony_ci{
11371cb0ef41Sopenharmony_ci  "name": "package-name"
11381cb0ef41Sopenharmony_ci}
11391cb0ef41Sopenharmony_ci```
11401cb0ef41Sopenharmony_ci
11411cb0ef41Sopenharmony_ciThe `"name"` field defines your package's name. Publishing to the
11421cb0ef41Sopenharmony_ci_npm_ registry requires a name that satisfies
11431cb0ef41Sopenharmony_ci[certain requirements](https://docs.npmjs.com/files/package.json#name).
11441cb0ef41Sopenharmony_ci
11451cb0ef41Sopenharmony_ciThe `"name"` field can be used in addition to the [`"exports"`][] field to
11461cb0ef41Sopenharmony_ci[self-reference][] a package using its name.
11471cb0ef41Sopenharmony_ci
11481cb0ef41Sopenharmony_ci### `"main"`
11491cb0ef41Sopenharmony_ci
11501cb0ef41Sopenharmony_ci<!-- YAML
11511cb0ef41Sopenharmony_ciadded: v0.4.0
11521cb0ef41Sopenharmony_ci-->
11531cb0ef41Sopenharmony_ci
11541cb0ef41Sopenharmony_ci* Type: {string}
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_ci```json
11571cb0ef41Sopenharmony_ci{
11581cb0ef41Sopenharmony_ci  "main": "./index.js"
11591cb0ef41Sopenharmony_ci}
11601cb0ef41Sopenharmony_ci```
11611cb0ef41Sopenharmony_ci
11621cb0ef41Sopenharmony_ciThe `"main"` field defines the entry point of a package when imported by name
11631cb0ef41Sopenharmony_civia a `node_modules` lookup.  Its value is a path.
11641cb0ef41Sopenharmony_ci
11651cb0ef41Sopenharmony_ciWhen a package has an [`"exports"`][] field, this will take precedence over the
11661cb0ef41Sopenharmony_ci`"main"` field when importing the package by name.
11671cb0ef41Sopenharmony_ci
11681cb0ef41Sopenharmony_ciIt also defines the script that is used when the [package directory is loaded
11691cb0ef41Sopenharmony_civia `require()`](modules.md#folders-as-modules).
11701cb0ef41Sopenharmony_ci
11711cb0ef41Sopenharmony_ci```cjs
11721cb0ef41Sopenharmony_ci// This resolves to ./path/to/directory/index.js.
11731cb0ef41Sopenharmony_cirequire('./path/to/directory');
11741cb0ef41Sopenharmony_ci```
11751cb0ef41Sopenharmony_ci
11761cb0ef41Sopenharmony_ci### `"packageManager"`
11771cb0ef41Sopenharmony_ci
11781cb0ef41Sopenharmony_ci<!-- YAML
11791cb0ef41Sopenharmony_ciadded:
11801cb0ef41Sopenharmony_ci  - v16.9.0
11811cb0ef41Sopenharmony_ci  - v14.19.0
11821cb0ef41Sopenharmony_ci-->
11831cb0ef41Sopenharmony_ci
11841cb0ef41Sopenharmony_ci> Stability: 1 - Experimental
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_ci* Type: {string}
11871cb0ef41Sopenharmony_ci
11881cb0ef41Sopenharmony_ci```json
11891cb0ef41Sopenharmony_ci{
11901cb0ef41Sopenharmony_ci  "packageManager": "<package manager name>@<version>"
11911cb0ef41Sopenharmony_ci}
11921cb0ef41Sopenharmony_ci```
11931cb0ef41Sopenharmony_ci
11941cb0ef41Sopenharmony_ciThe `"packageManager"` field defines which package manager is expected to be
11951cb0ef41Sopenharmony_ciused when working on the current project. It can be set to any of the
11961cb0ef41Sopenharmony_ci[supported package managers][], and will ensure that your teams use the exact
11971cb0ef41Sopenharmony_cisame package manager versions without having to install anything else other than
11981cb0ef41Sopenharmony_ciNode.js.
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ciThis field is currently experimental and needs to be opted-in; check the
12011cb0ef41Sopenharmony_ci[Corepack][] page for details about the procedure.
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ci### `"type"`
12041cb0ef41Sopenharmony_ci
12051cb0ef41Sopenharmony_ci<!-- YAML
12061cb0ef41Sopenharmony_ciadded: v12.0.0
12071cb0ef41Sopenharmony_cichanges:
12081cb0ef41Sopenharmony_ci  - version:
12091cb0ef41Sopenharmony_ci    - v13.2.0
12101cb0ef41Sopenharmony_ci    - v12.17.0
12111cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/29866
12121cb0ef41Sopenharmony_ci    description: Unflag `--experimental-modules`.
12131cb0ef41Sopenharmony_ci-->
12141cb0ef41Sopenharmony_ci
12151cb0ef41Sopenharmony_ci* Type: {string}
12161cb0ef41Sopenharmony_ci
12171cb0ef41Sopenharmony_ciThe `"type"` field defines the module format that Node.js uses for all
12181cb0ef41Sopenharmony_ci`.js` files that have that `package.json` file as their nearest parent.
12191cb0ef41Sopenharmony_ci
12201cb0ef41Sopenharmony_ciFiles ending with `.js` are loaded as ES modules when the nearest parent
12211cb0ef41Sopenharmony_ci`package.json` file contains a top-level field `"type"` with a value of
12221cb0ef41Sopenharmony_ci`"module"`.
12231cb0ef41Sopenharmony_ci
12241cb0ef41Sopenharmony_ciThe nearest parent `package.json` is defined as the first `package.json` found
12251cb0ef41Sopenharmony_ciwhen searching in the current folder, that folder's parent, and so on up
12261cb0ef41Sopenharmony_ciuntil a node\_modules folder or the volume root is reached.
12271cb0ef41Sopenharmony_ci
12281cb0ef41Sopenharmony_ci```json
12291cb0ef41Sopenharmony_ci// package.json
12301cb0ef41Sopenharmony_ci{
12311cb0ef41Sopenharmony_ci  "type": "module"
12321cb0ef41Sopenharmony_ci}
12331cb0ef41Sopenharmony_ci```
12341cb0ef41Sopenharmony_ci
12351cb0ef41Sopenharmony_ci```bash
12361cb0ef41Sopenharmony_ci# In same folder as preceding package.json
12371cb0ef41Sopenharmony_cinode my-app.js # Runs as ES module
12381cb0ef41Sopenharmony_ci```
12391cb0ef41Sopenharmony_ci
12401cb0ef41Sopenharmony_ciIf the nearest parent `package.json` lacks a `"type"` field, or contains
12411cb0ef41Sopenharmony_ci`"type": "commonjs"`, `.js` files are treated as [CommonJS][]. If the volume
12421cb0ef41Sopenharmony_ciroot is reached and no `package.json` is found, `.js` files are treated as
12431cb0ef41Sopenharmony_ci[CommonJS][].
12441cb0ef41Sopenharmony_ci
12451cb0ef41Sopenharmony_ci`import` statements of `.js` files are treated as ES modules if the nearest
12461cb0ef41Sopenharmony_ciparent `package.json` contains `"type": "module"`.
12471cb0ef41Sopenharmony_ci
12481cb0ef41Sopenharmony_ci```js
12491cb0ef41Sopenharmony_ci// my-app.js, part of the same example as above
12501cb0ef41Sopenharmony_ciimport './startup.js'; // Loaded as ES module because of package.json
12511cb0ef41Sopenharmony_ci```
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_ciRegardless of the value of the `"type"` field, `.mjs` files are always treated
12541cb0ef41Sopenharmony_cias ES modules and `.cjs` files are always treated as CommonJS.
12551cb0ef41Sopenharmony_ci
12561cb0ef41Sopenharmony_ci### `"exports"`
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_ci<!-- YAML
12591cb0ef41Sopenharmony_ciadded: v12.7.0
12601cb0ef41Sopenharmony_cichanges:
12611cb0ef41Sopenharmony_ci  - version:
12621cb0ef41Sopenharmony_ci    - v14.13.0
12631cb0ef41Sopenharmony_ci    - v12.20.0
12641cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/34718
12651cb0ef41Sopenharmony_ci    description: Add support for `"exports"` patterns.
12661cb0ef41Sopenharmony_ci  - version:
12671cb0ef41Sopenharmony_ci    - v13.7.0
12681cb0ef41Sopenharmony_ci    - v12.17.0
12691cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/29866
12701cb0ef41Sopenharmony_ci    description: Unflag conditional exports.
12711cb0ef41Sopenharmony_ci  - version:
12721cb0ef41Sopenharmony_ci    - v13.7.0
12731cb0ef41Sopenharmony_ci    - v12.16.0
12741cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31008
12751cb0ef41Sopenharmony_ci    description: Implement logical conditional exports ordering.
12761cb0ef41Sopenharmony_ci  - version:
12771cb0ef41Sopenharmony_ci    - v13.7.0
12781cb0ef41Sopenharmony_ci    - v12.16.0
12791cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/31001
12801cb0ef41Sopenharmony_ci    description: Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`.
12811cb0ef41Sopenharmony_ci  - version:
12821cb0ef41Sopenharmony_ci    - v13.2.0
12831cb0ef41Sopenharmony_ci    - v12.16.0
12841cb0ef41Sopenharmony_ci    pr-url: https://github.com/nodejs/node/pull/29978
12851cb0ef41Sopenharmony_ci    description: Implement conditional exports.
12861cb0ef41Sopenharmony_ci-->
12871cb0ef41Sopenharmony_ci
12881cb0ef41Sopenharmony_ci* Type: {Object} | {string} | {string\[]}
12891cb0ef41Sopenharmony_ci
12901cb0ef41Sopenharmony_ci```json
12911cb0ef41Sopenharmony_ci{
12921cb0ef41Sopenharmony_ci  "exports": "./index.js"
12931cb0ef41Sopenharmony_ci}
12941cb0ef41Sopenharmony_ci```
12951cb0ef41Sopenharmony_ci
12961cb0ef41Sopenharmony_ciThe `"exports"` field allows defining the [entry points][] of a package when
12971cb0ef41Sopenharmony_ciimported by name loaded either via a `node_modules` lookup or a
12981cb0ef41Sopenharmony_ci[self-reference][] to its own name. It is supported in Node.js 12+ as an
12991cb0ef41Sopenharmony_cialternative to the [`"main"`][] that can support defining [subpath exports][]
13001cb0ef41Sopenharmony_ciand [conditional exports][] while encapsulating internal unexported modules.
13011cb0ef41Sopenharmony_ci
13021cb0ef41Sopenharmony_ci[Conditional Exports][] can also be used within `"exports"` to define different
13031cb0ef41Sopenharmony_cipackage entry points per environment, including whether the package is
13041cb0ef41Sopenharmony_cireferenced via `require` or via `import`.
13051cb0ef41Sopenharmony_ci
13061cb0ef41Sopenharmony_ciAll paths defined in the `"exports"` must be relative file URLs starting with
13071cb0ef41Sopenharmony_ci`./`.
13081cb0ef41Sopenharmony_ci
13091cb0ef41Sopenharmony_ci### `"imports"`
13101cb0ef41Sopenharmony_ci
13111cb0ef41Sopenharmony_ci<!-- YAML
13121cb0ef41Sopenharmony_ciadded:
13131cb0ef41Sopenharmony_ci - v14.6.0
13141cb0ef41Sopenharmony_ci - v12.19.0
13151cb0ef41Sopenharmony_ci-->
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_ci* Type: {Object}
13181cb0ef41Sopenharmony_ci
13191cb0ef41Sopenharmony_ci```json
13201cb0ef41Sopenharmony_ci// package.json
13211cb0ef41Sopenharmony_ci{
13221cb0ef41Sopenharmony_ci  "imports": {
13231cb0ef41Sopenharmony_ci    "#dep": {
13241cb0ef41Sopenharmony_ci      "node": "dep-node-native",
13251cb0ef41Sopenharmony_ci      "default": "./dep-polyfill.js"
13261cb0ef41Sopenharmony_ci    }
13271cb0ef41Sopenharmony_ci  },
13281cb0ef41Sopenharmony_ci  "dependencies": {
13291cb0ef41Sopenharmony_ci    "dep-node-native": "^1.0.0"
13301cb0ef41Sopenharmony_ci  }
13311cb0ef41Sopenharmony_ci}
13321cb0ef41Sopenharmony_ci```
13331cb0ef41Sopenharmony_ci
13341cb0ef41Sopenharmony_ciEntries in the imports field must be strings starting with `#`.
13351cb0ef41Sopenharmony_ci
13361cb0ef41Sopenharmony_ciPackage imports permit mapping to external packages.
13371cb0ef41Sopenharmony_ci
13381cb0ef41Sopenharmony_ciThis field defines [subpath imports][] for the current package.
13391cb0ef41Sopenharmony_ci
13401cb0ef41Sopenharmony_ci[Babel]: https://babeljs.io/
13411cb0ef41Sopenharmony_ci[CommonJS]: modules.md
13421cb0ef41Sopenharmony_ci[Conditional exports]: #conditional-exports
13431cb0ef41Sopenharmony_ci[Corepack]: corepack.md
13441cb0ef41Sopenharmony_ci[ES module]: esm.md
13451cb0ef41Sopenharmony_ci[ES modules]: esm.md
13461cb0ef41Sopenharmony_ci[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions
13471cb0ef41Sopenharmony_ci[Runtime Keys]: https://runtime-keys.proposal.wintercg.org/
13481cb0ef41Sopenharmony_ci[WinterCG]: https://wintercg.org/
13491cb0ef41Sopenharmony_ci[`"exports"`]: #exports
13501cb0ef41Sopenharmony_ci[`"imports"`]: #imports
13511cb0ef41Sopenharmony_ci[`"main"`]: #main
13521cb0ef41Sopenharmony_ci[`"name"`]: #name
13531cb0ef41Sopenharmony_ci[`"packageManager"`]: #packagemanager
13541cb0ef41Sopenharmony_ci[`"type"`]: #type
13551cb0ef41Sopenharmony_ci[`--conditions` / `-C` flag]: #resolving-user-conditions
13561cb0ef41Sopenharmony_ci[`--experimental-default-type`]: cli.md#--experimental-default-typetype
13571cb0ef41Sopenharmony_ci[`--no-addons` flag]: cli.md#--no-addons
13581cb0ef41Sopenharmony_ci[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.md#err_package_path_not_exported
13591cb0ef41Sopenharmony_ci[`esm`]: https://github.com/standard-things/esm#readme
13601cb0ef41Sopenharmony_ci[`package.json`]: #nodejs-packagejson-field-definitions
13611cb0ef41Sopenharmony_ci[entry points]: #package-entry-points
13621cb0ef41Sopenharmony_ci[folders as modules]: modules.md#folders-as-modules
13631cb0ef41Sopenharmony_ci[import maps]: https://github.com/WICG/import-maps
13641cb0ef41Sopenharmony_ci[load ECMASCript modules from CommonJS modules]: modules.md#the-mjs-extension
13651cb0ef41Sopenharmony_ci[loader hooks]: esm.md#loaders
13661cb0ef41Sopenharmony_ci[packages folder mapping]: https://github.com/WICG/import-maps#packages-via-trailing-slashes
13671cb0ef41Sopenharmony_ci[self-reference]: #self-referencing-a-package-using-its-name
13681cb0ef41Sopenharmony_ci[subpath exports]: #subpath-exports
13691cb0ef41Sopenharmony_ci[subpath imports]: #subpath-imports
13701cb0ef41Sopenharmony_ci[supported package managers]: corepack.md#supported-package-managers
13711cb0ef41Sopenharmony_ci[the dual CommonJS/ES module packages section]: #dual-commonjses-module-packages
13721cb0ef41Sopenharmony_ci[the full specifier path]: esm.md#mandatory-file-extensions
1373