doc: correct module loading descriptions · nodejs/node@cd5c1ad

@@ -142,46 +142,56 @@ CommonJS. This includes the following:

142142

* Lexical redeclarations of the CommonJS wrapper variables (`require`, `module`,

143143

`exports`, `__dirname`, `__filename`).

144144145-

### Modules loaders

146-147-

Node.js has two systems for resolving a specifier and loading modules.

148-149-

There is the CommonJS module loader:

150-151-

* It is fully synchronous.

152-

* It is responsible for handling `require()` calls.

153-

* It is monkey patchable.

154-

* It supports [folders as modules][].

155-

* When resolving a specifier, if no exact match is found, it will try to add

156-

extensions (`.js`, `.json`, and finally `.node`) and then attempt to resolve

157-

[folders as modules][].

158-

* It treats `.json` as JSON text files.

159-

* `.node` files are interpreted as compiled addon modules loaded with

160-

`process.dlopen()`.

161-

* It treats all files that lack `.json` or `.node` extensions as JavaScript

162-

text files.

163-

* It can only be used to [load ECMAScript modules from CommonJS modules][] if

164-

the module graph is synchronous (that contains no top-level `await`).

165-

When used to load a JavaScript text file that is not an ECMAScript module,

166-

the file will be loaded as a CommonJS module.

167-168-

There is the ECMAScript module loader:

169-170-

* It is asynchronous, unless it's being used to load modules for `require()`.

171-

* It is responsible for handling `import` statements and `import()` expressions.

172-

* It is not monkey patchable, can be customized using [loader hooks][].

173-

* It does not support folders as modules, directory indexes (e.g.

174-

`'./startup/index.js'`) must be fully specified.

175-

* It does no extension searching. A file extension must be provided

176-

when the specifier is a relative or absolute file URL.

177-

* It can load JSON modules, but an import type attribute is required.

178-

* It accepts only `.js`, `.mjs`, and `.cjs` extensions for JavaScript text

179-

files.

180-

* It can be used to load JavaScript CommonJS modules. Such modules

181-

are passed through the `cjs-module-lexer` to try to identify named exports,

182-

which are available if they can be determined through static analysis.

183-

Imported CommonJS modules have their URLs converted to absolute

184-

paths and are then loaded via the CommonJS module loader.

145+

### Module resolution and loading

146+147+

Node.js has two types of module resolution and loading, chosen based on how the module is requested.

148+149+

When a module is requested via `require()` (available by default in CommonJS modules,

150+

and can be dynamically generated using `createRequire()` in both CommonJS and ES Modules):

151+152+

* Resolution:

153+

* The resolution initiated by `require()` supports [folders as modules][].

154+

* When resolving a specifier, if no exact match is found, `require()` will try to add

155+

extensions (`.js`, `.json`, and finally `.node`) and then attempt to resolve

156+

[folders as modules][].

157+

* It does not support URLs as specifiers by default.

158+

* Loading:

159+

* `.json` files are treated as JSON text files.

160+

* `.node` files are interpreted as compiled addon modules loaded with `process.dlopen()`.

161+

* `.ts`, `.mts` and `.cts` files are treated as [TypeScript][] text files.

162+

* Files with any other extension, or without extensions, are treated as JavaScript

163+

text files.

164+

* `require()` can only be used to [load ECMAScript modules from CommonJS modules][] if

165+

the [ECMAScript module][ES Module] _and its dependencies_ are synchronous

166+

(i.e. they do not contain top-level `await`).

167+168+

When a module is requested via static `import` statements (only available in ES Modules)

169+

or `import()` expressions (available in both CommonJS and ES Modules):

170+171+

* Resolution:

172+

* The resolution of `import`/`import()` does not support folders as modules,

173+

directory indexes (e.g. `'./startup/index.js'`) must be fully specified.

174+

* It does not perform extension searching. A file extension must be provided

175+

when the specifier is a relative or absolute file URL.

176+

* It supports `file://` and `data:` URLs as specifiers by default.

177+

* Loading:

178+

* `.json` files are treated as JSON text files. When importing JSON modules,

179+

an import type attribute is required (e.g.

180+

`import json from './data.json' with { type: 'json' }`).

181+

* `.node` files are interpreted as compiled addon modules loaded with

182+

`process.dlopen()`, if [`--experimental-addon-modules`][] is enabled.

183+

* `.ts`, `.mts` and `.cts` files are treated as [TypeScript][] text files.

184+

* It accepts only `.js`, `.mjs`, and `.cjs` extensions for JavaScript text

185+

files.

186+

* `.wasm` files are treated as [WebAssembly modules][].

187+

* Any other file extensions will result in a [`ERR_UNKNOWN_FILE_EXTENSION`][] error.

188+

Additional file extensions can be facilitated via [customization hooks][].

189+

* `import`/`import()` can be used to load JavaScript [CommonJS modules][commonjs].

190+

Such modules are passed through the `cjs-module-lexer` to try to identify named

191+

exports, which are available if they can be determined through static analysis.

192+193+

Regardless of how a module is requested, the resolution and loading process can be customized

194+

using [customization hooks][].

185195186196

### `package.json` and file extensions

187197

@@ -1151,21 +1161,25 @@ This field defines [subpath imports][] for the current package.

11511161

[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions

11521162

[Runtime Keys]: https://runtime-keys.proposal.wintercg.org/

11531163

[Syntax detection]: #syntax-detection

1164+

[TypeScript]: typescript.md

1165+

[WebAssembly modules]: esm.md#wasm-modules

11541166

[WinterCG]: https://wintercg.org/

11551167

[`"exports"`]: #exports

11561168

[`"imports"`]: #imports

11571169

[`"main"`]: #main

11581170

[`"name"`]: #name

11591171

[`"type"`]: #type

11601172

[`--conditions` / `-C` flag]: #resolving-user-conditions

1173+

[`--experimental-addon-modules`]: cli.md#--experimental-addon-modules

11611174

[`--no-addons` flag]: cli.md#--no-addons

11621175

[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.md#err_package_path_not_exported

1176+

[`ERR_UNKNOWN_FILE_EXTENSION`]: errors.md#err_unknown_file_extension

11631177

[`package.json`]: #nodejs-packagejson-field-definitions

1178+

[customization hooks]: module.md#customization-hooks

11641179

[entry points]: #package-entry-points

11651180

[folders as modules]: modules.md#folders-as-modules

11661181

[import maps]: https://github.com/WICG/import-maps

11671182

[load ECMAScript modules from CommonJS modules]: modules.md#loading-ecmascript-modules-using-require

1168-

[loader hooks]: esm.md#loaders

11691183

[packages folder mapping]: https://github.com/WICG/import-maps#packages-via-trailing-slashes

11701184

[self-reference]: #self-referencing-a-package-using-its-name

11711185

[subpath exports]: #subpath-exports