Assume /tmp/foo.txt exist. Reading the file with fs.fileReadSync('/tmp/foo.txt') works as expected, but using fs.fileReadSync('file:///tmp/foo.txt') fails to read the file.
I need to read files relative to the current file, but __dirname/__filename are not available when parsing modules. I can compute __dirname with import.meta.url by passing it to path.dirname, but the path is still prefixed with file://.
I don't remember why it's the case, but I think it is intended that fs methods don't accept URL strings. /cc @jasnell
What you can do instead is create an URL object like so:
const url = new URL(import.meta.url);
fs.readFileSync(url)
Yep, this is intentional. The reason is because it would be a non-compatible breaking change and would introduce a non-trivial performance regression even for the common cases.
Duplicate of #17658.
Any reason why import.meta.url.replace('file://', '') would not work?
@neroux You need some extra handling for URL percent encoding. Generally, some weirdnesses around encoded / characters need to be taken care of with file: URLs, but because import.meta.url can be trusted to always represent a valid file path that's not necessary. Additionally, on Windows one would need to also handle UNC paths which may have punycode-encoded hostnames.
See following, which is our implementation of a general purpose URL-to-file path converter https://github.com/nodejs/node/blob/b55a11d1b17b3e4b9650ef8e7b4e57ef83dc441d/lib/internal/url.js#L1335-L1386
@TimothyGu Good points, I guess I focused too much on the provided example :)
Thanks.
targos' URL solution does sound like the right approach in that case.
Most helpful comment
I don't remember why it's the case, but I think it is intended that
fsmethods don't accept URL strings. /cc @jasnellWhat you can do instead is create an URL object like so: