Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4759735
doc: update packages documentation for Node.js 12 EOL
guybedford Jun 11, 2022
4fad6db
lint fixes
guybedford Jun 11, 2022
924c758
Apply suggestions from code review
guybedford Jun 11, 2022
894a104
main -> index, rewordings
guybedford Jun 12, 2022
5cb9eda
also update conditional example
guybedford Jun 12, 2022
47c501a
latest suggestions
guybedford Jun 13, 2022
2c9d7c3
remove extension in module export case
guybedford Jun 14, 2022
b65c5e5
update patterns history
guybedford Jun 14, 2022
e102fce
update imports trailers support
guybedford Jun 14, 2022
f4184d6
reorder changes
guybedford Jun 14, 2022
9db527f
use patterns extensions variant in interop example
guybedford Jun 14, 2022
4cbd77f
note major upgrade path
guybedford Jun 14, 2022
d339608
fixup unextensioned feature export
guybedford Jun 14, 2022
c83484f
Apply suggestions from code review
guybedford Jun 14, 2022
2dec621
dedicated section on import maps compat
guybedford Jun 14, 2022
074c1f5
clarification
guybedford Jun 14, 2022
a196e03
more clarifications
guybedford Jun 14, 2022
82ce47c
compatibility -> interopoerability
guybedford Jun 14, 2022
d8a9064
typo, rewording
guybedford Jun 14, 2022
b9ffef7
remove duplicated point
guybedford Jun 14, 2022
5096cc7
rewordings, fixups
guybedford Jun 14, 2022
21263f2
fixup reference ordering
guybedford Jun 14, 2022
469e5e8
subpath extensions guidance section over import maps interop section
guybedford Jun 15, 2022
f2b426a
typo
guybedford Jun 15, 2022
7804776
update import map link
guybedford Jun 15, 2022
ad0861f
lint fixes for Jacob
guybedford Jun 15, 2022
14a9f4e
further clarifications
guybedford Jun 15, 2022
eebd97d
final recommendataion cleanup
guybedford Jun 15, 2022
b0a0df3
correct patterns change
guybedford Jun 15, 2022
03e84ea
extensioned v extensionless -> extensions in subpaths
guybedford Jun 15, 2022
757bb60
casing
guybedford Jun 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
subpath extensions guidance section over import maps interop section
  • Loading branch information
guybedford committed Jun 15, 2022
commit 469e5e8d0dca2335890c744b2f2391361334cd00
79 changes: 23 additions & 56 deletions doc/api/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,6 @@ to only the specific feature exports exposed:
}
```
Comment thread
GeoffreyBooth marked this conversation as resolved.

It is recommended to pick one of supporting extensioned or unextensioned
subpaths for consistent usage. In the above example the extensioned form is used
(ie via `import "my-package/feature/feat.js"`), which can be useful for better
[interoperability with import maps][].

### Main entry point export

When writing a new package supporting Node.js 12.20 and above (i.e. including
Expand Down Expand Up @@ -383,52 +378,24 @@ import submodule from 'es-module-package/private-module.js';
// Throws ERR_PACKAGE_PATH_NOT_EXPORTED
```

#### Interoperability with Import Maps

[Import maps][] are a separate cross-platform standard for module resolution,
already in use by some browsers, server-side JavaScript runtimes, and build
tools. Although not currently implemented in Node.js, there are plans to provide
import maps support in Node.js in future.

[Import maps][] are able to provide explicit specifier mappings for packages
and package subpaths, and therefore all mappings defined by Node.js package
exports and subpath exports can be mapped by a corresponding import map. In
addition they support [folder mappings][] but not pattern mappings like
Node.js supports.

Where interoperability with import maps is desired, it is recommended to use
explicit file extensions when defining package subpaths so that package
consumers write `import 'pkg/subpath.js'` instead of `import 'pkg/subpath'`.
The corresponding import map can then use a folder mapping to map multiple
subpaths where possible, instead of needing the more bloated form of a separate
map entry for each package subpath.

For example with the above package, the generated import map can be taken to be:

```json
{
"imports": {
"pkg": "/node_modules/pkg/index.js",
"pkg/": "/node_modules/pkg/src/"
}
}
```
#### Extensioned v Extensionless Subpaths
Comment thread
guybedford marked this conversation as resolved.
Outdated

instead of the larger import map to handle adding each subpath file extension:
It is recommended to pick either one of providing extensioned or unextensioned
subpaths for a package to ensure consistent usage. This keeps the package
contract clear for consumers, simplifies package subpath completions, and
ensures all dependent packages import with the same specifier mappings.

```json
{
"imports": {
"pkg": "/node_modules/pkg/index.js",
"pkg/submodule1": "/node_modules/pkg/src/submodule1.js",
"pkg/submodule2": "/node_modules/pkg/src/submodule2.js",
"pkg/submodule3": "/node_modules/pkg/src/submodule3.js",
}
}
```
Ultimately, it is the choice of the package author which form of subpath to
support - extensionless, like `import 'pkg/subpath'`, or extensioned, like
`import 'pkg/subpath.js'` and per the exports example above. Both conventions
are used in the Node.js ecosystem.

This also mirrors the requirement of using [the full specifier path][] in
relative and absolute import specifiers.
For packages where interoperability with [import maps][] is desired, using
Comment thread
GeoffreyBooth marked this conversation as resolved.
Outdated
explicit file extensions when defining package subpaths can be preferable since
the corresponding import map can then use a [folder mapping][] to map multiple
subpaths where possible, instead of the more bloated form of a separate map
entry for each package subpath. This also mirrors the requirement of using
[the full specifier path][] in relative and absolute import specifiers.

### Exports sugar

Expand Down Expand Up @@ -463,11 +430,11 @@ added:
- v12.19.0
-->

In addition to the [`"exports"`][] field, it is possible to define internal
package import maps that only apply to import specifiers from within the package
itself.
In addition to the [`"exports"`][] field, there is a package `"imports"` field
to create private mappings that only apply to import specifiers from within the
package itself.

Entries in the imports field must always start with `#` to ensure they are
Entries in the `"imports"` field must always start with `#` to ensure they are
disambiguated from external package specifiers.

For example, the imports field can be used to gain the benefits of conditional
Expand Down Expand Up @@ -495,8 +462,8 @@ file `./dep-polyfill.js` relative to the package in other environments.
Unlike the `"exports"` field, the `"imports"` field permits mapping to external
packages.

The resolution rules for the imports field are otherwise
analogous to the exports field.
The resolution rules for the imports field are otherwise analogous to the exports
field.

### Subpath patterns

Expand Down Expand Up @@ -1360,7 +1327,6 @@ This field defines [subpath imports][] for the current package.
[Corepack]: corepack.md
[ES module]: esm.md
[ES modules]: esm.md
[Import maps]: https://github.com/WICG/import-maps
[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions
[`"exports"`]: #exports
[`"imports"`]: #imports
Expand All @@ -1374,8 +1340,9 @@ This field defines [subpath imports][] for the current package.
[`esm`]: https://github.com/standard-things/esm#readme
[`package.json`]: #nodejs-packagejson-field-definitions
[entry points]: #package-entry-points
[folder mappings]: https://github.com/WICG/import-maps#extension-less-imports
[folder mapping]: https://github.com/WICG/import-maps#extension-less-imports
[folders as modules]: modules.md#folders-as-modules
[import maps]: https://github.com/WICG/import-maps
[interoperability with import maps]: #interoperability-with-import-maps
[load ECMASCript modules from CommonJS modules]: modules.md#the-mjs-extension
[loader hooks]: esm.md#loaders
Expand Down