如何构建 Chrome 扩展程序

Avatar of Sarah Drasner
Sarah Drasner

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

这个周末我创建了一个 Chrome 扩展程序,因为我发现自己一遍遍地执行相同的任务,并且想要将其自动化。此外,我是一个宅在家里躲避疫情的书呆子,所以我把积攒的能量都用在了构建东西上。这些年来我创建了一些 Chrome 扩展程序,希望这篇文章也能帮助你入门。让我们开始吧!

创建清单文件

第一步是在项目文件夹中创建一个 manifest.json 文件。它的作用类似于 package.json,它为 Chrome 网上应用店提供有关项目的重要信息,包括名称、版本、所需的权限等。以下是一个示例

{
 "manifest_version": 2,
 "name": "Sample Name",
 "version": "1.0.0",
 "description": "This is a sample description",
 "short_name": "Short Sample Name",
 "permissions": ["activeTab", "declarativeContent", "storage", "<all_urls>"],
 "content_scripts": [
   {
     "matches": ["<all_urls>"],
     "css": ["background.css"],
     "js": ["background.js"]
   }
 ],
 "browser_action": {
   "default_title": "Does a thing when you do a thing",
   "default_popup": "popup.html",
   "default_icon": {
     "16": "icons/icon16.png",
     "32": "icons/icon32.png"
   }
 }
}

您可能会注意到一些内容 - 首先:名称描述可以是您想要的任何内容。

权限取决于扩展程序需要执行的操作。在本例中,我们有 ["activeTab", "declarativeContent", "storage", "<all_urls>"],因为此特定扩展程序需要有关活动选项卡的信息,需要更改页面内容,需要访问 localStorage,并且需要在所有网站上处于活动状态。如果它只需要在一个网站上处于活动状态,我们可以删除该数组的最后一个索引。

可以在 Chrome 的扩展程序文档中找到所有权限及其含义的列表 Chrome 扩展程序文档

"content_scripts": [
  {
    "matches": ["<all_urls>"],
    "css": ["background.css"],
    "js": ["background.js"]
  }
],

content_scripts 部分设置扩展程序应处于活动状态的站点。如果您想要一个单独的站点,例如 Twitter,则应输入 ["https://twitter.com/*"]。CSS 和 JavaScript 文件是扩展程序所需的一切。例如,我的 高效 Twitter 扩展程序 使用这些文件来覆盖 Twitter 的默认外观。

"browser_action": {
  "default_title": "Does a thing when you do a thing",
  "default_popup": "popup.html",
  "default_icon": {
    "16": "icons/icon16.png",
    "32": "icons/icon32.png"
  }
}

browser_action 中的一些内容也是可选的。例如,如果扩展程序不需要弹出窗口来实现其功能,则可以删除 default_titledefault_popup。在这种情况下,只需要扩展程序的图标。如果扩展程序仅在某些站点上有效,则 Chrome 会在它处于非活动状态时将其图标灰显。

调试

清单文件、CSS 和 JavaScript 文件准备就绪后,请从浏览器的地址栏访问 chrome://extensions/ 并启用开发者模式。这将激活“加载未打包”按钮以添加扩展程序文件。还可以切换开发版本扩展程序是否处于活动状态。

我强烈建议此时开始一个 GitHub 存储库来对文件进行版本控制。这是保存工作的好方法。

更新扩展程序时,需要从此界面重新加载它。屏幕上会显示一个小的刷新图标。此外,如果扩展程序在开发过程中出现任何错误,它也会在此处显示一个带有堆栈跟踪和更多信息的错误按钮。

如果扩展程序需要使用从扩展程序图标弹出的弹出窗口,那么幸运的是,这非常简单。在清单文件中使用 browser_action 指定文件名称后,可以使用您喜欢的任何 HTML 和 CSS 构建页面,包括图像(我倾向于使用内联 SVG)。

我们可能希望向弹出窗口添加一些功能。这可能需要一些 JavaScript,因此请确保在清单文件中指定了 JavaScript 文件,并在您的弹出窗口文件中也链接了它,如下所示:<script src="background.js"></script>

在该文件中,首先创建功能,我们将能够访问弹出窗口 DOM,如下所示

document.addEventListener("DOMContentLoaded", () => {
 var button = document.getElementById("submit")

 button.addEventListener("click", (e) => {
   console.log(e)
 })
})

如果我们在 popup.html 文件中创建一个按钮,为其分配一个名为 submit 的 ID,然后返回一个控制台日志,您可能会注意到实际上没有在控制台中记录任何内容。这是因为我们处于不同的上下文中,这意味着我们需要右键单击弹出窗口并打开一组不同的 DevTools。

Showing the "Inspect" option to open DevTools after right-clicking on an element on the page.

我们现在可以访问日志记录和调试了!但请记住,如果在 localStorage 中设置了任何内容,则它将仅存在于扩展程序的 DevTools localStorage 中;而不是用户的浏览器 localStorage 中。(我第一次尝试时就遇到了这个问题!)

在扩展程序外部运行脚本

这都很好,但是假设我们想要运行一个可以访问当前选项卡信息的脚本?以下是如何执行此操作的几种方法。我通常会在 DOMContentLoaded 事件侦听器内部调用一个单独的函数

示例 1:激活文件

function exampleFunction() {
 chrome.tabs.executeScript(() => {
   chrome.tabs.executeScript({ file: "content.js" })
 })
}

示例 2:执行少量代码

如果只有少量代码需要运行,这种方法非常不错。但是,由于它需要将所有内容作为字符串或模板字面量传递,因此很快就会变得难以处理。

function exampleFunction() {
 chrome.tabs.executeScript({
   code: `console.log(‘hi there’)`
  })
}

示例 3:激活文件并传递参数

请记住,扩展程序和选项卡在不同的上下文中运行。这使得在它们之间传递参数变得并非易事。我们在这里要做的是嵌套前两个示例,将一些代码传递到第二个文件中。我将所有需要的内容存储在一个选项中,但我们需要将对象字符串化才能使其正常工作。

function exampleFunction(options) {
 chrome.tabs.executeScript(
   { code: "var options = " + JSON.stringify(options) },
   function() {
     chrome.tabs.executeScript({ file: "content.js" })
   }
 )
}

图标

即使清单文件只定义了两个图标,我们还需要另外两个才能正式将扩展程序提交到 Chrome 网上应用店:一个 128px 正方形的图标,以及我称为 icon128_proper.png 的图标,它也是 128px,但在图像边缘和图标之间有一点填充。

请记住,无论使用哪个图标,都需要在浏览器的亮模式和暗模式下看起来都很好。我通常在 Noun Project 上找到我的图标。

提交到 Chrome 网上应用店

现在,我们可以前往 Chrome 网上应用店开发者控制台 提交扩展程序!单击“新建项目”按钮,然后将压缩的项目文件拖放到上传器中。

然后,Chrome 会询问一些有关扩展程序的问题,并请求有关扩展程序中请求的权限以及为何需要这些权限的信息。友情提示:请求 “activeTab”“tabs” 权限需要更长时间的审查,以确保代码没有执行任何滥用行为。

就是这样!这应该可以让你开始构建 Chrome 浏览器扩展程序!🎉