ecma262 icon indicating copy to clipboard operation
ecma262 copied to clipboard

Can the intent and correct use of import.meta be clarified further?

Open jasnell opened this issue 8 months ago • 8 comments

The import.meta mechanism was intentionally left wide open for use by the runtimes to introduce contextual information about the module that was imported. Unfortunately, however, the ecosystem is starting to see quite questionable uses that do not really fall into the "contextual information about the module" category.

Probably the most visible/prominent such examples are Vite's use of import.meta.env and import.meta.hot.

Prior to its official formation as TC55, WinterCG had taken up a discussion around use of import.meta and the possible cross-runtime interop issues that it presents when user code begins to use import.meta in whatever way it wants, ignoring the fact that it is a globally shared namespace. We're already seeing some clashes in that namespace as evidence in the import-meta-registry where we have duplicative definitions of import.meta.dirname, import.meta.dir, import.meta.filename, import.meta.file, etc that are used in Node.js, Deno, and Bun.

A key concern is that if the ecosystem begins to see import.meta as Just Another Open Global Namespace They Can Add Whatever They Want To, we're going to end up with fairly significant interop issues later and increased issues around feature sniffing.

Obviously there's not a lot we can do without risking breaking web compat but stronger, clearer language in the spec about what import.meta is meant for and whether runtimes (or committees like TC55) are allowed/encouraged to lock it down further would likely be helpful.

/cc @ljharb

jasnell avatar Feb 19 '25 16:02 jasnell

In particular, I think it would be reasonable to make a normative requirement that anything on import.meta be something specific to that module - and to note that it is not intended as a replacement of globals or environment variables.

ljharb avatar Feb 19 '25 17:02 ljharb

I suppose the ship has sailed to require import.meta to become non-extensible (or frozen)?

mhofman avatar Feb 25 '25 03:02 mhofman

@mhofman that wouldn't address the OP tho, which is to indicate what hosts can put on the object.

ljharb avatar Feb 25 '25 19:02 ljharb

import.meta.hot seems fine, honestly; it's per-module functionality. Speaking as a user I would have preferred Vite namespace their stuff (so import.meta.vite.hot or something), but I don't think the spec should be saying that some kinds of hosts get to use top-level properties on import.meta and others have to be namespaced.

I agree import.meta.env seems bad and should just be a global variable.

I would be happy if we added a sentence of guidance to the spec to the effect of "values and functions on import.meta should be per-module; if a value or function is the same for all modules within an agent, it should be provided by a global variable" or something, but of course that doesn't actually bind anyone.

bakkot avatar Feb 25 '25 19:02 bakkot

Here is an idea: a requirement that any non-intrinsic object reachable by property crawl from import.meta be unique to that module, or be frozen. It wouldn't prevent things like .env per se, but it would make clear import.meta is meant to hold functionality specific for each module.

mhofman avatar Feb 25 '25 20:02 mhofman

That seems useful to me, but is also orthogonal to the goal of the issue.

ljharb avatar Feb 25 '25 20:02 ljharb

Note that freezing was already discussed and rejected: https://github.com/tc39/proposal-import-meta/issues/3

Whatever the direction will end up being, it'd be great if it allowed non-unique functions. For example,

function import.meta.resolve(url) {
  return new URL(url, this.url);
}

doesn't need to be unique per-module, even if it's goal is to provide per-module resolution.

nicolo-ribaudo avatar Feb 25 '25 20:02 nicolo-ribaudo

doesn't need to be unique per-module, even if it's goal is to provide per-module resolution.

Fair, I hadn't considered the this binding.

mhofman avatar Feb 25 '25 21:02 mhofman