From a3859aaf0f5a818c988ad303c0cde75187483a68 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 4 Mar 2020 23:53:05 +0200 Subject: [PATCH 01/39] docs: update conditional exports recommendations --- doc/api/esm.md | 132 +++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 77 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 7abaab87e0f6f5..7c6b4ed4e81f74 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -312,56 +312,6 @@ ECMAScript modules and versions that don't, for example: } ``` -#### Conditional Exports - -Conditional exports provide a way to map to different paths depending on -certain conditions. They are supported for both CommonJS and ES module imports. - -For example, a package that wants to provide different ES module exports for -Node.js and the browser can be written: - - -```js -// ./node_modules/pkg/package.json -{ - "type": "module", - "main": "./index.js", - "exports": { - "./feature": { - "import": "./feature-default.js", - "browser": "./feature-browser.js" - } - } -} -``` - -When resolving the `"."` export, if no matching target is found, the `"main"` -will be used as the final fallback. - -The conditions supported in Node.js condition matching: - -* `"default"` - the generic fallback that will always match. Can be a CommonJS - or ES module file. -* `"import"` - matched when the package is loaded via `import` or - `import()`. Can be any module format, this field does not set the type - interpretation. -* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES - module file. -* `"require"` - matched when the package is loaded via `require()`. - -Condition matching is applied in object order from first to last within the -`"exports"` object. - -Using the `"require"` condition it is possible to define a package that will -have a different exported value for CommonJS and ES modules, which can be a -hazard in that it can result in having two separate instances of the same -package in use in an application, which can cause a number of bugs. - -Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, -etc. could be defined in other runtimes or tools. Condition names must not start -with `"."` or be numbers. Further restrictions, definitions or guidance on -condition names may be provided in future. - #### Exports Sugar If the `"."` export is the only export, the `"exports"` field provides sugar @@ -388,49 +338,76 @@ can be written: } ``` -When using [Conditional Exports][], the rule is that all keys in the object -mapping must not start with a `"."` otherwise they would be indistinguishable -from exports subpaths. +#### Conditional Exports - -```js -{ - "exports": { - ".": { - "import": "./main.js", - "require": "./main.cjs" - } - } -} -``` +Conditional exports provide a way to map to different paths depending on +certain conditions. They are supported for both CommonJS and ES module imports. -can be written: +For example, a package that wants to provide different ES module exports for +require() and import can be written: ```js +// ./node_modules/pkg/package.json { + "main": "./main-require.cjs", "exports": { - "import": "./main.js", - "require": "./main.cjs" - } + "import": "./main-module.js", + "default": "./main-require.cjs" + }, + "type": "module" } ``` -If writing any exports value that mixes up these two forms, an error will be -thrown: +The conditions supported in Node.js condition matching: + +* `"default"` - the generic fallback that will always match. Can be a CommonJS + or ES module file. **This condition should always come last.** +* `"import"` - matched when the package is loaded via `import` or + `import()`. Can be any module format, this field does not set the type + interpretation. +* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES + module file. +* `"require"` - matched when the package is loaded via `require()`. + _Due to limited support in Node.js 13.x early versions it can be recommended + to avoid using this condition._ + +Condition matching is applied in object order from first to last within the +`"exports"` object. _The general rule is that conditions should be used +from most specific to least specific in object order._ + +Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, +etc. could be defined in other runtimes or tools. Further restrictions, +definitions or guidance on condition names may be provided in future. + +`"default"` is set to a CommonJS module in the example above since early +versions of Node.js 13.x support `"default"` but not `"import"` or `"require"` +conditions. If `"default"` did not resolve as CommonJS this would break the +use of `require('pkg')` in these Node.js versions when it matches the default. + +Using the `"import"` and `"require"` conditions can lead to some hazards, +which are explained further in [the dual mode packages section][]. + +Conditional exports can also be extended to exports subpaths, for example: ```js { - // Throws on resolution! + "main": "./main.js", "exports": { - "./feature": "./lib/feature.js", - "import": "./main.js", - "require": "./main.cjs" + ".": "./main.js", + "./feature": { + "browser": "./feature-browser.js", + "default": "./feature.js" + } } } ``` +Defines a package where `require('pkg/feature')` and `import 'pkg/feature'` +could provide different implementations between the browser and Node.js, +given third-part tool support for a `"browser"` condition. + ### Dual CommonJS/ES Module Packages Prior to the introduction of support for ES modules in Node.js, it was a common @@ -516,8 +493,8 @@ CommonJS entry point for `require`. "type": "module", "main": "./index.cjs", "exports": { - "require": "./index.cjs", - "import": "./wrapper.mjs" + "import": "./wrapper.mjs", + "default": "./index.cjs" } } ``` @@ -597,7 +574,7 @@ CommonJS and ES module entry points directly: "main": "./index.cjs", "exports": { "import": "./index.mjs", - "require": "./index.cjs" + "default": "./index.cjs" } } ``` @@ -1669,6 +1646,7 @@ success! [dynamic instantiate hook]: #esm_code_dynamicinstantiate_code_hook [special scheme]: https://url.spec.whatwg.org/#special-scheme [the official standard format]: https://tc39.github.io/ecma262/#sec-modules +[the dual mode packages section]: #esm_dual_commonjs_es_module_packages [transpiler loader example]: #esm_transpiler_loader [6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index [Top-Level Await]: https://github.com/tc39/proposal-top-level-await From 509e644c0765f4b5385dd00b90894add37bc5c54 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 5 Mar 2020 00:13:47 +0200 Subject: [PATCH 02/39] revert default / require guidance --- doc/api/esm.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 7c6b4ed4e81f74..4780ac050aca6a 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -353,7 +353,7 @@ require() and import can be written: "main": "./main-require.cjs", "exports": { "import": "./main-module.js", - "default": "./main-require.cjs" + "require": "./main-require.cjs" }, "type": "module" } @@ -362,15 +362,13 @@ require() and import can be written: The conditions supported in Node.js condition matching: * `"default"` - the generic fallback that will always match. Can be a CommonJS - or ES module file. **This condition should always come last.** + or ES module file. _This condition should always come last._ * `"import"` - matched when the package is loaded via `import` or `import()`. Can be any module format, this field does not set the type interpretation. * `"node"` - matched for any Node.js environment. Can be a CommonJS or ES module file. * `"require"` - matched when the package is loaded via `require()`. - _Due to limited support in Node.js 13.x early versions it can be recommended - to avoid using this condition._ Condition matching is applied in object order from first to last within the `"exports"` object. _The general rule is that conditions should be used @@ -380,11 +378,6 @@ Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, etc. could be defined in other runtimes or tools. Further restrictions, definitions or guidance on condition names may be provided in future. -`"default"` is set to a CommonJS module in the example above since early -versions of Node.js 13.x support `"default"` but not `"import"` or `"require"` -conditions. If `"default"` did not resolve as CommonJS this would break the -use of `require('pkg')` in these Node.js versions when it matches the default. - Using the `"import"` and `"require"` conditions can lead to some hazards, which are explained further in [the dual mode packages section][]. @@ -494,7 +487,7 @@ CommonJS entry point for `require`. "main": "./index.cjs", "exports": { "import": "./wrapper.mjs", - "default": "./index.cjs" + "require": "./index.cjs" } } ``` @@ -574,7 +567,7 @@ CommonJS and ES module entry points directly: "main": "./index.cjs", "exports": { "import": "./index.mjs", - "default": "./index.cjs" + "require": "./index.cjs" } } ``` From 177d3dc601f6371f62eb5655dda703c58c8cc51a Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Wed, 4 Mar 2020 18:16:14 -0500 Subject: [PATCH 03/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 4780ac050aca6a..43ea1ab9790596 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -344,7 +344,7 @@ Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports. For example, a package that wants to provide different ES module exports for -require() and import can be written: +`require()` and `import` can be written: ```js From 86f417b5450f6abe01c595bd97735bc7bbfc160c Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:58:39 -0500 Subject: [PATCH 04/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 43ea1ab9790596..25f2f187853a05 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -379,7 +379,8 @@ etc. could be defined in other runtimes or tools. Further restrictions, definitions or guidance on condition names may be provided in future. Using the `"import"` and `"require"` conditions can lead to some hazards, -which are explained further in [the dual mode packages section][]. +which are explained further in +[the dual CommonJS/ES module packages section][]. Conditional exports can also be extended to exports subpaths, for example: From b41d5b693c931c50656896b33bb7266c853584b6 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:58:47 -0500 Subject: [PATCH 05/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 25f2f187853a05..71f187b869ca10 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1640,7 +1640,7 @@ success! [dynamic instantiate hook]: #esm_code_dynamicinstantiate_code_hook [special scheme]: https://url.spec.whatwg.org/#special-scheme [the official standard format]: https://tc39.github.io/ecma262/#sec-modules -[the dual mode packages section]: #esm_dual_commonjs_es_module_packages +[the dual CommonJS/ES module packages section]: #esm_dual_commonjs_es_module_packages [transpiler loader example]: #esm_transpiler_loader [6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index [Top-Level Await]: https://github.com/tc39/proposal-top-level-await From d0302973613a7811df2f7a504efea1d5663c15d7 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:58:55 -0500 Subject: [PATCH 06/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 71f187b869ca10..8c13fa6194925e 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -359,7 +359,7 @@ For example, a package that wants to provide different ES module exports for } ``` -The conditions supported in Node.js condition matching: +Node.js supports the following conditions: * `"default"` - the generic fallback that will always match. Can be a CommonJS or ES module file. _This condition should always come last._ From f2e8b265f840f70b54b60c9fafca6ef60f7fc877 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:59:04 -0500 Subject: [PATCH 07/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 8c13fa6194925e..f926b1d54a7985 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -348,7 +348,7 @@ For example, a package that wants to provide different ES module exports for ```js -// ./node_modules/pkg/package.json +// package.json { "main": "./main-require.cjs", "exports": { From 05ee0db4cb7b6f40c27d0e759fc3dfcfa2f54444 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:59:37 -0500 Subject: [PATCH 08/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index f926b1d54a7985..a2e70af5337903 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -364,8 +364,8 @@ Node.js supports the following conditions: * `"default"` - the generic fallback that will always match. Can be a CommonJS or ES module file. _This condition should always come last._ * `"import"` - matched when the package is loaded via `import` or - `import()`. Can be any module format, this field does not set the type - interpretation. + `import()`. Can reference either an ES module or CommonJS file, as both + `import` and `import()` can load either ES module or CommonJS sources. * `"node"` - matched for any Node.js environment. Can be a CommonJS or ES module file. * `"require"` - matched when the package is loaded via `require()`. From e9ed602ce7c42c59a8042d94654c7c6e7b6949d8 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 06:59:54 -0500 Subject: [PATCH 09/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index a2e70af5337903..8330d154dc0850 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -375,8 +375,9 @@ Condition matching is applied in object order from first to last within the from most specific to least specific in object order._ Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, -etc. could be defined in other runtimes or tools. Further restrictions, -definitions or guidance on condition names may be provided in future. +etc. are ignored by Node.js but may be used by other runtimes or tools. +Further restrictions, definitions or guidance on condition names may be +provided in the future. Using the `"import"` and `"require"` conditions can lead to some hazards, which are explained further in From c251c50e48604b3e4c3a88ff29101feef0abaee0 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 07:00:08 -0500 Subject: [PATCH 10/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/esm.md b/doc/api/esm.md index 8330d154dc0850..78320578d13260 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -369,6 +369,7 @@ Node.js supports the following conditions: * `"node"` - matched for any Node.js environment. Can be a CommonJS or ES module file. * `"require"` - matched when the package is loaded via `require()`. + As `require()` only supports CommonJS, the referenced file must be CommonJS. Condition matching is applied in object order from first to last within the `"exports"` object. _The general rule is that conditions should be used From 74206e76d2c2bcb362b11e51b0ad62eff9cf7d3e Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 14:15:19 +0200 Subject: [PATCH 11/39] reorder conditions, note nesting, update encapsulation note, exports updates --- doc/api/esm.md | 118 +++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 78320578d13260..168d9014e16b93 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -188,75 +188,61 @@ defined in `"exports"`. If package entry points are defined in both `"main"` and `"exports"`. [Conditional Exports][] can also be used within `"exports"` to define different package entry points per environment. -#### `package.json` `"main"` +#### Package Exports Main -The `package.json` `"main"` field defines the entry point for a package, -whether the package is included into CommonJS via `require` or into an ES -module via `import`. +To set the main entry point for a package, it is advisable to use both +`"exports"` and the `"main"`: ```js -// ./node_modules/es-module-package/package.json { - "type": "module", - "main": "./src/index.js" + "main": "./main.js", + "exports": "./main.js" } ``` -```js -// ./my-app.mjs - -import { something } from 'es-module-package'; -// Loads from ./node_modules/es-module-package/src/index.js -``` - -An attempt to `require` the above `es-module-package` would attempt to load -`./node_modules/es-module-package/src/index.js` as CommonJS, which would throw -an error as Node.js would not be able to parse the `export` statement in -CommonJS. - -As with `import` statements, for ES module usage the value of `"main"` must be -a full path including extension: `"./index.mjs"`, not `"./index"`. +The benefit of doing this is that when using the `"exports"` field all +subpaths of the package will no longer be available to importers under +`require('pkg/subpath.js')`, and instead they will get a new error, +`ERR_PACKAGE_PATH_NOT_EXPORTED`. -If the `package.json` `"type"` field is omitted, a `.js` file in `"main"` will -be interpreted as CommonJS. +This new encapsulation of exports provides new more reliable guarantees +about package interfaces for tools and when handling semver upgrades for a +package. It is not a strong encapsulation since +`require('/path/to/pkg/subpath.js')` will still work correctly. -The `"main"` field can point to exactly one file, regardless of whether the -package is referenced via `require` (in a CommonJS context) or `import` (in an -ES module context). +#### Package Exports Subpaths -#### Package Exports - -By default, all subpaths from a package can be imported (`import 'pkg/x.js'`). -Custom subpath aliasing and encapsulation can be provided through the -`"exports"` field. +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: ```js -// ./node_modules/es-module-package/package.json { + "main": "./main.js", "exports": { + ".": "./main.js", "./submodule": "./src/submodule.js" } } ``` +Now only the defined subpath in `"exports"` can be imported by a +consumer: + ```js import submodule from 'es-module-package/submodule'; // Loads ./node_modules/es-module-package/src/submodule.js ``` -In addition to defining an alias, subpaths not defined by `"exports"` will -throw when an attempt is made to import them: +While other subpaths will still error: ```js import submodule from 'es-module-package/private-module.js'; -// Throws ERR_MODULE_NOT_FOUND +// Throws ERR_PACKAGE_PATH_NOT_EXPORTED ``` -> Note: this is not a strong encapsulation as any private modules can still be -> loaded by absolute paths. - Folders can also be mapped with package exports: @@ -274,10 +260,6 @@ import feature from 'es-module-package/features/x.js'; // Loads ./node_modules/es-module-package/src/features/x.js ``` -If a package has no exports, setting `"exports": false` can be used instead of -`"exports": {}` to indicate the package does not intend for submodules to be -exposed. - Any invalid exports entries will be ignored. This includes exports not starting with `"./"` or a missing trailing `"/"` for directory exports. @@ -296,22 +278,6 @@ in order to be forwards-compatible with possible fallback workflows in future: Since `"not:valid"` is not a supported target, `"./submodule.js"` is used instead as the fallback, as if it were the only target. -Defining a `"."` export will define the main entry point for the package, -and will always take precedence over the `"main"` field in the `package.json`. - -This allows defining a different entry point for Node.js versions that support -ECMAScript modules and versions that don't, for example: - - -```js -{ - "main": "./main-legacy.cjs", - "exports": { - ".": "./main-modern.cjs" - } -} -``` - #### Exports Sugar If the `"."` export is the only export, the `"exports"` field provides sugar @@ -361,15 +327,16 @@ For example, a package that wants to provide different ES module exports for Node.js supports the following conditions: -* `"default"` - the generic fallback that will always match. Can be a CommonJS - or ES module file. _This condition should always come last._ * `"import"` - matched when the package is loaded via `import` or `import()`. Can reference either an ES module or CommonJS file, as both `import` and `import()` can load either ES module or CommonJS sources. -* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES - module file. * `"require"` - matched when the package is loaded via `require()`. As `require()` only supports CommonJS, the referenced file must be CommonJS. +* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES + module file. _This condition should always come after `"import"` or + `"require"`._ +* `"default"` - the generic fallback that will always match. Can be a CommonJS + or ES module file. _This condition should always come last._ Condition matching is applied in object order from first to last within the `"exports"` object. _The general rule is that conditions should be used @@ -404,6 +371,33 @@ Defines a package where `require('pkg/feature')` and `import 'pkg/feature'` could provide different implementations between the browser and Node.js, given third-part tool support for a `"browser"` condition. +#### Nested conditions + +In addition to direct mappings, conditional exports also supports nested +conditions with nested condition objects. + +For example, to define a package that only has dual mode entry points for +use in Node.js but not the browser: + + +```js +{ + "main": "./main.js", + "exports": { + "browser": "./feature-browser.mjs", + "node": { + "import": "./feature-node.mjs", + "require": "./feature-node.cjs" + } + } +} +``` + +Conditions continue to be matched in order as with flat conditions. If +a nested conditional does not have any mapping it will continue checking +the remaining conditions of the parent condition. In this way nested +conditions behave fully analogously to nested `if` statements in JS. + ### Dual CommonJS/ES Module Packages Prior to the introduction of support for ES modules in Node.js, it was a common From 28e315750d1ce2bee062fb9203eb3a346aafc474 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 14:24:00 +0200 Subject: [PATCH 12/39] fixup numbering in spec --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 168d9014e16b93..e22bc6d8f6c2ba 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1519,7 +1519,7 @@ The resolver can throw the following errors: **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_, _env_) -> 1.If _target_ is a String, then +> 1. If _target_ is a String, then > 1. If _target_ does not start with _"./"_ or contains any _"node_modules"_ > segments including _"node_modules"_ percent-encoding, throw an > _Invalid Package Target_ error. From 88ed6e24ed95095e726fdb30911c5620745ea664 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 14:54:28 +0200 Subject: [PATCH 13/39] update package exports section --- doc/api/esm.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index e22bc6d8f6c2ba..41c0b815cb8c25 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -175,18 +175,19 @@ unspecified. ## Packages -### Package Entry Points +### Package Exports There are two fields that can define entry points for a package: `"main"` and `"exports"`. The `"main"` field is supported in all versions of Node.js, but its capabilities are limited: it only defines the main entry point of the package. -The `"exports"` field, part of [Package Exports][], 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. + +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. #### Package Exports Main From 37d439acc2eda512e22641b45207caaf12e08e11 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 15:12:41 +0200 Subject: [PATCH 14/39] remove unused definition --- doc/api/esm.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 41c0b815cb8c25..41ecd5c9fa25d5 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1620,7 +1620,6 @@ success! [ECMAScript-modules implementation]: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md [ES Module Integration Proposal for Web Assembly]: https://github.com/webassembly/esm-integration [Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md -[Package Exports]: #esm_package_exports [Terminology]: #esm_terminology [WHATWG JSON modules specification]: https://html.spec.whatwg.org/#creating-a-json-module-script [`"exports"` field]: #esm_package_exports From 96f226c6f10ad8f8b1736ad4543f28dd0ec89640 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 7 Mar 2020 01:19:59 +0200 Subject: [PATCH 15/39] note on esm main --- doc/api/esm.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 41ecd5c9fa25d5..bf78fc90035608 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -175,7 +175,7 @@ unspecified. ## Packages -### Package Exports +### Package Entry Points There are two fields that can define entry points for a package: `"main"` and `"exports"`. The `"main"` field is supported in all versions of Node.js, but its @@ -189,6 +189,14 @@ in versions of Node.js that support `"exports"`. [Conditional Exports][] can also be used within `"exports"` to define different package entry points per environment. +When using both `import` and `require` the `"exports"` field will be resolved +if it is set, otherwise the `"main"` field will be resolved. + +When setting any package entry points to ES modules, `require()` will not work in +both modern and legacy Node.js versions, so it is important to carefully follow +[the dual CommonJS/ES module packages section][] to properly handle these types +of backwards-compatible ES module support. + #### Package Exports Main To set the main entry point for a package, it is advisable to use both From c454cc3a419f9f4907781b48e80ba0c1e0a9083d Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 6 Mar 2020 18:21:16 -0500 Subject: [PATCH 16/39] Update doc/api/esm.md --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index bf78fc90035608..fc6920aaa692fc 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -218,7 +218,7 @@ subpaths of the package will no longer be available to importers under This new encapsulation of exports provides new more reliable guarantees about package interfaces for tools and when handling semver upgrades for a package. It is not a strong encapsulation since -`require('/path/to/pkg/subpath.js')` will still work correctly. +a direct require of any absolute subpath of the package such as `require('/path/to/node_modules/pkg/subpath.js')` will still work correctly. #### Package Exports Subpaths From cf615caab8026643acda5f0613702abe8bc79839 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 7 Mar 2020 01:37:46 +0200 Subject: [PATCH 17/39] rename packages heading --- doc/api/esm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index fc6920aaa692fc..5ded42e402e9b9 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -173,9 +173,9 @@ For completeness there is also `--input-type=commonjs`, for explicitly running string input as CommonJS. This is the default behavior if `--input-type` is unspecified. -## Packages +## Packages Entry Points -### Package Entry Points +### Package Exports There are two fields that can define entry points for a package: `"main"` and `"exports"`. The `"main"` field is supported in all versions of Node.js, but its From 4f34a4115f0e083bf4cfeea67854acef8e42896b Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 7 Mar 2020 01:45:25 +0200 Subject: [PATCH 18/39] fixup line lengths --- doc/api/esm.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 5ded42e402e9b9..4f48f326a9ef30 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -192,10 +192,10 @@ environment. When using both `import` and `require` the `"exports"` field will be resolved if it is set, otherwise the `"main"` field will be resolved. -When setting any package entry points to ES modules, `require()` will not work in -both modern and legacy Node.js versions, so it is important to carefully follow -[the dual CommonJS/ES module packages section][] to properly handle these types -of backwards-compatible ES module support. +When setting any package entry points to ES modules, `require()` will not work +in both modern and legacy Node.js versions, so it is important to carefully +follow [the dual CommonJS/ES module packages section][] to properly handle +these types of backwards-compatible ES module support. #### Package Exports Main @@ -217,8 +217,9 @@ subpaths of the package will no longer be available to importers under This new encapsulation of exports provides new 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 work correctly. +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 work correctly. #### Package Exports Subpaths From 493d2b1166fa7c29d69dd41c18c0940e975e51d1 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 7 Mar 2020 01:54:53 +0200 Subject: [PATCH 19/39] update exports overview --- doc/api/esm.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 4f48f326a9ef30..bc747abea7ca95 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -189,13 +189,16 @@ in versions of Node.js that support `"exports"`. [Conditional Exports][] can also be used within `"exports"` to define different package entry points per environment. -When using both `import` and `require` the `"exports"` field will be resolved -if it is set, otherwise the `"main"` field will be resolved. +If both `"exports"` and `"main"` are defined, the `"exports"` field takes +precedence over `"main"`. -When setting any package entry points to ES modules, `require()` will not work -in both modern and legacy Node.js versions, so it is important to carefully -follow [the dual CommonJS/ES module packages section][] to properly handle -these types of backwards-compatible ES module support. +All package entry points apply to both `import` and `require`; `"exports"` and +`"main"` are **not** specific to ES modules or CommonJS. + +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][]. #### Package Exports Main From b7e03fc9dce974bef8fdfaeb9f3b036c4c701d79 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 8 Mar 2020 16:58:58 +0200 Subject: [PATCH 20/39] fallbacks as its own section, refine directory mapping notes --- doc/api/esm.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index bc747abea7ca95..0d294859b54c79 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -256,7 +256,7 @@ import submodule from 'es-module-package/private-module.js'; // Throws ERR_PACKAGE_PATH_NOT_EXPORTED ``` -Folders can also be mapped with package exports: +Entire folders can also be mapped with package exports: ```js @@ -268,16 +268,23 @@ Folders can also be mapped with package exports: } ``` +With the above, all modules within the `./src/features/` folder +are exposed deeply to `import` and `require`: + ```js import feature from 'es-module-package/features/x.js'; // Loads ./node_modules/es-module-package/src/features/x.js ``` -Any invalid exports entries will be ignored. This includes exports not -starting with `"./"` or a missing trailing `"/"` for directory exports. +When using folder mappings, ensure that you do want to expose every +module inside the subfolder. Any modules which are not public +should be moved to another folder to retain the encapsulation +benefits of exports. + +#### Package Exports Fallbacks -Array fallback support is provided for exports, similarly to import maps -in order to be forwards-compatible with possible fallback workflows in future: +For possible new specifier support in future, array fallbacks are +supported for all invalid specifiers: ```js @@ -288,7 +295,7 @@ in order to be forwards-compatible with possible fallback workflows in future: } ``` -Since `"not:valid"` is not a supported target, `"./submodule.js"` is used +Since `"not:valid"` is not a valid specifier, `"./submodule.js"` is used instead as the fallback, as if it were the only target. #### Exports Sugar From 2f64d571a46513467bad55f2501c6294dd1a2e10 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 8 Mar 2020 17:17:02 +0200 Subject: [PATCH 21/39] package entry points -> packages --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 0d294859b54c79..8d21427cdb0f77 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -173,7 +173,7 @@ For completeness there is also `--input-type=commonjs`, for explicitly running string input as CommonJS. This is the default behavior if `--input-type` is unspecified. -## Packages Entry Points +## Packages ### Package Exports From 09d76a71ace3efed2203654ab136f44e4993f66b Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:13:33 +0200 Subject: [PATCH 22/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 8d21427cdb0f77..2e8c90eefab9d0 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -177,7 +177,7 @@ unspecified. ### Package Exports -There are two fields that can define entry points for a package: `"main"` and +In a package’s `package.json` file, two fields can define entry points for a package: `"main"` and `"exports"`. The `"main"` field is supported in all versions of Node.js, but its capabilities are limited: it only defines the main entry point of the package. From b2125e6e4862f494f74e7d2c0865294682854fb5 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:14:06 +0200 Subject: [PATCH 23/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 2e8c90eefab9d0..0ec7f2411fba90 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -187,7 +187,7 @@ 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. +environment, including whether the package is referenced via `require` or via `import`. If both `"exports"` and `"main"` are defined, the `"exports"` field takes precedence over `"main"`. From ca38c5ad7b142ee0191054a46992dd4d005991e2 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:14:59 +0200 Subject: [PATCH 24/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 0ec7f2411fba90..589bcf9d32a8c1 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -202,8 +202,8 @@ see [the dual CommonJS/ES module packages section][]. #### Package Exports Main -To set the main entry point for a package, it is advisable to use both -`"exports"` and the `"main"`: +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: ```js From fc7f258ad09eef10b95f11aa28fa3890cd4de714 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:15:38 +0200 Subject: [PATCH 25/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 589bcf9d32a8c1..5baab911724499 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -218,7 +218,7 @@ subpaths of the package will no longer be available to importers under `require('pkg/subpath.js')`, and instead they will get a new error, `ERR_PACKAGE_PATH_NOT_EXPORTED`. -This new encapsulation of exports provides new more reliable guarantees +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 From 606eec3da9bf8b842629a040c8ab6ce41962d6fd Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:15:56 +0200 Subject: [PATCH 26/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 5baab911724499..feb4f0b26c0052 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -222,7 +222,7 @@ 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 work correctly. +`require('/path/to/node_modules/pkg/subpath.js')` will still load `subpath.js`. #### Package Exports Subpaths From 6a28834b3447b57ba784f6c555f28c695a3f6f85 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:18:37 +0200 Subject: [PATCH 27/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index feb4f0b26c0052..15f73e14d22541 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -249,7 +249,7 @@ import submodule from 'es-module-package/submodule'; // Loads ./node_modules/es-module-package/src/submodule.js ``` -While other subpaths will still error: +While other subpaths will error: ```js import submodule from 'es-module-package/private-module.js'; From 598da7298a246cc8ab513b868ce1502fad028e5c Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:18:48 +0200 Subject: [PATCH 28/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 15f73e14d22541..acd0f37303bec9 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -389,7 +389,7 @@ Conditional exports can also be extended to exports subpaths, for example: Defines a package where `require('pkg/feature')` and `import 'pkg/feature'` could provide different implementations between the browser and Node.js, -given third-part tool support for a `"browser"` condition. +given third-party tool support for a `"browser"` condition. #### Nested conditions From 59729d46534b839fba121f3069fce47ce80a1fab Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:18:59 +0200 Subject: [PATCH 29/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index acd0f37303bec9..ddae44dba800d3 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -393,8 +393,7 @@ given third-party tool support for a `"browser"` condition. #### Nested conditions -In addition to direct mappings, conditional exports also supports nested -conditions with nested condition objects. +In addition to direct mappings, Node.js also supports nested condition objects. For example, to define a package that only has dual mode entry points for use in Node.js but not the browser: From 15bdd258d217306965b69c192c187ceca313a586 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:19:09 +0200 Subject: [PATCH 30/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index ddae44dba800d3..53b3a57d117767 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -415,7 +415,7 @@ use in Node.js but not the browser: Conditions continue to be matched in order as with flat conditions. If a nested conditional does not have any mapping it will continue checking the remaining conditions of the parent condition. In this way nested -conditions behave fully analogously to nested `if` statements in JS. +conditions behave analogously to nested JavaScript `if` statements. ### Dual CommonJS/ES Module Packages From a74474c60a5673ab484f12ae4ee03c58328c0ddb Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 11 Mar 2020 22:26:17 +0200 Subject: [PATCH 31/39] fixup line length --- doc/api/esm.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 53b3a57d117767..24c86689b8f064 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -177,9 +177,10 @@ unspecified. ### Package Exports -In a package’s `package.json` file, two fields can define entry points for a package: `"main"` and -`"exports"`. The `"main"` field is supported in all versions of Node.js, but its -capabilities are limited: it only defines the main entry point of the package. +In a package’s `package.json` file, two fields can define entry points for a +package: `"main"` and `"exports"`. The `"main"` field is supported in all +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 @@ -187,7 +188,8 @@ 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`. +environment, including whether the package is referenced via `require` or via +`import`. If both `"exports"` and `"main"` are defined, the `"exports"` field takes precedence over `"main"`. From 20ebd1a2048acd5d7fc07585dd31b43327d9800f Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 00:20:44 +0200 Subject: [PATCH 32/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 24c86689b8f064..6e9f3a1ab93cf3 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -226,7 +226,7 @@ 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`. -#### Package Exports Subpaths +#### 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 From 33d7d9cdecffdbe999a6f0742ffa951e8b34e637 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 00:21:27 +0200 Subject: [PATCH 33/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 6e9f3a1ab93cf3..c955b2ae37ad53 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -202,7 +202,7 @@ 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][]. -#### Package Exports Main +#### Main Entry Point Export 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: From 13e1c71d8e182fc51290053add583186ed9df9c7 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 00:59:36 +0200 Subject: [PATCH 34/39] Update doc/api/esm.md Co-Authored-By: Geoffrey Booth --- doc/api/esm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index c955b2ae37ad53..dea003e7d44747 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -175,7 +175,7 @@ unspecified. ## Packages -### Package Exports +### Package Entry Points In a package’s `package.json` file, two fields can define entry points for a package: `"main"` and `"exports"`. The `"main"` field is supported in all From 766940ee15c7fd322c5651f700e95f221aa5aef3 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 01:15:24 +0200 Subject: [PATCH 35/39] remove exports link --- doc/api/esm.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index dea003e7d44747..bcc9e5a4c9723f 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1642,7 +1642,6 @@ success! [Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md [Terminology]: #esm_terminology [WHATWG JSON modules specification]: https://html.spec.whatwg.org/#creating-a-json-module-script -[`"exports"` field]: #esm_package_exports [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs [`esm`]: https://github.com/standard-things/esm#readme [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export From 814f6721cad3e66c244ca9ecad30af72b829fca6 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 01:31:45 +0200 Subject: [PATCH 36/39] Update doc/api/esm.md --- doc/api/esm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index bcc9e5a4c9723f..42f92b98aa4aa3 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -194,8 +194,8 @@ environment, including whether the package is referenced via `require` or via If both `"exports"` and `"main"` are defined, the `"exports"` field takes precedence over `"main"`. -All package entry points apply to both `import` and `require`; `"exports"` and -`"main"` are **not** specific to ES modules or CommonJS. +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. 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 From 756c801545348ce59c44c3dbf1375d385d84cbbc Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 01:34:02 +0200 Subject: [PATCH 37/39] Update errors.md --- doc/api/errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/errors.md b/doc/api/errors.md index c244bfd7f0042f..443eb56cb59af3 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -2550,7 +2550,7 @@ such as `process.stdout.on('data')`. [crypto digest algorithm]: crypto.html#crypto_crypto_gethashes [domains]: domain.html [event emitter-based]: events.html#events_class_eventemitter -[exports]: esm.html#esm_package_exports +[exports]: esm.html#package_entry_points [file descriptors]: https://en.wikipedia.org/wiki/File_descriptor [policy]: policy.html [stream-based]: stream.html From b6e8394330537bce92dc49f94d6dc65ef418e29a Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 01:58:31 +0200 Subject: [PATCH 38/39] update link --- doc/api/errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/errors.md b/doc/api/errors.md index 443eb56cb59af3..204de8bbc7c4a3 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -2550,7 +2550,7 @@ such as `process.stdout.on('data')`. [crypto digest algorithm]: crypto.html#crypto_crypto_gethashes [domains]: domain.html [event emitter-based]: events.html#events_class_eventemitter -[exports]: esm.html#package_entry_points +[exports]: esm.html#esm_package_entry_points [file descriptors]: https://en.wikipedia.org/wiki/File_descriptor [policy]: policy.html [stream-based]: stream.html From 748cbad9649e8822dd3f01dd81226a456541305e Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 12 Mar 2020 02:11:03 +0200 Subject: [PATCH 39/39] linting fixes --- doc/api/esm.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 42f92b98aa4aa3..8da05541889532 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -194,8 +194,9 @@ environment, including whether the package is referenced via `require` or via If both `"exports"` and `"main"` are defined, the `"exports"` field takes precedence over `"main"`. -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. +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. 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 @@ -849,8 +850,8 @@ can either be an URL-style relative path like `'./file.mjs'` or a package name like `'fs'`. Like in CommonJS, files within packages can be accessed by appending a path to -the package name; unless the package’s `package.json` contains an [`"exports"` -field][], in which case files within packages need to be accessed via the path +the package name; unless the package’s `package.json` contains an `"exports"` +field, in which case files within packages need to be accessed via the path defined in `"exports"`. ```js