| 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 |
| 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:
|
| 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 |