Chrome扩展程序中的多个JS文件 - 如何加载它们?

时间:2013-09-06 06:50:01

标签: javascript google-chrome google-chrome-extension browser-extension

我写了一个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文件扩展的方法。

5 个答案:

答案 0 :(得分:25)

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

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

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

答案 1 :(得分:15)

如果您想在后台页面的上下文中加载javascript文件并希望避免使用eval,则可以在后台页面的DOM中添加script标记。例如,如果您的文件存在于您的扩展程序的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);
}

答案 2 :(得分:2)

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

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

Web worker可以生成新的worker,甚至还有一个importScript(“new-script.js”)方法。

但是,网络工作者往往非常有限。查看here以获取关于Web worker的精彩文章。

但是,我不知道他们是否会工作。另一个选择是使用XMLHTTPRequest(AJAX)来动态检索脚本,并对其进行评估。但是,在非HTTPS连接上,由于中间人攻击,这可能会被阻止。 或者,您可以将Chrome添加到manifest.json

,强制Chrome从非加密连接中获取eval脚本(但请不要这样做)
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": ["http://badpractic.es/insecure.js"]

有关AJAX方法的更深入讨论,请参阅Load remote webpage in background page: Chrome Extension

所以你的选择似乎有限。

这当然会一次性加载它们:

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["background.js","background2.js","background3.js"] //and so on
  },
  ...
}

答案 3 :(得分:1)

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

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

  • 错误报告在“第1行第1列”中报告,因为此解决方案直接将代码注入func.call - 调试非常困难
  • 加载的JS文件未出现在console / chromebug
  • 如果当前标签使用HTTPS Chrome会禁止评估脚本,尤其是来自本地环境(file:///)的脚本,因此它有时无法按预期工作

答案 4 :(得分:0)

我所做的不是延迟加载,而是单击chrome扩展名图标时,我先加载了一些文件。就我而言,我希望我的效用文件先于其他利用它们的人:

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"});
});