-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
doc: clarify module system selection #41383
Changes from 2 commits
1b1159a
dd7140f
97515fd
c19d161
ce3edd0
be6f791
e9c0b15
4c697b7
2cea6a8
21b45bf
93d6a23
fe05b72
5de6698
b08ec87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -94,12 +94,12 @@ provides interoperability between them and its original module format, | |||||
|
||||||
<!-- type=misc --> | ||||||
|
||||||
Node.js treats JavaScript code as CommonJS modules by default. | ||||||
Authors can tell Node.js to treat JavaScript code as ECMAScript modules | ||||||
Node.js has two module systems: [CommonJS][] modules and ECMAScript modules. | ||||||
|
||||||
Authors can tell Node.js to use the ECMAScript modules loader | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I just don’t think the docs should have any references to “the CommonJS modules loader” or the “ECMAScript modules loader”—no average user knows what those are. There’s just Node, and how it interprets source code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK but using the ES module loader has more effect than on simply JS code (it no longer accepts There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add those other implications here, then. Most people reading these docs wouldn't know about those nuances just because the loader is mentioned. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've tried to address that in ce3edd0, PTAL. |
||||||
via the `.mjs` file extension, the `package.json` [`"type"`][] field, or the | ||||||
aduh95 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
`--input-type` flag. See | ||||||
[Modules: Packages](packages.md#determining-module-system) for more | ||||||
details. | ||||||
[`--input-type`][] flag. Outside of those cases, Node.js will use the CommonJS | ||||||
module loader. See [Determining module system][] for more details. | ||||||
aduh95 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
<!-- Anchors to make sure old links find a target --> | ||||||
|
||||||
|
@@ -1425,6 +1425,7 @@ success! | |||||
[CommonJS]: modules.md | ||||||
[Conditional exports]: packages.md#conditional-exports | ||||||
[Core modules]: modules.md#core-modules | ||||||
[Determining module system]: packages.md#determining-module-system | ||||||
[Dynamic `import()`]: https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports | ||||||
[ECMAScript Top-Level `await` proposal]: https://github.com/tc39/proposal-top-level-await/ | ||||||
[ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration | ||||||
|
@@ -1437,6 +1438,7 @@ success! | |||||
[WHATWG JSON modules specification]: https://html.spec.whatwg.org/#creating-a-json-module-script | ||||||
[`"exports"`]: packages.md#exports | ||||||
[`"type"`]: packages.md#type | ||||||
[`--input-type`]: cli.md#--input-typetype | ||||||
[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ||||||
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer | ||||||
[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -61,7 +61,34 @@ module.exports = class Square { | |||||||||||||||||
}; | ||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
The module system is implemented in the `require('module')` module. | ||||||||||||||||||
The CommonJS module system is implemented in the [`module` core module][]. | ||||||||||||||||||
|
||||||||||||||||||
## Enabling | ||||||||||||||||||
|
||||||||||||||||||
<!-- type=misc --> | ||||||||||||||||||
|
||||||||||||||||||
Node.js has two module systems: CommonJS modules and [ECMAScript modules][]. | ||||||||||||||||||
|
||||||||||||||||||
By default, Node.js will treat the following as CommonJS modules: | ||||||||||||||||||
|
||||||||||||||||||
* Files with a `.cjs` extension; | ||||||||||||||||||
|
||||||||||||||||||
* Files with a `.js` extension when the nearest parent `package.json` file | ||||||||||||||||||
contains a top-level field [`"type"`][] with a value of `"commonjs"`. | ||||||||||||||||||
|
||||||||||||||||||
* Files with a `.js` extension when the nearest parent `package.json` file | ||||||||||||||||||
doesn't contain a top-level field [`"type"`][]. | ||||||||||||||||||
|
||||||||||||||||||
* Files with an extension that is not `.mjs`, `.cjs`, `.json`, `.node`, or `.js` | ||||||||||||||||||
(when the nearest parent `package.json` file contains a top-level field | ||||||||||||||||||
[`"type"`][] with a value of `"module"`, those files will be recognized as | ||||||||||||||||||
CommonJS modules only if they are being `require`d, not when used as the | ||||||||||||||||||
command-line entry point of the program). | ||||||||||||||||||
|
||||||||||||||||||
See [Determining module system][] for more details. | ||||||||||||||||||
|
||||||||||||||||||
Calling `require()` always use the CommonJS loader, calling `import()` always | ||||||||||||||||||
use the [ECMAScript modules][] loader. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think your suggestion is correct, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure, that was my understanding but maybe it's wrong and a JSON file can count as a CommonJS module. The lack of official spec makes the definition blurry so it's probably not worth debating it. |
||||||||||||||||||
|
||||||||||||||||||
## Accessing the main module | ||||||||||||||||||
|
||||||||||||||||||
|
@@ -1047,13 +1074,15 @@ This section was moved to | |||||||||||||||||
[ECMAScript Modules]: esm.md | ||||||||||||||||||
[GLOBAL_FOLDERS]: #loading-from-the-global-folders | ||||||||||||||||||
[`"main"`]: packages.md#main | ||||||||||||||||||
[`"type"`]: packages.md#type | ||||||||||||||||||
[`ERR_REQUIRE_ESM`]: errors.md#err_require_esm | ||||||||||||||||||
[`Error`]: errors.md#class-error | ||||||||||||||||||
[`__dirname`]: #__dirname | ||||||||||||||||||
[`__filename`]: #__filename | ||||||||||||||||||
[`import()`]: https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports | ||||||||||||||||||
[`module.children`]: #modulechildren | ||||||||||||||||||
[`module.id`]: #moduleid | ||||||||||||||||||
[`module` core module]: module.md | ||||||||||||||||||
[`module` object]: #the-module-object | ||||||||||||||||||
[`package.json`]: packages.md#nodejs-packagejson-field-definitions | ||||||||||||||||||
[`path.dirname()`]: path.md#pathdirnamepath | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"doc/api/synopsis.md": { | ||
"command line options": "cli.html#command-line-options", | ||
"command line options": "cli.html#options", | ||
"web server": "http.html" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A user so new to Node that they’re reading this page is highly unlikely to know what the CommonJS modules loader is, or even
path.resolve
. Is there a way we can describe what it means for the string to be parsed by those things, that doesn’t assume any prior Node knowledge?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm all for simplifying what can be simplified, but I also strongly think docs should not omit details on the only basis that new users won't be familiar. I think it's fair to assume no one that has participated in the discussion in this PR is new to Node.js (euphemism), yet folks have expressed surprise at node behavior regarding entry point specifier: to me, that indicates that it should be documented.
Maybe instead we should try to define what is the CommonJS module loader and link to that?
Regarding
path.resolve
, should we replace that withif it's not an absolute path, it's resolved as a relative path from the current working directory
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re
path.resolve
, sure, that sounds good.Re the loaders, if you want to mention them then I think you need to introduce them. Something like:
The last sentence is the key: I’m defining what either of these loaders is by describing what it does. (What it “is” is a Node.js subsystem, but that’s not very informative.)
And within this brief overview, you can link to the detailed sections describing each loader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A specifier passed to
import
is always resolved and loaded by the ES module loader (which may in turn pass the resolved URL to the CJS loader), and a specifier passed torequire
is always resolved and loaded by the CJS loader. I must be missing something, I don't understand what you mean in this last sentence...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the user's perspective, saying that
import
is always handled by the ESM loader implies that the reference would always be treated as ESM. What matters is that Node can treat some imports as CommonJS and some as ESM. As in, what Node is doing is more important than what Node subsystem is doing it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will depend if the user is a loader author (or maybe even a loader user) imho. If loaders were not public, I would agree that's just an implementation detail that would not belong in the docs. Unless we want to make separate docs for loaders, I think we should have this information somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can say that one loader or the other is responsible, that's fine. My point is to go further and explain what it means that a particular loader handles something: what does it do as a result?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to address that in ce3edd0, PTAL.