简体   繁体   中英

In a JavaScript module, how do I load a class from an external file?

I'm writing a Chrome Extension, and trying to keep the functions isolated. I want the functional page to instantiate a class from another file. Could someone tell me what I'm dong wrong?

The error message:

VM792:4 Uncaught ReferenceError: ExternalClass is not defined
    at processThatPage (<anonymous>:4:5)
    at <anonymous>:5:3

The class file (lib/externalclass.js):

/* jshint esversion: 8 */
/* global console */

export class ExternalClass {
    constructor() {
        console.log("constructing the external class");
    }
}

The file that's trying to import the class (lib/processpage.js):

/* jshint esversion: 8 */
/* global console */

import { ExternalClass } from "./externalclass.js";

export function processThatPage() {
    let dltracker;
    console.log("Trying to make external class");
    dltracker = new ExternalClass();
}

The entry point: automata.js

/* jshint esversion: 8 */
/* global console */
/* global chrome */

import { processThatPage } from "./lib/processpage.js";

chrome.runtime.onInstalled.addListener(() => {
  chrome.tabs.onUpdated.addListener( pageLoadCheck);
});

async function pageLoadCheck(tabId, changeInfo, tab) {
    if (changeInfo.status === 'complete' && tab.url.startsWith("https://www.target.net/path"))
    {
        chrome.scripting.executeScript(
        {
            target: { tabId: tab.id },
            func: processThatPage,
            world: "MAIN"
        });
    }
}

Just for completeness, the manifest (manifest.json):

{
  "name": "My Automator",
  "description": "What I'm trying to accomplish",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "automata.js",
    "type": "module"
  },
  "permissions": ["storage", "tabs", "scripting", "downloads", "alarms"],
  "host_permissions": ["http://*.target.net/*", "https://*.target.net/*"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  },
  "options_page": "options.html"
}

I hope this is a simple one. Thanks!

executeScript doesn't run the function itself, it simply takes the text of the function , sends it into the web page, where it creates a new Function from this text and runs it.

It means that the injected function can't access outer functions/classes/variables in its parent scope.

Solutions:

  1. include everything inside the function;

  2. call executeScript for the dependencies first, but note that this doesn't work with module scripts, so the stuff you want to expose must be global or it can be an IIFE like this:

     (() = { function globalFoo() {...... } function bar() {...... } Object.assign(window, {globalFoo}); })();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM