Skip to content

Add import.meta #46

Open
Open

Description

@andreubotella

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.

Activity

  1. ljharb commented on Jul 6, 2023

    @ljharb
    Member

    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.

  2. andreubotella commented on Jul 7, 2023

    @andreubotella
    MemberAuthor

    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.

  3. devsnek commented on Jul 7, 2023

    @devsnek

    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.

  4. lucacasonato commented on Jul 7, 2023

    @lucacasonato
    Member

    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 both
    • deno run, then new Worker: it is false in all modules in a worker
    • node index.mjs: it is true in index.mjs
    • node index.cjs: it is false in all modules
    • node index.cjs dynamically importing index.mjs: it is false in all modules
    • node then new Worker (with worker threads): it is false in all modules in the worker
    • node --test main_test.js side_test.js: it is false in all modules
    • workerd run index.js: it is true in index.js
    • In browsers, it is always false
  5. littledan commented on Jul 7, 2023

    @littledan

    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.

  6. ljharb commented on Jul 7, 2023

    @ljharb
    Member

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

  7. devsnek commented on Jul 7, 2023

    @devsnek

    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.

  8. lucacasonato commented on Jul 8, 2023

    @lucacasonato
    Member

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

  9. andreubotella commented on Jul 25, 2023

    @andreubotella
    MemberAuthor

    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.

  10. added a commit that references this issue on Jul 25, 2023
    d7f7ffd
  11. nicolo-ribaudo commented on Jul 25, 2023

    @nicolo-ribaudo

    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.

  12. guybedford commented on Aug 2, 2023

    @guybedford

    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.

  13. trusktr commented on Dec 4, 2023

    @trusktr

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

  14. jasnell commented on Dec 7, 2023

    @jasnell
    Contributor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions