承诺支持 Chrome 扩展 API?
Promise support for Chrome Extensions API?
过去几周我一直在编写一些浏览器扩展,直到今天我认为 Firefox 的 WebExtension 应该在 Chrome 中自动工作。所以我试着根据Mozilla的例子来写我的代码。
但是今天我意识到 API 扩展文档中没有提到 Promises。
我在所有扩展的代码中都严格使用 Promises。
所以现在我的问题是,我的代码可以在 Chrome 中运行吗?或者,如果我在最顶部添加一个 var browser = chrome
声明,它会起作用吗?
或者 Chrome 根本不支持 API 上的 Promise?
如果 Chrome 还不支持 API 函数上的 Promises,将来会支持它们吗?
注意,我知道这个项目:https://github.com/mozilla/webextension-polyfill
但我不愿意经历在所有地方都包含该库的麻烦。此外,它还有恼人的错误。
此外,我没有 Chrome 或 Chromium,出于隐私和安全原因我无法安装它们。
编辑:
...until today I thought that a WebExtension for Firefox should work pretty much automatically in Chrome.
WebExtensions 是在考虑到 Chrome 扩展的向后兼容性的情况下创建的。 chrome.*
命名空间可用于受支持的 API。这里的目标是简化将现有扩展移植到 FF 以快速 bootstrap 生态系统。
但是,Mozilla 忽略了与 browser.*
命名空间的向前兼容性。 Mozilla 决定为 API 采用基于 promise 的方法,但仅限于该新命名空间。
So now my question is, will my code work in Chrome?
Or would it work if I add a var browser = chrome
declaration at the very top?
没有;它们的行为不同并且具有不同的签名。 Chrome 将拒绝不需要显式回调的呼叫。 browser.*
变体将改为发出 Promise。
Or does Chrome not support Promises on the API at all?
If Chrome doesn't support Promises on the API functions yet, will it support them in the future?
如评论中所述,API is considered by Chrome, and it has been implemented, or started to be implemented, for MV3 extensions. However, there exist polyfills, including the one you mentioned 基于 Promise 的重写。除了自己包装方法来创建自己的 polyfill 之外,没有其他解决方案。
And besides that I don't have Chrome or Chromium and I can't install them for privacy and security reasons.
那么你无论如何都无法正确测试你的端口;对于您的潜在用户而言,这不是一个好方法。在这种情况下,你最好不要移植。
我创建这个库 https://github.com/lawlietmester/webextension 是为了在没有像 webextension-polyfill 那样的通用规则的情况下做到这一点。
我的库是一种跨浏览器方式,可以在不修改原始 chrome/browser 的情况下制作一个 Browser
对象。就像以前的jQuery。
只使用一次 - 在后台进程中导入它并使其在后台全局使用,然后对于其他导入(例如从弹出窗口)使用 import from
( typeof browser === 'undefined' ? chrome : browser ).extension.getBackgroundPage().Browser
我没看过browser
API,所以我可能有失偏颇,但如果只不同的是Firefox APIs return promises 而不是使用回调,chrome-promise 库可能会有所帮助。它将所有需要回调的 API 调用包装在 return 承诺的函数中。
然后您可以在 Chrome 中执行类似的操作:
var browser = new ChromePromise();
然后进行 promise 调用:
browser.storage.local.get(null).then(data => console.log(data));
如果您将 browser
变量定义为全局变量并在任何其他脚本之前包含该脚本,您可以将其作为全局变量使用,而不必在每个要使用它的文件中包含 polyfill .
编辑: chrome-promise
的作者不再维护它,除了修复错误。他们在需要的各种扩展上下文中列出了一些替代库 here, including the Mozilla webextension-polyfill rejected by the OP. That library's readme explains how to make it available as a global variable。
官方 promise 支持终于来了,并且已经在一些 API 上实现了。撰写本文时:
chrome.runtime.onInstalled.addListener(async () => {
let url = chrome.runtime.getURL("hello.html");
let tab = await chrome.tabs.create({ url });
console.log(`Created tab ${tab.id}`);
});
如您所见,只在 chrome
对象上实现了 promise 支持,该对象现在同时支持 Promises 和回调。 Firefox 仍然使用 browser
对象作为承诺 API.
我在 Spellbook 上的方法是将必要的方法转换为 return 承诺并检查 chrome.runtime.lastError 包装回调。
但现在我只是遍历了所有合适的 chrome API 方法,并使用上述方法将它们变成基于 promise 的方法。
这是 Spellbook 上的 relevant commit。
我打算将其提取到一个名为 Rosegarden 的小型库中,因为 Mozilla 的 webextension-polyfill 似乎太复杂了...
过去几周我一直在编写一些浏览器扩展,直到今天我认为 Firefox 的 WebExtension 应该在 Chrome 中自动工作。所以我试着根据Mozilla的例子来写我的代码。
但是今天我意识到 API 扩展文档中没有提到 Promises。
我在所有扩展的代码中都严格使用 Promises。
所以现在我的问题是,我的代码可以在 Chrome 中运行吗?或者,如果我在最顶部添加一个 var browser = chrome
声明,它会起作用吗?
或者 Chrome 根本不支持 API 上的 Promise?
如果 Chrome 还不支持 API 函数上的 Promises,将来会支持它们吗?
注意,我知道这个项目:https://github.com/mozilla/webextension-polyfill
但我不愿意经历在所有地方都包含该库的麻烦。此外,它还有恼人的错误。
此外,我没有 Chrome 或 Chromium,出于隐私和安全原因我无法安装它们。
编辑:
...until today I thought that a WebExtension for Firefox should work pretty much automatically in Chrome.
WebExtensions 是在考虑到 Chrome 扩展的向后兼容性的情况下创建的。 chrome.*
命名空间可用于受支持的 API。这里的目标是简化将现有扩展移植到 FF 以快速 bootstrap 生态系统。
但是,Mozilla 忽略了与 browser.*
命名空间的向前兼容性。 Mozilla 决定为 API 采用基于 promise 的方法,但仅限于该新命名空间。
So now my question is, will my code work in Chrome?
Or would it work if I add avar browser = chrome
declaration at the very top?
没有;它们的行为不同并且具有不同的签名。 Chrome 将拒绝不需要显式回调的呼叫。 browser.*
变体将改为发出 Promise。
Or does Chrome not support Promises on the API at all?
If Chrome doesn't support Promises on the API functions yet, will it support them in the future?
如评论中所述,API is considered by Chrome, and it has been implemented, or started to be implemented, for MV3 extensions. However, there exist polyfills, including the one you mentioned 基于 Promise 的重写。除了自己包装方法来创建自己的 polyfill 之外,没有其他解决方案。
And besides that I don't have Chrome or Chromium and I can't install them for privacy and security reasons.
那么你无论如何都无法正确测试你的端口;对于您的潜在用户而言,这不是一个好方法。在这种情况下,你最好不要移植。
我创建这个库 https://github.com/lawlietmester/webextension 是为了在没有像 webextension-polyfill 那样的通用规则的情况下做到这一点。
我的库是一种跨浏览器方式,可以在不修改原始 chrome/browser 的情况下制作一个 Browser
对象。就像以前的jQuery。
只使用一次 - 在后台进程中导入它并使其在后台全局使用,然后对于其他导入(例如从弹出窗口)使用 import from
( typeof browser === 'undefined' ? chrome : browser ).extension.getBackgroundPage().Browser
我没看过browser
API,所以我可能有失偏颇,但如果只不同的是Firefox APIs return promises 而不是使用回调,chrome-promise 库可能会有所帮助。它将所有需要回调的 API 调用包装在 return 承诺的函数中。
然后您可以在 Chrome 中执行类似的操作:
var browser = new ChromePromise();
然后进行 promise 调用:
browser.storage.local.get(null).then(data => console.log(data));
如果您将 browser
变量定义为全局变量并在任何其他脚本之前包含该脚本,您可以将其作为全局变量使用,而不必在每个要使用它的文件中包含 polyfill .
编辑: chrome-promise
的作者不再维护它,除了修复错误。他们在需要的各种扩展上下文中列出了一些替代库 here, including the Mozilla webextension-polyfill rejected by the OP. That library's readme explains how to make it available as a global variable。
官方 promise 支持终于来了,并且已经在一些 API 上实现了。撰写本文时:
chrome.runtime.onInstalled.addListener(async () => {
let url = chrome.runtime.getURL("hello.html");
let tab = await chrome.tabs.create({ url });
console.log(`Created tab ${tab.id}`);
});
如您所见,只在 chrome
对象上实现了 promise 支持,该对象现在同时支持 Promises 和回调。 Firefox 仍然使用 browser
对象作为承诺 API.
我在 Spellbook 上的方法是将必要的方法转换为 return 承诺并检查 chrome.runtime.lastError 包装回调。
但现在我只是遍历了所有合适的 chrome API 方法,并使用上述方法将它们变成基于 promise 的方法。
这是 Spellbook 上的 relevant commit。
我打算将其提取到一个名为 Rosegarden 的小型库中,因为 Mozilla 的 webextension-polyfill 似乎太复杂了...