If the discussion is about a polyfill for import() <https://github.com/tc39/proposal-dynamic-import> (not the static import)
it's not too hard: https://gist.github.com/caub/458cfe944f8abcf7b1aec608d0a878cc ```js (async()=>{ const [Stuff, {foo, bar}] = await Promise.all(['./x', './y'].map(require)); // .. })() ``` 2017-04-22 16:31 GMT+02:00 Andrea Giammarchi <[email protected]>: > > Why not just allow `export await` in all export syntactic forms? > > that would work for me, and it would be like my initial, and second, > example: `export default await Promise.all(...).then(...)` > > however, just to better understand what you're up to, I wonder if the > module would be held, in a non blocking way, until all asynchronous exports > have been resolved (desired) as opposite of introducing complexity for > hybrid modules where you have to await everything to be sure it won't break > (shenanigans) > > TL;DR unless the following would be possible too, please consider making > modules available only once fully resolved through their exports > > ```js > import await * as module from './module.js'; > ``` > > Regards > > > > > On Sat, Apr 22, 2017 at 3:08 PM, Matthew Robb <[email protected]> > wrote: > >> I know you probably didn't want things to go this direction in the >> conversation but this made me think up a generic way to do this. Why not >> just allow `export await` in all export syntactic forms? This would not be >> the same as top level await but a signal that the export will be the result >> of an asynchronous operation that follows the await. >> >> Then you could potentially do `export default await (async ()=>{ >> >> })();` >> >> On Apr 21, 2017 3:10 PM, "Bradley Meck" <[email protected]> wrote: >> >> > how's that different from a Promise ? >> >> `later` is not const and could change over time. Could even be set via >> something like: >> >> ``` >> setInterval(() => later = Date.now(), 1e3); >> ``` >> >> On Fri, Apr 21, 2017 at 2:00 PM, Andrea Giammarchi < >> [email protected]> wrote: >> >>> > let later; >>> > export default {then(notify) { if (ready) notify(later); else >>> queue(notify); }} >>> >>> how's that different from a Promise ? >>> >>> Don't get me wrong, I have a module [1] that does that already (use a >>> symbol as key and that's it) but yet for an importer, if that has to be >>> handled like a Promise, then why not just a Promise ? >>> >>> This is the bit I don't get. >>> >>> Thanks >>> >>> [1] https://github.com/WebReflection/broadcast#broadcast-- >>> >>> >>> >>> On Fri, Apr 21, 2017 at 7:38 PM, Bradley Meck <[email protected]> >>> wrote: >>> >>>> > how asynchronous export helps here ? >>>> >>>> >>> I cannot think about a single use case for wanting that: it's not >>>> usable from within the module, it won't be usable outside unless checked >>>> via ... an interval ? >>>> >>>> As stated in previous email: >>>> >>>> >> The previous email was stating there are use cases for updating >>>> exports. >>>> >>>> If you are updating exports that in general means live bindings / >>>> asynchronous work. >>>> >>>> > already covered by `export default new Promise(async () => {})` , >>>> right ? >>>> >>>> Kind of, this sacrifices live binding since `default` can only ever >>>> have 1 value. Something could use a thenable to export multiple values over >>>> time however similar to a live binding: >>>> >>>> ``` >>>> let later; >>>> export default {then(notify) { if (ready) notify(later); else >>>> queue(notify); }} >>>> ``` >>>> >>>> > how is the module consumer supposed to know when these exports are >>>> ready? >>>> >>>> > if it's an event emitted, libraries trusting the event that already >>>> happened will never know, so we are back to polling, which is a very bad >>>> approach, IMO, and if the solution is a Promise then it's covered already. >>>> >>>> Please read my previous email: >>>> >>>> >> The answer is no pattern has been standardized so it depends on >>>> your proposed solution. A `then()`-able is already in spec and seems like a >>>> possible choice (though I wouldn't use a Promise); top level await could be >>>> another but blocks the module graph. TDZ poll/checking on imports could be >>>> another (though not-preferable) solution. I am sure we could bikeshed other >>>> approaches. >>>> >>>> > so if two importers happen at different times the second importer >>>> can compromise with undesired features the first one or vice-verssa? >>>> >>>> No, ESM modules are only evaluated once. Such checks are most likely >>>> done up front. However, enabling a debugger for example might cause a new >>>> set of exports to be loaded/exported. >>>> >>>> > So, like I've said, I don't see real-world scenarios for exported >>>> modules that changes without notice. >>>> It looks unpractical and undesired. >>>> >>>> As stated in previous email: >>>> >>>> > Exporting asynchronously doesn't provide any coordination point ... >>>> >>>> The rest of my email(s) have been talking about coordination. >>>> >>>> On Fri, Apr 21, 2017 at 1:28 PM, Andrea Giammarchi < >>>> [email protected]> wrote: >>>> >>>>> > It could be something that is being mocked/spied upon. >>>>> >>>>> how asynchronous export helps here ? >>>>> >>>>> >>>>> >>>>> > It could be part of a circular dependency and so the modules do get >>>>> a hold of eachother without finishing evaluation. >>>>> >>>>> already covered by `export default new Promise(async () => {})` , >>>>> right ? >>>>> >>>>> >>>>> >>>>> > It could be that it lazily/async populates its exports due to costs. >>>>> >>>>> how is the module consumer supposed to know when these exports are >>>>> ready? >>>>> >>>>> if it's an event emitted, libraries trusting the event that already >>>>> happened will never know, so we are back to polling, which is a very bad >>>>> approach, IMO, and if the solution is a Promise then it's covered already. >>>>> >>>>> >>>>> >>>>> > It could be that it is relying upon context to determine if >>>>> something should be exported (debug flag etc.) >>>>> >>>>> so if two importers happen at different times the second importer can >>>>> compromise with undesired features the first one or vice-verssa? >>>>> >>>>> Dynamic exports are possible since ever on CommonJS world (same as >>>>> imports) and I've truly rarely seen the need to lazy export or lazy >>>>> import. >>>>> Conditional import yes, and conditional exports too but never at distance. >>>>> >>>>> So, like I've said, I don't see real-world scenarios for exported >>>>> modules that changes without notice. >>>>> It looks unpractical and undesired. >>>>> >>>>> Can you point at me at a single module that needs to do that? >>>>> Maybe I'm missing something. >>>>> >>>>> Thanks >>>>> >>>>> >>>>> >>>>> >>>>> On Fri, Apr 21, 2017 at 7:18 PM, Bradley Meck <[email protected]> >>>>> wrote: >>>>> >>>>>> > Let me ask again: as a module consumer, how are you supposed to >>>>>> know when an export is available? >>>>>> >>>>>> The previous email was stating there are use cases for updating >>>>>> exports. >>>>>> >>>>>> The answer is no pattern has been standardized so it depends on your >>>>>> proposed solution. A `then()`-able is already in spec and seems like a >>>>>> possible choice (though I wouldn't use a Promise); top level await could >>>>>> be >>>>>> another but blocks the module graph. TDZ poll/checking on imports could >>>>>> be >>>>>> another (though not-preferable) solution. I am sure we could bikeshed >>>>>> other >>>>>> approaches. >>>>>> >>>>>> I don't see "None of these haven't been solved already through >>>>>> better pattern." as a response to all the use cases I described. >>>>>> >>>>>> On Fri, Apr 21, 2017 at 1:13 PM, Andrea Giammarchi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> None of these haven't been solved already through better pattern. >>>>>>> >>>>>>> Let me ask again: as a module consumer, how are you supposed to know >>>>>>> when an export is available? >>>>>>> >>>>>>> On Fri, Apr 21, 2017 at 7:08 PM, Bradley Meck < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Could be several reasons, it could be exporting a counter/log that >>>>>>>> changes over time. >>>>>>>> >>>>>>>> It could be something that is being mocked/spied upon. >>>>>>>> >>>>>>>> It could be part of a circular dependency and so the modules do get >>>>>>>> a hold of eachother without finishing evaluation. >>>>>>>> >>>>>>>> It could be that it lazily/async populates its exports due to costs. >>>>>>>> >>>>>>>> It could be that it is relying upon context to determine if >>>>>>>> something should be exported (debug flag etc.) >>>>>>>> >>>>>>>> Probably plenty more reasons. >>>>>>>> >>>>>>>> On Fri, Apr 21, 2017 at 11:58 AM, Andrea Giammarchi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> > a Promise cannot change value over time, unlike a live binding. >>>>>>>>> >>>>>>>>> when is a module that changes values and without any notification >>>>>>>>> desirable? >>>>>>>>> >>>>>>>>> I cannot think about a single use case for wanting that: it's not >>>>>>>>> usable from within the module, it won't be usable outside unless >>>>>>>>> checked >>>>>>>>> via ... an interval ? >>>>>>>>> >>>>>>>>> The main point here is that asynchronous import might also >>>>>>>>> inevitably mean asynchronous exports. >>>>>>>>> >>>>>>>>> Early access to unusable modules doesn't seem a real-world >>>>>>>>> solution to me. >>>>>>>>> >>>>>>>>> What am I missing? >>>>>>>>> >>>>>>>>> Best Regards >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Fri, Apr 21, 2017 at 5:48 PM, Bradley Meck < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> I have been thinking about this some, I do think there is >>>>>>>>>> something here, but am not sure it warrants any changes. Exporting >>>>>>>>>> asynchronously doesn't provide any coordination point so the general >>>>>>>>>> idea >>>>>>>>>> is to export a Promise, but a Promise cannot change value over time, >>>>>>>>>> unlike >>>>>>>>>> a live binding. So, a more appropriate way might be to export a >>>>>>>>>> "ready" >>>>>>>>>> binding that is a Promise. Without some kind of async coordination >>>>>>>>>> like a >>>>>>>>>> `.then()`-able you would also suffer from `undefined` being a >>>>>>>>>> possible >>>>>>>>>> initialized and uninitialized value. >>>>>>>>>> >>>>>>>>>> ``` >>>>>>>>>> let later; >>>>>>>>>> export {later}; >>>>>>>>>> export const ready = someAsyncWork().then(v => later = v); >>>>>>>>>> ``` >>>>>>>>>> >>>>>>>>>> This does still mean that `later` can be accessed before it is >>>>>>>>>> ready, in my opinion somewhat against the idea of a TDZ wanting to >>>>>>>>>> wait for >>>>>>>>>> access to be ready. >>>>>>>>>> >>>>>>>>>> I would be interested in something like: >>>>>>>>>> >>>>>>>>>> ``` >>>>>>>>>> async let later; >>>>>>>>>> export {later}; >>>>>>>>>> export const ready = someAsyncWork().then(v => later = v); >>>>>>>>>> ``` >>>>>>>>>> >>>>>>>>>> That preserves the TDZ until assignment. Or, something that wraps >>>>>>>>>> `later` in a non-promise `.then()`-able that `import` understands >>>>>>>>>> and can >>>>>>>>>> unwrap to a live binding. >>>>>>>>>> >>>>>>>>>> All of that said, I am not sure this specific of a use warrants >>>>>>>>>> language changes as I can think of problems with the ideas I have >>>>>>>>>> proposed >>>>>>>>>> as well. >>>>>>>>>> >>>>>>>>>> On Fri, Apr 21, 2017 at 11:24 AM, Benoit Marchant < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> I really like that idea >>>>>>>>>>> >>>>>>>>>>> On Apr 21, 2017, at 08:22, Andrea Giammarchi < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>> nobody has any thought on this ? >>>>>>>>>>> >>>>>>>>>>> Maybe the following pattern would be just about enough to solve >>>>>>>>>>> a generic asynchronous import/export ? >>>>>>>>>>> >>>>>>>>>>> ```js >>>>>>>>>>> export default new Promise(async $export => { >>>>>>>>>>> >>>>>>>>>>> const utils = await import('./utils.js').default; >>>>>>>>>>> >>>>>>>>>>> $export({module: 'asynchronous', utils}); >>>>>>>>>>> >>>>>>>>>>> }); >>>>>>>>>>> ``` >>>>>>>>>>> >>>>>>>>>>> Best Regards >>>>>>>>>>> >>>>>>>>>>> On Thu, Apr 20, 2017 at 11:51 AM, Andrea Giammarchi < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Even if unpolyfillable through simple `function import() {}` >>>>>>>>>>>> declaration, >>>>>>>>>>>> I've managed to create a polyfill/payground for the ESnext's >>>>>>>>>>>> dynamic import() [1] >>>>>>>>>>>> >>>>>>>>>>>> This also made me wonder if there's any plan to provide a way >>>>>>>>>>>> to asynchronously >>>>>>>>>>>> export modules that depends on those that use asynchronous >>>>>>>>>>>> import. >>>>>>>>>>>> >>>>>>>>>>>> Since AFAIK modules have no top-level await, the only pattern I >>>>>>>>>>>> can see right now >>>>>>>>>>>> to import something asynchronous is the following one: >>>>>>>>>>>> >>>>>>>>>>>> ```js >>>>>>>>>>>> // module ./js/c.js >>>>>>>>>>>> export default Promise.all([ >>>>>>>>>>>> import('./js/a.js'), >>>>>>>>>>>> import('./js/a.js') >>>>>>>>>>>> ]).then([a, b] => { >>>>>>>>>>>> const module = {a, b, c() {}}; >>>>>>>>>>>> return module; >>>>>>>>>>>> }); >>>>>>>>>>>> >>>>>>>>>>>> // module that uses ./js/c.js >>>>>>>>>>>> import('./js/c.js').then(m => m.default).then(c => { >>>>>>>>>>>> c.a(); c.b(); c.c(); >>>>>>>>>>>> }); >>>>>>>>>>>> ``` >>>>>>>>>>>> >>>>>>>>>>>> However, above boilerplate doesn't seem ideal compared with >>>>>>>>>>>> something like the following: >>>>>>>>>>>> >>>>>>>>>>>> ```js >>>>>>>>>>>> // module ./js/c.js >>>>>>>>>>>> export default await Promise.all([ >>>>>>>>>>>> import('./js/a.js'), >>>>>>>>>>>> import('./js/a.js') >>>>>>>>>>>> ]).then([a, b] => { >>>>>>>>>>>> const module = {a, b, c() {}}; >>>>>>>>>>>> return module; >>>>>>>>>>>> }); >>>>>>>>>>>> >>>>>>>>>>>> // module that uses ./js/c.js >>>>>>>>>>>> import * as c from './js/c.js'; >>>>>>>>>>>> ``` >>>>>>>>>>>> >>>>>>>>>>>> But again, AFAIK that's not possible. >>>>>>>>>>>> >>>>>>>>>>>> The clear advantage is that the module consumer wouldn't need >>>>>>>>>>>> to know, or care, >>>>>>>>>>>> if the loaded module depends on some dynamic, asynchronous, >>>>>>>>>>>> import, >>>>>>>>>>>> meaning modules can be updated and eventually moved to async >>>>>>>>>>>> transparently >>>>>>>>>>>> for any module consumer. >>>>>>>>>>>> >>>>>>>>>>>> As summary, is any solution worth exploring/improving/fixing/pla >>>>>>>>>>>> nning? >>>>>>>>>>>> >>>>>>>>>>>> Thank you. >>>>>>>>>>>> Best Regards >>>>>>>>>>>> >>>>>>>>>>>> [1] https://github.com/WebReflection/import.js#importjs >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> [email protected] >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> [email protected] >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> > > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

