xin_oss-upload
v1.0.0
Published
上传到oss的工具
Downloads
104
Readme
@xin/oss-upload
多厂商 OSS 文件上传工具库,支持阿里云 OSS、腾讯云 COS、七牛云,提供统一的 API 接口。
安装
pnpm add @xin/oss-upload快速开始
工厂函数(推荐)
使用 createOSSUploader 根据配置自动创建对应厂商的上传器:
import { createOSSUploader } from '@xin/oss-upload'
const uploader = createOSSUploader({
vendor: 'aliyun',
region: 'oss-cn-hangzhou',
accessKeyId: 'YOUR_ACCESS_KEY_ID',
accessKeySecret: 'YOUR_ACCESS_KEY_SECRET',
bucket: 'your-bucket',
})
const result = await uploader.uploadFile('/path/to/local/file.jpg', {
targetPath: 'images/file.jpg',
})
console.log(result.url) // 访问 URL
console.log(result.size) // 文件大小(字节)
console.log(result.costTime) // 上传耗时(ms)直接实例化
import { AliyunOSSUploader } from '@xin/oss-upload'
const uploader = new AliyunOSSUploader({ ... })配置项
通用配置(所有厂商)
| 字段 | 类型 | 必填 | 说明 |
| -------------- | --------- | ---- | ------------------------- |
| vendor | string | ✅ | 厂商标识,见下方各厂商配置 |
| secure | boolean | — | 是否使用 HTTPS,默认 true |
| customDomain | string | — | 自定义 CDN 域名(不含协议)|
阿里云 OSS — vendor: 'aliyun'
import { createOSSUploader } from '@xin/oss-upload'
const uploader = createOSSUploader({
vendor: 'aliyun',
region: 'oss-cn-hangzhou', // OSS 地域
accessKeyId: 'YOUR_KEY_ID',
accessKeySecret: 'YOUR_KEY_SECRET',
bucket: 'your-bucket',
endpoint: 'oss-cn-hangzhou.aliyuncs.com', // 可选,自定义 Endpoint
customDomain: 'cdn.example.com', // 可选,自定义域名
})| 字段 | 类型 | 必填 | 说明 |
| ----------------- | -------- | ---- | ----------------- |
| region | string | ✅ | OSS 地域 |
| accessKeyId | string | ✅ | AccessKey ID |
| accessKeySecret | string | ✅ | AccessKey Secret |
| bucket | string | ✅ | 存储空间名称 |
| endpoint | string | — | 自定义 Endpoint |
腾讯云 COS — vendor: 'tencent'
const uploader = createOSSUploader({
vendor: 'tencent',
region: 'ap-guangzhou', // COS 地域
secretId: 'YOUR_SECRET_ID',
secretKey: 'YOUR_SECRET_KEY',
bucket: 'your-bucket', // 不含 AppId 的桶名
appId: '1250000000', // 腾讯云 AppId
customDomain: 'cdn.example.com', // 可选
})完整存储桶名称由
bucket-appId拼接,SDK 内部自动处理。
| 字段 | 类型 | 必填 | 说明 |
| ----------- | -------- | ---- | ----------------- |
| region | string | ✅ | COS 地域 |
| secretId | string | ✅ | SecretId |
| secretKey | string | ✅ | SecretKey |
| bucket | string | ✅ | 存储桶名(不含 AppId)|
| appId | string | ✅ | 腾讯云 AppId |
七牛云 — vendor: 'qiniu'
const uploader = createOSSUploader({
vendor: 'qiniu',
zone: 'z0', // 存储区域
accessKey: 'YOUR_ACCESS_KEY',
secretKey: 'YOUR_SECRET_KEY',
bucket: 'your-bucket',
domain: 'cdn.example.com', // 空间绑定的域名(必填)
})| 字段 | 类型 | 必填 | 说明 |
| ----------- | -------- | ---- | --------------------- |
| zone | string | ✅ | 存储区域,见下方枚举 |
| accessKey | string | ✅ | AccessKey |
| secretKey | string | ✅ | SecretKey |
| bucket | string | ✅ | 存储空间名称 |
| domain | string | ✅ | 空间绑定的访问域名 |
zone 枚举值:
| 值 | 区域 |
| ----- | ------ |
| z0 | 华东 |
| z1 | 华北 |
| z2 | 华南 |
| na0 | 北美 |
| as0 | 东南亚 |
上传选项 UploadOptions
await uploader.uploadFile('/local/path/file.jpg', {
targetPath: 'images/2024/file.jpg', // 必填,OSS 上的目标路径
overwrite: false, // 是否覆盖同名文件,默认 false
timeout: 60000, // 超时时间(ms),默认 60000
partSize: 10 * 1024 * 1024, // 分片大小(字节),默认 10MB
parallel: 5, // 分片并发数,默认 5
onProgress: (percent) => { // 进度回调,0-100
console.log(`上传进度: ${percent}%`)
},
})| 字段 | 类型 | 必填 | 默认值 | 说明 |
| ------------ | ----------------------------- | ---- | -------- | -------------- |
| targetPath | string | ✅ | — | OSS 目标路径 |
| overwrite | boolean | — | false | 是否覆盖已有文件 |
| timeout | number | — | 60000 | 超时(ms) |
| partSize | number | — | 10MB | 分片大小 |
| parallel | number | — | 5 | 分片并发数 |
| onProgress | (percent: number) => void | — | — | 进度回调(0-100)|
上传结果 UploadResult
interface UploadResult {
url: string // 文件访问 URL
path: string // OSS 上的存储路径
size: number // 文件大小(字节)
costTime: number // 上传耗时(ms)
md5?: string // 文件 MD5(部分厂商提供)
}方法
所有上传器均继承自 BaseOSSUploader,提供以下方法:
uploadFile(filePath, options)
上传本地文件到 OSS。
const result = await uploader.uploadFile('/local/file.jpg', {
targetPath: 'uploads/file.jpg',
})deleteFile(objectName)
删除 OSS 上的文件,文件不存在时也返回 true。
const success = await uploader.deleteFile('uploads/file.jpg')getFileUrl(objectName)
获取文件的访问 URL(不包含签名,适用于公开读 Bucket)。
const url = uploader.getFileUrl('uploads/file.jpg')destroy()
释放客户端资源。
uploader.destroy()错误处理
所有错误均以 OSSUploadError 抛出:
import { OSSUploadError } from '@xin/oss-upload'
try {
await uploader.uploadFile('/path/to/file.jpg', {
targetPath: 'images/file.jpg',
})
} catch (err) {
if (err instanceof OSSUploadError) {
console.error('错误信息:', err.message)
console.error('错误码:', err.code)
console.error('请求 ID:', err.requestId)
}
}常见错误码:
| code | 说明 |
| ----------------------- | ------------------------ |
| INVALID_CONFIG | 配置项缺失或非法 |
| CLIENT_INIT_FAILED | SDK 客户端初始化失败 |
| CLIENT_NOT_INIT | 客户端未初始化(已销毁) |
| NOT_A_FILE | 指定路径不是文件 |
| FILE_EXISTS | 文件已存在且未开启覆盖 |
| CHECK_FILE_FAILED | 检查文件存在性失败 |
| UPLOAD_FAILED | 上传失败 |
| DELETE_FAILED | 删除失败 |
完整示例
import { createOSSUploader, OSSUploadError } from '@xin/oss-upload'
// 1. 创建上传器
const uploader = createOSSUploader({
vendor: 'tencent',
region: 'ap-guangzhou',
secretId: process.env.COS_SECRET_ID!,
secretKey: process.env.COS_SECRET_KEY!,
bucket: 'my-bucket',
appId: '1250000000',
customDomain: 'cdn.example.com',
})
// 2. 上传文件
try {
const result = await uploader.uploadFile('./avatar.png', {
targetPath: `avatars/${Date.now()}.png`,
overwrite: false,
onProgress: (p) => console.log(`${p}%`),
})
console.log('上传成功:', result.url)
} catch (err) {
if (err instanceof OSSUploadError) {
console.error(`[${err.code}] ${err.message}`)
}
}
// 3. 删除文件
await uploader.deleteFile('avatars/old.png')
// 4. 释放资源
uploader.destroy()开发
pnpm install # 安装依赖
pnpm test # 运行测试
pnpm test:watch # 监听模式
pnpm build # 构建发布产物