您可能听说过 Mozilla 的 WebExtensions,这是我们为编写多进程兼容的附加组件实现的新浏览器扩展 API。也许您一直在好奇它是什么,以及如何使用它。好吧,我来帮忙!我认为 MDN 的 WebExtensions 文档 是一个非常好的起点
WebExtensions 是一种编写 Firefox 扩展的新方法。
该技术是为了跨浏览器兼容性而开发的:在很大程度上,该 API 与 扩展 API 兼容,后者受 Google Chrome 和 Opera 支持。为这些浏览器编写的扩展程序在大多数情况下只需稍作修改即可在 Firefox 中运行。该 API 还完全兼容 多进程 Firefox。
我唯一想补充的是,虽然 Mozilla 正在实现 Chrome 和 Opera 支持的大部分 API,但我们并不局限于仅使用该 API。在有意义的地方,我们将添加新功能并与其他浏览器制造商讨论也实施这些功能。最后,由于 WebExtension API 仍在开发中,因此最好在此教程中使用 Firefox Nightly,以便获得最新、符合标准的行为。但请记住,这仍然是实验性技术——可能会出现故障!
开始
好的,让我们从一个相当简单的附加组件开始。我们将添加一个按钮,当您单击它时,它将在新标签页中打开 我最喜欢的网站之一。
我们需要的第一文件是 manifest.json
,以告诉 Firefox 有关我们的附加组件的信息。
{
"manifest_version": 2,
"name": "Cat Gifs!",
"version": "1.0",
"applications": {
"gecko": {
"id": "catgifs@mozilla.org"
}
},
"browser_action": {
"default_title": "Cat Gifs!"
}
}
太好了!我们完成了!希望您的代码看起来有点像 这样。当然,我们还不知道它是否有效,所以让我们在 Firefox 中安装它(我们正在使用 Firefox Nightly 获取最新的实现)。您可以尝试将 manifest.json
或整个目录拖放到 Firefox 上,但这真的不会达到您想要的效果。
安装
要使 Firefox 将您的扩展程序识别为附加组件,您需要提供一个以 .xpi
结尾的 zip 文件,所以让我们首先安装 7-Zip,然后键入 7z a catgifs.xpi manifest.json
。(如果您使用的是 Mac 或 Linux,则 zip
命令应该内置,因此只需键入 zip catgifs.xpi manifest.json
。)然后,您可以将 catgifs.xpi
拖放到 Firefox 上,它将显示错误,因为我们的扩展程序未签名。
我们可以通过转到 about:config
,在搜索框中键入 xpinstall.signatures.required
,双击该条目将其设置为 false,然后关闭该选项卡来解决此问题。之后,当我们将 catgifs.xpi
放到 Firefox 上时,我们将获得安装新附加组件的选项!
需要注意的是,从 Firefox 44 开始(今年晚些时候),附加组件将 需要签名才能安装在 Firefox Beta 或浏览器发行版上,因此即使您设置了下面显示的偏好设置,您也很快仍需要运行 Firefox Nightly 或 Developer Edition 才能遵循本教程。
当然,我们的附加组件目前还没有做太多事情。
所以让我们修复它!
添加功能
首先,我们将以下几行添加到 manifest.json
中,位于包含 browser_action
的行的上方
"background": {
"scripts": ["background.js"],
"persistent": false
},
现在,当然,它指向一个尚不存在的 background.js
文件,所以我们也应该创建它。让我们将以下 javascript 粘贴到其中
'use strict';
/*global chrome:false */
chrome.browserAction.setBadgeText({text: '(ツ)'});
chrome.browserAction.setBadgeBackgroundColor({color: '#eae'});
chrome.browserAction.onClicked.addListener(function(aTab) {
chrome.tabs.create({'url': 'http://chilloutandwatchsomecatgifs.com/', 'active': true});
});
您应该会看到类似于 这样 的内容。通过键入 7z a catgifs.xpi manifest.json background.js
(或 zip catgifs.xpi manifest.json background.js
)重新创建附加组件,并将 catgifs.xpi
再次拖放到 Firefox 上,现在,当我们单击该按钮时,我们应该会得到一个新标签页!😄
自动化构建
我不知道您怎么样,但我最终键入了 7z a catgifs.xpi manifest.json
令人沮丧的次数,并想知道为什么我的 background.js
文件没有运行。因为我知道这篇文章的最终去向,我知道我们将要添加更多文件,所以我认为现在是时候添加构建脚本了。我听说如今首选的构建工具是 gulp
,所以我会在这里等您 去安装它,并在您完成时回来。(我需要安装 Node,然后两次安装 gulp。我不确定为什么。)
因此,现在我们已经安装了 gulp,我们应该创建一个名为 gulpfile.js
的文件来告诉它如何构建我们的附加组件。
'use strict';
var gulp = require('gulp');
var files = ['manifest.json', 'background.js'];
var xpiName = 'catgifs.xpi';
gulp.task('default', function () {
console.log(files, xpiName)
});
一旦您使该文件看起来 像这样,您可以键入 gulp
,并看到如下输出
现在,您可能会注意到我们实际上并没有构建附加组件。为此,我们需要安装另一个软件包来压缩文件。因此,键入 npm install gulp-zip
,然后更改 gulpfile.js
以包含以下内容
'use strict';
var gulp = require('gulp');
var zip = require('gulp-zip');
var files = ['manifest.json', 'background.js'];
var xpiName = 'catgifs.xpi';
gulp.task('default', function () {
gulp.src(files)
.pipe(zip(xpiName))
.pipe(gulp.dest('.'));
});
一旦您的 gulpfile.js
看起来 像这样,当我们运行它时,它将创建 catgifs.xpi
(正如我们可以通过查看时间戳或删除它并查看它是否重新创建来判断)。
修复错误
现在,如果您像我一样,您会多次单击该按钮以对其进行测试并确保它正常工作,并且您可能最终会得到很多标签页。虽然这将确保您保持格外冷静,但如果我们在单击按钮时创建它或切换到它(如果它存在),则可能只保留一个标签页会更好。所以让我们继续添加它。
我们要做的第一件事是查看标签页是否存在,所以让我们编辑 background.js
中的 browserAction.onClicked
侦听器以包含以下内容
chrome.browserAction.onClicked.addListener(function(aTab) {
chrome.tabs.query({'url': 'http://chilloutandwatchsomecatgifs.com/'}, (tabs) => {
if (tabs.length === 0) {
// There is no catgif tab!
chrome.tabs.create({'url': 'http://chilloutandwatchsomecatgifs.com/', 'active': true});
} else {
// Do something here…
}
});
});
嗯,这很奇怪,无论已经有多少个猫 GIF 标签页,它总是会创建一个新标签页……事实证明,我们的附加组件还没有权限查看现有标签页的 URL,这就是它找不到它们的原因,所以让我们继续通过在 browser_action
上方插入以下代码来添加它
"permissions": [
"tabs"
],
一旦您的代码看起来 类似于这样,重新运行 gulp
以重新构建附加组件,并拖放以安装它,然后当我们对其进行测试时,瞧!只有一个猫 GIF 标签页!当然,如果我们在另一个标签页上,它不会执行任何操作,所以让我们修复它。我们可以更改 else
块以包含以下内容
// Do something here…
chrome.tabs.query({'url': 'http://chilloutandwatchsomecatgifs.com/', 'active': true}, (active) => {
if (active.length === 0) {
chrome.tabs.update(tabs[0].id, {'active': true});
}
});
确保它看起来 像这样,重新构建,重新安装,然后瞧,它起作用了!
使其看起来漂亮
好吧,它可以工作了,但它并不漂亮。让我们做几件事来稍微修复它。
首先,我们可以添加一个自定义图标,以便我们的附加组件看起来不像所有其他没有设置其图标的附加组件……为此,我们在 manifest_version
行之后将以下内容添加到 manifest.json
中
"icons": {
"48": "icon.png",
"128": "icon128.png"
},
当然,我们需要下载一张漂亮的图片作为我们的图标,所以让我们将 这张图片 的副本保存为 icon.png
,并将 这张图片 保存为 icon128.png
。
我们还应该为按钮提供一个更漂亮的图标,所以回到 manifest.json
,让我们在 browser_action
块中的 default_title
之前添加以下几行
"default_icon": {
"19": "button.png",
"38": "button38.png"
},
并将 此图像 保存为 button.png
,并将 此图像 保存为 button38.png
。
最后,我们需要告诉我们的构建脚本有关新文件的信息,因此将 gulpfile.js
的 files
行更改为
var files = ['manifest.json', 'background.js', '*.png'];
重新运行构建,并重新安装附加组件,然后 我们完成了!😀
还有一件事……
好吧,我们还可以尝试做另一件事。我的意思是,我们有一个在 Firefox 中完美运行的附加组件,但新 WebExtension API 的优点之一是您可以在 Firefox 和 Chrome 上运行相同的附加组件(或具有最少更改的附加组件)。所以让我们看看在两个浏览器上运行它需要做些什么!
我们将首先启动 Chrome,并尝试加载附加组件,看看它会给我们什么错误。要加载我们的扩展程序,我们需要转到 chrome://extensions/
,并选中“开发者模式”复选框,如下所示
然后,我们可以单击“加载解压的扩展程序...”按钮,并选择我们的目录以加载我们的附加组件!哦,看来我们遇到了错误。
由于 applications
密钥是 Firefox 所必需的,所以我认为我们可以安全地忽略此错误。无论如何,该按钮出现了!当我们点击它时……
所以,我想我们完成了!(我过去曾在此处有一个关于如何加载 babel.js 的部分,因为我使用的 Chrome 版本不支持 ES6 的 箭头函数,但显然他们已经升级了他们的 JavaScript 引擎,现在一切正常。😉)
最后,如果您有任何疑问或在遵循本教程时遇到任何问题,请随时在此处发表评论,或通过 电子邮件 或在 twitter 上与我联系!如果您在开发 WebExtensions 时遇到问题或有建设性反馈,团队将在 Discourse 论坛 上倾听。
24 条评论