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.
Sounds good.
Mmmh... I would really like to migrate our existing JSM code to ES without breaking add-ons or Thunderbird, which rely upon a specific url for the jsm. This means that even after we have migrated a JSM code from url
foo
to an ES module,Cu.import(foo)
needs to carry on working.I see two ways to do it:
The latter will not work for the Backstage Pass (or will require some annotations, changes in tests and a few pieces of build system hackery), but I guess I can live with that.
@jorendorff To be sure, what's the problem with implementing the
export
syntax in JSMs?