This document shows a possible migration path from Cu.import()
to ES6 modules for the code of Firefox.
Add-ons and Thunderbird should not be affected by the migration.
- Make sure that calling ES6
import foo
in chrome code always returns the same object regardless of the global from which it is called, as is the case currently withCu.import()
. - Make sure that evaluating
import foo
in chrome code blocks the embedding as is the case currently withCu.import()
. - Inform developers that they should now use ES6 modules instead of jsm for their new code.
- Reject patches that introduce new jsm modules. Optionally, patch mozReview to do this automatically.
@jonco, how hard are 1. and 2.?
- Patch
mozJSComponentLoader
to acceptexport { a, b, c }
instead ofEXPORTED_SYMBOLS
when available. For compatibility with add-ons and Thunderbird,EXPORTED_SYMBOLS
will remain usable as long asCu.import()
exists. - Start migrating the code from
EXPORTED_SYMBOLS
toexport
. An automatic rewrite should cover most cases.
@jonco, how ard is 1.?
- Patch
mozJSComponentLoader
so thatCu.import(foo)
andimport foo
from chrome code access the same singleton. Essentially,Cu.import()
becomes a variant ofimport foo
that returns a backstage pass instead of only the symbols actually exported. Keeping this compatibility will be necessary to ensure that we can migrate piecewise without breaking the unicity of module instances, as well as for compatibility with add-ons, Thunderbird. - Inform developers that they should now use
import foo
in their new code, rather thanCu.import()
. - Reject patches that introduce new instances of
Cu.import()
. Optionally, patch mozReview to do this automatically. - Start migrating the code from
Cu.import()
toimport foo
. An automatic rewrite should cover most cases.
@jonco How hard is 1?
At this stage, we will still have the following cases to contend with:
- uses of
XPCOM.defineLazyModuleGetter
; - conditional imports;
- scoped imports and imports from within a function.
As far as I can tell, none of these cases has a simple counterpart in ES6 modules. I believe, however, that once we have reached this stage, we will have improved considerably the state of our codebase and gained experience that we may then use to handle the missing cases.
Eventually, we may also want to get rid of backstage passes.
Limiting feedback to stage 1:
import foo
in Chrome code causes the whole module to be blocked until foo loads. This is more block-y thanCu.import()
.Also note that ES
import
is not a function and you can't pass variables or arbitrary expressions to it, likeMost imports are pretty basic, and don't care about any of these details. For the special cases that do, the easiest way would be to keep
Cu.import
and have it support loading ES6 modules as well as jsms.