我正在尝试将我的 chrome 扩展从清单版本 2 迁移到 3。现在后台脚本已被清单 v3 中的服务人员替换,我不能再使用 html 文件并js
在脚本标签中引用文件。
有什么方法可以将我的单个脚本文件导入service_worker.js
文件中?
我在互联网上搜索了几乎所有内容,但找不到任何解决方案。甚至这里的官方文档注册后台脚本也没有太大帮助。任何帮助,将不胜感激。
我正在尝试将我的 chrome 扩展从清单版本 2 迁移到 3。现在后台脚本已被清单 v3 中的服务人员替换,我不能再使用 html 文件并js
在脚本标签中引用文件。
有什么方法可以将我的单个脚本文件导入service_worker.js
文件中?
我在互联网上搜索了几乎所有内容,但找不到任何解决方案。甚至这里的官方文档注册后台脚本也没有太大帮助。任何帮助,将不胜感激。
首先,重要的警告:
警告!由于架构限制,如果在其编译期间发生未处理的异常(如未闭合括号之类的语法错误)或初始化(例如访问未定义的变量),则无法注册服务工作者,因此我们将代码包装在try/catch
. 请注意,在 Chrome 93 之前,该错误并未显示在任何地方(这是一个错误),现在它显示在 chrome://extensions 页面的扩展卡上的错误列表中。
警告!工作文件必须位于 Chrome 版本早于 93的根路径中。
警告!不要导入像jQuery这样的基于 DOM 的库,因为 service worker 没有 DOM,所以没有document
,XMLHttpRequest
等等。
这个内置函数同步获取并运行脚本,以便它们的全局变量和函数立即可用。
清单.json:
"background": { "service_worker": "bg-loader.js" },
bg-loader.js 只是单独文件中实际代码的 try/catch 包装器:
try {
importScripts('/path/file.js', '/path2/file2.js' /*, and so on */);
} catch (e) {
console.error(e);
}
如果某个文件抛出错误,则不会导入后续文件。如果您想忽略此类错误并继续导入,请在其自己的 try-catch 块中单独导入此文件。
不要忘记指定文件扩展名,通常是.js
或.mjs
.
根据规范,我们必须使用服务工作者的install
事件并导入我们希望稍后能够在异步事件中导入的所有脚本(从技术上讲,是 JS 事件循环初始任务之外的任何内容)。此处理程序仅在安装或更新扩展或重新加载未打包的扩展时调用(因为它等于更新)。
这在 MV3 中很复杂,因为服务工作者是为 Web 设计的,远程脚本可能无法离线使用。希望它会在crbug/1198822中得到简化。
另请参阅:WebPack 的 webpack-target-webextension插件。
self.oninstall = () => {
tryImport('/js/some-complex-script.js');
};
function tryImport(...fileNames) {
try {
importScripts(...fileNames);
return true;
} catch (e) {
console.error(e);
}
}
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.action === 'somethingComplex') {
if (tryImport('/js/some-complex-script.js')) {
// calling a global function from some-complex-script.js
someComplexScriptAsyncHandler(msg, sender, sendResponse);
return true;
}
}
});
通过添加到manifest.json"type": "module"
中的声明启用。background
import
可以使用静态语句。import()
尚未实现 ( crbug/1198822 )。清单.json:
"background": { "service_worker": "bg.js", "type": "module" },
"minimum_chrome_version": 92,
bg.js:
模块名称必须以路径开头并以 .js 或 .mjs 之类的扩展名结尾
import {foo} from '/path/file.js';
import './file2.js';
// each imported module should also use try/catch for their own init
try { init(); } catch (e) { console.error(e); }
function init() {
// .........
}