@yeez-tech/ydl
v0.0.14
Published
一个用于文件下载的 JavaScript/TypeScript 库,提供简单易用的文件下载功能。
Readme
Download Library
一个用于文件下载的 JavaScript/TypeScript 库,提供简单易用的文件下载功能。
功能特性
- 支持文件下载
- 支持进度监控
- 支持断点续传
- 支持一个文件多个源
- 支持提示文本本地化
- 支持多个文件并发下载
安装
使用 npm:
npm install @yeez-tech/ydl使用 yarn:
yarn add @yeez-tech/ydl生成验证文件
下载器在下载目标文件前,需要首先下载验证文件,验证文件中包含了目标文件的大小、块信息、哈希值等信息,用于验证下载结果的正确性。
本库提供了工具ydl-vf,用于生成该验证文件。
- 创建验证文件: ydl-vf create INPUT_FILE OUTPUT_FILE
- 读取验证文件: ydl-vf read VERIFICATION_FILE
- 验证文件: ydl-vf verify FILE_TO_VERIFY VERIFICATION_FILE
使用方法
基本用法
import { Downloader, initDL, ProgressIO } from "@yeez-tech/ydl";
class MyProgressIO extends ProgressIO {}
// 初始化环境
await initDL();
// 定义进度IO对象
const io = new MyProgressIO();
//初始化下载器
const dl = new Downloader(500, io, {});
const taskId = dl.download({ 0: [url] }, vdfUrl, filePath);
// 暂停任务
dl.pause(taskId);
// 恢复任务
dl.resume(taskId);
//获取任务信息
const task = dl.getTask(taskId);
// 获取任务状态
const taskStatus = dl.taskStatus(taskId);
// 获取所有任务
const allTasks = dl.getAllTasks();
// 更新任务的 URLs(可在下载过程中动态切换镜像源)
dl.updateUrls(taskId, {
0: ["https://new-mirror.example.com/file.bin"],
1: ["https://fallback.example.com/file.bin"],
});
// 删除任务
dl.remove(taskId);
//关闭下载器
dl.close();⚠️ 注意事项
本库使用 Node.js Worker Threads,需要确保 worker 文件(DVTaskProcessor.js、IOTaskProcessor.js)的路径是正确的(某些打包工具中,打包时会使用不同的路径,如Electron)。Downloader中默认会在download-lib.js同目录下的utils/目录下查找,但是用户也可以额外的指定相应的路径,如下所示。
const ioTaskProcessorPath = await import.meta.resolve('@yeez-tech/ydl/utils/IOTaskProcessor');
const dvTaskProcessorPath = await import.meta.resolve('@yeez-tech/ydl/utils/DVTaskProcessor');
const dl = new Downloader(500, io, {}, ioTaskProcessorPath, dvTaskProcessorPath);URL 与 Header 配置
download(urls, checkFileUrl, outputFile) 支持为同一个任务的多个镜像源配置权重和自定义 HTTP Header:
const urls = {
0: [
{
url: "https://cdn-a.example.com/video.bin",
headers: {
"User-Agent": "MyApp/1.0",
Referer: "https://example.com/download",
Authorization: "Bearer <token>",
},
},
// 同一优先级下可以放多个源,下载器会根据速度/权重自动切换
{
url: "https://cdn-b.example.com/video.bin",
},
],
1: [
{
url: "https://fallback.example.com/video.bin",
headers: {
Cookie: "session=abc123",
},
},
],
};
const checkFile = {
url: "https://cdn-a.example.com/video.bin.dvf",
headers: {
"User-Agent": "MyApp/Checkfile",
},
};
const taskId = dl.download(urls, checkFile, "/absolute/path/to/video.bin");urls是一个"优先级 → URL 列表"的映射:- key 为字符串数字(
"0","1"...),数值越小优先级越高; - 每个 value 是 URL 或
{ url, headers }对象,表示同一任务的不同镜像源; - headers 支持任意自定义字段(User-Agent、Referer、Authorization、Cookie 等),会透传给所有 range 请求和重试。
- key 为字符串数字(
checkFileUrl也可以是字符串或{ url, headers }对象,用于下载.dvf校验文件。outputFile支持绝对或相对路径,下载完成并通过校验后会自动删除生成的.dmf/.dvf临时文件。
动态更新 URLs:在下载过程中可以使用 updateUrls(taskId, urls) 更新任务的镜像源列表,下载器会自动切换到新的 URLs。这对于处理源服务器故障或需要切换 CDN 的场景很有用。注意:updateUrls 只更新主文件的 URLs,不会影响 checkFileUrl。
自定义 IO 对象
下载器在下载过程中会将下载任务、进度信息保存到外部存储中,为了保证保存信息的一致性,我们定义了保存进度的接口,并在合适的时机调用这些接口以保存、读取下载任务。
用户需要根据自身的需要继承并实现该接口,可以将任务信息保存到文件中,也可以保存到页面缓存或数据库(如 SQLite)中。
import { ProgressIO } from "@yeez-tech/ydl";
class MyIO extends ProgressIO {
constructor(type) {
super(type);
}
getAllDownloadTasks() {
//读取所有任务
}
saveDownloadTask(task) {
//保存任务
}
removeDownloadTask(task) {
// 删除任务
}
}下载器的事件
可以在下载器中监听多个事件,以了解下载器的状态。
dl.on("speed", (taskIdSpeed) => {
// 速度更新
// taskIdSpeed 结构: { taskId: { total: number, urls: Record<string, number> } }
// total: 该任务的总下载速度(所有 URL 速度之和,单位:字节/秒)
// urls: 每个 URL 的下载速度,key 为 URL,value 为速度(单位:字节/秒)
for (const [taskId, speedInfo] of Object.entries(taskIdSpeed)) {
console.log(`Task ${taskId}: total speed = ${speedInfo.total} bytes/s`);
for (const [url, urlSpeed] of Object.entries(speedInfo.urls)) {
console.log(` URL ${url}: speed = ${urlSpeed} bytes/s`);
}
}
})
.on("download-progress", (taskId, complete, total) => {
// 下载进度
})
.on("verify-progress", (taskId, complete, total) => {
// 验证进度
})
.on("start-download-checkfile", (taskId) => {
// 开始下载检查文件
})
.on("download-checkfile-done", (taskId) => {
// 下载检查文件完成
})
.on("start-verify", (taskId) => {
// 开始验证下载文件
})
.on("download-succ", (taskId) => {
// 下载成功
})
.on("error", (err) => {
// 错误
});各个事件发生的顺序如下:
start-download-checkfile -> download-checkfile-done -> download-progresss -> ... -> download-progress -> start-verfiy -> verify-progress -> ... -> verify-progress -> download-succ各个阶段,均可能发生error事件。
错误处理
调用 Downloader 中的方法时,错误信息会立刻抛出,用户应该进行相应的处理,如果是异步操作,则会通过error事件返回。
多语言支持
库提供了中英文支持,主要用于 error 事件中的错误信息,错误信息会根据系统中的语言设定显示相应的语言。
dl.on("error", (err) => {
console.log(err.message); //本地化语言
});语言支持基于 i18next 实现,如果需要扩展新的语言,可以调用 setAppTranslationDirs增加新的语言,如果需要手动指定语言,可以调用setLanguage。
API 文档
Downloader
下载器主类
参数:
timeInterval: 速度更新间隔(毫秒)progressIO: ProgressIO 实例,用于持久化下载任务options: 配置选项
示例:
import { Downloader, initDL, ProgressIO } from "@yeez-tech/ydl";
class MyProgressIO extends ProgressIO {
getAllDownloadTasks() {
return [];
}
saveDownloadTask(task) {
/* 保存任务 */
}
removeDownloadTask(task) {
/* 删除任务 */
}
}
async function example() {
await initDL();
const io = new MyProgressIO();
const downloader = new Downloader(500, io, {});
// 使用下载器...
downloader.close();
}开发指南
项目设置
- 克隆仓库:
git clone <repository-url>
cd download-lib- 安装依赖:
npm install开发命令
npm run dev- 启动开发环境npm run build- 构建项目npm run test- 运行测试npm run debug- 运行调试脚本npm run types- 生成类型声明文件npm run lint- 运行代码检查
开发流程
本地开发
- 在
packages目录下开发功能 - 使用
npm run debug运行调试脚本 (scripts/dev.ts) - 实时测试功能
- 在
测试
- 在
packages/__test__目录下编写测试用例 - 使用
npm run test运行测试
- 在
构建
- 使用
npm run build构建项目 - 构建产物将输出到
dist目录
- 使用
本地测试
- 使用
npm run publish:local在本地发布 - 使用
yalc在其他项目中测试
- 使用
目录结构
download-lib/
├── packages/ # 源代码目录
│ ├── index.ts # 主入口文件
│ ├── utils/ # 工具函数
│ └── __test__/ # 测试文件
├── scripts/ # 开发脚本
│ └── dev.ts # 开发调试脚本
├── dist/ # 构建输出目录
└── package.json # 项目配置文件提交规范
项目使用 husky 和 lint-staged 进行代码规范控制:
代码提交前会自动运行:
- ESLint 检查
- TypeScript 类型检查
- 单元测试
提交信息格式:
feat: 添加新功能
fix: 修复问题
docs: 更新文档
style: 代码格式调整
refactor: 代码重构
test: 添加测试
chore: 构建过程或辅助工具的变动发布
- 构建项目:
npm run build- 发布到 npm:
npm run publish许可证
商业软件,闭源。
贡献指南
- Fork 项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
更新日志
[0.0.0] - 开发中
- 初始版本
- 基本下载功能实现
[待开发功能]
- 超大文件,例如 100TB 时,是否会存在整数溢出问题,需要检查
- 动态更新下载链接
- 支持 http,https 等网络代理
生成组件类库
相关命令
- 项目运行 npm run dev
- 构建类库 npm run build
- 快捷创建组件 npm run gen (该命令会根据输入生成组件模板,包括组件 serve 与 store 以及 test)
- 单测 npm run test
项目规范
- 请按照 standard 标准书写代码,在 commit 阶段配备 lint,无 lint 错误方可提交
- 请不要将与生产环境无关的依赖安装到 dependencies 中
组件库本地调试
- 请安装 yalc npm i yalc -g
- 发布本地依赖 npm run publish:local
- 目标项目安装该库 yalc add xxx
组件库更新
组件库修改后请重新构建 npm run build
- 本地推送组件更新 npm run push 已安装本库的项目即更新为最新代码 注意:由于 vite 存在缓存 node_module 依赖,如果推送后页面没有刷新,可以尝试使用 vite --force 重启项目,这将重新构建运行中的项目依赖
组件库运行中可能存在的问题
- 接口相关代码不会走 mock,全部调用真实接口,可能出现接口 404,接入时请确保接口调通
