Skip to content

Remove restriction on '/' prefixes #49449

Description

@bmeck

Given that we have self referential packages, and "imports" in package.json. In addition since // is reserved I think we should remove the reservation since it will by the default URL parser be treated as protocol relative.

Activity

  1. hybrist commented on Aug 5, 2020

    @hybrist
    Contributor

    To be clear, this is about direct import specifiers (https://nodejs.org/api/esm.html#esm_import_specifiers), e.g.:

    // imports file:///usr/local/etc/mytool.config.mjs, assuming import.meta.url has file:// protocol.
    import config from '/usr/local/etc/mytool.config.mjs';

    I think that makes sense. Given "imports", I don't see a strong reason to reserve design space here (IIRC package-relative was the only thing ever discussed for this spot).

  2. ljharb commented on Aug 5, 2020

    @ljharb
    SponsorMember

    Wait, why would we want to allow this? What are the use cases for root-absolute specifiers?

    I can't conceive of a time in CJS where requiring from a /-prefixed path wasn't a bug (or bad design, as was later revealed when it was ran on a different machine).

  3. bmeck commented on Aug 5, 2020

    @bmeck
    MemberAuthor

    @ljharb because it adds consistency and I cannot think of a reason to disallow these specifiers on concrete concerns if we are not reserving them for future features. Any future feature using those prefixes not matching the generally accepted behavior of URL resolution would be bad so it isn't like we can use the feature for other purposes beyond pinning to some kind of root.

  4. ljharb commented on Aug 5, 2020

    @ljharb
    SponsorMember

    I absolutely agree that if / is allowed as a non-// prefix, it would have to function as an absolute path, but I don't think "consistency" is a good argument to enable something that is almost always a footgun.

  5. bmeck commented on Aug 5, 2020

    @bmeck
    MemberAuthor

    @ljharb why is it a footgun? is there clear reasoning here or is it just a linting issue?

  6. ljharb commented on Aug 5, 2020

    @ljharb
    SponsorMember

    It's a footgun because it's not project-portable or machine-portable; any time you have code that uses /, it's highly likely to break on someone else's machine (including a different docker image, host vs guest, if you migrate from one computer to a new one, etc).

  7. bmeck commented on Aug 5, 2020

    @bmeck
    MemberAuthor

    @ljharb that statement is true for any given one off script that isn't installed via a package manager and uses bare specifiers for things. I do see utility in various things like the ability to import '/etc/config/foo.json'; regardless.

  8. hybrist commented on Aug 5, 2020

    @hybrist
    Contributor

    I have definitely imported things using absolute paths. If it's top-level application code that will only ever run in a docker container, I don't see anything wrong with importing something (like a config file) from an absolute path. I haven't seen strong evidence that this behavior caused issues in require but have seen people use it there for - what I would consider - valid reasons. But that's admittedly anecdotal.

  9. hybrist commented on Aug 11, 2020

    @hybrist
    Contributor

    AFAIK (note: I don't use node as a web server) Node.js doesn't have a directory like this, so we can't really mimic this behavior.

    Node.js does have a "directory" like this - because modules in node use the file: protocol and host-relative resolution of / works the same here as it does in HTTP URLs. Resolving /zapp relative to file:///foo/bar is well-defined across platforms. Most importantly it's not generally a path relative to the system root, not even on OSs with POSIX paths. Resolving /a%20b.js will not resolve to the file with POSIX path /a%20b.js. It will resolve to a "completely" different path: /a b.js. Those are two different files.

    The fact that Apache may serve some of the http: URLs from some directory on disk is a special case with one particular configuration. E.g. Apache could serve some URLs from a constant string in the config or from running a CGI script or from various directories depending on URL patterns. In terms of resolution, that shouldn't really matter.

  10. ljharb commented on Aug 11, 2020

    @ljharb
    SponsorMember

    That node's implementation uses URLs doesn't mean that node module specifiers are conceptually URLs - they're file paths (which happen to be a subset of URLs).

  11. bmeck commented on Aug 11, 2020

    @bmeck
    MemberAuthor

    @ljharb the file specifiers are URLs, not paths, they do have fragments taken into consideration.

  12. ljharb commented on Aug 11, 2020

    @ljharb
    SponsorMember

    I realize they are URLs. I'm saying most users will never think of them that way.

  13. bmeck commented on Aug 11, 2020

    @bmeck
    MemberAuthor

    @ljharb people are using this preservation of URL aspects for things like cache busting or ferrying meta-data already, it isn't something we can decouple.

    see docs

  14. hybrist commented on Aug 11, 2020

    @hybrist
    Contributor

    That node's implementation uses URLs doesn't mean that node module specifiers are conceptually URLs - they're file paths (which happen to be a subset of URLs).

    I think it would be dangerous if we allow users to think that they are file paths. If allowing / reinforces that notion, then I'd consider it an argument to keep / "forbidden". Code like import(path.resolve(filename))) may look at first glance like it should work but it will not be portable or safe. It will only work if both filename and the working directory happen to only contain URL-safe characters that are interpreted the same way in both filenames and file: URLs. True for many common filenames but not true for arbitrary filenames.

  15. ljharb commented on Aug 11, 2020

    @ljharb
    SponsorMember

    @DerekNonGeneric that's because MDN is geared towards the web, not node, and on the web, that's a domain-relative URL.

    I feel very strongly that if a leading / is allowed, it can only ever mean "the filesystem root", because that's what it already means in CJS.

  16. hybrist commented on Aug 11, 2020

    @hybrist
    Contributor

    I feel very strongly that if a leading / is allowed, it can only ever mean "the filesystem root", because that's what it already means in CJS.

    Yes, for file: referrers, it would roughly be "the file system root". But if we explain it as "just like CommonJS", we're asking for trouble. Because while it may be relative to the file system root, it's not a file system path (!). The following will load two different files, even though the specifiers are equal and both interpreted relative to the file system root:

    require('/tmp/a%20b.js'); // the file "/tmp/a%20b.js" ("file:///tmp/a%2520b.js")
    import('/tmp/a%20b.js'); // the file "/tmp/a b.js" ("file:///tmp/a%20b.js")

    If we don't think people can differentiate between those two different paths, maybe we shouldn't allow a leading slash in import.

    P.S.: I think we can expect people to think of imports as URL-based longer term. There's way more JavaScript-first devs than node.js-first devs and hopefully the former will become used to thinking in URLs when using import.

  17. bmeck commented on Aug 12, 2020

    @bmeck
    MemberAuthor

    @DerekNonGeneric that seems like you just want to run a chroot around node, not that node would actually need to do anything.

  18. ljharb commented on Aug 18, 2020

    @ljharb
    SponsorMember

    Wait, what does / in CJS on Windows map to now??

  19. ljharb commented on Aug 18, 2020

    @ljharb
    SponsorMember

    Right, but "c:" isn't necessarily the fs root on windows - where linux has /, and all volumes are mounted under that, windows has up to 26 (i think) volume roots, and i'm not aware there is any pathable location that contains all of them.

    Perhaps it maps to the root of the working directory's drive?

  20. bmeck commented on Aug 18, 2020

    @bmeck
    MemberAuthor

    @DerekNonGeneric

    that's not cross-platform, I don't understand how that is the suggestion here.

    It works on everywhere but windows natively and windows has workarounds for this via cygwin, windows subsystem for linux, etc. The point was that the request doesn't seem to be something that node needs to specifically handle, and the details of chroot are quite complex.

  21. bmeck commented on Aug 18, 2020

    @bmeck
    MemberAuthor

    @DerekNonGeneric there is no point that I stated that windows is second class.

  22. hybrist commented on Aug 18, 2020

    @hybrist
    Contributor

    After reading the other recent thread, I think my bigger concern is with *nix platforms where people may confuse /some/file/url/path with /some/os/file/name and then run into issues with the different encoding. It seemed very hard to get the point across that there are (some) practical differences between the two because they look so similar.

    I would be in favor of a clear warning in our resolver when resolving a host-relative URL against a file: URL, suggesting people use an explicit protocol. Not a really strong opinion (there's plenty of common file naming patterns where it's fine) but it may be worth it.

  23. added
    moduleIssues and PRs related to the module subsystem.
    on Sep 1, 2023
  24. github-actions commented on Jun 27, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  25. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jun 27, 2026
  26. github-actions commented on Jul 28, 2026

    @github-actions
    Contributor

    This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
    If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    moduleIssues and PRs related to the module subsystem.staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions