- 前端
- 音视频
【免费下载链接】hls-downloader
Web Extension for sniffing and downloading HTTP Live streams (HLS)
本篇文章以仓库根目录的 AGENTS.md(Repository Guidelines)为核心骨架,面向计划为本项目提交代码、运行自动化变更或深入理解其工程结构的开发者。文章系统讲解 HLS Downloader 的 pnpm workspace 多包架构、构建与测试命令、开发模式、产物处理、代码风格与提交规范,并结合 package.json、pnpm-workspace.yaml、README.md 及各子包AGENTS.md的源码与配置证据进行纵深验证。读完本文,你将掌握如何干净地安装依赖、构建 Chrome/Firefox 扩展产物、运行单测与覆盖率、使用 watch 模式联调,以及符合仓库规范的代码风格与 commit 写法。
仓库定位:Web 扩展「HLS Downloader」
AGENTS.md开篇即点明仓库性质:这是HLS Downloader 浏览器扩展,功能是嗅探并下载 HTTP Live Streams(HLS)视频流。它通过ffmpeg.wasm在本地完成音视频合成,全程不上传任何数据,被 README.md 描述为 “Free • Open Source • MIT Licensed”。AGENTS.md的全部约定都是为“自动化变更或提交 Pull Request 时遵循的规则”服务的,因此这份文档既是给人类贡献者的指南,也是给代码 Agent 的操作手册。
从 pnpm-workspace.yaml 可以看到,项目使用 pnpm 管理依赖,并锁定packageManager: pnpm@10.34.4、node >= 22.12.0(见 package.json)。
架构总览:src/下的五个包
AGENTS.md用一段列表定义了仓库的包结构,五个子包全部位于src/下,并在 pnpm-workspace.yaml 中注册为 workspace packages:
| 包目录 | 职责 | 关键证据 |
|---|---|---|
core | 共享业务逻辑(TypeScript),源码在src/core/src,编译产物输出到src/core/lib | src/core/AGENTS.md |
background | 初始化扩展 store,并装配IndexedDBFS、FetchLoader、M3u8Parser等服务 | 见下方调用链 |
popup | 面向播放列表与下载交互的 React 用户界面 | src/popup/AGENTS.md |
design-system | 供 popup 消费的 UI 组件库 | src/design-system/AGENTS.md |
assets | 扩展 manifest 与图标 | src/assets/manifest.json |
分层规则:业务逻辑必须落在 core
AGENTS.md明确了一条硬性分层规则:
- 新功能以use-cases的形式实现于
src/core/src/use-cases; - 通过controllers下的 epics(
src/core/src/controllers)进行编排; - background 脚本只负责协调这些函数,不得内嵌业务逻辑。
从源码结构看,src/core/src/use-cases目录下确实存在create-bucket.ts、prepare-download-bucket.ts、write-to-bucket.ts、write-to-file.ts、inspect-level-encryption.ts、download-subtitle-track.ts、sanitize-filename.ts等 21 个独立用例文件;src/core/src/controllers下则有add-playlist-epic.ts、download-job-epic.ts、save-as-job-epic.ts、storage-epics.ts等 18 个 epic 文件,二者一一呼应,印证了 “use-cases 承载实现、epics 负责编排” 的架构主张。
background包正是这一规则的落地样例:它的入口 src/background/src/index.ts 只做四件事——恢复下载跟踪状态、从 core 引入createStore创建 Redux store、通过webext-redux的createWrapStore包装、然后订阅 store 并持久化状态。它把四个核心服务作为依赖注入进 store:
const store = createStore( { decryptor: CryptoDecryptor, fs: DiskBackedFS, loader: FetchLoader, parser: M3u8Parser, }, state, );这四条注入链路分别对应src/background/src/services/下的crypto-decryptor.ts、disk-backed-fs.ts、fetch-loader.ts、m3u8-parser.ts,与AGENTS.md提到的IndexedDBFS、FetchLoader、M3u8Parser一致(当前版本的磁盘型文件系统实现名为DiskBackedFS,封装了 IndexedDB 与 OPFS 两种后端,可从seekable-opfs-output.ts、indexedb-fs.ts、opfs-storage.ts等文件推断)。
UI 复用:统一从 design-system 取组件
AGENTS.md规定 UI 组件应来自src/design-system/src,以保证扩展内样式一致。src/design-system/src/components/ui目录下提供button.tsx、card.tsx、input.tsx、progress.tsx、select.tsx、tabs.tsx、switch.tsx等基础组件,且每个组件几乎都配了.stories.tsx文件(如button.stories.tsx),这是因为 src/design-system/AGENTS.md 要求“新组件必须补充 Storybook stories”。popup 侧则通过 src/popup/AGENTS.md 的约定消费这些组件,保持两个包之间的单一依赖方向。
构建与测试:一条命令打通全链路
AGENTS.md给出的构建/测试命令非常精简,但其背后对应着根 package.json 中一组精心编排的脚本,下面逐一展开实际行为与注意事项。
安装依赖
pnpm install推荐按 README.md 的做法对齐锁定的工具链,避免 Corepack 与签名密钥过期问题:
npm install --global pnpm@10.34.4 pnpm install --frozen-lockfile运行全部测试
pnpm testpretest钩子会先构建core与design-system(因为其余包的测试依赖其编译产物lib/),随后通过pnpm --parallel --filter ./src/core --filter ./src/background --filter ./src/design-system --filter ./src/popup run test并行执行四个包的测试套件。你也可以只跑单个包,例如pnpm test:background、pnpm test:popup(对应各子包AGENTS.md中“改动后请运行对应包测试”的要求)。
构建产物
pnpm run build该命令由prebuild(clean+copy-assets)、build:packages与build:zip三阶段组成,最终产出:
dist/目录(各包编译后的合成目录);extension-chrome.zip(Chromium 系浏览器安装包);extension-firefox.xpi(Firefox 安装包,由zip命令生成)。
注意:构建需要系统已安装
zip命令(见 README.md),且默认目标是 Manifest V2。要生成面向 Chromium 的 Manifest V3 包,使用MV_TARGET=mv3 pnpm run build,或直接用pnpm run build:mv2/pnpm run build:mv3;完整变体构建可用pnpm run build:all与pnpm run build:all-variants(后者额外产出不含 blocklist 的 “Experimental No Blocklist” 版本)。
覆盖率与 e2e
pnpm test:coverage:并行运行四个包的test:coverage,再由scripts/coverage-report.mjs汇总、scripts/coverage-badge.mjs生成徽章(即根目录的coverage-badge.svg);pnpm test:e2e:local:执行 scripts/e2e-local-browser.mjs,构建 MV3 扩展并启动真实浏览器,对真实在线 HLS 流完成“嗅探 → 预览 → 选择播放列表 → 下载 → 校验输出媒体文件”的端到端冒烟测试;可通过E2E_BROWSER、E2E_HLS_URL、E2E_CLEAN_DOWNLOAD环境变量定制,且 CI 环境下会自动跳过。
开发模式:watch 联调
AGENTS.md推荐开发时使用 watch 模式:
pnpm run dev其背后是DIST_DIR=dist/mv3 MV_TARGET=mv3 pnpm --parallel --filter ./src/core --filter ./src/design-system --filter ./src/background --filter ./src/popup run dev:四个包的构建进程并行监听,任一源码变更即触发增量重编译并同步复制 assets 到dist/,非常适合边改边在浏览器里加载未打包扩展调试。
此外可用pnpm storybook预览 popup 与 design-system 组件(Storybook 的入口被配置在 popup 包中,见 package.json),新 UI 组件可以在脱离真实扩展环境的情况下快速验收。
产物处理:dist/与归档包不进版本库
AGENTS.md的 Artifact Handling 一节明确了两条纪律:
dist/、extension-chrome.zip、extension-firefox.xpi、extension-archive.zip均为临时构建输出,已被.gitignore忽略,不得提交;- 构建验证完毕后应执行
pnpm run clean(即rimraf dist dist-mv2 dist-mv3 extension-*.zip extension-*.xpi source-code*.zip)清理工作区,保持工作树干净。
这解释了为何项目根目录看不到任何dist/目录——它只存在于本地构建过程中。
编码风格与生成文件禁区
AGENTS.md的 Coding Style 规则可直接落地为可执行的代码约定:
- 所有
.ts、.tsx、.js、.json文件统一使用两个空格缩进; - 严禁直接编辑
src/core/lib:该目录由src/core/src的 TypeScript 源码编译生成。这一点在 src/core/AGENTS.md 中被再次强调,意味着任何对 core 逻辑的修改都必须落在src/下的源文件,再通过构建回灌到lib/,避免手工改动被后续构建覆盖造成漂移。
提交规范:<type>: <summary>
AGENTS.md要求 commit message 遵循 Conventional Commits 风格:
<type>: <summary>例如feat: add download button。文档列出的常用类型为feat、fix、chore、test、docs;README.md 给出的提交示例feat: add awesome idea与此完全一致。建议在实践中再补上refactor、perf、style等常规类型,只要保持<type>: <summary>的格式即可被自动化的 changelog / 语义化版本工具正确解析。
文档维护义务
AGENTS.md的 Documentation 一节提出了一个对协作仓库尤为重要的要求:
- 若构建步骤或项目布局发生变化,必须同步更新 README.md,避免新贡献者按旧文档操作时“踩坑”;
- 更完整的贡献政策见 CONTRIBUTING.md(Pull Request 流程、SemVer 版本号约定、双人 sign-off 合并策略等)与行为准则文档。
子包 AGENTS.md:一份文档、五处落点
值得说明的是,仓库的规范体系并非只有根目录一份AGENTS.md:src/core、src/background、src/design-system、src/popup四个包各自还有一份精简版指南(如 src/core/AGENTS.md、src/popup/AGENTS.md),它们把根文档的通用规则细化为包内纪律:
- core:业务逻辑与 Redux 状态所在,
lib/是生成目录不可手改,新功能必须配单元测试并跑pnpm test:core,测试约定参照 src/core/TEST.md(覆盖目标为 Statements 80% / Branches 70% / Functions 80% / Lines 80%); - background:只做服务装配与 use-case 协调,改动后跑
pnpm test:background; - design-system:popup 的共享 UI 组件库,新组件须补 Storybook stories,验证用
pnpm --filter ./src/design-system run build; - popup:React 界面,必须复用 design-system 组件,改动后跑
pnpm test:popup。
这份“根文档统辖全局 + 子包文档细化落地”的双层结构,正是大型 pnpm workspace 中管理多包协作规范的常见实践,值得在引入新包时沿用。
给自动化 Agent 的行动清单
把AGENTS.md的规则压缩成可执行的检查清单,无论是人工 PR 还是代码 Agent 流程,都建议按序自检:
- 定位功能归属:新逻辑进
src/core/src/use-cases,编排走src/core/src/controllers,background 只做依赖装配; - UI 复用:优先从
src/design-system/src取组件,新增组件补.stories.tsx; - 缩进与禁区:全仓两空格;不碰
src/core/lib; - 测试先行:改动后跑对应包测试(
pnpm test:core/pnpm test:background/pnpm test:popup),全量回归用pnpm test; - 构建验证后清理:
pnpm run build验证产物,随后pnpm run clean,不提交dist/与各类 zip/xpi; - 提交与文档:commit 遵循
<type>: <summary>;若改变了构建步骤或目录布局,同步更新README.md。
小结
根目录 AGENTS.md 以不到 70 行的篇幅定义了 HLS Downloader 的工程宪法:五个包的职责边界、use-cases/epics/background 三层业务组织方式、统一的 build/test/dev 命令、构建产物清理纪律、双空格缩进规范、Conventional Commits 提交格式,以及 README 同步更新的文档义务。这些规则并非纸面约定——pnpm-workspace.yaml里的包注册、package.json里pretest/predev钩子与build:zip脚本、src/background/src/index.ts中的依赖装配、src/core/src/use-cases与src/core/src/controllers的目录结构,都是其可验证的实现证据。按本文的清单执行,即可在遵守仓库规范的前提下高效地为 HLS Downloader 贡献代码。
- 前端
- 音视频
【免费下载链接】hls-downloader
Web Extension for sniffing and downloading HTTP Live streams (HLS)
相关推荐
手把手:5 步用 Charles 诊断大麦抢票的网络问题(附排查清单)
手把手:5 步用 Charles 诊断大麦抢票的网络问题(附排查清单) 这个仓库是一套大麦抢票的自动化工具,观演人、城市、日期场次、价格都能按你的条件多选。移动
GUI 自动化RPAPolly 仓库的 Coding Agent 开发指南:构建、测试、架构与工程规范全解析
Polly 仓库的 Coding Agent 开发指南:构建、测试、架构与工程规范全解析 导读 本文基于 Polly 开源仓库根目录的 AGENTS.md ht
后端微服务Telepresence 仓库开发与贡献指南:构建、测试、架构与发布流程全解析
Telepresence 仓库开发与贡献指南:构建、测试、架构与发布流程全解析 导读 AGENTS.md 是 Telepresence 开源仓库为贡献者与 AI
云原生开发工具微服务网络
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考