简体   繁体   English

在 JavaScript 模块中,如何从外部文件加载 class?

[英]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.我正在编写一个 Chrome 扩展程序,并试图将功能隔离开来。 I want the functional page to instantiate a class from another file.我希望功能页面从另一个文件实例化 class。 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): class 文件(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):试图导入 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入口点: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):为了完整起见,清单 (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. executeScript 本身并不运行 function,它只是获取function 的文本,将其发送到 web 页面,然后根据该文本创建一个新的Function并运行它。

It means that the injected function can't access outer functions/classes/variables in its parent scope.这意味着注入的 function 无法访问其父 scope 中的外部函数/类/变量。

Solutions:解决方案:

  1. include everything inside the function;包括 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:首先为依赖项调用 executeScript,但请注意,这不适用于模块脚本,因此您要公开的内容必须是全局的,或者它可以是这样的 IIFE:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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