wintercg / proposal-common-minimum-api

https://common-min-api.proposal.wintercg.org/
Other
216 stars 15 forks source link

Add `import.meta` #46

Open andreubotella opened 1 year ago

andreubotella commented 1 year ago

In today's WinterCG meeting we agreed to add import.meta to the common minimum API, including the web's url property and resolve method, but also Deno's main property.

ljharb commented 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.

andreubotella commented 1 year ago

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.

devsnek commented 1 year ago

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.

lucacasonato commented 1 year ago

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:

littledan commented 1 year ago

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.

ljharb commented 1 year ago

@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?

devsnek commented 1 year ago

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.

lucacasonato commented 1 year ago

@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).

andreubotella commented 11 months ago

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.

nicolo-ribaudo commented 11 months ago

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.

guybedford commented 11 months ago

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.

trusktr commented 7 months ago

Related conversation in TC39 forums: import.meta.isEntry to detect top-level root module(s)

jasnell commented 7 months ago

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.