编写您的第一个浏览器扩展教程 - 第 1 部分
本教程基于我在 2019 年纽约 Codeland 会议上举办的研讨会。
为了本教程的目的,我们将使用 Firefox,但大多数概念也适用于其他浏览器。
本教程的代码可以在这里找到
什么是浏览器扩展?
从最基本的形式来看,浏览器扩展只是一个 JavaScript 文件,它在您的浏览器中运行代码来修改/改善您的浏览体验。
你是否曾经浏览某个网页时,希望能够有所改进?也许是广告太多?也许是字体不好看?也许是配色太鲜艳?
无论如何,如果您希望看到的更改是可以在浏览器中发生的事情(即,它是前端的更改,不涉及任何后端),那么您很有可能可以编写浏览器扩展来完成它。
有些更改比其他更改更容易实现,但一般来说,如果更改是 Web 开发人员可以使用 JavaScript 实现的,那么您可能可以编写扩展来自己完成!
浏览器扩展的结构
浏览器扩展的大小和复杂程度各不相同,但本质上,它们都共享相同的基本模板。
这是一个简单的扩展:
sample-extension
└───images
│ └───icon-48.png
│ └───icon-96.png
│ └───image1.jpg
│ └───image2.jpg
│
└───manifest.json
└───sample-extnsion.js
该扩展位于我称为的文件夹中sample-extension
。
该扩展程序的核心是一个名为 的文件manifest.json
。清单是一个 JSON 文件,其中包含浏览器所需的信息,以便确定何时以及如何运行该扩展程序。我们稍后会仔细研究清单。
您的扩展的实际代码位于我调用的 JavaScript 文件中sample-extension.js
。
随着扩展变得越来越复杂,您可能希望将代码拆分成子目录中的多个文件,但这是一个相当简单的扩展。
最后,您希望包含的任何图像(包括用于在浏览器附加组件商店中推广扩展程序的图标)都可以放入我称为的子文件夹中images
。
責任表。
清单是扩展的核心;它决定了浏览器如何知道要运行哪些代码,以及何时以及如何运行它。
让我们看一个简单扩展的示例清单:
{
"manifest_version": 2,
"name": "<EXTENSION-NAME>",
"version": "1.0",
"description": "<A USEFUL DESCRIPTION>",
"icons": {
"48": "<URL TO AN ICON>",
"96": "<URL TO AN ICON>"
},
"content_scripts": [
{
"matches": ["<URL MATCHER>"],
"js": ["<RELATIVE PATH TO A JS FILE>"]
}
]
}
看起来很多!让我们看一下相关部分:
-
"name"
:是您的扩展程序的名称(用于将其列在您的浏览器的附加组件商店中)。 -
"version"
:是您的扩展程序的版本号。随着您的改进,您将不断增加此版本号,以确保用户运行的是最新版本。 -
"description"
:是有关您的浏览器功能的人类可读的描述,因此在附加组件商店中遇到它的人都知道它是什么。 -
"icons"
:您可以在此处提供将与您的扩展程序一起显示在附加组件商店中的图标(两种尺寸分别用于附加组件商店描述和缩略图)。 -
"content_scripts"
:这是清单的主要部分;它告诉浏览器要运行哪些代码以及何时运行。它包含两个键:"matches"
:采用扩展程序应运行的 URL 数组。"js"
:采用 JavaScript 文件的路径数组,当您的浏览器遇到中的一个 URL 时,它将运行这些文件"matches"
。
您还可以提供其他键来代表扩展程序可以执行的不同功能。它们列在这里。
现在我们已经掌握了所需的所有信息,让我们开始编码吧!
让我们开始吧!
你好 DEV!
我们将从我能想到的最简单的扩展开始,可以说是浏览器扩展的“Hello World”。
- 首先为我们的扩展创建一个目录。在终端中输入:
mkdir first-extension
cd first-extension
- 在目录中,
first-extension
让我们创建清单:
touch manifest.json
- 现在,使用您最喜欢的编辑器打开我们刚刚创建的清单并粘贴以下 JSON(我通常不喜欢从教程中复制/粘贴代码;我认为花时间输入内容可以建立肌肉记忆并更好地保留信息,但我不会让您自己输入所有这些 JSON):
{
"manifest_version": 2,
"name": "first-extension",
"version": "1.0",
"description": "Our very first browser extension!",
"content_scripts": [
{
"matches": ["*://*.dev.to/*"],
"js": ["first-extension.js"]
}
]
}
-
我们从之前看到的通用清单中更改的部分是:
- 我们添加了名称和描述。
- 我们摆脱了
icons
在扩展中不使用图标的关键。 - 我们给
matches
键提供了一个数组,其中包含 dev.to 的 URL,即我们的扩展程序将在其上运行的网站。- 三个星号是通配符,可以匹配:1)任何协议(HTTP 和 HTTPS),2)dev.to 的任何子域(例如 shop.dev.to),以及 3)dev.to 上的任何页面(例如https://dev.to/yechielk)。
- 我们给
js
键提供了一个包含文件名的数组,first-extension.js
该文件名是我们将为扩展编写代码的文件。
-
换句话说,我们的清单所说的是,当我们的浏览器访问任何与我们提供的模式匹配的 URL(即 dev.to 上的任何页面)时,它都应该运行文件中的代码
first-extension.js
。 -
此时,最好确认一下我们确实有一个
first-extension.js
文件。让我们回到终端:
touch first-extension.js
-
太棒了!现在(技术上)我们已经有了一个可以运行的浏览器扩展。
-
接下来我们需要做的是告诉我们的浏览器加载我们的扩展。
-
在 Firefox 中转到以下页面:“about:debugging”。
-
在右上角附近单击“加载临时附加组件...”按钮
-
导航到我们为扩展创建的文件夹并选择
manifst.json
文件。 -
您应该会看到我们的
first-extension
扩展出现在“临时扩展”下。
-
我们的扩展程序现已加载完毕,可以运行了。如果我们导航到 dev.to,浏览器就会执行 中的代码
first-extension.js
。当然,我们无法感知,因为中没有代码,first-extension.js
所以让我们来解决这个问题。 -
大多数人会放一个
console.log()
,看看他们是否可以在他们的控制台中看到一些东西,但我认为alert
更酷,所以让我们这样做吧! -
打开
first-extension.js
并添加以下内容:
alert("Hello DEV!")
-
如果刷新 dev.to ,什么也不会发生;我们的浏览器仍在运行我们加载的旧代码。每次修改代码后,我们都需要重新加载扩展程序。
-
回到“about:debugging”页面,查看我们加载的临时扩展。在底部附近应该有一个小链接,上面写着“Reload”。点击它,然后刷新 dev.to。你应该会看到我们的警告弹出!
- 恭喜!您现在有一个可以运行的浏览器扩展程序了!
故障排除
如果您无法弹出警报,甚至无法加载扩展程序,请仔细检查清单文件是否为有效的 JSON 文件,且没有语法错误(您可以使用jsonlint等在线验证工具来确保没有遗漏任何逗号等)。确保文件名中没有拼写错误,"js"
并且清单文件中的名称与文件的实际名称一致。
研讨会上,一些参与者遇到的一个问题是,他们忘记"icons"
从清单中删除该键。如果该键存在,而值又不是有效的文件路径,浏览器就会在尝试加载图标时崩溃。
退出 Twitter!
-
这很酷!不过,我们来写个真正有用的扩展吧。比如,在你上推特 10 分钟后,它会提醒你该休息一下,保持心理健康。
-
让我们回到清单并将
"matches"
密钥的值从 DEV website 更改为 Twitter:
"content_scripts": [
{
- "matches": ["*://*.dev.to/*"],
+ "matches": ["*://*.twitter.com/*"],
"js": ["first-extension.js"]
}
]
-
如果我们在“about:debugging”中重新加载扩展程序并访问 Twitter.com,我们应该会看到警报弹出。这只是为了确保一切正常。
-
让我们修改我们的
first-extension.js
以添加我们想要的功能。 -
我们可以使用 JavaScript 的内置
setInterval
函数,以设定的时间间隔运行回调函数。 -
该
setInterval
函数接受两个参数:一个要运行的函数,以及一个以毫秒为单位的运行间隔。 -
首先将间隔设置为 10 分钟。我们可以这样做:
const interval = 600000 // 600,000 milliseconds = 10 minutes
但我发现把间隔分解成各个组成部分会更易读。这样几周后再看代码时就更容易理解了:
const interval = 1000 * 60 * 10 // 1000ms = 1 second * 60 = 1 minute * 10 = 10 minutes
- 接下来,让我们编写一个每十分钟运行一次的函数。我们希望该函数能够弹出一个警告,提醒我们退出 Twitter。它应该如下所示:
function reminder() {
alert("Get off Twitter!")
}
- 现在我们已经准备好了所有需要的部分。剩下的就是把它们组合在一起,然后调用我们的
setInterval
函数:
setInterval(reminder, interval)
- 现在,我们已经有了一个可以执行所需操作的浏览器扩展。唯一的问题是,为了测试它,我们必须等待 10 分钟,所以
现在让我们将间隔改为 10 秒,而不是 10 分钟:
- const interval = 1000 * 60 * 10
+ const interval = 1000 * 10
-
让我们在“about:debugging”中重新加载我们的扩展并转到 Twitter.com。
-
如果我们等待 10 秒,我们就会看到警报弹出!
-
如果我们关闭警报,我们应该会在 10 秒后再次看到它弹出。
-
我们可以返回
first-extension.js
并将间隔切换回 10 分钟:
- const interval = 1000 * 10
+ const interval = 1000 * 60* 10
- 恭喜,我们完成了!
下一步是什么?
所以现在我们有了一个实际的、有用的浏览器扩展,但是当您想到有趣的浏览器扩展时,您想到的很可能是那些实际上改变网页内容的扩展。
浏览器扩展通过使用 DOM 操作(一类允许其与网页交互和操作网页的 JavaScript 函数)来实现这一点。
在本系列的第二部分中,我们将构建一个有趣的扩展,在尝试修复技术中损坏的招聘系统的同时,还包括猫!
文章来源:https://dev.to/yechielk/writing-your-first-browser-extension-part-1-d5e