Regarding, docs, I would recommend the anatomy page:
But basically it’s just normal JavaScript thing. The same way you can have multiple scripts loading in one page, you can load multiple script files loading into any of your contexts.
For example, for contexts where you use .html file (like Options page or Popup page), you just include your “utils.js” above your “options.js” script to make sure it get’s loaded before. If you have .html file for your background script, then same way there. If not, then just add it to the manifest file.
Regarding context scripts - again, if you have them defined in the manifest, then just add “utils.js” script before your context script file (they get loaded in the specified order). If you are injecting them dynamically using “executeScript”, the
n just inject your “utils.js” before and await the promise it returns.
Actually what I’m describing here is well described by the webextension-polyfill library.
Just to clarify, all those scripts shares the same window object if they are executed in the same context, that’s why your background scripts can share functions.
Regarding the async code issues you mentioned
I’m a bit skeptical about it , sure there are some nasty things to be aware of, but if you follow all the rules and make sure there are no race conditions, then it should work 100% time. Huge part of my add-on is now asynchronous and ever since I’ve fixed the race conditions when bootstrapping my add-on, there are no more bug reports.