Using ES6 modules in background scripts

I looked how one may use a background script es a new ES6 module. However, it seems to be very hard to easily do this.

Usually you embed it like this.

“background”: {
 “script”: [ “background.js” ]
}

However, with a ES6 module, this does not seem to work, because usually (e.g. when you embed it in a HTML you have to ad the attribute type="module". In a manifest.json this does not seem possible…


So the problem has been discussed in this article and there a simple workaround has been suggested:
Just include a HTML file instead of (only) a JS file in the manifest.json:

“background”: {
 “page”: “background.html”
}

However, this is of course not very nice and still a workaround.

  • If nobody else comes up with some idea, I guess it is not implemented in Firefox. I’d open a Bugzilla issue then.
  • Also, as for current actions, it should be documented on MDN, that this is not really possible. (and maybe document the workaround)
1 Like

There is at the very least an issue open to allow loading es modules as content scripts, since that is not possible with current manifest declarations. And would for sure have higher priority than adding the API for the background page. At the same time I assume adding it for the background page will be much easier once it’s possible for content scripts.

Currently mdn does not document at all how es modules behave, though the knowledgeable programmer would be aware that es modules require a special loading mode and thus hopefully realize that they need to load their scripts with type=“module” (which by no means is a work around).

Edit: just stumbled across the bug requesting the very thing for the bg page: https://bugzilla.mozilla.org/show_bug.cgi?id=1394303

3 Likes

Hu?`Actually background pages do work. At least syntactically Firefox accepts them (JS itself still needs some testing) and the (already linked) MDN doc does not mention any such limitation.

You are right, it would be mainly a matter of adding a key that triggers a different bg page template (though the properties would have to be mutually exclusive, which is fun) and it involves some C++ nonetheless.

Yet, the fact that you can already use modules with the bg page should, in my eyes, make work to add a shortcut less important than supporting them for content scripts.

Okay, so good to hear the workaround works. And sure, it is then less a priority, but would still be good. Because that background page is very obviously a workaround and thus no proper solution for this use case.

Hi @rugkx, could you please share your experience with ES6 modules regarding webextensions development?
I’ve noticed even Firefox ESR 60 now supports modules so there should be no reason not to use this feature, right?

I want to start big refactoring of my code so I want to be sure I won’t regret it :slight_smile:.

1 Like

So, yes, I have been using ES6 modules for some time in my add-ons now.
Except of some workarounds as mentioned in this thread here, they work nicely.

Basically you can see it being used in https://github.com/rugk/offline-qr-code/ e.g.
I have even split many modules out of this, so I can re-use them between add-ons. See the whole TinyWebEx org. I do currently use git submodules to integrate them into the main repo(s) of the add-ons.

The only issue is that they can only statically include other files, i.e. I e.g. often include a settings file from ../data/settings.js in one TinyWebEx module, which you have to create manually in the right place.
But well… this is a trade-off, and certainly better than a single JS file, e.g.

I have not yet tried whether these could be published as NodeJS modules or so (WebCompat AFAIK does support ES6 modules, so they could possibly be compiled), so they can be re-used in other ways.

1 Like

I’ve started refactoring my code using modules and it’s really really nice! I should have done this long time ago.

I had a same problem with my “utils” modules from git submodule being wrongly referenced, but luckily you can move your submodule to a different folder using git mv.

The only problem I’m having is with Web Console - somehow I’m no longer able to call functions or access variables defined in my main module. I can still access global stuff, like await browser.storage.local.get(), but not my own functions or imported modules.
Any workarounds?

You could probably use the dynamic import() function in the console to load the module that you want to call a function of.

1 Like

The problem is just that dynamic imports are not yet available in Firefox. (still behind an about:config setting in Firefox 66)

Yes, but Firefox Developer Edition is already 67 where it works :slight_smile:.

As a workaround for developer it’s ok… Thank you @freaktechnik!

EDIT:

This flag is enabled by default on nightly builds from Nightly 67.

So it will be also part of the next ESR 68 (YES!).

Not necessarily, the flag will probably be kept in nightly, but it may graduate in 68.

True, but it’s already set in Beta (Developer Edition), so I really hope that means it’s coming to release 67 in less than two weeks! :slight_smile:

Dev Edition has additional flags flipped for devs, as compared to beta.