35

我写了一个 Chrome 扩展程序。我的 background.js 文件很大,所以我想将它拆分为更小的部分,并在需要时加载指定的方法(某种延迟加载)。

我用 Firefox 做到了这一点:

// ( call for load specified lib )
var libPath = redExt.basePath + 'content/redExt/lib/' + redExt.browser + '/' + libName + '.js';
var service = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
service.loadSubScript("chrome://" + libPath);
// ( executing loaded file )

在基于 Webkit 的浏览器中是否有可能以类似的方式进行操作?我找到了如何将多个 JS 文件注入匹配页面(使用manifest.json)的解决方案,但找不到仅包含 JS 文件以进行扩展的方法。

4

5 回答 5

46

更新:此解决方案仅在您使用清单 V2 时才有效。

您也可以通过此处描述的极其简单的方法执行此操作: https ://developer.chrome.com/extensions/background_pages#manifest

{
  "name": "My extension",
  ...
  "background": {
    "scripts": [
      "lib/fileone.js",
      "lib/filetwo.js",
      "background.js"
    ]
  },
  ...
}

您不会进行延迟加载,但它确实允许您将代码分解为多个文件并指定将它们加载到后台页面的顺序。

于 2015-01-08T12:57:47.407 回答
16

如果您想在背景页面的上下文中加载 javascript 文件并避免使用eval,您只需将script标签添加到背景页面的 DOM 即可。例如,如果您的文件存在于lib扩展程序的文件夹中,则此方法有效:

function loadScript(scriptName, callback) {
    var scriptEl = document.createElement('script');
    scriptEl.src = chrome.extension.getURL('lib/' + scriptName + '.js');
    scriptEl.addEventListener('load', callback, false);
    document.head.appendChild(scriptEl);
}
于 2013-09-06T20:48:32.640 回答
4

也许你可以尝试使用网络工作者。在你的 background.js 中,包括:

var worker = new Worker('new-script.js');

网络工作者可以产生新的工作者,甚至有一个 importScript("new-script.js") 方法。

然而,网络工作者往往非常有限。在此处查看有关 Web 工作者的精彩文章。

但是,我不知道它们是否会起作用。另一种选择是使用 XMLHTTPRequest (AJAX) 动态检索脚本并对其进行评估。然而,通过非 HTTPS 连接,这可能由于中间人攻击而被阻止。或者,您可以通过将其添加到以下内容来强制 Chrome 从非加密连接(但不要这样做)评估脚本manifest.json

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": ["http://badpractic.es/insecure.js"]

有关AJAX 方法的更深入讨论,请参阅在后台页面加载远程网页:Chrome 扩展。

所以你的选择似乎是有限的。

这当然会一次加载它们:

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["background.js","background2.js","background3.js"] //and so on
  },
  ...
}
于 2013-09-06T06:58:26.387 回答
1

找到了可能的解决方案。RequireJS 的 main 方法 require 有一个简单的实现,它使用 JavaScript 回调跟踪来查找加载主扩展文件的事件,并使用扩展上下文绑定执行它。 https://github.com/salsita/browser-require/blob/master/require.js

它似乎有效,但这个解决方案有一些缺点:

  • 错误报告在“第 1 行,第 1 列”中报告,因为此解决方案直接将代码注入func.call- 调试非常困难
  • 加载的 JS 文件没有出现在控制台/chromebug 中
  • 如果当前选项卡使用 HTTPS,Chrome 将禁止评估脚本,尤其是来自本地上下文 ( file:///) 的脚本,因此它有时无法按预期工作
于 2013-09-06T07:17:36.920 回答
1

我所做的不是延迟加载,而是在单击我的 chrome 扩展图标时先加载一些文件。就我而言,我希望我的 util 文件在其他使用它们之前:

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction1.js"});
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction2.js"});
  chrome.tabs.executeScript(null, {file: "src/main.js"});
  chrome.tabs.executeScript(null, {file: "src/otherFeature.js"});
});
于 2019-10-13T22:33:00.460 回答