Skip to content
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

Closed

Conversation

GeoffreyBooth
Copy link

Copy link
Member

@ljharb ljharb left a 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.

import-meta-path-helpers.md Outdated Show resolved Hide resolved

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.
Copy link
Member

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.

Copy link

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

import-meta-path-helpers.md Outdated Show resolved Hide resolved

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`.

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.

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.
Copy link

@pi0 pi0 Aug 11, 2023

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)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

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.

Copy link

@pi0 pi0 Aug 12, 2023

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.

@GeoffreyBooth
Copy link
Author

@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 import.meta path helpers at some point.

@Jarred-Sumner does Bun have any notes on this proposal?

import-meta-path-helpers.md Outdated Show resolved Hide resolved
Co-authored-by: Antoine du Hamel <[email protected]>
Copy link
Contributor

@Ethan-Arrowood Ethan-Arrowood left a 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.

🚀

Copy link

@styfle styfle left a 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))

import-meta-path-helpers.md Outdated Show resolved Hide resolved
@lucacasonato
Copy link
Member

lucacasonato commented Sep 6, 2023

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.

@GeoffreyBooth
Copy link
Author

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 import.meta properties representing the absolute path of a file: module, and the absolute path of the parent folder of that module, then these are the names to use and their semantics. So Deno can choose not to implement them, however if this proposal is accepted and someday the Deno project changes their position, then they would implement the properties using these names and these behaviors. That’s different than simply rejecting the proposal and each runtime doing as they wish; accepting this proposal would mean agreeing on a common standard even if that standard is opt-in.

@lucacasonato
Copy link
Member

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.

@jasnell
Copy link
Contributor

jasnell commented Sep 7, 2023

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

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.

@jasnell
Copy link
Contributor

jasnell commented Nov 11, 2023

I believe we can close this now that the PR landed over in the import.meta registry repo

@jasnell jasnell closed this Nov 11, 2023
@GeoffreyBooth GeoffreyBooth deleted the import-meta-path-helpers branch November 11, 2023 17:17
@GeoffreyBooth
Copy link
Author

Now that Node, Bun and Deno have all implemented this, should it become part of the common minimum?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

import.meta.filename and import.meta.dirname