Web-Dev-For-Beginners 浏览器扩展项目(一):浏览器工作原理与「Carbon Trigger」扩展开发入门
【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners
本文基于 Web-Dev-For-Beginners 课程浏览器扩展模块的第一课「All about Browsers」(日文版位于 translations/README.ja.md)展开:先讲清浏览器为什么能获取并渲染网页、不同浏览器之间有何差异,再按照课程配套代码(start目录)完整演示如何用 npm + Webpack 构建一个显示本地碳足迹的浏览器扩展,并在 Edge 中以「加载已解压的扩展」方式安装运行。读完后你将能独立搭建扩展的双视图 HTML 界面(配置表单 + 结果展示)、跑通 Webpack 构建流程,并理解manifest.json中每个入口文件的作用。
为什么做扩展之前要先理解浏览器
浏览器扩展(Browser Extension)本质上是为浏览器添加功能的小型应用。这一系列课程的目标是构建能在 Chrome、Firefox、Edge 上运行的扩展,因此第一步必须理解浏览器本身的工作方式。
按照课程文档的定义,浏览器是让终端用户从服务器获取内容并显示为网页的软件应用。一点历史背景:最早的浏览器叫WorldWideWeb,由 Sir Tim Berners-Lee 于 1990 年创建。用户输入 URL(Uniform Resource Locator)地址访问互联网时,通常经由http或https地址(即超文本传输协议 HTTP/HTTPS)让浏览器与 Web 服务器通信并获取网页内容;随后浏览器的**渲染引擎(Rendering Engine)**负责在用户设备(手机、桌面、笔记本等)上把页面显示出来。
除渲染之外,浏览器还具备几项与扩展开发密切相关的核心能力:
- 缓存(Cache):浏览器会缓存内容,不必每次都从服务器重新获取;
- 历史记录(History):记录用户的浏览活动;
- Cookie:一类包含用户活动信息的小型数据,可用于保存用户状态。
课程特别强调:没有两个浏览器是完全一样的。每个浏览器各有优劣,专业的 Web 开发者必须理解如何让网页跨浏览器正常工作,包括适配手机这类小视口设备以及离线用户。因此,文档建议把「查询各浏览器对某项技术的支持情况」的 caniuse 站点加入书签;至于「你的用户到底在用哪些浏览器」,可以通过在 Web 开发流程中安装各种分析(Analytics)包来获知——它们会告诉你哪些浏览器在你的用户群体中最流行。这些判断直接决定了扩展开发时该优先支持哪个浏览器、该做哪些降级处理。
为什么要做浏览器扩展
文档给出的理由很务实:当你想快速访问那些反复执行的任务时,扩展就派上用场。典型例子包括:
- 需要频繁查看各种网页的配色时,安装一个**取色器(Color Picker)**类扩展;
- 懒得记密码时,使用密码管理器类扩展。
从源码结构看,这类扩展有一个共同特点:它们倾向于管理有限、边界清晰的单一任务,而这正是扩展形态成立的原因——不需要独立应用或复杂工作流,工具直接在浏览器界面里触手可及。文档也留了一个反思问题:你最喜欢的浏览器扩展是什么?它完成了什么任务?
扩展的构建与安装流程
在写代码之前,课程先走了一遍完整的构建—部署流程。各浏览器管理扩展的方式略有差异,但 Chrome 与 Firefox 的流程与文档中以 Edge 为例演示的过程类似。
核心流程只有四步:
- 用
npm构建扩展(仓库中对应的脚本见下文,实际命令为npm run build,文档简写为npm build); - 点击浏览器右上角的「设置与更多」按钮(
...图标),进入扩展管理页(Edge 为edge://extensions); - 首次安装:选择
load unpacked(加载已解压的扩展),上传构建产物文件夹——本项目是/dist目录; - 更新已安装的扩展:点击对应扩展的
reload重新加载即可。
对于已发布到商店的扩展,则直接前往各浏览器对应的扩展商店安装(如 Microsoft Edge 扩展商店),那里提供经过审核、带自动更新的正式版本;而load unpacked这类「侧载」方式仅用于开发阶段测试自己未发布的扩展。
仓库中的构建配置佐证
start目录的 package.json 完整定义了这套构建流程:
- 环境要求(engines):
npm >= 9.0.0、node >= 18.0.0; - 脚本(scripts):
"build": "webpack"与"watch": "webpack --watch"——npm run build执行一次性构建,npm run watch则监听源码变化自动重建,适合开发期反复调试; - 依赖(devDependencies):
webpack ^5.105.0、webpack-cli ^5.1.4;运行时依赖(dependencies)仅有axios ^1.15.0,供后续课程调用 CO2 Signal API 使用。
也就是说,「构建扩展」这一步的实质是:Webpack 把src/index.js编译、打包成浏览器可直接加载的dist/main.js。
manifest.json:扩展的身份证
start目录已预置了构建产物 dist/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" } }逐字段对照仓库文件:
"background": { "service_worker": "background.js" }:声明后台脚本 background.js。Manifest V3 用 Service Worker 取代旧版的后台页;起步代码中它目前只有两行注释(//add listener here和//draw the icon here),留给后续课程填充;"action": { "default_popup": "index.html" }:点击扩展工具栏图标时弹出的页面,即 index.html,也就是本课程的「主界面」;"host_permissions": ["<all_urls>"]:授予扩展对任意来源网络的访问权限——这是后续调用外部 CO2 Signal API 的前提,也是课程后续「后台任务与性能」一课会重点审视的点;- 预置的 index.html 中已经留好了两处占位注释
<!--form area-->与<!--result area-->,并引入styles.css与main.js(当前main.js是 0 字节空文件,等待 Webpack 构建产物填充)。
项目准备:动手前需要的四样东西
课程要构建的扩展是一个「Carbon Trigger」:显示你所在地区电力使用的碳足迹与能源构成,帮助你在高碳时段对能耗较大的活动做出判断。开始前需要准备:
| 所需资源 | 获取方式 |
|---|---|
| API Key | 在 CO2 Signal 官方页面填写邮箱免费领取 |
| 地区代码 | 查电力地图(Electricity Map)对应你所在地区的 zone 代码,例如波士顿使用US-NEISO |
| 起步代码 | 下载本仓库的 start 目录(5-browser-extension/start/README.md 有完整说明),所有代码都将在该文件夹中完成 |
| NPM | 包管理工具;本地安装后依据package.json安装项目依赖并供 Web 资产使用 |
文档提醒:拿到 API Key 和地区代码后,先记到笔记的某个地方备用——后面测试扩展功能时马上会用到。另外注意安全惯例:不要把 API Key 等敏感凭据提交到代码仓库(课程后续会用浏览器本地存储来管理它,见下文「参考答案」部分)。
项目结构:dist 与 src 的分工
文档给出的结构如下(结合start目录实际内容补全):
start/ ├── package.json # 项目依赖与 build/watch 脚本 ├── src/ │ └── index.js # 你的 JS 代码写在这里 └── dist/ # 作为扩展加载的默认文件夹 ├── manifest.json # 扩展配置(见上文) ├── index.html # 前端 HTML 标记(含 form/result 占位) ├── background.js # 后台 Service Worker ├── main.js # Webpack 构建产物(初始为空文件) ├── styles.css # 预置样式(基于 Basic.css 风格,含暗色模式适配) └── images/ # 弹窗页头图等图片资源各文件的职责:
manifest.json:定义扩展元数据、权限与入口点;index.html:用户点击扩展图标时呈现的界面(popup);background.js:处理后台任务与浏览器事件监听(MV3 Service Worker);main.js:构建后的最终打包 JS——执行npm run build后打开这个文件,就能看到你的源码被打包(bundle)后的样子;src/index.js:你的开发代码所在地,编译后变成main.js。
起步代码 start/src/index.js 目前是一个 17 行的编号骨架,按注释编号标出了六段待填逻辑:
//1 // form fields // results divs //6 //call the API //5 //set up user's api key and region //4 // handle form submission //3 initial checks //2 // set listeners and start app这正是后续课程的填空路线图:先拿到表单与结果区元素(1)、绑定监听并启动应用(2)、做初始检查(3)、处理表单提交(4)、保存用户的 API Key 与地区(5),最后调用 API(6)。
构建扩展的 HTML:表单与结果区
这个扩展有两个视图:一个用于收集 API Key 与地区代码(首次配置),另一个用于展示地区碳使用量(即文首两张截图)。文档要求在 dist/index.html 的<!--form area-->与<!--result area-->占位处写入以下标记。
配置表单
<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>这是一个把配置信息写入本地存储(localStorage)的表单。结构上值得注意的细节:
<label for="...">与id一一关联(region/api),保证可访问性;- 两个输入框都带
required属性,浏览器原生校验会阻止空值提交; class="form-data"、class="region-name"、class="api-key"是后续 JS 定位元素的钩子——对照完成版 solution/src/index.js,它正是用document.querySelector('.form-data')、'.region-name'、'.api-key'取出这三个元素,所以类名就是前后端的接口契约,写错类名后面全部对不上。
结果展示区
在表单之后追加结果区:
<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 数据期间显示「loading...」,成功后display: none |
.errors | API 调用失败或数据缺失时显示错误信息 |
.data | 开发期保留的原始数据调试位 |
.result-container | 最终呈现格式化结果(.my-region、.carbon-usage、.fossil-fuel三个<span>由 JS 填充文本) |
.clear-btn | 「Change region」按钮,允许用户重置配置、更换地区 |
对照 solution/src/index.js 可以看到,.loading、.errors、.result-container、.carbon-usage、.fossil-fuel、.my-region、.clear-btn全部通过querySelector取出,与上面每个类名一一对应。
安装依赖并构建
写入 HTML 后,按文档执行第一次构建:
npm install这条命令依据package.json安装扩展构建所需的依赖:Webpack 等开发依赖与运行时的axios。安装完成后执行构建(npm run build,即package.json中"build": "webpack"脚本):Webpack 会把src/index.js编译打包,产物写入/dist/main.js——打开该文件即可看到源码被 bundle 后的结果。
此时把扩展构建产物加载进 Edge(首次load unpacked选择/dist,之后改完代码重新构建再reload),就能看到表单被预置的 styles.css 干净地渲染出来——该样式表自带 CSS 变量主题与prefers-color-scheme: dark暗色模式适配,扩展弹窗会跟随系统深浅色切换。这一步就迈出了构建浏览器扩展的第一脚,后续课程将在此基础上让它变得真正可用。
完成版是如何运转的(供对照参考)
5-browser-extension/solution/src/index.js 完整实现了骨架中六段逻辑,可以作为学习完全部课程后的对照标准:
init()(L89-L116):启动时从localStorage读取apiKey与region。两者缺失则显示配置表单(视图一);已存在则跳过表单直接拉取数据(视图二)——这正是「两个视图」切换的机制;displayCarbonUsage(apiKey, region)(L34-L68):用axios请求https://api.co2signal.com/v1/latest,以countryCode参数传入地区代码、请求头auth-token携带 API Key;返回后校验carbonIntensity与fossilFuelPercentage字段,分别渲染为「克 CO2/千瓦时」与「化石燃料发电占比」,失败时把错误写进.errors;calculateColor(value)(L17-L32):把碳强度映射到色阶[0, 150, 600, 750, 800]与五色数组['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02'](绿→黄→棕→深棕),再通过chrome.runtime.sendMessage({ action: 'updateIcon', ... })把颜色发给后台脚本,由 background.js 绘制工具栏图标上的彩色圆点——这就是 start/README.md 中「彩色圆点」概念的实现(该创意源自 Energy Lollipop 扩展);reset(e)(L118-L123):「Change region」按钮只清除localStorage中的region(保留 API Key),再走一次init()。
注意一个关键的安全实践:API Key 与地区代码通过localStorage.setItem('apiKey' / 'region', ...)存在浏览器本地(L72-L74),而不是硬编码进src/index.js随仓库分发——这呼应了课程「永远不要把 API Key 提交进代码仓库」的提醒。
挑战、作业与延伸阅读
- 挑战:去浏览器扩展商店安装一个扩展,研究它的文件组织方式——你能从它的
manifest.json和打包产物里发现什么?(安装过程本身就是一次对本文流程的逆向练习。) - 课后作业:重新为你的扩展做样式。
start目录的样式虽然完整,但课程要求你编辑styles.css让扩展拥有自己的风格;评分标准是「代码以可用的新样式提交」为满分档。 - 复习与自学习:本课时顺带接触了浏览器史,文档建议进一步阅读三个方向的资料——Web 浏览器的历史、World Wide Web 的发明历程,以及 Web 发明者 Tim Berners-Lee 关于「三十年后的 Web」的访谈,理解最初的设计愿景如何影响今天的扩展生态。
- 下一步:完成本课后的下一课是 表单、浏览器与本地存储,将把本文搭好的表单接上真实的数据流。
小结
本课时的知识密度集中在三处:一是浏览器「URL → HTTP(S) 请求 → 渲染引擎显示」的基本链路,以及跨浏览器差异对开发决策的影响;二是「npm run build→load unpacked/reload」这条贯穿整个系列的扩展开发工作流;三是dist/src分离的项目结构与 Manifest V3 的入口文件约定(background.jsService Worker +index.htmlpopup)。只要dist里四件套(manifest、HTML、background、main.js)齐备且类名与 JS 选择器对齐,扩展就能在浏览器中稳定运行——这是后续所有课程共同的起点。
【免费下载链接】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),仅供参考