16:51
<guybedford>
This very interesting case came up in Node.js today -https://github.com/bojavou/disambiguate-namespace
16:52
<guybedford>
Apparently when export * as X from 'x' was specified, we inadvertantly specified value deduping!!?????
16:52
<guybedford>
that is export * from './a'; export * from './b' where both a and b contain the source text export * as X from 'x' IS NOT AMBIGUOUS!
16:52
<guybedford>
might be some V8 / Firefox divergence in the implementation
16:56
<guybedford>
are we sure this is the correctly specified behaviour and not algorithmically incorrect?
16:57
<guybedford>
would be interested to hear others' takes on this
17:03
<nicolo-ribaudo>
I have no idea about what is the expected behaviour, but it'd be interesting to dig up the notes to see if it was every discussed
17:20
<guybedford>
Firefox and V8 do different things - it's an error in V8 and works in Firefox
17:20
<guybedford>
strictly speaking, Firefox is following the spec correctly
17:33
<nicolo-ribaudo>
My intuition is that the spec behaviour is correct, since those two exports are pointing to the same binding internally
17:34
<nicolo-ribaudo>
For most people either behaviour would be ok though, since nobody thinks about the binding of the namespace object (but only about its value)
17:35
<nicolo-ribaudo>
It's the same as export { foo as X } from "X" in both a and b is not ambiguous, because they both point to the binding foo. * is just a special binding name, the same way as default is
17:35
<guybedford>
I suppose so!
18:15
<Jack Works>
so for this case, import {x} from '...'; export {x} must be reflected as "reexport" x from '...'
18:15
<Jack Works>
This very interesting case came up in Node.js today -https://github.com/bojavou/disambiguate-namespace
otherwise this might not be reflected
21:59
<kriskowal>
On the topic of bindings vs imports, exports, and reexports, I observed during TG3 that a virtual module source constructor needs bindings, but doesn’t necessarily need to be able to see the bindings of another module source. To make a mock, seeing the exports of another module is sufficient to create the appropriate bindings. So, I am no longer convinced there’s an issue with coherence.
22:03
<kriskowal>

Consider:

const source = new ModuleSouce({
  bindings: [
    {import: 'x', as: 'a', from: '1.js' },
    {import: 'x', as: 'b', from: '2.js'},
    {export: 'default'},
    {exportAllFrom: '3.js'},
  ],
  evaluate(ns) {
    ns.default = ns.a + ns.b;
  },
});
source.exports() // ['default']
source.imports() // ['1.js', '2.js']
source.reexports() // ['3.js']
22:05
<guybedford>
the argument that is currently swaying it back for me is actually this ambiguous question though
22:05
<guybedford>
that even if we can determine the names, determining ambiguous exports requires the reexports information
22:05
<guybedford>
so you can make a wrapper with just knowing export star and direct exports
22:06
<guybedford>
but you can't detect ambiguous exports without reexports info
22:06
<guybedford>
I know when we previously discussed that we determined that was okay not to be able to do
22:06
<guybedford>
but there's certainly an argument there still I suppose
22:07
<kriskowal>
We may need to go deeper into concrete cases to resolve the question.
22:07
<kriskowal>
I have so far struggled to come up with a compelling “auto-mock” with the primitives we have.
22:09
<kriskowal>
But with some more specific constraints and limitations, there’s probably a reasonable, practical module adapter for something like instrumenting all exported functions.
22:10
<kriskowal>
It probably remains useful to think about the question in relation to virtual module sources.
22:10
<guybedford>
I guess the use case question is also - how useful is it to trace reexports
22:10
<guybedford>
and determine their original definer
22:11
<kriskowal>
Right. We need a motivating use case. I can imagine one, but it’s pretty imaginary: providing primitives for LSP to navigate the the definition of an imported name.
22:12
<kriskowal>
That’s tenuous because your LSP is going to be looking at the full source text.
22:14
<kriskowal>
The real and present motivating use case for module source reflection is a bundler, and for a bundler, all you need is imports() (assuming it includes reexports()). You need exports() only to fail-during-bundling if there’s a name collision between multiple reexports.
22:15
<kriskowal>
I suppose the ambiguity does come to bear, though, even in the bundling case. You would have to know that two names from disparate reexports correspond to the same value to know whether there was a conflict.
22:17
kriskowal
drives another nail into his export-star-from plushie
22:57
<guybedford>
right so previously we determined perhaps exact conflict detection isn't a necessary use case
22:57
<guybedford>
but if it is we can readdress that too
22:59
<guybedford>
I've posted https://github.com/tc39/proposal-esm-phase-imports/issues/20