-
-
Notifications
You must be signed in to change notification settings - Fork 35k
doc: clarify module system selection #41383
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
Changes from 1 commit
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
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -69,10 +69,26 @@ The CommonJS module system is implemented in the [`module` core module][]. | |||||||||||||||||
|
|
||||||||||||||||||
| Node.js has two module systems: CommonJS modules and [ECMAScript modules][]. | ||||||||||||||||||
|
|
||||||||||||||||||
| Authors can tell Node.js to use the ECMAScript modules loader | ||||||||||||||||||
| via the `.mjs` file extension, the `package.json` [`"type"`][] field, or the | ||||||||||||||||||
| [`--input-type`][] flag. Outside of those cases, Node.js will use the CommonJS | ||||||||||||||||||
| module loader. See [Determining module system][] for more details. | ||||||||||||||||||
| 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. | ||||||||||||||||||
|
||||||||||||||||||
| Calling `require()` always use the CommonJS loader, calling `import()` always | |
| use the [ECMAScript modules][] loader. | |
| Calls to `require()` will always try to load the referenced resource as a | |
| CommonJS module. `import()` expressions will load _either_ an | |
| ES module or a CommonJS module, depending on how | |
| the file being imported should be interpreted. | |
| `import()` can be used to reference ES modules from | |
| CommonJS code. |
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 don't think your suggestion is correct, require('./file.json') will first try to load a JSON file before trying to load it as CJS.
I mean, I get that using jargon and expect the reader to know what we mean by "loader" is not a low-bar, but this is a technical documentation, I'd rather use the technical terms than write a potentially mis-leading or incomplete documentation.
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.
If require is loading json, it's loading it as a CommonJS module. Does a CommonJS module need to be JavaScript?
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.
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.
| 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.
Uh oh!
There was an error while loading. Please reload this page.
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
importis 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 torequireis 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
importis 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.