-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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.main #49440
Comments
I'm a bit confused what it does - does it mean "it was the |
it's true if the file was the entrypoint. for node i'd rather it be called something else cuz the term main already has package-scoped meaning. |
Right, but anything that's Also yes, |
I really like the if (require.main === module) {
console.log('This is a CLI tool! Usage: ...');
} We currently have no version of the above check in ECMAScript modules, so this is a problem that comes up, and there is currently no easy way to do this without it feeling like a hack. As an already-paved use case, users are familiar with the The above check then becomes: if (import.meta.main) {
console.log('This is a CLI tool! Usage: ...');
} and the really nice thing about this pattern is that it works in browsers and other environments completely fine without any need for compatibility API layers or compilation. For these reasons I'm 100% supportive of |
Doesn’t that use case predate the current community preference, which is to have separate packages for a library and a CLI? |
@ljharb this use case is explicitly documented in https://github.com/nodejs/node/blob/master/doc/api/modules.md#accessing-the-main-module. |
Sure but so is every aspect of the require algorithm :-) the better question is, is it still a common or desired use case to determine if something is the entry point, and how does that change now that dynamic import allows multiple entry points? |
@ljharb yes it is a desired feature. The |
The feature seems fine then (it’d only be true in the top-level process entry point); the name, definitely not (but we can bikeshed that). |
Does this absolutely need to be in our first iteration or can we get feedback / focus on other things? |
Thanks for bringing this up @MylesBorins. I (think) we can say this is post-MVP but it's good to have on our radar. |
can definitely be post MVP. Just wanted to document what's going on in ecosystem |
Well, I'm not part of the organization, but as a cli maintainer, this proposal seems so interesting. Can I start to try implementing this in https://github.com/nodejs/node and possibly a PR now? |
I'm not a huge fan of the concept of main. imo you should have separate files for bin and lib, which is something other languages do just fine, and installers like npm and yarn already let you specify separate bins. |
@shian15810 thanks for showing an interest in the modules work! Contributions are very much welcome to Node.js core and the module work here. We do have some consensus issues for this feature due to our not wanting to provide unnecessary features without seeing a strong need for them in the initial modules implementation. A PR to Node.js core would certainly drive discussion, and may even sway consensus. Also hearing more about your use case as a CLI maintainer and how this is useful could help us better understand the importance of the feature to you (including for example the points raised by Gus above). Even if the PR sits without approval, we may be able to come back to it in a few months even as well. |
The use case of mine is that both As far as I can tell, with a package.json having
However, with a package.json having What's left is just In addition, according to this, In my imagination, if So yeah, I agree with @devsnek in this case, that is pointing Also, I agree with @guybedford regarding strong backwards compatibility, even though TC39 states that As a last note, I've read somewhere in this repo stating that in the context of esmodule, there is no concept of main such as in commonjs, correct me if I'm wrong. But I certainly think that there must be some other use cases of determining the main script, just like |
Going to abandon this for now, please feel free to reopen |
I still believe this is an important feature, to be put in the same basket as CJS features not available in ESM like It's not a common feature, but it is definitely a heavily ingrained one where it is used, and has a small collection of users that absolutely do expect this functionality (mainly CLI developers). |
i am still against the concept of a main module in general. |
@guybedford Which labels are relevant here? Can you add them to make it easier to related to the context please — ie |
@devsnek Can you elaborate more? Main here is the main entrypoint, so it is like
|
@guybedford Awesome, that really helps 💯 |
@SMotaal i dislike the idea of differentiating entrypoints. you can just use a separate file for your bin. |
being an entrypoint doesn't inherently mean it's a cli (for example, cf workers). additionally, some hosts like browsers don't map well to the concept of entrypoints. depending on how you think about it, a webpage may either have several or no entrypoints. Even if you choose to think about a browser having several instead of none, none of the several would be a cli. |
@devsnek certainly it is one style, I am not saying your style is wrong, but others also have justifications that cannot be open to judgement because this all comes down to matters of opinion. As it happens, any given module in a package can be called as a result of at least two paths, a main entrypoint in the package, or an entrypoint for which the package is a direct or indirect dependency… some packages may actually consider this a functional parameter depending on their purpose.
Yes, I think this is the bottom line… And, so no disagreement or disapproval is intended, just wanting us to consider the more diverse landscapes that we may not ourselves be interested in (yet). |
To clarify some of the above, the only module that gets This is the Node.js application entry point main, not package entry points, or realm / worker entry points. An equivalent way to achieve this check would be to do Perhaps the above explicit check would be enough though. |
@lwr - Is your comment above related to the |
@lwr - The es-main tests cover this case (running |
@tschaub ok, I saw it is fixed in tschaub/es-main#28 |
For me it would be useful if one had access to a URL of the executed script, in CJS provided by |
Same here, the With cjs we can just use It's worth noting that I don't see any reason why this should be on |
The consensus is |
What's wrong with that? |
This makes it stiffer for use with Node. |
Using |
Since Node 20.11.0: if ( import.meta.filename === process?.argv[1] ) {
// Node main script
} |
This only works for a limited set of cases. For example, if you have an // example.js
console.log('main?', import.meta.filename === process?.argv[1]); This prints However, it prints If you were to create a symbolic link with If you try to use this same logic in a "bin" script, executing it with Ideally, |
It would be interesting to hear which of the original objectors to |
But, if the use case is "CLI entry point" only, what if we went back to basics?
// import this and that...
export default function main (...argv) {
// ...CLI entrypoint code..
}
// ...the rest of your app... Running this with It even uses nice modern spread syntax to prevent people from overdoing things and bolting more incompatible crap onto the entrypoint. Essential! Furthermore, being able to import an app's main CLI module could (re-)enable composability of command-line tools (that have a compliant (Signed: a guy who still has to use a CommonJS kludge to launch his Node CLI apps that are otherwise ESM all the way down.) Footnotes
|
If you're in a CJS module and the entrypoint was ESM, neither |
Another limitation of this is it would return false positive if the same module is loaded twice (e.g. entry point is
What would be the value of |
🦗 🦗 🦗 So what's wrong with using the |
@egasimus you can probably find tons of modules that have been written with a default export which they don't expect to be run when module is the entrypoint. #32223 (comment) suggested using a named |
The value would be the same as |
The glaring difference is that |
I see, I misunderstood the intended meaning of |
Welcome in 2024 |
We *badly* need an import.meta.main. nodejs/node#49440
Deno just added this.
Should we?
denoland/deno#1835
The text was updated successfully, but these errors were encountered: