
就这几行import{S3Client}frombun// 阿里 const aliyunnew S3Client({accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!, bucket:my-bucket, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})await aliyun.write(hello.txt,兄弟们好啊)// 腾讯 const txnew S3Client({accessKeyId: process.env.TX_KEY!, secretAccessKey: process.env.TX_SECRET!, bucket:my-bucket-1250000000, endpoint:https://cos.ap-guangzhou.myqcloud.com,})await tx.write(hello.txt,兄弟们好啊)// 华为 const hwnew S3Client({accessKeyId: process.env.HW_KEY!, secretAccessKey: process.env.HW_SECRET!, bucket:my-bucket, endpoint:https://obs.cn-north-4.myhuaweicloud.com,})await hw.write(hello.txt,兄弟们好啊)同一份 Bun.S3 API阿里、腾讯、华为三家云全通。bun run demo.ts完事儿。痛点每家云一套 SDK兄弟们搞过后端上传下载的都知道。文件存储这事儿国内国外云厂商各写一套 SDK• 阿里OSS用ali-oss• 腾讯COS用cos-nodejs-sdk-v5• 华为OBS用esdk-obs-nodejs• AWSS3用aws-sdk**想换一家**代码全部推倒重写。更糟的是这堆 SDK• 包大冷启动 80MB 往上• 文档各看各的调半天• 流式上传、分片上传、签名算法各搞一套**老板让你上华为云**你对着阿里 SDK 写好的代码干瞪眼。解决方案S3 是行业事实标准S3 是 AWS 在2006 年搞出来的对象存储。S3 协议太成功了现在已经是行业事实标准。啥叫事实标准•AWS S3自己当然支持•阿里云 OSS100% 兼容 S3•腾讯云 COS100% 兼容 S3•华为云 OBS100% 兼容 S3• Cloudflare R2、MinIO、七牛、京东云、金山云全部兼容一套 API 写完换云只改 endpoint。而 Bun率先把 S3 客户端焊死在运行时里。Bun.S3Client一个类吃遍所有 S3 兼容服务。**这是 Bun 1.2 才有的真本事**Node.js 至今没原生 S3要装aws-sdk一大坨。一句话啥是 S3 协议S3 协议就是一套 HTTP REST API•PUT /bucket/key上传文件•GET /bucket/key下载文件•DELETE /bucket/key删除文件•LIST /bucket列文件每家云厂商对外暴露这四个动词加上AWS 签名 v4鉴权。**只要你的代码按 S3 协议发请求**哪家云都能接住。阿里 OSSendpoint 是关键阿里云 OSS 的 S3 兼容端点长这样import{S3Client}frombunconst ossnew S3Client({accessKeyId:LTAIxxxxxxxx, secretAccessKey:xxxxxxxx, bucket:my-bucket, region:oss-cn-hangzhou, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})await oss.write(hello.txt,兄弟们好啊)const txtawait oss.file(hello.txt).text()console.log(txt)**坑点bucket 名要全球唯一。**阿里控制台开完桶把名字填到bucket字段。region用oss-cn-hangzhou这种格式跟 AWS 的us-east-1不一样别照搬。腾讯 COSbucket 名带 APPID腾讯 COS 有点特殊。bucket 名必须带 APPID 后缀import{S3Client}frombunconst cosnew S3Client({accessKeyId:AKIDxxxxxxxx, secretAccessKey:xxxxxxxx, bucket:my-bucket-1250000000, // ← 注意 APPID region:ap-guangzhou, endpoint:https://cos.ap-guangzhou.myqcloud.com,})await cos.write(hello.txt,兄弟们好啊)1250000000这种数字就是你腾讯云账号的 APPID。**没加 APPID**404 报错找不到桶。控制台创建桶的时候会带复制粘贴即可。华为云 OBSendpoint 长得很像华为云 OBS 跟 AWS S3 几乎一模一样。连region字段格式都照搬import{S3Client}frombunconst obsnew S3Client({accessKeyId:HECxxxxxxxx, secretAccessKey:xxxxxxxx, bucket:my-bucket, region:cn-north-4, endpoint:https://obs.cn-north-4.myhuaweicloud.com,})await obs.write(hello.txt,兄弟们好啊)华为云的region格式跟 AWS 一致•cn-north-4北京•cn-east-3上海•cn-south-1广州从 AWS 迁到华为云改个 endpoint 就行。一份代码通吃三家工厂模式兄弟们写过电商/OA/CRM 的都知道。多云适配是硬需求。把三家云封装成工厂import{S3Client}frombuntypeVendoraliyun|tencent|huaweiconst config: RecordVendor, any{aliyun:{bucket: process.env.ALI_BUCKET!, region:oss-cn-hangzhou, endpoint:https://oss-cn-hangzhou.aliyuncs.com, accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!,}, tencent:{bucket: process.env.TX_BUCKET!, // 带 APPID region:ap-guangzhou, endpoint:https://cos.ap-guangzhou.myqcloud.com, accessKeyId: process.env.TX_KEY!, secretAccessKey: process.env.TX_SECRET!,}, huawei:{bucket: process.env.HW_BUCKET!, region:cn-north-4, endpoint:https://obs.cn-north-4.myhuaweicloud.com, accessKeyId: process.env.HW_KEY!, secretAccessKey: process.env.HW_SECRET!,},}exportfunctiongetS3(vendor: Vendor){returnnew S3Client(config[vendor])}// 用法 const ossgetS3(aliyun)await oss.write(hello.txt,兄弟们好啊)**业务代码只调getS3(aliyun)**内部云厂商怎么换外面一行不用改。读文件text / json / streamS3Client.file()返回的S3File继承自Blob。跟Bun.file用法一模一样import{S3Client}frombunconst ossnew S3Client({accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!, bucket:my-bucket, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})// 读 JSON const dataawait oss.file(user.json).json()// 读字符串 const textawait oss.file(readme.txt).text()// 读字节 const bytesawait oss.file(image.png).bytes()// 大文件流式读 const streamoss.file(big.log).stream()forawait(const chunk of stream){process.stdout.write(chunk)}流式读省内存GB 级日志不爆掉。写文件fetch 响应直接转存write()第二个参数接 Response能直接把网络资源存到云import{S3Client}frombunconst ossnew S3Client({accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!, bucket:my-bucket, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})// 下载网络图片直接存到阿里 OSS const resawait fetch(https://example.com/photo.jpg)await oss.write(uploads/photo.jpg, res)没用 Bun 之前你得这么写// 老套路先下到内存再上传 const resawait fetch(https://example.com/photo.jpg)const bufferBuffer.from(await res.arrayBuffer())await oss.put(uploads/photo.jpg, buffer)Bun 直接把 fetch 响应流过去零内存拷贝。presign URL临时直传最香的功能前端直传云端文件不过你服务器。import{S3Client}frombunconst ossnew S3Client({accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!, bucket:my-bucket, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})//10分钟过期的上传链接 const uploadUrloss.file(uploads/avatar.jpg).presign({method:PUT, expiresIn:600, type:image/jpeg, acl:public-read,})// 把这个 URL 发给前端 console.log(前端用这个 URL PUT 即可, uploadUrl)前端代码// 前端 constfiledocument.querySelector(input).files[0]await fetch(uploadUrl,{method:PUT, body: file, headers:{Content-Type:image/jpeg},})这套东西做用户上传头像、资料文件省到爆。服务器只发 URL**文件流直接从浏览器到云**省一大笔 CDN 流量费。三家云都能用签名算法走 AWS v4 通用规范。列文件 删文件管理后台经常要清旧文件import{S3Client}frombunconst ossnew S3Client({accessKeyId: process.env.ALI_KEY!, secretAccessKey: process.env.ALI_SECRET!, bucket:my-bucket, endpoint:https://oss-cn-hangzhou.aliyuncs.com,})// 列前100个 uploads/ 下的文件 const listawait oss.list({prefix:uploads/, maxKeys:100})for(const obj of list.contents ??[]){console.log(${obj.key}→ ${obj.size}字节)}// 分页if(list.isTruncated){const nextawait oss.list({prefix:uploads/, startAfter: list.contents!.at(-1)!.key,})}// 判断文件是否存在 const existsawait oss.exists(uploads/1.png)// 删除 await oss.delete(uploads/old.txt)**同一套 API三家云都能用**写一次列文件逻辑永远不用重写。性能比 aws-sdk 快 10 倍Bun 官方测试相同硬件、相同网络|场景|Bun.S3|aws-sdk v3|| :-- | :-- | :-- ||小文件读取|3.2 GB/s|0.3 GB/s||大文件流式读|1.8 GB/s|0.2 GB/s||小文件上传|1.5 GB/s|0.15 GB/s|快 10 倍左右。Bun 用 Zig 写了底层 HTTP 客户端跳过 Node 的 V8 libuv 老路。**冷启动也从 80MB 降到 0**因为Bun.S3Client是内置的不占 node_modules。避坑指南兄弟们有几个坑先说在前面1. 签名 region 别瞎写阿里 OSS 用oss-cn-hangzhou腾讯 COS 用ap-guangzhou华为 OBS 用cn-north-4AWS 用us-east-1。各家格式不一样照搬必报错。2. 腾讯 COS 的 bucket 带 APPIDmy-bucket-12500000001250000000这串数字不能少。3. 阿里 OSS 的 ACL 字段值有别// 阿里 await oss.write(public.html, html,{acl:public-read, type:text/html,})阿里、腾讯、华为三家 ACL 字符串基本通用但个别值不一样看云厂商文档。4. path-style 和 virtual-host-styleAWS 默认用virtual-host-stylehttps://my-bucket.s3.amazonaws.com/key阿里、腾讯、华为默认用path-stylehttps://oss-cn-hangzhou.aliyuncs.com/my-bucket/keyBun 帮你自动处理一般不用管。5. Bun 版本Bun ≥ 1.2.0才内置 S3 客户端。bun--version# 1.3.x 就行啥时候用 Bun.S3|场景|推荐|| :-- | :-- ||新项目团队用 Bun|直接用 Bun.S3||老项目 Node aws-sdk|别动稳定优先||国内多家云适配|用 Bun.S3换 endpoint 就行||大文件GB 级流式处理|用 Bun.S3自动分片||前端直传 / 临时下载链接|用 Bun.S3presign 同步生成|总结S3 这个协议20 年前 AWS 搞出来现在已经是行业事实标准。国内三家• 阿里 OSS 100% 兼容• 腾讯 COS 100% 兼容• 华为云 OBS 100% 兼容国外一堆• AWS S3 自己• Cloudflare R2• MinIO• Google Cloud Storage• DigitalOcean Spaces学会 S3 API一把钥匙开 10 把锁。而 Bun 率先把 S3 焊死在运行时里Bun.S3Client一个类通吃所有。**比 aws-sdk 快 10 倍****0 依赖、0 冷启动**3 行代码搞定上传下载。兄弟们下次再有人问你 “怎么对接国内多家云存储”直接把这篇甩给他省你半小时口舌。觉得有用点个在看、转发。评论区聊聊你们公司在用哪家的对象存储有没有被多云适配折腾过