1

I am writing an extension for Firefox v97, and the main script is a content script. The final extension will perform different behavior depending on the top-level domain of the current page. Coming from OOP, I'd like to separate the code into one function per page type and store them in separate files for easier readability.

What I normally do with OOP languages, and what I'd like to do here with Javascript (unless there's a different best practice other than putting everything into a single long code file), is have three Javascript files, main, us, and de.

The directory tree is:

identifyCountry/
   main.js
   scriptsPerCountry/
      us.js
      de.js

us will look like:

function foo {
   console.log("American website.");
}

de will look like:

function bar {
   console.log("German website.");
}

main, if written in an OOP style, would look like:

currUrl = window.location.href;
if (//.com/.test(currUrl) {
   us.foo();
} else if (//.de/.test(currUrl) {
   de.bar();
}

How could I do this?

The most common proposed solution that I have found is to load all three JS scripts into the HTML page, but I'd prefer not to do that since, being an extension using content scripts, I think that I'd need to inject code into the existing HTML code of the page, which is a security risk.

I've also tried exporting the functions with the following example for us.

Rewrite us to look like:

function foo {
   console.log("American website.");
}

export { foo };

and re-write de similarly.

Rewrite main to look like:

import { foo } from './scriptsPerCountry/us.js';
import { bar } from './scriptsPerCountry/de.js';
currUrl = window.location.href;
if (//.com/.test(currUrl) {
   us.foo();
} else if (//.de/.test(currUrl) {
   de.bar();
}

When I do this, I get this error in Firefox:

SyntaxError: import declarations may only appear at top level of a module

that can't be fixed unless I declare main as a module-type script, which I don't think is possible without injecting script into the HTML again.

Gicci
  • 41
  • 6
  • How do you execute `main` without injecting it into the page? – Bergi Feb 13 '22 at 00:40
  • @Bergi I include ```main.js``` under the ```content_scripts``` section of the ```manifest.json``` for the add-on, like so: ```"content_scripts": [{"js": ["main.js"]}``` – Gicci Feb 13 '22 at 03:18

1 Answers1

0

I finally figured this out on my own. To do this with a Firefox extension, one way is to just declare multiple JavaScript scripts within the manifest.json file. An example (matches doesn't need to look like this):

  "content_scripts": [
    {
        "matches": ["*://*/*"],
        "js": [
            "main.js",
            "scriptsPerCountry/us.js",
            "scriptsPerCountry/de.js"
        ]
    }

Then, you can have, for example, us.js just look like this (no export):

function foo {
   console.log("American website.");
}

...and de.js would look like this:

function bar {
   console.log("German website.");
}

...and then main.js can look like this (no import) and everything will work:

currUrl = window.location.href;
if (//.com/.test(currUrl) {
   foo();
} else if (//.de/.test(currUrl) {
   bar();
}

Any functions within each script will be loaded into the global scope, no import or export statements nor declaring that the scripts be modular are necessary.

Gicci
  • 41
  • 6