Repository navigation
URL version of process.cwd() #49273
Description
Activity
- addedfeature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
on Aug 21, 2023 - addedprocessIssues and PRs related to the process subsystem.Issues and PRs related to the process subsystem.whatwg-urlIssues and PRs related to the WHATWG URL implementation.Issues and PRs related to the WHATWG URL implementation.
on Aug 21, 2023 What not use paths? Do you have a specific use case in mind?
In general,
- Cases when we have to use urls. For example,
const settingsLocation = new URL('../.config/settings.json', env.MYBASEDIR ?? cwdURL()); validateOrMutate(settingsLocation); const settings = await import(settingsLocation, { assert: { type: 'json' } });
- any third-party module that accepts only URL, e.g. for compatibility with browsers
- perhaps, eventually Fetch API
- Cases when we want to use urls. For example, if
- we deal not only with local filesystem, e.g. to be polymorphic with
file:///usr/portage/net-dialup/andrsync://winchester.local/portage/net-dialup/ - we want to make sure that on non-posix OS relative paths are not misinterpreted on input and not generated with backslashes on output
- we want to write API that accepts urlstrings, and we don't want heuristics to determine if it's URL or path
- All of
/pathToFileURL\((process\.)?cwd\(/, js:file://${cwd}, ts:file://${cwd} - ESM in Node.js core:
lib/repl.jslib/internal/process/pre_execution.jslib/internal/modules/esm/resolve.jslib/internal/modules/esm/loader.js
In most of these, having
URLinstance that is resolved against cwd would allow avoid conversion (or even double conversion) between URL and path and having a mix of these in code (which can easily become a bug farm, as many operations keep working until there is directory with%/?/#, or URL with hash, or the code runs on Windows).
As specific usecase, let's say, I want to read a file defined by URL (can be string, can be relative), in a way like
const buffer = myFsReadFileSyncByURL('./path/to/file.bin?position=30&length=8#btwAmRelativeURL'); const text = await (await myFetch('path/to/file%20with%20spaces.txt')).text();
It's simple with absolute
URL, but there's no concise way to resolve relative URL into it: WHATWG URL standard doesn't support relative URLs (at least, yet),url.fileURLToPath('file:./path')resolves against/or throws if protocol is omitted.Also as a matter of fact, even if we want to switch context from URLs to paths. we don't have
relativeFileURLtoRelativePath()utility either.I think what you want is similar to Rust's Path struct where you can easily mutate the pathname, get URL components and change them without sacrificing the DX and performance.
Reacted by Mert Can Altingithub-actions commented
on Feb 19, 2024 on Feb 19, 2024 – with GitHub ActionsContributorMore actionsThere has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Feb 19, 2024 github-actions commented
on Mar 21, 2024 on Mar 21, 2024 – with GitHub ActionsContributorMore actionsThere has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.
For more information on how the project manages feature requests, please consult the feature request management document.
FWIW I also ran into this issue today with using
process.cwd()as part of a path passed to dynamicimport(), and the error was pretty confusing (and only on Windows);$ pnpm eslint . --max-warnings 0 Oops! Something went wrong! :( ESLint: 8.57.0 Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'd:' at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:239:11) at defaultLoad (node:internal/modules/esm/load:130:3) at ModuleLoader.load (node:internal/modules/esm/loader:409:13) at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:291:56) at new ModuleJob (node:internal/modules/esm/module_job:65:26) at #createModuleJob (node:internal/modules/esm/loader:303:17) at ModuleLoader.getJobFromResolveResult (node:internal/modules/esm/loader:260:34) at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:241:17) at async ModuleLoader.import (node:internal/modules/esm/loader:328:23) Error: Process completed with exit code 1.
Doesn't show any user code in stack trace. In my case, I was using the dynamic import inside of a
eslint.config.js(ESLint Flat Config) file:// ✅ Working on macOS and Linux, 💥 Throws error on Windows await import(`${process.cwd()}/package.json`, { assert: { type: 'json' }, });
Eventually I guessed my way to figure out it was the
process.cwd()failing only on Windows inside the dynamicimport(), and also usedpathToFileURLfromnode:url:+import { pathToFileURL } from 'node:url'; -await import(`${process.cwd()}/package.json`, { +await import(pathToFileURL(`${process.cwd()}/package.json`).href, { assert: { type: 'json' }, });
What is the problem this feature will solve?
Right now we don't have convenient way to get current working directory in URL form such as
file:///path/to/current/working/directory/.Having easy access to this form would allow to resolve local paths using WHATWG URL constructor, i.e.
new URL('../path/to/file', cwdURL), without need to importpathand worry about platform-specific separators.Getting this form in userspace is not very convenient:
What is the feature you are proposing to solve the problem?
URLinstances withfile:protocol inprocess.chdir(directory).process.cwdURL()that returnsURLinstance or string.resolve(...urls)method that would construct new absolute URL on top of cwd if all providedurlsare relative.url.resolve()is not vacant and has different behaviour, so it should have different name or place.Better naming suggestions are very welcome.
What alternatives have you considered?
file:protocol that would resolve relativepathnameagainst cwd instead of root, i.e.: