I’ve run into something like this. An object A has the role to augment 
another’s B capability, but should only do so if someone actually 
require/import B. Right now A forces B to load, because we haven’t built in our 
Mr require package (browser+node) the api that would create the promise of a 
module without causing it to load, but if someone require(B), then that promise 
would resole and A would be able to add to B.

Hope that clear enough!

Benoit 


> On Apr 21, 2017, at 11:38 AM, 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] <mailto:[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] 
> <mailto:[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] <mailto:[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] 
> <mailto:[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] <mailto:[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] 
> <mailto:[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] 
> <mailto:[email protected]>> wrote:
> I really like that idea
> 
> On Apr 21, 2017, at 08:22, Andrea Giammarchi <[email protected] 
> <mailto:[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] <mailto:[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/planning?
>> 
>> Thank you.
>> Best Regards
>> 
>> [1] https://github.com/WebReflection/import.js#importjs 
>> <https://github.com/WebReflection/import.js#importjs>
>> _______________________________________________
>> es-discuss mailing list
>> [email protected] <mailto:[email protected]>
>> https://mail.mozilla.org/listinfo/es-discuss 
>> <https://mail.mozilla.org/listinfo/es-discuss>
> 
> _______________________________________________
> es-discuss mailing list
> [email protected] <mailto:[email protected]>
> https://mail.mozilla.org/listinfo/es-discuss 
> <https://mail.mozilla.org/listinfo/es-discuss>
> 
> 
> 
> 
> 
> 
> 
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to