Open andreubotella opened 1 year ago
I missed the meeting, but what exactly is import.meta.main
? node had a lot of discussion about why it could be harmful to add something like that; I'd love to understand better.
In Deno, import.meta.main
is a boolean property that is true for the module that was loaded as the entrypoint to the process (or to the isolate/agent, see below). In Deno you don't have scripts, only modules, and therefore some module needs to be the one invoked by the CLI call. That is what import.meta.main
marks, and it would work much like require.main === module
in CommonJS.
(Btw, in the meeting @lucacasonato mentioned that in Deno, import.meta.main
was always false in workers, such that this property being true would mean this is the entrypoint module of the process, rather than of the isolate/agent. But this turns out not to be true: import.meta.main
is true for the worker's entrypoint module. I can see use cases for it working both ways (e.g. if you're the worker entrypoint, you might handle communication with the main thread), but this probably merits some extra discussion.)
Since we want to include browsers as web-interoperable runtimes, and there are WinterCG-adjacent runtimes like NativeScript that aren't server-side, the idea was to define import.meta.main
as an optional property. After all, browsers can have multiple entrypoints to the module graph, but none of them is ever an entrypoint to the window. So I guess this would leave room for Node.js to not support it.
But as far as I understand, the main person who opposed adding this to Node.js was @devsnek, and their concerns were mostly about how, since package.json
supports specifying both a library entrypoint (main
) and a CLI entrypoint (bin
), and any CLI initialization code should go on a separate CLI entrypoint. But this seems very specific to how package.json
works in Node.js, and it doesn't necessarily apply to other runtimes.
their concerns were mostly about how, since package.json supports specifying both a library entrypoint (main) and a CLI entrypoint (bin), and any CLI initialization code should go on a separate CLI entrypoint.
Just to clarify, the reason I dislike import.meta.main
is because a module, during its lifetime, can be imported in multiple ways. When you split the binary into a separate file the usage is unambiguous. One of my suggested approaches was indeed to use package.json
but there are alternatives. In the context of wintercg I think my suggestion would be doing location.href === import.meta.url
. This removes the specific module instance from the calculation and therefore resolves the ambiguity.
In the context of wintercg I think my suggestion would be doing
location.href
===import.meta.url
I fail to see how this is any different from import.meta.main
. In what cases would this return a different result?
Also location.href
in no runtime (except FF in very weird cases) can point to a file:///
URL. Node does not have location
, and Deno never sets location without manual user intervention (--location
).
I think we should standardize the import.meta.main
property to true
for modules that are unambiguously the entrypoint of an agent cluster. This would mean:
deno run main.js
: it is true
in main.js
deno run main.js
dynamically importing side.js
: it is true
in main.js
, false
in side.js
deno test main_test.js side_test.js
: it is false in bothdeno run
, then new Worker
: it is false in all modules in a workernode index.mjs
: it is true
in index.mjs
node index.cjs
: it is false
in all modulesnode index.cjs
dynamically importing index.mjs
: it is false
in all modulesnode
then new Worker
(with worker threads): it is false in all modules in the workernode --test main_test.js side_test.js
: it is false
in all modulesworkerd run index.js
: it is true
in index.jsfalse
I'm a little worried about the prospect of defining things as "normative optional". If we want to define multiple conformance classes--e.g., one for servers and one "generic" that might omit some server features--let's do that, but it should be clear which sort of implementation should try to conform to which set of things. We shouldn't define something as normative optional just because Node and Deno disagree on substance whether it's a good idea--the whole point of WinterCG is to make these sorts of environments more compatible with each other.
@lucacasonato if "is this the main" doesn't make sense for all wintercg runtimes - which it doesn't sound like it does for node - then it seems inappropriate for wintercg?
To be very very clear I am not putting any weight into Node's official position here. I was just clarifying my opinion since I was pinged.
@ljharb I don't see where you got the conclusion: "which it doesn't sound like it does for node". For example, my proposal above outlines how it can make sense (exactly the same way as it does in Deno).
I'm trying to spec this, and it's not clear how to define an agent cluster's entrypoint module in a way that excludes <script type="module">
in browsers.
You may add an implementation-defined "is an entry point? given a module script" algorithm with the normative requirement that, if "is an entry point? given X" returns true at any point, then `is an entry point? given Y" can only return true if X is Y. It's a bit hand-wavy, but hopefully clear enough and implementations will not diverge.
main
has a very specific meaning in posix in terms of an application run to completion semantic (and for JS, until the task queue is drained), alluding to that kind of definition might be possible and it clearly distinguishes browser apps which have no concept of run to completion then as well.
Related conversation in TC39 forums: import.meta.isEntry
to detect top-level root module(s)
We now have the import.meta
registry (https://github.com/wintercg/import-meta-registry). I would suggest that import.meta.url
and import.meta.resolve()
are the only two we should specifically address in the common minimum spec.
In today's WinterCG meeting we agreed to add
import.meta
to the common minimum API, including the web'surl
property andresolve
method, but also Deno'smain
property.