【问题标题】:In a JavaScript module, how do I load a class from an external file?在 JavaScript 模块中,如何从外部文件加载类?
【发布时间】:2023-01-31 08:21:44
【问题描述】:

我正在编写一个 Chrome 扩展程序,并试图将功能隔离开来。我希望功能页面从另一个文件实例化一个类。有人能告诉我我做错了什么吗?

错误信息:

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

类文件(lib/externalclass.js):

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

export class ExternalClass {
    constructor() {
        console.log("constructing the external 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();
}

入口点: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"
        });
    }
}

为了完整起见,清单 (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"
}

我希望这是一个简单的。谢谢!

【问题讨论】:

    标签: javascript google-chrome-extension import module


    【解决方案1】:

    executeScript 本身并不运行该函数,它只是接收the text of the function,将其发送到网页,然后根据该文本创建一个新的Function 并运行它。

    这意味着注入函数无法访问其父范围内的外部函数/类/变量。

    解决方案:

    1. 包括函数内的所有内容;

    2. 首先为依赖项调用 executeScript,但请注意,这不适用于模块脚本,因此您要公开的内容必须是全局的,或者它可以是这样的 IIFE:

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

    【讨论】:

    • 谢谢。是的,我现在看到了问题。我错误地认为 processThatPage 可以访问在其自己的文件中声明的内容。我不断遇到“Javascript 不会那样做”的墙。问题是 ExternalClass 不是函数;它是一个从一个调用到下一个调用保持状态的对象,processThatPage 需要能够找到它或创建它。你有什么我应该怎么做的例子吗?
    • 这是一个单独的问题,其解决方案取决于该状态。您可以使用内容中的消息,也可以是注入函数或 chrome.storage 返回的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多