-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
import.meta.main #49440
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
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. |
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
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-stale
|
As @Beedeebee said almost 3 years ago, can we have an official position if this is going forward or not? I see that the problem is that no one wants to commit to decide and being responsible if the outcome goes sideways. That will always be the problem with decisions by committee. However, as both Deno an Bun have Otherwise, we could just close this issue and discuss this on WinterTC (TC55) wintercg/proposal-minimum-common-api#46 probably for more 3 years. |
Would be great to have a proper solution, because it should be easy to use, but it's not as simple to even get it right currently. For example, es-main works ok, but is-main does not. import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
const extRegExp = /\.[^./\\]*$/
const stripExt = (path: string) => path.replace(extRegExp, '')
export const isMain = (meta: ImportMeta, cmd = process.argv[1]): boolean =>
// Unlike path.resolve, require.resolve returns a real path,
// so it is compatible with package bins in node_modules/.bin,
// e.g. when running via npx/pnpx.
!!meta && !!cmd && stripExt(fileURLToPath(meta.url)) === stripExt(createRequire(meta.url).resolve(cmd)) And yes, having |
Should be reopened, but not sure one can transfer ownership of this issue though? As @MylesBorins seems to wants all of his GitHub issues closed now I guess that should also be respected? |
If you want to work on making this happen I'd say open another issue and reference this one. GitHubs design makes any open issues I've created a never ending Todo list / noise. Think of it like forking 😄 |
Understandable. |
This module provides an equivalent to `require.main === module` for ECMAScript modules. See nodejs/node#49440 This module is imported in testPrep.mts
This module provides an equivalent to `require.main === module` for ECMAScript modules. See nodejs/node#49440 This module is imported in testPrep.mts
Ugh, considering moving back from bun for my scripts and thought most of the friction would be gone after the release of |
Deno just added this.
Should we?
denoland/deno#1835
The text was updated successfully, but these errors were encountered: