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

Unsupported character(s) in import module-name #41052

Closed
notroid5 opened this issue Dec 2, 2021 · 5 comments
Closed

Unsupported character(s) in import module-name #41052

notroid5 opened this issue Dec 2, 2021 · 5 comments
Labels
esm Issues and PRs related to the ECMAScript Modules implementation.

Comments

@notroid5
Copy link
Contributor

notroid5 commented Dec 2, 2021

Version

16.13.0

Platform

Microsoft Windows NT 10.0.19043.0 x64

Subsystem

No response

What steps will reproduce the bug?

  • create a file to run the code, e.g. server.js:
import { userZero } from './#user/user0.js'
console.log(userZero)
  • create package.json:
{
    "type": "module"
}
  • create a folder starting with # (probably not the only unsupported character), e.g. #user
  • create a file in this folder, e.g. user0.js:
export const userZero = 'This is a user.'

How often does it reproduce? Is there a required condition?

Node.js always throws an unconditional error during the import.

What is the expected behavior?

It should log the string.

What do you see instead?

PS D:\issue> node .\server.js
node:internal/process/esm_loader:94
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import 'D:\issue\' is not supported resolving ES modules imported from D:\issue\server.js
Did you mean to import ../#user/user0.js?
    at new NodeError (node:internal/errors:371:5)
    at finalizeResolution (node:internal/modules/esm/resolve:412:17)
    at moduleResolve (node:internal/modules/esm/resolve:932:10)
    at defaultResolve (node:internal/modules/esm/resolve:1044:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:422:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:222:40)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///D:/issue/#user/user0.js'
}

Additional information

  • npm -v: 8.1.0
  • It does not matter whether a relative or absolute path is used, although the error is slightly different
  • Trying to escape \ the # does not work
  • If you remove the #, it works as expected
  • Node.js seems to think I want to import a directory before the #, yet is aware of the rest of the full path...?
  • The suggested solution ("Did you mean to import ...") is complete nonsense in this case
  • I couldn't find a list if unsupported characters for import module-names, so I have to assume there is none, which would mean that every character should be supported, especially since it's just a string pointing to a file
  • Thought I was going crazy when this simple import refused to work, so I made sure everything else works fine multiple times...

Edit: Typo

@devsnek
Copy link
Member

devsnek commented Dec 2, 2021

import specifiers are URLs. you'll need to replace # with %23 and \ with %5C

@devsnek devsnek closed this as completed Dec 2, 2021
@devsnek devsnek added the esm Issues and PRs related to the ECMAScript Modules implementation. label Dec 2, 2021
@notroid5
Copy link
Contributor Author

notroid5 commented Dec 2, 2021

Okay, that works but is this documented somewhere?
And even if, import works with local paths, so it is expected to replace problematic characters by itself and not by the user.
Which it clearly does not, ergo this issue.

@Trott
Copy link
Member

Trott commented Dec 2, 2021

Okay, that works but is this documented somewhere?

Yes. https://nodejs.org/api/esm.html#urls

ES modules are resolved and cached as URLs. This means that files containing special characters such as # and ? need to be escaped.

There is probably room for improvement. For example, it could indicate the type of escaping, as escaping with \ won't work.

If you or someone else reading this would like to suggest an improvement, you can click the "Edit On GitHub" link at the top of that page, or you can edit the doc/api/esm.md file in this repository and submit the change as a pull request.

@Trott
Copy link
Member

Trott commented Dec 2, 2021

And even if, import works with local paths, so it is expected to replace problematic characters by itself and not by the user.

There's probably a discussion to be had about whether this calls for a doc enhancement, a change in the error message, or an actual change in the behavior of the ESM system. (I would imagine that last one seems unlikely to happen, but I'm not deeply engaged in the discussions around that stuff so I could be very wrong.) (Also, those three options are not mutually exclusive.)

@nodejs/modules

@aduh95
Copy link
Contributor

aduh95 commented Dec 3, 2021

import works with local paths

Well precisely it doesn't, hence your issue. If all the parts of your path only contains alphanumeric characters, and you are using an OS that accepts / to as path separator, you may think that those URLs are paths, but it's just a coincidence. On Windows, you may have noticed you cannot use \ to separate folders in the specifiers, no matter how you try to escape those, because it's not a path.

So you are trying to specify a relative URL, the problem is that # is a special character for URLs:

$ new URL('./#user/user0.js', 'file:///local/cwd/')
URL {
hash: "#user/user0.js"
host: ""
hostname: ""
href: "file:///local/cwd/#user/user0.js"
origin: "file://"
password: ""
pathname: "/local/cwd/"
port: ""
protocol: "file:"
search: ""
searchParams: URLSearchParams {}
username: ""
[[Prototype]]: URL
}

The same thing would appear if you were using ? in your directory name (although that's not a problem you can have on Windows, as it forbids use of ? in file names for some reason).

nodejs-github-bot pushed a commit that referenced this issue Dec 7, 2021
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Dec 13, 2021
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Dec 14, 2021
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Jan 31, 2022
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Jan 31, 2022
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Linkgoron pushed a commit to Linkgoron/node that referenced this issue Jan 31, 2022
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: nodejs#41052

PR-URL: nodejs#41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Feb 1, 2022
This should make it clear(er) how to escape special characters like `#`
and `?`.

Ref: #41052

PR-URL: #41074
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

No branches or pull requests

4 participants