-
Notifications
You must be signed in to change notification settings - Fork 13
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
import.meta path helpers proposal #54
import.meta path helpers proposal #54
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for filename and dirname. Code using these properties isn’t portable intrinsically, double underscores are gross, and it’s a good thing that the import.meta
syntax makes that clear.
|
||
A string containing the full absolute filesystem path of the folder containing the current module, like CommonJS `__dirname`. This is the same as `dirname(fileURLToPath(import.meta.url))` in Node.js. An example value would be `/Users/Geoffrey/my-project/src`. | ||
|
||
The value should not have a trailing slash. This is consistent with CommonJS `__dirname`, so that it can be used as a drop-in replacement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s also consistent with filesystems, where the trailing slash means inside the directory, and without the slash means the directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
|
||
Bun has shipped `import.meta.path`, an equivalent to the `import.meta.filename` proposed here; and `import.meta.dir`, an equivalent to the `import.meta.dirname` proposed here. | ||
|
||
On the one hand, Bun’s names are shorter and `import.meta.path` is arguably more correct of a name for a value that refers to a full absolute path like `/Users/Geoffrey/my-project/src/index.js` rather than just the filename `index.js`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, all of path
, pathname
, filename
, and filepath
are open to interpretation as to what they refer to. All of them can be a synonym of dirname
as defined in this document, or refer to the full absolute path to the file.
|
||
On the other hand, `__filename` and `__dirname` are _so_ well known by developers, being used by just about every Node.js developer who has written any CommonJS code over the past decade-plus, that preserving those names might aid in usability due to familiarity and consistency with documentation of existing ecosystem libraries. | ||
|
||
We feel that on balance, the familiarity and legacy of `__filename` and `__dirname` outweighs the benefits of new names that are shorter and more technically correct. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct.
|
||
These properties would be optional, even if a runtime supports filesystem-based modules. This allows for runtimes where modules are _primarily_ run from HTTP / HTTPS URLs to avoid creating a portability hazard where these properties exist while developers are working locally but are undefined when the code is deployed. | ||
|
||
This portability hazard is a primary objection to this proposal. We feel that on balance, the convenience of these properties outweighs the potential hazard; and that a different portability hazard exists without these helpers, in that developers will write code such as `fileURLToPath(import.meta.url)` that works locally but not over CDN similarly to how `import.meta.filename` would work locally but not over CDN. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really wish we have clarification and standards about Windows path normalization and consider forward slash possibility as standard once we have a chance with new spec or at least mentioned briefly to be under considration.
An example URL would be file:///C:/path/
and normalized today as C:\path
with Node.js utils.
Modern Windows systems well support forward slashes (some history). Forward slashes make life much better in the Javascript ecosystem where as backslash is a escape character. upath and pathe are already being used by >18M users weekly.
(sorry for rambling in the comments, just wanted to trigger a discussion from somewhere)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: denoland/deno#957, nodejs/node#25324.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same thought too at first, but now I’m not so sure. I think the existing behavior is because Node’s path
module assembles the parts of the path, then does essentially parts.join(path.sep)
, and the path separator for Windows is a backslash. It could very well be that this is 13-year-old behavior for old versions of Windows that aren’t relevant anymore, I don’t know. I also wonder if it would be bad to be inconsistent within the same runtime: currently in Node, __filename
and fileURLToPath(import.meta.url)
return backslash-delimited paths in Windows, so having a forward-slash path in import.meta.filename
might be surprising. As far as the spec is concerned, maybe this is best left as an implementation detail for hosts to determine; other runtimes without path-based APIs that use backslashes might be freer to standardize on forward slashes everywhere. Though I’m open to defining the slashes as needing to be forward slashes if those who know this topic better than me can confirm that it’s safe and wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the references. I think it might be sensible for Node.js util which is inheriting legacy reasons for preserving backslashes (while I hope that would be something they might consider for the new import.meta.filename
API for the sake of portability...).
Since this is a proposal, would it makes sense to at least mention the possibility of a "recommendation" to prefer forward slashes and increasing web/url compatibility? Especially with new runtimes adopting import.meta.filename
props, they can do it in a non-breaking sense.
AFAIK bun is not windows supported yet, that would be a really good example of adoption and increasing compatibility with toolings. Today Nuxt, Vitest and dozens of packages in the ecosystem are doing this normalization in each place to just make sure windows is compatible... unofficially due to Node.js legacy behavior.
@lucacasonato I know you said in #50 that Deno would be uninterested in implementing this API, but I’d appreciate your input on this just in case Deno’s opinion changes someday; ideally the spec we agree on is something that would work for Deno should the team decide to support @Jarred-Sumner does Bun have any notes on this proposal? |
Co-authored-by: Antoine du Hamel <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love this.
i do think I like Bun's path
and dir
more, but y'all make a great point about how familiar we all are with filename
and dirname
already.
I can't tell you how many times I've created __filename
and __dirname
utils for my ESM projects lol.
🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks! 🎉
I'm looking forward to deleting boilerplate code once this is implemented 😃
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __dirname = dirname(fileURLToPath(import.meta.url))
I am still strongly opposed to including this in the common minimum API, for the reasons I have elaborated in the issue this PR references. Deno will not implement- it's not common minimum. |
The proposal specifies that these properties would be optional for runtimes to implement if they wish: as in, if a runtime wants to provide |
This is the common minimum API though. The maximum set of APIs supported across all compatible runtimes. If there are optional features not gated on capabilities of the runtime, but on implementer interest, it is by definition not a common minimum subset. It is then just a loose collection of recommendations and does not fulfil it's purpose. As such, this is the wrong place for this API because there is no consensus among implementers. |
FWIW, this is why I had suggested this as a separate md file ( like the ALS subset ) for now rather than adding to the actual common minimum index.bs file, and we can always find a better home for it. |
I believe we can close this now that the PR landed over in the import.meta registry repo |
Now that Node, Bun and Deno have all implemented this, should it become part of the common minimum? |
Resolves #50. cc @mcollina @jasnell @Jarred-Sumner