Skip to content
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

Bare specifiers definition. #53022

Open
gitspeaks opened this issue May 16, 2024 · 24 comments
Open

Bare specifiers definition. #53022

gitspeaks opened this issue May 16, 2024 · 24 comments
Labels
doc Issues and PRs related to the documentations. loaders Issues and PRs related to ES module loaders

Comments

@gitspeaks
Copy link

gitspeaks commented May 16, 2024

Affected URL(s)

https://nodejs.org/docs/latest-v20.x/api/esm.html#terminology

Description of the problem

"Bare specifiers like 'some-package' or 'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an "exports" field."

Incorrect, including the file extension in bare specifiers is not necessary for packages with "main" field.

Example:

index.mjs:

import * as module from 'mymodule'
module.greet();

node_modules/mymodule/index.mjs:

export function greet() {
    console.log('Hello from module!');
}

node_modules/mymodule/package.json:

{
  "name": "mymodule",
  "version": "1.0.0",
  "main": "index.mjs",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}
node index.mjs

Hello from module!

@gitspeaks gitspeaks added the doc Issues and PRs related to the documentations. label May 16, 2024
@RedYetiDev
Copy link
Member

Would you like to open a PR to add your proposed changes?

@RedYetiDev RedYetiDev added the loaders Issues and PRs related to ES module loaders label May 16, 2024
@aduh95
Copy link
Contributor

aduh95 commented May 16, 2024

I don't know if your example shows that the sentence is incorrect. It would be incorrect if you were able to show an example of a package with an "exports" field where adding the file extension would be necessary.
IIUC your example disproves the sentence "Including the file extension is always necessary for packages without an "exports" field.", but that sentence is not in our docs.

@gitspeaks
Copy link
Author

From the docs: "Including the file extension is only necessary for packages without an "exports" field."

The package in my example does not have an "exports" field and yet it is not necessary to include the file extension to load it.

It's as simple as that.

@aduh95
Copy link
Contributor

aduh95 commented May 16, 2024

I don’t see a contradiction, but I’m not a native speaker so maybe there’s some nuance I’m missing. That being said, if someone suggests a better wording, it would likely gets accepted.

@gitspeaks
Copy link
Author

gitspeaks commented May 16, 2024

I don’t see a contradiction, but I’m not a native speaker so maybe there’s some nuance I’m missing. That being said, if someone suggests a better wording, it would likely gets accepted

I don't understand what you're saying. I didn't suggest anything. I pointed at a false assertion, no more, no less.

@aduh95
Copy link
Contributor

aduh95 commented May 16, 2024

I didn’t say you suggested anything.

I pointed at a false assertion

Are you saying that “only necessary” and “always necessary” mean the same thing? I’m not trying to sound dismissive, I’m only trying to express my interpretation of the docs you cited.

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

I believe @gitspeaks is suggesting that according to the documentation, you must specify the full file path (with extension) when the package doesn't export anything with exports, although main can also serve this purpose.

But, in my opinion, @gitspeaks is misunderstanding the documentation. IIUC It is referring to getting a module by its path, and not by its module name (E.G my-module/my-file.js)

They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively

In your example, you are getting the main entry point. Do you also not require an extension when getting a feature module?

@gitspeaks
Copy link
Author

@aduh95

Are you saying that “only necessary” and “always necessary” mean the same thing?

In this context, I don't see a reasonable interpretation otherwise.

Quote: "Including the file extension is only necessary for packages without an 'exports' field."

  1. The sentence says nothing about packages WITH an 'exports' field.
  2. If you interpret "only necessary" not as "always necessary," then the logical implication is that there are packages WITHOUT 'exports' fields that must include a file extension, and there are packages that don't.

In other words, the sentence says nothing! Does that seem reasonable to you?

@RedYetiDev I understand the documentation completely.

Here is the example adjusted to show a bare specifier that includes a file extension. Note that the module does not include an 'exports' key.

However, all this is irrelevant to the point I'm making.

index.mjs

import * as module from 'mymodule/index.mjs'
module.greet();

node_modules/mymodule/index.mjs

export function greet() {
    console.log('Hello from module!');
}

node_modules/mymodule/package.json

{
  "name": "mymodule",
  "version": "1.0.0",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}
node index.mjs

Hello from module!

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

And if you remove the extension?

(Also, if this is irrelevant, than I don't think I am understanding the statement you're making)

@gitspeaks
Copy link
Author

And if you remove the extension?

Of course it won't work, the module does not have an export field.

(Also, if this is irrelevant, than I don't think I am understanding the statement you're making)

Read: "Including the file extension is only necessary for packages without an 'exports' field or a 'main' field."

Does this help?

@gitspeaks
Copy link
Author

Now, you might ask yourself why I didn't just state: Including the file extension is only necessary for packages without an 'exports' field or a 'main' field from the very beginning. The answer is simple: I don't know if including the file extension is only necessary for packages without an 'exports' field or a 'main' field, or if there are other exceptions.
I just discovered one.

@aduh95
Copy link
Contributor

aduh95 commented May 16, 2024

In this context, I don't see a reasonable interpretation otherwise.

If you ask yourself "is it necessary to include the file extension?", the docs responds "only for packages without an "exports" field". The fact that you don't need to provide an extension to load the "main" module doesn't seem to contradict that.

Read: "Including the file extension is only necessary for packages without an 'exports' field or a 'main' field."

That would be incorrect, you still need to include the file extension (e.g. try to load mymodule/index, it will fail no matter if there's a "main" field or not; it could succeed only if there's an "exports" field with a ./index entry (or a subpath pattern that includes ./index)).

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

I’m sorry, but I’m still not understanding the issue here, I think the docs are correct (as @aduh95 has said)

@gitspeaks
Copy link
Author

To sum-up:

import * as module from 'mymodule'

  1. 'mymodule' is bare specifier
  2. 'mymodule' is a name of a package
  3. the project.json does not include exports field
  4. the project.json does include a main field.
  5. No need to specify any file extension.

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

So, a change like this would be what you find sutable? Or maybe a removal of the note at the end?

Original:

Bare specifiers like 'some-package' or 'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an "exports" field.

Changed:

Bare specifiers like 'some-package' or 'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for requiring feature modules in packages without an "exports" field.

@gitspeaks
Copy link
Author

gitspeaks commented May 16, 2024

If the goal of the 'note at the end' was to simply say that the bare specifier of a 'feature module' is the file name of the feature module prefixed by the package name, then of course I would delete the mention of the 'exports' field of a package, as it is simply irrelevant.

I would just write:

Bare specifiers are module identifiers like 'some-package' or 'some-package/shuffle'. These specifiers can point to the main entry point of a package by using just the package name or to a specific feature module within a package by prefixing the package name to the feature module file name like 'some-package/some-feature.mjs'.

@gitspeaks
Copy link
Author

edit: "some-package/some-feature.mjs"

@RedYetiDev
Copy link
Member

Bare specifiers are module identifiers like 'some-package' or 'some-package/shuffle'. These specifiers can point to the main entry point of a package by using just the package name, or to a specific feature module within a package by appending the feature-module file path to the package name, E.G. some-package/some-feature.mjs.

Note: I've adjusted this from the original, my changes are marked in bold.

@aduh95 would this wording work? (with any slight adjustments that would need to be made)

@gitspeaks
Copy link
Author

gitspeaks commented May 16, 2024

"by appending the feature-module file path to the package name"

I disagree. "feature-module file path" can be confused with the file's file-system path.

Just add another example with a deeper path:

"Bare specifiers are module identifiers like 'some-package' or 'some-package/shuffle'. These specifiers can point to the main entry point of a package by using just the package name or to a specific feature module within a package by prefixing the package name to the feature module file name like 'some-package/some-feature.mjs' or 'some-package/some-submodule/some-feature.mjs."

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

file path refers to the path-to-a-file (E.G. /dir/file.txt)
file name refers to the file's basename + extension (E.G. file.txt).

relative file path is probably the best term, with file path in second.

Bare specifiers are module identifiers like 'some-package' or 'some-package/shuffle'. These specifiers can point to the main entry point of a package by using just the package name, or to a specific feature module within a package by appending the feature-module's relative file path to the package name, E.G. some-package/some-feature.mjs.

@gitspeaks
Copy link
Author

gitspeaks commented May 16, 2024

I suggest:

"Bare specifiers are module identifiers like some-package or some-package/shuffle. These specifiers can point to the main entry point of a package by using just the package name, or to a specific feature module within a package by using the feature module's file path relative to the package name like some-package/some-feature.mjs or some-package/some-module/some-feature.mjs"

@RedYetiDev
Copy link
Member

RedYetiDev commented May 16, 2024

or some-package/some-module/some-feature.mjs

This might be redundant, but I'd like for @nodejs/loaders to weigh in on this "issue" in general, that group (including @aduh95) are the final judges, not me.

@gitspeaks
Copy link
Author

Alternatively:

"Bare specifiers are module identifiers like some-package or some-package/shuffle. These specifiers can point to the main entry point of a package by using just the package name, or to a specific feature module within a package by using the feature module's file path relative to the package name like some-package/path/to/some-feature.mjs

@gitspeaks
Copy link
Author

Including Exported Feature Module Paths:

"Bare specifiers are module identifiers like some-package or some-package/shuffle. These specifiers can point to the main entry point of a package by using just the package name, or to a specific feature module within a package by using the feature module's file path relative to the package name, like some-package/path/to/some-feature.mjs, or by using an exported feature module's path, like some-package/some-feature."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. loaders Issues and PRs related to ES module loaders
Projects
None yet
Development

No branches or pull requests

3 participants