On 26/09/16 19:50,
zbran...@mozilla.com wrote:
> So, it seems to me that we're talking about two aspects of module loading:
>
>
> 1) Singleton vs. per-instance
>
> Cu.import allows us to share a single object between all the code that references it.
>
> ES6 modules are not meant to do that.
If I understand ES6 modules correctly, two imports from the same webpage
will return the same module instance, right?
How hard would it be to consider all chrome code (of a JSRuntime) as a
single webpage? That's pretty much a requirement for any module loader
we would use for our chrome code.
> 2) Conditional vs. static
>
> Cu.import allows us to decide *when* we're loading the code for side-effects, or even *if* we're going to load it at all.
>
> if (needed) {
> Cu.import(...);
> }
>
> or
>
> XPCOMUtils.defineLazyModuleGetter(this, 'Services',
> 'resource://gre/modules/Services.jsm');
>
> -----------------
>
> The latter one may be resolved by some future ECMA proposals like:
> -
https://github.com/domenic/proposal-import-function
> -
https://github.com/benjamn/reify/blob/master/PROPOSAL.md
>
> The former is a more tricky. I'm not sure how can we, within statement import world annotate the difference.
> In the import-function world we could maybe do:
>
> import('resource://gre/modules/Services.jsm', {singleton: true}).then();
>
> but for static I don't see a semantically compatible way to annotate singleton reference.
I *think* that we can get rid all instances of the former, but I also
think that it's a multi-year project to do it all across our code.
@zb, do you think that it would be possible to have a migration path
from jsm towards ES6 modules that would let us do it one module at a
time? Let's assume for the moment that we can rewrite `Cu.import` to
somehow expose ES6 modules as jsm modules.
Also, how would you envision add-ons (which could add some kind of
modules dynamically) in a world of ES6 modules?
3) The issue of loading the source code
All module systems need to load their source before proceeding. If I
understand correctly, ES6 modules rely upon the same network stack as
the rest of Gecko to load the source code, while jsm rely only upon the
much more limited nsIJar* and nsILocalFile.
Barring any mistake, some of our network stack is written in JS. @zb, do
you see any way to untangle this?
4) The issue of pausing C++
There is still the issue of C++ code calling JS code and expecting it to
return only once it has entirely loaded + . Currently, this is made
possible by `Cu.import` performing a blocking read on the source file.
It is my understanding that ES6 modules, being designed for the web,
don't expect any kind of sync I/O, and "just" block `onload`.
Transitioning to ES6 modules would undoubtedly require some hackery here
to pause the calling C++ code.
5) The issue of the backstage wrapper
Currently, a number of tests rely upon `Cu.import` to expose the
backstage pass wrapper, i.e.
let {privateSymbol} = Cu.import(...);
// `privateSymbol` was not exported, but hey, it's still here.
Well, I *hope* it's just tests.
We would need a way to keep these tests working with ES6 modules.
Perhaps by requiring these tests to continue using a `Cu.import`
modified to work with ES6 modules.
That's all from the top of my head. At this stage, I suspect that the
best gain/effort ratio is migrating to RequireJS modules, but I'd be
happy to be proved wrong.
Cheers,
David