07:32
<nicolo-ribaudo>
The use case for exports() is that you might want to wrap your module in another, and you need to know if there is a default to re-export or not
07:33
<nicolo-ribaudo>
Or you want to wrap it and wrap all its exported functions in some logging utility
11:03
<littledan>
I don’t think this proposal has enough machinery to let you do those re-exports because the set of exported names has to be static.
11:04
<littledan>
That is what has always confused me about the presence of these methods in the proposal. And bundlers are operating at a very different “time” from the other operations on module sources.
11:06
<Jack Works>
for the virtualization motivation, it's important to emulate ES module semantics. although this proposal itself cannot achieve that, with a bunch of other proposals we may do that in the future. the ability to detect ambiguous star export is also needed to fully implement ES semantics
11:17
<littledan>
for the virtualization motivation, it's important to emulate ES module semantics. although this proposal itself cannot achieve that, with a bunch of other proposals we may do that in the future. the ability to detect ambiguous star export is also needed to fully implement ES semantics
Agreed. The question in my mind was, which parts will and won’t be useful to incrementally ship, when we aren’t yet including that bunch of other proposals yet. I think we all agree on not cutting off the ability to detect ambiguous star exports in the future, right?
11:20
<Jack Works>
if we reflect "import {x} from y; export { x }" as imports: [x from y]; export: [x from y], like the source code was "export { x } from y", we can detect this case without make the api surface complex
14:24
<nicolo-ribaudo>

The set has to be static at module creation time. i.e. you could do this:

async function wrapModuleHidingX(url) {
  const source = await import.source(url);
  const names = source.exportNames().filter(name => name !== "x");
  return new ModuleSource(`
    export { ${ names.join(",") } } from "${url}";
  `);
}
15:49
<nicolo-ribaudo>

From the modules call today:

// mod1
export let a;
export { a as b };

// mod2
export { a as x } from "mod1";

// mod3
export { b as x } from "mod3";

// mod4
export * from "mod2"
export * from "mod3"

If the use case is to detect not-actually-ambiguous ambigous re-exports, then the source of mod1 needs a way to say that a and b internally refer to the same local binding

15:52
<guybedford>
from the above discussion - it is not enough to have a reexports analysis providing { importName, exportName } it must provide the full list of { importName, exportName, localName } for both reexported and local bindings
17:27
<kriskowal>
I should note, though it is a minor and possibly moot thing, if we do go with the names imports, exports, and reexports, it would simplify migration for ses if these were accessors, since they have been direct own value properties of module source objects in our system for some years.
17:29
<guybedford>
I think there may still be a compat concern there, since we would likely want to treat import { x } from 'x'; export { x } as a reexport and not an exports value
17:30
<kriskowal>
If the spec converges on bindings, we won’t have any trouble migrating.
17:31
<kriskowal>
If we converge on imports(), exports(), reexports() methods, differentiating legacy will be possible but weird.
17:35
<guybedford>

We were considering supporting a single exports() with form { exportName, importName, localName, module }, where the existence of module implies reexports.

Our discussion today was that it might make sense to update exports() to return an object, but still leave out this binding info for now until we have a use case. But that by returning an object we could be forwards compatible with full bindings information if needed in future.

17:44
<kriskowal>
In this universe, does imports() capture all import specifiers regardless of whether they’re in import or export statements?
17:45
<guybedford>
yes, but without bindings information on imports
17:45
<kriskowal>
And thus imports() and exports() would obviate reexports()?
17:46
<guybedford>
exports() would effectively be the union of direct and indirect exports yes
17:46
<kriskowal>
A nice thing about this idea in abstract is that imports() and exports() would serve fully orthogonal motivating use cases.
17:47
<kriskowal>
That is, imports is for capturing transitive dependencies and exports is for foretelling link errors.
17:48
<kriskowal>
Bundlers need the former, and bundlers would be more polite with the latter.
17:49
<kriskowal>
And I don’t think anyone loves reexports. It would not be missed.
17:50
<guybedford>
okay, I will update exports() to be the more general object form for now, but just as { exportName: string }[]. Then will create another issue for tracking complete bindings analysis being added to the object for further discussion
17:54
<kriskowal>
Would not mind workshopping the property names.
17:55
<kriskowal>
e.g., { export, import = export, lexical = export, from? }
18:00
<guybedford>
would you be open to using the Name suffix in those?
18:01
<guybedford>
{ exportName, importName, lexicalName, from? }
18:01
<guybedford>
then that would align with defining { exportName } as the current structure for now
18:02
<guybedford>
with importName, lexicalName and from? as the required additions for full bindings analysis
18:03
<kriskowal>
I don’t love the Name suffix aesthetically. I wouldn’t object, though.
18:26
<guybedford>
would you be open to renaming lexical to local in exchange for dropping the Name suffix!?
18:41
<guybedford>
I've posted https://github.com/tc39/proposal-esm-phase-imports/pull/21
21:05
<kriskowal>
Yes :)
21:07
<kriskowal>
It would follow that the bindings argument for a virtual module source would be a similar shape to the exports(), but would include bindings that had no corresponding export name.
21:09
<kriskowal>
Any chance wildcard exports might be consolidated into exports?
21:10
<kriskowal>
I know there’s a challenge that '*' is a bindable name distinct from wildcard exports.
21:11
<kriskowal>
I believe that’s why Moddable proposed {exportAllFrom} as a distinct binding type from {export, as?, from}.