☰
读懂 Carbon Trigger 浏览器扩展完整版代码:用 CO2 数据实时提醒区域用电强度
2026/10/11 17:02:48 网站建设 项目流程

读懂 Carbon Trigger 浏览器扩展完整版代码:用 CO2 数据实时提醒区域用电强度

【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners

这是一篇面向 Web 开发者与浏览器扩展初学者的技术解析,围绕微软开源课程仓库 Web-Dev-For-Beginners 中的 5-browser-extension 实战项目成品代码展开。文章将带你从零搭建并加载一款使用 tmrow 的 CO2 Signal API 追踪区域电力碳排放强度的 Chromium 浏览器扩展,并深入源码剖析"彩色圆点 + 实时数据面板"背后的实现原理,让你掌握 Manifest V3 扩展、webpack 构建、chrome.action API 与 localStorage 状态管理的完整套路。

一、扩展要解决什么问题

Carbon Trigger 是一款以"提醒"为核心的浏览器扩展:它调用 tmrow 的 CO2 Signal API,查询你所在区域当前的电力碳排放强度,并把结论以浏览器扩展栏里的一个彩色圆点直观呈现出来。绿色代表当前区域发电比较"清洁"、适合执行耗电任务;随着碳强度升高,圆点逐渐变深,提示你把高耗能工作延后。当你临时查看这个圆点时,就能基于真实数据决定"现在是否适合跑大型构建、渲染视频或执行其他能耗密集型任务"。

该"圆点"提示系统最初源自作者受加利福尼亚州排放监控工具 Energy Lollipop 扩展启发而引入的设计。

本仓库中该项目包含两个子目录:需要你动手补全的起步版 5-browser-extension/start,以及包含全部完成代码的成品版 5-browser-extension/solution。本文解析的对象是完成版 solution,其说明文档对应英文原版 solution README。

二、运行环境与前置条件

在开始之前,请确认本机已安装 Node.js 与 npm 包管理器。

关于版本要求,solution 的 package.json 中通过 engines 字段明确了最低运行环境:

"engines": { "npm": ">=9.0.0", "node": ">=18.0.0" }

同时可以注意到,该项目的构建工具链与依赖非常精简:

  • 开发依赖:webpack ^5.105.4、webpack-cli ^5.1.4,用于将 ES Module 源码打包为扩展可直接使用的产物;
  • 运行依赖:axios ^1.15.0,用于向后端 API 发起 HTTP 请求。

从源码结构来看,这是一个不需要 React/Vue 等框架、仅由原生 JS + axios + webpack 组成的轻量扩展项目,非常适合作为理解浏览器扩展数据流的第一课。

三、安装依赖并完成 webpack 构建

将 5-browser-extension/solution 目录的代码下载/复制到本地文件夹后,依次执行两条命令。

第一步,安装全部依赖:

npm install

第二步,通过 webpack 构建扩展:

npm run build

若希望在开发过程中监听文件变更并自动重新打包,可以改用 watch 脚本:

npm run watch

以上三个命令分别对应 package.json 中scripts段的test、watch与build配置。

构建完成后,会在 solution 目录下生成dist/文件夹,里面是浏览器可直接加载的完整扩展包。在当前仓库中该产物已被提交,你可以直接查看其内容,包含 5 个文件:

  • manifest.json —— 扩展清单,MV3 声明文件;
  • background.js—— 后台 service worker,负责响应图标更新消息;
  • main.js—— 由 src/index.js 打包生成的 popup 逻辑;
  • index.html—— 扩展弹出面板的页面结构;
  • styles.css—— 面板样式。

四、加载扩展到 Edge(或 Chromium 系浏览器)

构建出dist/之后即可把它安装进浏览器,以 Microsoft Edge 为例步骤如下:

  1. 打开浏览器,点击右上角"三点"菜单,找到Extensions(扩展)面板;
  2. 在扩展管理页开启"开发人员模式(Developer mode)";
  3. 点击Load Unpacked(加载解压缩的扩展);
  4. 在弹出的文件选择框中,定位并打开项目里的dist文件夹;
  5. 扩展随即被加载,工具栏会出现 Carbon Trigger 的图标。

从 manifest.json 可以看到它遵循 Manifest V3 规范:

{ "manifest_version": 3, "name": "My Carbon Trigger", "version": "0.1.0", "host_permissions": ["<all_urls>"], "background": { "service_worker": "background.js" }, "action": { "default_popup": "index.html" } }

各字段的作用分别是:

  • manifest_version: 3:采用最新的 MV3 标准,后台逻辑改用 service worker;
  • host_permissions: ["<all_urls>"]:声明扩展可以向任意域名发起跨域请求,这是它能调用 CO2 Signal 在线 API 的前提;
  • background.service_worker:注册后台脚本,用于响应 popup 发来的图标更新消息;
  • action.default_popup:点击工具栏图标时弹出index.html面板。

五、申请 API Key 与查询区域编码

扩展需要两类外部信息才能工作:API Key与区域编码。

  1. CO2 Signal API Key:打开 CO2 Signal 官网,在页面输入框中填写邮箱即可申请(官方以邮件形式发送 Key);
  2. 区域编码:需要找到你所在地区在 Electricity Map 上对应的电力区代码,可通过其官方 zones 接口(http://api.electricitymap.org/v3/zones)查询,区域 ID 形如US-NEISO(如波士顿地区即使用US-NEISO)、FR(法国)等。它是 API 请求中countryCode参数所期望的格式。

获取到这两项后,把它们输入扩展弹出面板中的对应表单并提交,扩展就会开始拉取数据。

六、源码剖析:从表单提交到彩色圆点

理解整条数据链路,只需跟随 src/index.js 的几个核心函数。

6.1 表单提交与本地持久化

handleSubmit拦截表单的 submit 事件,将用户填写的 apiKey 与 region 交给setUpUser。后者先通过localStorage.setItem把两项配置写入本地存储(这就是刷新后无需重新填写的机制),随即发起首次数据请求:

const setUpUser = async (apiKey, region) => { localStorage.setItem('apiKey', apiKey); localStorage.setItem('region', region); ... displayCarbonUsage(apiKey, region); };

6.2 拉取碳强度数据

displayCarbonUsage使用 axios 向https://api.co2signal.com/v1/latest发起 GET 请求,countryCode参数传入区域编码、auth-token请求头传入 API Key:

await axios .get('https://api.co2signal.com/v1/latest', { params: { countryCode: region }, headers: { 'auth-token': apiKey }, }) ...

拿到响应后,代码会先校验返回数据中是否真的包含carbonIntensity(碳强度)与fossilFuelPercentage(化石燃料发电占比)字段,缺失则抛出异常;随后把碳强度向下取整并交由calculateColor处理,同时在面板中渲染三条信息:

  • 当前区域名称(Region);
  • 碳用量:carbonIntensity的整数值 +grams C02 emitted per kilowatt hour(每千瓦时二氧化碳克数);
  • 化石燃料占比:fossilFuelPercentage.toFixed(2)+%(发电所用化石燃料百分比)。

若请求失败(例如区域代码不存在),则进入 catch 分支,在界面提示Sorry, data unavailable for the selected region.,并隐藏结果区域。

6.3 碳强度映射为圆点颜色

calculateColor是本扩展的核心设计。它预先定义了一组碳强度"刻度"与一组对应颜色:

let co2Scale = [0, 150, 600, 750, 800]; let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02'];

算法思路是:先把当前碳强度值与刻度数组逐一比较,找出最接近的刻度值;再依据该刻度值在数组中的位置,从颜色表中选取对应色值,最后把颜色通过消息发送给后台:

chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } });

即:碳强度越低,圆点越接近绿色#2AA364;中等强度映射为黄色#F5EB4D;较高强度逐渐过渡到深棕/深色#9E4229、#381D02——从源码结构看,高值区间共用最深色以表示"高碳强度、谨慎执行耗电任务"。

6.4 后台绘制图标

popup 里发送的消息由 dist/background.js 中的消息监听器接收。MV3 下扩展图标无法直接改用 CSS 颜色,因此后台代码使用OffscreenCanvas现场绘制一张纯色圆点图像,再调用chrome.action.setIcon更新工具栏图标:

chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { if (msg.action === 'updateIcon') { chrome.action.setIcon({ imageData: drawIcon(msg.value) }); } });

drawIcon在 200×200 的离屏画布上以指定颜色填充一个圆,再取其中 100×100 的区域作为图标位图——这即是"彩色圆点"会随区域用电强度实时变色的底层实现,注释表明该创意借鉴自 Energy Lollipop 扩展。

6.5 启动恢复与重置区域

init是扩展的入口逻辑:打开面板时先读取 localStorage,若尚未保存 apiKey/region,则显示填写表单;若已有历史配置,则隐藏表单并直接调用displayCarbonUsage恢复数据。同时无论哪种情况,启动时都会把图标先置为通用的绿色,表示"正常状态"。

面板底部的Change region(更换区域)按钮则触发reset:仅删除 localStorage 中的region键,随后重新执行init,让用户再次进入填写界面。若直接刷新浏览器页面,popup 会因 localStorage 持久化而保留上一次的配置与数据。

七、扩展使用体验小结

把 API Key 与区域代码输入扩展界面后,浏览器扩展栏中的彩色圆点会持续反映该区域的用电强度,并指导你何时适合执行高耗能活动。这一整套"表单配置 → localStorage 持久化 → 在线 API 拉取 → 颜色映射 → 后台图标重绘"的流程,完整覆盖了 MV3 扩展开发中最典型的数据与 UI 交互场景。

八、延伸学习路径

该扩展只是 Web-Dev-For-Beginners 课程仓库中 5-browser-extension 模块的阶段性成果。如果你想从头掌握相关知识,可以按顺序阅读该模块的系列课程,并结合起步代码亲手实现:

  • 关于浏览器:了解浏览器工作原理与扩展运行环境;
  • 表单、浏览器与本地存储:掌握表单取值、浏览器 API 与 localStorage 的使用,这正是本扩展配置持久化的基础;
  • 后台任务与性能:认识后台脚本、service worker 与性能优化,对应本扩展中监听消息、重绘图标的后台逻辑。

动手实践则建议以起步版 5-browser-extension/start 为模板,对照 完成版源码 逐行补齐src/index.js中缺失的函数——当你在浏览器里看到那个圆点随本地区域发电数据变绿、变黄、变深时,便意味着你已完整打通了从 API 数据到浏览器扩展 UI 的整条链路。

【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询