How to import js file to background.js in chrome extension from the same folder
Asked Answered
M

2

18

I'm having a problem importing the file "score.js" that is in same library of the "background.js" (scripts libary). I'm new to both js and chrome extensions. I looked into require.js and did this.

Background.html:

<!doctype html>
<html>
  <head>
    <title>Tab Manager</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  </head>
  <body>
    <h1>Tab Manager</h1>
    <script data-main="scripts/score.js" src="scripts/require.js"></script>
  </body>
</html>

background.js:

// gets a dictionary of existing windows ids as keys and tab arrays as values.
function get_windows() 
{
    var window_dict = {};
    chrome.windows.getAll({populate:true}, windowArr =>{
        var i;
        for (i = 0; i < windowArr.length; i++) {
            var window = windowArr[i];
            var window_id = window.id;
            var tabs = window.tabs;
            window_dict[window_id] = tabs;
          }
        console.log(window_dict);
        main(window_dict);
    })
    
}

function starting_scores(window_dict)
{
    var scores = [];
    var i;
    var j = 0;
    var total_tabs = [];
    for (const [window_id, tabs] of Object.entries(window_dict)) {
        for (i = 0; i < tabs.length; i++){
            scores[j] = new Score(tabs[i], window_id);
            j = j++;
        }}
    return scores;
}

function main(window_dict)
{
    var scores = starting_scores(window_dict);
    console.log(scores);
}

get_windows();

score.js:

class Score
{   
    // Constructor
    constructor(tab, window_id)
        {
        this.window_id = window_id; // The window id of the window that contains the tab.
        this.tab = tab; 
        this.url = tab.url;
        this.active = tab.active; // If the tab is currently looked at then it's active.
        this.audible = tab.audible; // If the tab is playing audio then audible will be true.
        this.discarded = tab.discarded; // If the tab is already unloaded but not closed this will be true.

        /* If the new tab is active then the timer is set to zero because 
        the user hasn't spent any time not using the tab. Otherwise a timer starts. */
        if(this.active == true){
            this.timer == 0;}
        else{
            this.timer = performance.now;}
        }
    
    // Get methods
    getWindowId() {
        return this.window_id;
    }
    getTab() {
        return this.tab;
    }
    getUrl() {
        return this.url;
    }
    getActive() {
        return this.active;
    }
    getAudible() {
        return this.audible;
    }
    getDiscarded() {
        return this.discarded;
    }
    getTimer() {
        return this.timer;
    }

    // Set methods
    setWindowId(window_id) {
        this.window_id = window_id;
    }
    setTab(tab) {
        this.tab = tab;
    }
    setUrl(url) {
        this.url = url;
    }
    setActive(active) {
        this.active = active;
    }
    setAudible(audible) {
        this.audible = audible;
    }
    setDiscarded(discarded) {
        this.discarded = discarded;
    }
    setTimer(timer) {
        this.timer = timer;
    }
}

I'm trying to build an extension that makes a score for usage for each tab and then removes the ones with low score. Don't mind the logic I just can't get score.js to work in background.js

Any help is apreciated.

Mott answered 12/5, 2021 at 20:17 Comment(0)
F
25

An update to @wOxxOm's answer, starting with Manifest v3, you cannot use background.page, but you can load the script as a module directly.

manifest.json

"background": {
    "service_worker": "background.js",
    "type": "module"
}

background.js

import Score from './score.js';

score.js

export default class Score
Frida answered 3/12, 2021 at 18:7 Comment(6)
now it is showing Service worker registration failedSassenach
Looks like that happens if the background script throws an error during installation: https://mcmap.net/q/350632/-service-worker-registration-failed-chrome-extensionFrida
@TrevinAvery what about content.js file? Can I import functions in it?Footsie
I don't know what content.js is, but you can probably load it as a module, either through the background as shown above or through a script tag as shown in @wOxxOm's answer. If you do, anything you export will be accessible. So simply export the functions you want.Frida
If someone is stuck on Service worker registration failed since last =one hour, the solution is to do import Score from './score.js'; and not import Score from './score';. Just putting it out here .Haler
Adding "type": "module" absolutely, 100% does not work at all. Not even a little bit. import Score from './score.js'; instead of import Score from './score'; also does not work at all.Shop
F
8

ManifestV3

There are several methods:
https://stackoverflow.com/a/66408379

ManifestV2

Remove require.js and use the built-in ES modules import.

manifest.json:

"background": {
  "page": "background.html"
}

background.html, the entire file is just one line:

<script src="background.js" type="module"></script>

background.js, insert at the beginning of the file:

import Score from './score.js';

The imported script score.js, change the first line:

export default class Score

Remember that if you don't use a bundler/compiler like WebPack the file name in import must include the path (./ means "same directory") and the file extension, otherwise it won't work. A typical file extension for a module is .mjs.

Flatting answered 13/5, 2021 at 4:21 Comment(3)
Thanks so much. I was having so much trouble importing files I thought js was just not for me. This is actually for a school project I'm doing and it's due soon. This helped me a ton and enabled me to keep coding.Mott
(manifest V3) I get this Extension Error: Uncaught SyntaxError: Unexpected token 'export'Uno
@Alex75, this answer is for ManifestV2. See chrome extension mv3 - Modularize service worker js fileFlatting

© 2022 - 2024 — McMap. All rights reserved.