Repository navigation
Add import.meta.directory and import.meta.file properties #47756
Description
Activity
- addedfeature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
on Apr 28, 2023 dirShould be
directory. Lets not abbreviate for the sake of it.Reacted by Axel D. and Moshe Atlow- addedesmIssues and PRs related to the ECMAScript Modules implementation.Issues and PRs related to the ECMAScript Modules implementation.
on Apr 30, 2023 - changed the title
[-]Add `import.meta.dir` and `import.meta.file` properties[/-][+]Add `import.meta.directory` and `import.meta.file` properties[/+]on May 1, 2023 Absolutely. I amended OP and title accordingly.
What would we use as values when the module is loaded from outside of the FS? E.g. from the network or from a custom loader.
Reacted by Moshe Atlow and Tobias NießenOne option may be to define both as
: string | nothing.I’m not sure it’s worth adding something that you can rely upon because it may not be defined. Maybe we should ask why
import.meta.urland the URL API doesn’t work for you today. You say in the OP that you’d like an absolute file path, why? What’s your use case, if I may ask?Reacted by Tobias NießenSure.
Webpack, for instance, requires an absolute path. This requirement brought me to the idea that something intrinsic, important is missing.
Multi-threaded applications or libraries might also prefer to work with absolute paths.
That looks like an issue on Webpack side rather than Node.js. Did you try reaching out to them? In the mean time, you can use
fileURLToPath(import.meta.url)when you need a path, but IMO not supportingfile:URL should be considered a bug.
I suggest we close this issue for now, we can reopen it a compelling use case arises, and we find a compromise for non-FS modules, and other JS runtimes show interest. Wdyt?I have a different perspective. Writing desktop applications or libraries will not be able to use
import.meta.url. They need to be presented with a file system path.I have a different perspective. Writing desktop applications or libraries will not be able to use
import.meta.url. They need to be presented with a file system path.Why is that? What is it that you can do with an absolute path that you can’t do with a
file:URL?After further digging into the Webpack issue I'm facing, I'm not quite sure if it isn't a Webpack issue after all.
However, from my observation I noticed that the
pathlibrary yields inconsistent output:import * as path from 'node:path'; const url = import.meta.url; const dir = path.dirname(import.meta.url); const newdir = path.join(path.dirname(import.meta.url), 'dust'); console.log(`url: ${url}`); console.log(`dir: ${dir}`); console.log(`newdir: ${newdir}`);
… yields:
url: file:///D:/Documents/Visual%20Studio-Projekte/HTML/MyProject.js/webpack/webpack.config.mjs dir: file:///D:/Documents/Visual%20Studio-Projekte/HTML/MyProject.js/webpack newdir: file:\D:\Documents\Visual%20Studio-Projekte\HTML\MyProject.js\webpack\dustpath.join()converts the path format whilepath.dirname()doesn't. The two different formats lead to ambiguous results, thereby rendering manual path operations error prone.6 remaining items
It fails because you convert it to a string. You need a URL instance.
Reacted by Antoine du HamelYes, you are right. My machine is currently building, so I'm very slow in responding and amending my comments at the moment.
Yet, it doesn't look like
Urlprovides path manipulation methods, likepathdoes. Or am I missing something?URL APIs won’t provide path manipulation, only URL manipulations.
I’ve been using the URL APIs for quite some time myself, and it’s quite rare I need to translate them into a path (and when I do it’s to content a third party library that haven’t upgraded to supportURL).EDIT: I should point out that there are specific use case that are not supported (e.g.
basename,extname). One might be tempted to considere those niche-enough that no one bothered to create an equivalent API, but it’s not too late.@aduh95: I comprehend and agree.
So, if
pathhas become, well, obsolete, then why not deprecate thepathlibrary and add corresponding methods tourl?node:pathis still useful when dealing with paths, however it is not the correct API to deal with URLs. Sorry if I gave you the impression that it was obsolete, it's not (it's still quite useful on CJS modules for example).why not […] add corresponding methods to
url?yeah why not, PRs welcome!
I could give it a try. Would you mind pointing me to the
urllib source?Never mind … found it.
I tried a preliminary solution on this issue, just to see if it works (PR: #47982).
Unfortunately, I'm not able to set-up a running development system in due time.
Would you mind checking if the changes I made are appropriate? I could add further path related methods then.
Why don't you use
path.basename(url.fileURLToPath('file:///C:/user/repos/mine/main.js'))etc.? This will throw, as expected, when the URL is not actually a file URL -- which is good, because most applications should treat the pathname of non-file URLs as opaque. If you really want to parse paths of arbitrary URLs, you can usepath.posix.basename(new URL('file:///C:/user/repos/mine/main.js').pathname)etc. -- but don't be surprised if the results are meaningless.Slowly I feel being kidded with. I added these two properties because @aduh95 suggested to do so. I didn't feel like and I didn't express that I'd like to have these two properties at hand.
I regularly need
path.join(),path.normalize(),path.resolve(),path.dirname(). These are the ones I (and probably others) regularly need when dealing with desktop applications.That's not a niche. It's rather a quite daily business.
Reacted by Brian BurnsI regularly need
path.join(),path.normalize(),path.resolve(),path.dirname(). These are the ones I (and probably others) regularly need when dealing with desktop applications.That's not a niche. It's rather a quite daily business.
As multiple people have tried to explain throughout this discussion, that's a valid use case and it is already possible using, for example,
fileURLToPathorURL.prototype.pathname.This is widely used. If you take a look at the MDN page about
import.meta, you will even find examples that do just that.
That's exactly what this issue is about: Providing
pathcompatible data.Your original feature request was the addition of new properties to
import.meta. This is unlikely because it would break compatibility with the HTML Standard. As explained multiple times, it is easy to obtain a path fromimport.meta.url, assuming it is indeed a file URL.In #47982, you added
Fixes: #47756, so I assumed that PR was supposed to resolve this issue. Based on your last comment in this issue, that seems unlikely now.Could you please clarify what exactly your feature request is at this point?
Apologies if I led you into a dead end here @SetTrend, this was not my intent. I was thinking on adding them to
node:urlor to add support forURLinstances innode:pathAPIs, as any change to theURLclass would need to be added to the WHATWG spec. Maybe we should start by documenting how to use each API, and from there see which use case could be improved. Something like:- Access relative files:
- in CommonJS:
const path = require('node:path'); const subdir = path.join(__dirname, 'subdir'); const filePath = path.join(subdir, 'somefile.txt');
- In ES module:
const subdir = new URL('./subdir/', import.meta.url); const fileURL = new URL('./somefile.txt', subdir);
- in CommonJS:
- Get the file extension:
- in CommonJS:
const path = require('node:path'); const filePath = path.join(__dirname, 'somefile.txt'); console.log(path.extname(filePath)); // '.txt'
- In ES module:
import { posix as path } from 'node:path'; const fileURL = new URL('./somefile.txt', import.meta.url); console.log(path.extname(fileURL.pathname)); // '.txt'
- in CommonJS:
- etc.
And maybe we'll find that the current APIs are good enough as is, and it would help folks who are familiar with
node:pathmigrate to the non-Node.js-specificURLAPI.Reacted by Brian Burns- Access relative files:
Thanks for clarifying.
Given that some programs store a number of variables for storing their data within a hierarchy, and given the user is able to set these variables, I still have the impression that
URLwill be cumbersome for dealing with those:import URL from 'node:url'; let langId= ...; let images = ...; let packages = ...; let libLocation = ...; const newUrl = new URL(langId, new URL(images, new URL(packages, new URL(libLocation, import.meta.url))));
If
langId,images,packages, andlibLocationare strings, here's how you would do it:// No import is needed, URL is available as a global. // If you want to import it, you can do this as such: import { URL } from 'node:url'; let langId= ...; let images = ...; let packages = ...; let libLocation = ...; const newUrl = new URL(`./${libLocation}/${packages}/${images}/${langId}/`, import.meta.url);
More likely you would store the intermediate folder references as URL instances:
let langId= ...; const libLocation = new URL('./lib/', import.meta.url); const packages = new URL('./packages/', libLocation); const images = new URL('./images/', packages); const newUrl = new URL(`./${langId}/`, images);
All in all, it's not a perfect API but it's the most closest thing to perfect: it's standard. I encourage you to use it over
node:pathon ESM, and to request the libraries you are using to add support for it. It does take a bit of work to get familiar with it, I personally think it's worth it as that's knowledge that can be applied for any JS runtime, but also feel free to convert file URLs to paths and keep using the API you are used to if you prefer.Anyways, I'm going to close this issue, as it's derived quite some bit from the original request. Feel free to continue the discussion and ask more questions though.
Reacted by Tobias Nießen and Brian Burns
What is the problem this feature will solve?
Currently,
import.meta.urlgets the current file's absolute file path in URL format. This format cannot be used withnode:pathfor creating absolute file paths.The proposed additional properties will provide the current file's file path details in a format that can be used with
node:path.What is the feature you are proposing to solve the problem?
import.metashould provide the following additional properties:directoryfileExample
Given the following absolute file path (on Windows):
…
import.metawould provide the following properties:{ "directory" : "C:\\user\\repos\\mine\\" "file" : "main.js" "url" : "file:///C:/user/repos/mine/main.js" }