Hi everyone.

ESMification <https://bugzilla.mozilla.org/show_bug.cgi?id=1308512> is a 
project to switch the Mozilla-specific JSMs in privileged code to the standard 
ECMAScript modules (ESM).

Recently, the preparatory phase has started to impact larger parts of the 
codebase. In the interest of keeping everyone informed, we will send out a few 
updates regarding the transition process. This is the first such update on 
what's going on and future planning
Ongoing Preparation Work
Preparation work is split into 4 parts.
Add New APIs

Just like `ChromeUtils.import` and friends for JSM, we're going to add new APIs 
for importing and handling ESMs.

Basic import API: `ChromeUtils.importESM` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1771678>
Defining lazy getter: `ChromeUtils.defineESMGetters` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1768870>
Registering window/process actors: `esmURI` property 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1771092> for each existing API
Static component registration: `esm` property 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1769002> in components.conf
Querying loaded modules: `Cu.isESMLoaded` and `Cu.loadedESMs` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1768819>
NOTE: the name of the APIs is subject to change

Most of the work is almost ready, and we can land them once the API naming 
convention gets fixed.

The filename extension for the system (privileged) ESM is `.sys.mjs`.  This is 
to distinguish between regular ES module files that use `.mjs`.
Add Compatibility Layer for existing APIs

To make the migration easier, and also to avoid breaking out-of-tree code, the 
existing APIs like `ChromeUtils.import` are automatically redirected to 
ESM-ified files, if the JSM is already ESM-ified.
Import APIs such as `ChromeUtils.import`  
<https://bugzilla.mozilla.org/show_bug.cgi?id=1766761>
Querying loaded modules: `Cu.isModuleLoaded` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1768922> and `Cu.loadedModules` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1769029>
This allows migration to be done per single file, or subtree, without affecting 
other files, or out-of-tree code.

Also, lexical variables in JSM are now exposed 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1768060> to `Cu.import` return 
value, and there’s no need to copy lexical variables to the global `this` 
property by `this.foo = foo;`.

Those layers are already available in 103.

Rewrite ESM-incompatible part in JSM

JSM has a per-module global `this` object, which has been used to declare 
global variables and lazy getters. The standard ECMAScript module does not have 
the global `this` object, and code that relies on it needs to be rewritten.

Rewrite `this.foo = ...` with `const foo = ...` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1610653>
Rewrite lazy getters to use a plain `lazy` object 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1608279>
Use plain object instead of global `this` for `Cu.cloneInto` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1765737>
Use `.jsm` extension consistently 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1609269>
Most of the work is almost done, or getting reviewed.

Please refer to the Lazy Getter Update email and the Lazy Getter Implementation 
document 
<https://docs.google.com/document/d/1LjKkl-hSnXy82r0QO6XWg-A7TbJ9EkCvaQOqP_YgwtQ/edit?usp=sharing>
 for more information.
Add ESLint rules

We’ll prepare ESLint rules both for JSMs and ESMs.

For JSMs, new rules will be mostly to avoid adding ESM-incompatible code, and 
some of them will be applied also to ESMs:
Reject global `this` <https://bugzilla.mozilla.org/show_bug.cgi?id=1607331>
Reject modification to `globalThis` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1772299>
Check `lazy` object properties 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1771173>
For ESMs, new rules will be to catch some edge cases:
Reject top-level await <https://bugzilla.mozilla.org/show_bug.cgi?id=1768031> 
(this is not supported yet, because of synchronous-ness)
Avoid misuse of `import` declarations 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1771751>
Standardize the lazy object name 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1771097>
Planning
In-tree JSM-to-ESM Migration Phase 1

The first phase of the migration covers the following:
Rename `*.jsm` to `*.sys.mjs`
Replace `EXPORTED_SYMBOLS` with `export` declaration
Replace `ChromeUtils.import` for the module with either:
static `import` declaration, if it’s in the system ESM’s top-level
`ChromeUtils.importESM` otherwise
Rewrite lazy getter for the module
Rewrite `moz.build` for the module
Rewrite `components.conf` for the module
Rewrite `ChromeUtils.registerWindowActor` for the module
Rewrite `ChromeUtils.registerProcessActor` for the module
Rewrite `Cu.isModuleLoaded` for the module
Rewrite `Cu.loadedModules` for the module

The migration will be semi-automatic, with scripts 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1612572> for simple cases, and 
manual work for edge cases. Each team will work at their own pace to apply the 
scripts and identify edge cases. 

It’s not necessary to migrate all JSMs to ESM. Difficult cases can be left as 
JSM.

We’ll send the detailed document once it’s ready.

In-tree Migration phase 2

Once all in-tree code becomes ESM, each team can rewrite those files to be more 
standard ESM-style, such as using `export default` etc.

Out-of-tree Migration

There are multiple out-of-tree consumers of JSM:
Firefox’s privileged extensions
Thunderbird’s extensions
non-sandboxed AutoConfig scripts

And we need to keep the compatibility with them.

During the in-tree migration phase 1, the above compatibility layer guarantees 
the compatibility as long as:
The set of exported symbols is same
The behavior of the exported symbols is same
The URL is same, except for the extension part (`.jsm` to `.sys.mjs`)

Once the in-tree migration phase 1 finishes, we’ll call for the out-of-tree 
migration, to use the new APIs.

The out-of-tree code migration period will take some cycles.

Cleanup on the API

Once the out-of-tree migration finishes, we’ll perform cleanup, including 
gradually removing the deprecated APIs or special behavior around that:
Remove 2nd parameter of `ChromeUtils.import` 
<https://bugzilla.mozilla.org/show_bug.cgi?id=1758481>
Stop exposing the global object via Cu.import return value, or maybe remove 
Cu.import

Non-deprecated JSM APIs such as `ChromeUtils.import` aren’t removed, for 
in-tree difficult-to-migrate cases, and also for out-of-tree compatibility.

-- 
You received this message because you are subscribed to the Google Groups 
"[email protected]" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/a/mozilla.org/d/msgid/dev-platform/D08A277E-332F-4F2B-9279-7786ECC1C6A0%40gmail.com.

Reply via email to