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

Multiple JS files in Chrome Extension - how to load them?

提问人:Tomasz Banasiak 提问时间:9/6/2013 更新时间:11/18/2023 访问量:44233

问:

我写了一个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 文件注入匹配页面的解决方案(使用 ),但找不到仅用于扩展的包含 JS 文件的方法。manifest.json

javascript google-chrome-extension 浏览器扩展

评论


答:

4赞 mdenton8 9/6/2013 #1

也许,您可以尝试使用 Web Worker。在后台.js中,包括:

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

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

然而,Web 工作者往往非常有限。在这里查看一篇关于 Web Worker 的精彩文章。

但是,我不知道它们是否有效。另一个选项是使用 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
  },
  ...
}

评论

1赞 mdenton8 9/6/2013
哦,对不起,我没有意识到你想要延迟加载。我去看看,对不起
0赞 Tomasz Banasiak 9/6/2013
好吧,但我想防止一次加载所有文件。我的扩展有时不使用所有方法,因此我只想加载当前需要的方法。在FireFox中,我有方法(例如。 加载 ) 并希望在 Chrome/Safari 中创建类似的解决方案:)usestorage = myExtension.use('storage')/lib/storage.js
0赞 mdenton8 9/6/2013
我给了你一些建议。再次检查我的答案?-马 特
0赞 Tomasz Banasiak 9/6/2013
Workers 是某种解决方案,但在我的情况下,它们的局限性使它们失去了资格 - 而且我必须重写几乎所有代码才能将其用作 worker 服务。但是我已经对你的答案投了赞成票,因为如果有人在编写任何代码之前正在寻找这个答案,那将会有所帮助。
0赞 mdenton8 9/6/2013
我很欣赏赞成票。也许 AJAX 方法对您更有帮助?你试过吗?
1赞 Tomasz Banasiak 9/6/2013 #2

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

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

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

评论

0赞 mdenton8 9/6/2013
你是对的,这是一个非常好的扩展。或多或少是 AJAX 方法的良好实现。当然,您可以允许对脚本进行不安全的评估,但您知道这样做会对下载您的扩展的任何用户造成某种信任的破坏。祝你好运。
0赞 mdenton8 9/6/2013
只是想知道,对于第一个问题,您不能在 Chrome 开发人员工具中按 F11 进入下一个函数调用吗?
16赞 rsanchez 9/7/2013 #3

如果您想在后台页面的上下文中加载 javascript 文件并希望避免使用 ,您只需在后台页面的 DOM 中添加一个标签即可。例如,如果您的文件存在于扩展的文件夹中,则此方法有效:evalscriptlib

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

评论

0赞 mdenton8 9/7/2013
因此,您指定了一个背景页面而不是脚本,然后将脚本添加到该页面?
0赞 rsanchez 9/7/2013
@mdenton8 将此函数包含在后台页面脚本中。然后,您可以调用它来运行该页面中的脚本。
0赞 user5508297 7/29/2016
这个答案@rsanchez过时了吗?你现在会建议按照 Omn 在 2015 年的回答中建议的方式去做吗?还是这两种方法各有利弊?
0赞 Farzad Yousefzadeh 11/10/2017
我可以确认这个解决方案对我有用并且仍然有效。
49赞 Omn 1/8/2015 #4

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

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

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

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

评论

0赞 Xan 1/8/2015
我能理解你想用你的答案说什么,但很难理解(你在那一页中到底指的是什么?一个小小的代码片段会大大改善你的答案。按原样,此答案是“仅链接”,可能会被删除。
0赞 user5508297 7/29/2016
@Omn,与上面 Rsanchez 建议的方法相比,您的方法的优缺点是什么?
10赞 Kamafeather 8/28/2018
注意:文件顺序很重要!scripts
0赞 Omn 9/20/2018
@Kamafeather 这就是为什么答案说这允许您“指定 [文件] 加载到后台页面的顺序”。
2赞 Ryan Walker 10/14/2019 #5

我所做的不是延迟加载,而是在单击我的 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"});
});
4赞 matt richards 9/1/2022 #6

Manifest v3 发生了很大变化

developer.chrome.com:Extension Service Worker 基础知识

mdn : 导入脚本

TL;博士

importScripts('script-1.js','script-2.js');

或更完整

  var err;
  try{      
        importScripts('nmhost/ext-nmhost.js');            
  }
  catch(err2){
        err    = err2;
  }
  if(err){    //handle error        
        console.error(err);            
  }
  

我有一个有用的示例浏览器扩展,它利用了,该扩展允许使用本机消息传递协议从浏览器启动提升和非提升的程序,请参阅 github : simple-nativemessaging - 示例目录importScripts

关于此主题的进一步阅读

chrome 开发者 : 提高扩展程序的安全性

chrome 开发者 : 迁移到 Service Worker

对于那些希望使用旧清单 v2 进行开发的人,可以从以下位置下载以前版本的 Chromium chromium.org : 下载 Chrome / Chromium 的旧版本,Chrome 88(2021 年 1 月 19 日)或更高版本通常支持 manifest V3。

评论

1赞 JLowther 6/27/2023
效果很好,非常简单,谢谢!