Search code examples
javascriptscopefirefox-addonseparation-of-concerns

Mozilla Extensions: Variable Scopes


AFAIK, all top-level variables in content scripts must be globally unique within the window. So if two content scripts both include a line like let port = ...;, they will break the extension. This behavior makes separation of concerns very difficult, because if you group functionality into directories and files, you will be obfuscating which variable names are still okay to use. Is there a canonical way to avoid this issue?

Here's a minimal example:

manifest.json

{
  "manifest_version": 2,
  "name": "test",  
  "version": "1.0",

  "applications": {
    "gecko": {
      "id": "test_script@example.com"
    }
  },

  "content_scripts": [
    {
      "matches": ["*://*.google.com/*"],
      "js": ["read/index.js", "write/index.js"]
    }
  ] 
}

read/index.js

console.log("i am read");

write/index.js

console.log("i am write");

When a Google page is loaded, "i am read" and "i am write" will be printed to the console. But what if we make few small changes to the content scripts:

read/index.js

let message = "i am read";
console.log(message);

write/index.js

let message = "i am write";
console.log(message);

Now only "i am read" will print.


Solution

  • I was being silly. Thank you LukStorms for the answer: I just have to wrap the code in the script files in a function to set the appropriate scope. It's been a while since I coded in JavaScript I guess...

    For posterity, there are two common ways to wrap you code that I know of:

    (() => {
      code here...
    })()
    

    and

    function main() {
      code here...
    }
    main();