chrome 扩展 mv3 - 模块化服务工作者 js 文件

Posted

技术标签:

【中文标题】chrome 扩展 mv3 - 模块化服务工作者 js 文件【英文标题】:chrome extension mv3 - Modularize service worker js file 【发布时间】:2021-05-30 01:33:55 【问题描述】:

我正在尝试将我的 chrome 扩展从清单版本 2 迁移到 3。现在后台脚本已被清单 v3 中的服务人员替换,我不能再使用 html 文件并在脚本标签中引用 js 文件。

有什么方法可以将我的单个脚本文件导入service_worker.js 文件?

我在互联网上搜索了几乎所有内容,但找不到任何解决方案。甚至这里的官方文档Register background scripts 也没有太大帮助。任何帮助将不胜感激。

【问题讨论】:

使用内置的 importScripts 功能,另见Web Workers - How To Import Modules 谢谢@wOxxOm。它对我有用。我昨天试过了,但是服务人员由于某种原因无法启动。 【参考方案1】:

首先,重要的警告:

警告!由于架构限制,如果在其编译(如未闭合括号之类的语法错误)或初始化(例如访问未定义的变量)期间发生未处理的异常,则无法注册服务工作者) 所以我们将把代码包装在try/catch 中。请注意,在 Chrome 93 之前,该错误并未显示在任何地方(它是 bug),现在它显示在 chrome://extensions 页面的扩展卡上的错误列表中。

警告!工作文件必须在根路径in Chrome versions older than 93。

警告! 不要导入像 jQuery 这样的基于 DOM 的库,因为 service worker 没有 DOM,所以没有 documentXMLHttpRequest 等等开。

1。 importScripts

此内置函数同步获取并运行脚本,以便它们的全局变量和函数立即可用。

manifest.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

1b。监听器中的 importScripts

根据规范,我们必须使用 service worker 的 install 事件并导入我们希望稍后能够在异步事件中导入的所有脚本(从技术上讲,初始任务之外的任何内容 JS 事件循环的 em>)。此处理程序仅在安装或更新扩展或重新加载解压缩的扩展时调用(因为它等于更新)。

这在 MV3 中很复杂,因为服务工作者是为 Web 设计的,远程脚本可能无法离线使用。希望它会在crbug/1198822 中得到简化。

另请参阅:webpack-target-webextension WebPack 插件。

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

2。 Chrome 92 及更高版本中的 ES 模块

通过在 manifest.json 中的 background 声明中添加 "type": "module" 启用。

可以使用静态import 语句。 动态 import() 尚未实现 (crbug/1198822)。

manifest.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() 
  // .........

【讨论】:

我收到一个错误“ importScripts() of new scripts after service worker install is not allowed.” 我有一些异步方法来处理导入的脚本,这是不允许的吗? @wOxxOm 看我的帖子***.com/q/67000104/12550657 遗憾的是我得到了变体:2. ES modules in Chrome 92 and newer 错误An unknown error occurred when fetching the script.。导入完成:import BuM from './lib/BackupsManager'; 和 BackupsManager 是默认导出 BackupsManager 的单例实例。你知道为什么会发生这种情况吗@wOxxOm 通过省略 .js 文件扩展名,您没有使用 ES 模块导入语法,这就是它失败的原因。

以上是关于chrome 扩展 mv3 - 模块化服务工作者 js 文件的主要内容,如果未能解决你的问题,请参考以下文章

executeScript 未定义或不是 ManifestV3 扩展中的函数

Chrome 扩展后台脚本如何与网页服务工作者通信?

Chrome扩展程序后台脚本如何与网页服务工作者进行通信?

Chrome 扩展中的持久服务工作者

Chrome 扩展中的持久服务工作者

Chrome 扩展中的 CORS HTTPS 到 HTTP 网络服务