cleidigh / ThunderKdB

Thunderbird Addon Code Knowledge Base
11 stars 7 forks source link

Load a JS code module in all TB versions #11

Open eyalroz opened 5 years ago

eyalroz commented 5 years ago

(This question is about Javascript code modules, i.e. not the newer, JS-language modules)

In the old days, and for many years, you loaded your JSM modules using Components.utils.import(); but in recent TB versions, this doesn't work. On the other hand - ChromeUtils.import(), which works in TB 68, but doesn't even exist in older versions.

Now, you might think: Why can't I just use some version-independent library and have it import for me? Well, problem is, you would need to load that library first, which means loading a... JS code module :-( . This is (AFAICT) boilerplate code which you'll have to have at least once in every Javascript file.

So, how do you TB-version-portably load a module?

eyalroz commented 5 years ago

On the module side itself, there's nothing special you need to do. It's just the regular:

var EXPORTED_SYMBOLS = ["Foo", "Bar"];

what you can put in the script that's loading the module is the following:

var moduleURI = "chrome://FooExtension/content/FooModules.jsm";
if (typeof(ChromeUtils) != "undefined") {
  if (ChromeUtils.import) {
    var { Foo, Bar } = ChromeUtils.import(moduleURI);
  }
  else { Components.utils.import(moduleURI); }
}
else { Components.utils.import(moduleURI); }

This will work with TB versions at least as far back as 31, and probably earlier still.

You can see this in action in removedupes and BiDi Mail UI, (specifically, here and here. Note that the module files do not have a .jsm suffix at the moment.