首页
/ Web-Dev-For-Beginners 浏览器扩展第一课:从浏览器架构到碳排放追踪扩展的落地实战

Web-Dev-For-Beginners 浏览器扩展第一课:从浏览器架构到碳排放追踪扩展的落地实战

2026-09-06 13:02:37作者:邓越浪Henry

本文基于 Web-Dev-For-Beginners 仓库的浏览器扩展项目第一课 About the Browsers 展开,系统讲解浏览器的工作架构与扩展运行机制、扩展的安装与管理流程,并完整继承原课程中“碳排放追踪扩展(Carbon Trigger)”的界面构建实操——包括配置表单与结果视图的完整 HTML、构建工具链配置、npm install/npm run build 工作流程。读完本文,你将能够解释浏览器从 URL 到页面的完整处理链路、在开发者模式下加载本地扩展,并理解仓库中配套源码(表单类名、localStorage 持久化、消息通信)与本课界面代码之间的对应关系。

完成的 Carbon Trigger 浏览器扩展运行界面,展示区域碳排放与化石燃料占比

一、课程定位:为什么构建扩展前先要理解浏览器

浏览器扩展是运行在浏览器内部、用于增强浏览体验的“微型应用”。正如 5-browser-extension/README.md 中所述,本系列课程要构建的扩展可在 Edge、Chrome 和 Firefox 中运行:它会查询 CO2 Signal API,获取指定区域的电力碳排放强度与化石燃料占比,把“当前区域的碳足迹读数”直接呈现在浏览器工具栏里——比如据此判断是否应该推迟运行烘干机等高耗电活动。

原课程在开篇给出了一个关键观点:在构建第一个扩展之前,必须先理解浏览器本身如何工作。扩展并不是独立于浏览器运行的程序,而是嵌入浏览器既有系统的“插件”,只有理解了渲染引擎、JavaScript 引擎、网络栈、存储 API 与安全模型,才能做出与浏览器系统无缝集成的扩展。原课程用一张思维导图概括了浏览器架构的四大板块:

mindmap
  root((Browser Architecture))
    Core Components
      Rendering Engine
      JavaScript Engine
      Network Stack
      Storage APIs
    User Interface
      Address Bar
      Tab Management
      Bookmarks
      Extension Icons
    Extension System
      Manifest Files
      Content Scripts
      Background Pages
      Popup Windows
    Security Model
      Same-Origin Policy
      Permissions API
      Content Security
      Isolated Worlds
    Development Tools
      DevTools Integration
      Debug Console
      Performance Monitor
      Extension Inspector

历史上早期浏览器的界面截图合集

一个历史细节值得记住:世界上第一个浏览器 WorldWideWeb 由 Tim Berners-Lee 于 1990 年创建。早期浏览器只是“文档解释器”,而现代浏览器已经演化为集渲染引擎、JS 引擎、网络栈与扩展系统于一体的复杂平台。

二、浏览器如何处理网页内容

当你输入 URL 并回车后,浏览器在数秒内完成一系列协调操作。原课程给出的时序图(保留了扩展的介入点)如下:

sequenceDiagram
    participant User
    participant Browser
    participant Extension
    participant DNS
    participant Server

    User->>Browser: Types URL and presses Enter
    Browser->>Extension: Trigger beforeRequest event
    Extension->>Extension: Check if URL needs modification
    Browser->>DNS: Looks up server IP address
    DNS->>Browser: Returns IP address
    Browser->>Server: Requests web page content
    Server->>Browser: Sends HTML, CSS, and JavaScript
    Browser->>Extension: Trigger beforeResponse event
    Extension->>Extension: Modify content in case
    Browser->>User: Renders complete web page
    Extension->>User: Show extension UI updates

这个流程完成了五件事:

  1. DNS 解析:通过 DNS 查询把人类可读的 URL 翻译成服务器 IP 地址;
  2. 建立连接:使用 HTTP/HTTPS 协议与服务器建立(加密)连接;
  3. 发起请求:向服务器请求具体的页面内容;
  4. 接收资源:获取 HTML 标记、CSS 样式与 JavaScript 代码;
  5. 渲染:将全部内容解析并渲染成你看到的交互式网页。

原课程还强调了一个容易被初学者忽略的点:扩展可以在多个环节介入。时序图中的 beforeRequestbeforeResponse 事件钩子表明,扩展既可以在请求发出前修改 URL,也可以在响应返回后改写内容,最后再更新自己的工具栏 UI。这就是“理解浏览器链路 → 找到扩展集成点”的方法论。

快速自检:能否完整走一遍“输入 URL → 看到网页”的路径?标准答案是:DNS 查询 → HTTP 请求 → 解析 HTML/CSS/JS → 渲染 → 扩展在多个步骤上可修改内容。

浏览器的核心特性与扩展机会

现代浏览器提供了大量可被扩展开发者利用的能力,原课程以表格形式总结了特性、用途与对应的扩展机会:

特性 用途 扩展机会
渲染引擎(Rendering Engine) 展示 HTML、CSS 与 JavaScript 内容修改、样式注入
JavaScript 引擎 执行 JavaScript 代码 自定义脚本、与 API 交互
本地存储(Local Storage) 在本地保存数据 用户偏好、缓存数据
网络栈(Network Stack) 处理网络请求 请求监控、数据分析
安全模型(Security Model) 保护用户免受恶意内容侵害 内容过滤、安全增强

理解这些特性的价值在于:识别扩展最能创造价值的切入点、为功能选择合适的浏览器 API、设计出与浏览器系统高效协作的扩展,并确保扩展遵循浏览器安全最佳实践。

本课程的实践项目正是多个特性的组合运用:表单界面(渲染引擎 + JS 引擎)、API Key 与区域码的持久化(本地存储)、调用 CO2 Signal API(网络栈)。后一节课 Forms and local storage 会专门深入表单与本地存储的实现。

三、跨浏览器开发的考量

不同浏览器对同一标准的实现存在细微差异——Chrome、Firefox 与 Safari 各有独特的行为,扩展开发者必须在开发时予以考虑。原课程给出的四条关键建议:

  • 测试:在 Chrome、Firefox 与 Edge 中测试你的扩展;
  • 适配:适配不同浏览器的扩展 API 与 manifest 格式差异;
  • 处理:不同的性能特征与限制;
  • 兜底:为某些浏览器不支持的特性提供回退方案。

实践提示:可以使用 caniuse.com 这类兼容性查询站点来确认目标浏览器对某项 Web 技术的支持情况。此外,如果你在产品中安装了统计组件,可以据此了解用户偏好的浏览器分布,从而决定优先支持哪些浏览器。

四、扩展的安装与管理:开发者模式加载流程

理解安装流程,有助于你预判用户安装扩展时的体验。各现代浏览器的安装流程基本标准化,仅在界面细节上有差异。以 Edge 为例:打开 edge://extensions 页面后,必须打开“开发者模式”开关,才能使用“加载解压缩的扩展(Load Unpacked)”功能。

Edge 浏览器中打开的 edge://extensions 页面,显示扩展管理面板与开发者模式设置

注意:测试自己开发的扩展时,务必开启开发者模式,并允许安装来自其他商店的扩展。

开发期扩展的安装工作流

原课程给出的完整工作流如下:

flowchart TD
    A[Write Code] --> B[Build Extension]
    B --> C{First Install?}
    C -->|Yes| D[Load Unpacked]
    C -->|No| E[Reload Extension]
    D --> F[Test Functionality]
    E --> F
    F --> G{Working Correctly?}
    G -->|No| H[Debug Issues]
    G -->|Yes| I[Ready for Users]
    H --> A
    I --> J[Publish to Store]

对应的命令与操作步骤:

# Step 1: 构建你的扩展
npm run build

该命令完成的事情:把源码编译为浏览器可用的文件、将 JS 模块打包成优化后的产物、在 /dist 文件夹中生成最终扩展文件、为安装与测试做好准备。

Step 2:打开浏览器扩展管理页。点击右上角“设置及其他”按钮(... 图标),从下拉菜单中选择“Extensions(扩展)”。

Step 3:加载扩展

  • 首次安装:选择 load unpacked(加载解压缩的扩展),选中项目的 /dist 文件夹;
  • 更新:在已安装的扩展旁点击 reload(重新加载);
  • 测试:开启 “Developer mode”(开发者模式)以解锁更多调试功能。

说明:以上流程仅针对自己构建的扩展。安装已发布的扩展应前往官方扩展商店(如 Microsoft Edge Add-ons 商店)。

三类安装方式的区别值得记牢:

  • 开发期安装(development installations):用于测试尚未发布的扩展;
  • 商店安装(store installations):提供经过审核、支持自动更新的已发布扩展;
  • 侧载安装(sideloading):允许从官方商店之外安装扩展,前提同样是开启开发者模式。

五、实战项目:构建碳排放追踪扩展(Carbon Trigger)

本课的实践目标:构建一个展示你所在区域能源使用碳足迹的浏览器扩展。它既是扩展开发的完整入门,也是一个有现实意义的环境工具。

扩展运行后在浏览器工具栏中的效果示意

项目前置资源

开发前需要准备两类资源:

  • CO2 Signal API Key:向 CO2 Signal 官方站点提交邮箱即可获取免费 API Key;
  • 区域代码(Region code):通过 Electricity Map 查询你所在区域的代码(例如波士顿使用 US-NEISO);
  • Node.js 与 NPM:用于安装项目依赖的包管理工具;
  • 起步代码:仓库中的 start 文件夹,下载后即可开始开发。

安全提醒:API Key 等敏感凭据绝不能提交到代码仓库,原课程建议在安全的笔记中记录这些值以便开发时随时取用,并在后续步骤中演示安全的处理方式。

环境要求与依赖验证(结合仓库源码)

start/package.json 可以看到该项目的真实环境约束与依赖构成:

{
  "name": "carbon-trigger-extension",
  "version": "1.0.0",
  "engines": {
    "npm": ">=9.0.0",
    "node": ">=18.0.0"
  },
  "scripts": {
    "watch": "webpack --watch",
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^5.105.0",
    "webpack-cli": "^5.1.4"
  },
  "dependencies": {
    "axios": "^1.15.0"
  }
}

由此可确认三个实操要点:

  1. 环境前提:Node.js ≥ 18 且 npm ≥ 9,否则 npm install 可能失败;
  2. 构建脚本npm run build 实际执行的就是 webpack;仓库额外提供了 npm run watchwebpack --watch),修改源码后可自动重新打包,适合开发期使用;
  3. 运行时依赖axios 是唯一的运行时依赖,用于在扩展中发起 API 请求(下一节结合 solution 代码验证)。

项目结构

原课程给出的项目结构及每个文件的职责如下:

project-root/
├── dist/                    # 构建产物
│   ├── manifest.json        # 扩展配置
│   ├── index.html           # 用户界面标记
│   ├── background.js        # 后台脚本功能
│   └── main.js              # 编译后的 JavaScript 包
├── src/                     # 源码开发文件
│   └── index.js             # 你的主要 JavaScript 代码
├── package.json             # 项目依赖与脚本
└── webpack.config.js        # 构建配置
  • manifest.json:定义扩展的元数据、权限与入口点;
  • index.html:创建用户点击扩展图标时出现的界面;
  • background.js:处理后台任务与浏览器事件监听;
  • main.js:构建过程结束后包含最终打包的 JavaScript;
  • src/index.js:存放你的主开发代码,会被编译进 main.js

需要说明的是:从仓库实际结构看,startsolution 文件夹只包含 src/index.jspackage.json 等源文件,dist/ 目录(manifest.json、index.html、background.js、main.js)是执行 npm run build 后由 Webpack 生成的构建产物,不属于仓库提交内容。

起步代码 start/src/index.js 是一个带编号注释的空骨架(form fields → results divs → initial checks → listeners → API call),提示你按“DOM 查询 → 初始化检查 → 事件监听 → API 调用”的顺序填充逻辑。

构建配置表单(Setup View)

扩展采用双屏结构:首次使用时展示配置界面,配置完成后展示结果界面。原课程要求在 /dist/index.html 中加入如下表单:

<form class="form-data" autocomplete="on">
    <div>
        <h2>New? Add your Information</h2>
    </div>
    <div>
        <label for="region">Region Name</label>
        <input type="text" id="region" required class="region-name" />
    </div>
    <div>
        <label for="api">Your API Key from tmrow</label>
        <input type="text" id="api" required class="api-key" />
    </div>
    <button class="search-btn">Submit</button>
</form>

这段表单的要点:

  • 建立语义化的表单结构,label 与 input 正确关联(可访问性);
  • autocomplete="on" 启用浏览器自动填充,改善录入体验;
  • 两个字段均带 required 属性,未填写时无法提交;
  • 使用描述性类名(.form-data.region-name.api-key.search-btn)便于后续样式定位与 JS 选择。

这些类名不是随意起的——在完整实现 solution/src/index.js 中可以一一对应:

// form fields
const form = document.querySelector('.form-data');
const region = document.querySelector('.region-name');
const apiKey = document.querySelector('.api-key');

构建结果展示区(Results View)

在表单下方加入结果区结构:

<div class="result">
    <div class="loading">loading...</div>
    <div class="errors"></div>
    <div class="data"></div>
    <div class="result-container">
        <p><strong>Region: </strong><span class="my-region"></span></p>
        <p><strong>Carbon Usage: </strong><span class="carbon-usage"></span></p>
        <p><strong>Fossil Fuel Percentage: </strong><span class="fossil-fuel"></span></p>
    </div>
    <button class="clear-btn">Change region</button>
</div>

各部分职责:

  • .loading:API 数据拉取期间展示加载提示;
  • .errors:API 调用失败或数据非法时展示错误信息;
  • .data:存放原始数据,便于开发期调试;
  • .result-container:向用户展示格式化后的碳排放信息;
  • .clear-btn:允许用户更换区域、重新配置扩展。

solution 代码揭示了这套结构背后的完整状态机:init() 启动时先从 localStorage 读取 apiKeyregion,若缺失则显示表单、隐藏结果区;若已存在则直接进入数据拉取流程。表单提交后 setUpUser() 把配置写入 localStorage,让配置在后续会话中持续有效。reset()(即 “Change region” 按钮)会执行 localStorage.removeItem('region') 并重新 init()。错误处理上,displayCarbonUsage() 在请求失败时会隐藏加载与结果区,并在 .errors 中写入 “Sorry, data unavailable for the selected region.”——这解释了为什么结果区必须预留独立的错误容器。

值得前瞻的一个细节:solution 中还通过 chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } }) 把碳强度映射成的颜色传给后台脚本,让工具栏图标随碳排放高低变色(色标为 0/150/600/750/800 克对应的绿色到深棕色)。这正是下一课 Background tasks and performance 要展开的后台任务主题,本课的界面代码为此预留了数据结构。

安装依赖并测试构建

npm install

安装过程完成的工作:下载 package.json 中声明的 Webpack 等开发依赖、配置构建工具链、为扩展构建与测试做好准备、启用代码打包、优化与跨浏览器兼容能力。

构建流程要点:Webpack 会把 /src/index.js 打包成 /dist/main.js,这个过程对代码做生产级优化并保证浏览器兼容性。

此时就可以进行第一轮验证:

  1. 运行 npm run build 编译代码;
  2. 以开发者模式把扩展加载进浏览器;
  3. 确认表单正常展示且观感专业;
  4. 检查所有表单元素对齐、功能正常。

到此你已完成扩展开发第一阶段:搭好了界面 HTML 骨架、创建了配置与结果两套语义化 UI、建立了行业标准工具链(Webpack + NPM),并为下一步加入交互 JS 铺好了路。

六、挑战与作业

原课程布置了两类练习:

Copilot Agent 挑战:为扩展的表单加入验证与反馈功能——编写 JS 校验函数,检查 API Key 字段至少 20 个字符、区域码符合 US-NEISO 这类格式;通过把输入框边框改为绿色(合法)/红色(非法)提供视觉反馈;并加入显示/隐藏 API Key 的开关以增强安全性。

动手挑战:到扩展商店安装一个扩展,研究它的文件结构,看看你能发现什么(例如 manifest 声明的权限、打包后的脚本形态)。

本课的正式作业是 Restyle Your Browser Extension:为扩展建立独特的视觉身份,围绕配色(环境主题 + 对比度无障碍)、字体(小尺寸下可读、明暗主题均可用)、布局间距三个维度修改 CSS,并按“分析现有设计 → 设计自定义样式 → 实现 → npm run build 加载测试”的流程迭代,最终提交修改后的 CSS、多状态截图与设计决策说明。作业文档中还给出了 .form-data.result-container 两个选择器的样式起点示例,以及基础/进阶/高阶三档创意挑战与四维评分表(视觉设计、功能、代码质量、可访问性)。

学习路径速览

原课程还给出了由短到长的学习清单,可用作进度自查:

  • 5 分钟内可做:打开 chrome://extensions 探索已装扩展;在 DevTools Network 面板观察页面加载;用 Ctrl+U 查看页面源码;选中任意元素在 DevTools 中修改 CSS;
  • 1 小时内可做:完成课后测验;手写一个基础 manifest.json;构建一个弹出 Hello World 的最小扩展;在开发者模式下测试加载;
  • 1 周内:完成一个有实用价值的功能扩展;理解 content scripts、background scripts 与 popup 交互;掌握 storage、tabs、messaging 等浏览器 API;
  • 1 个月:构建多个解决不同问题的扩展;进阶浏览器 API 与安全实践;向开源扩展项目贡献代码;精通跨浏览器兼容与渐进增强。

七、小结

这一课建立了三条主线:其一,浏览器是“渲染引擎 + JS 引擎 + 网络栈 + 存储 + 安全模型”的组合体,扩展在请求、响应、渲染等多个环节存在集成点;其二,开发期扩展通过 npm run build 生成 dist 产物,再经开发者模式的 “Load Unpacked / Reload” 循环进行快速迭代,仓库中 npm run watch 脚本可进一步降低该循环成本;其三,碳排放扩展的双屏 UI(配置表单 + 结果区)以语义化类名把 HTML 结构与 JS 逻辑解耦,为后续课程接入 localStorage 持久化、API 调用与后台图标更新做好了铺垫。下一课 Forms and local storage 将把表单提交、API 请求与本地存储串成完整的交互闭环。

登录后查看全文
热门项目推荐
相关项目推荐