-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
esm: implement import.meta.command #51538
Conversation
Review requested:
|
#49440 spans four years and has 91 comments. Do you mind summarizing the outcome or lack thereof? In particular, it feels like it would be unfortunate to ship something that is just like |
@GeoffreyBooth the first few comments before the issue was closed pretty much summarize it I think, it's not a long read, it's the comments that follow that are.
Deno just defines it as "the entry point" which IMO is not clearly defined. By clearly stating this is equating with the POSIX command model we rule out many different cases where there might previously be entry point ambiguity. @devsnek would be great to hear your opinion on this one again if you have any thoughts to share. |
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.
This needs docs. In particular, I’m curious how you will describe which “entry point” gets import.meta.command
when there are multiple possibilities, for example what we normally think of as the entry point but also --require
or --import
modules that load earlier. Is it always process.argv1
? Always the very first loaded module? Each of them?
Also what about workers?
lib/internal/modules/run_main.js
Outdated
* This should really just be implemented as a parameter, but executeUserEntryPoint is | ||
* exposed publicly as `runMain` which has backwards-compatibility requirements, hence | ||
* this approach. |
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.
Would it not be backward-compatible to just add an extra parameter at the end?
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've updated the comment to note this is not actually a backwards compat concern so much as a concern that we mustn't expose setting the command main to userland as it is an entirely internally-defined concept.
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.
Surely there’s a less awkward workaround than calling a function that sets a module-scope property ahead of time? Since runMain
gets called multiple times, like for --import
and so on, this approach feels error-prone. Perhaps the additional parameter could be an undocumented options object, and Node core checks that this object contains a particular symbol on it? And this symbol would be something that’s defined internally and therefore unusable by user code.
What, this? Essentially that it’s a bad idea to use this pattern? In my mind that’s a very weak argument; if other runtimes offer this, we should do so as well for compatibility, and that’s far more important. Perhaps there are other patterns that have advantages over this one, but there’s nothing inherently wrong with doing everything in one file, and plenty of scripting use cases where that’s desirable. That thread was also just an issue, not a PR, so it doesn’t have the specifics that this PR has of exactly how the new property gets implemented and when it gets applied. Perhaps this specificity will help cut through some of the debate. In particular, could we simply rename |
Unfortunately Deno sets it to true within a Worker in this scenario: main.mjs
worker.mjs
Furthermore we are also defining it not to apply for any module registry other than the top-level loader. So all other realms, workers etc would not get this property. |
I guess what would be the harm if we did the same? Or more broadly, are there any cases where we wouldn’t want to just copy Deno’s behaviors? |
I think Deno and Bun have more loosely defined the concept of entry point here as any top-level execution context, whereas this definition is confined to the concept of the Node.js JS module file representing the running process as implemented in JavaScript. This is all edge case territory - counter examples would be pretty obscure. I feel like I've said enough though, I think it would be good to get a wider perspective before we drown out the discussion here as well. I'm open to alternatives. |
at this point i think my (NON BLOCKING!!!) opinion would be that coming to agreement in wintercg (or wherever else) about what this api should be is probably the most healthy thing that could happen for the ecosystem. if |
I agree with @devsnek that it would be unfortunate if this were to diverge from I think rather than creating something a new |
Preface: I've only had time to read a couple dozen messages, not all of them.
When I first read I don't know why, but I intuitively understood |
My only concern with this name is that it sounds like it should be the entire command, like all the arguments and flags etc. Hence maybe |
Isn't that |
Worth noting that |
The edge cases are basically workers, module registries in other realms but on the same thread (shadowrealm) and even other module registries in the same realm (vm.Module, eventually to be TC39 loaders). The argument is that in all of these other module registry contexts, that do not correspond to that one specifier in that one top-level module registry, this property should not be set. If supporting I think that concern combined with the superior ergonomics justifies keeping this feature on |
Two other options:
I'm hesitant to put something on |
The obvious difference between those two values is that one is stable on a given thread, the other one is not (there's simply no way to have two modules read two different values for the same property, try to think how we could implement that).
This is assuming there will never be a world where the same URL could load two different modules. The ES spec already allows that using import attributes, so that seems like a rather fragile design.
Since Node.js does not implement |
This implements a new
import.meta.command
as an alternative naming forimport.meta.main
. The justification for renaming is clarity in the definition of when this property applies for a given module, after the extensive discussion in #49440.The specification for this field is provided at the same time to the WinterCG repo for
import.meta
in wintercg/import-meta-registry#4.