src/lib/plugins/storage/s3.ts

src/lib/plugins/storage/s3.ts

AWS S3 存储插件,支持文件上传到 Amazon S3 或兼容 S3 协议的服务(MinIO、Wasabi 等)。

概述

该插件基于 AWS SDK for JavaScript v3,提供完整的 S3 文件上传和管理功能。

主要导出

s3StoragePlugin

存储插件实例,实现了 StoragePlugin 接口。

import { s3StoragePlugin } from "@/lib/plugins/storage/s3";

功能特性

动态加载 AWS SDK

使用动态导入避免在非 S3 模式下打包 AWS SDK:

async function getS3Client() {
  const s3Module = await import(/* webpackIgnore: true */ "@aws-sdk/client-s3");
  return s3Module;
}

文件上传

  • 支持 File 对象和 Buffer
  • 自动生成唯一文件名
  • 支持自定义文件夹路径
  • 自动检测或指定 MIME 类型

文件删除

  • 支持通过 key 或完整 URL 删除
  • 自动从 URL 中提取 key

S3 兼容服务支持

通过 S3_ENDPOINT 环境变量支持兼容 S3 的服务:

  • MinIO
  • DigitalOcean Spaces
  • Wasabi
  • Cloudflare R2
  • 其他 S3 兼容服务

环境变量

# 必需
S3_BUCKET=your-bucket-name
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key-id
S3_SECRET_ACCESS_KEY=your-secret-access-key

# 可选(用于 S3 兼容服务)
S3_ENDPOINT=https://s3.custom-endpoint.com

API 参考

isConfigured

检查 S3 是否已正确配置:

isConfigured: () => boolean

验证所有必需的环境变量是否已设置。

upload

上传文件到 S3:

async upload(
  file: File | Buffer, 
  options?: UploadOptions
): Promise<UploadResult>

参数:

参数类型说明
file`File \Buffer`要上传的文件
options?.filenamestring自定义文件名(可选)
options?.mimeTypestringMIME 类型(Buffer 时必需)
options?.folderstring目标文件夹(默认:"uploads")

返回值:

interface UploadResult {
  url: string;      // 文件访问 URL
  key: string;      // S3 对象 key
  size: number;     // 文件大小(字节)
  mimeType?: string; // MIME 类型
}

示例:

// 上传文件对象
const result = await s3StoragePlugin.upload(file, {
  folder: "avatars",
});

// 上传 Buffer
const result = await s3StoragePlugin.upload(buffer, {
  filename: "custom-name.jpg",
  mimeType: "image/jpeg",
  folder: "images",
});

delete

从 S3 删除文件:

async delete(keyOrUrl: string): Promise<void>

支持两种格式:

  • Key: uploads/file-1234567890-abc123.jpg
  • URL: https://s3.region.amazonaws.com/bucket/uploads/file-1234567890-abc123.jpg

示例:

// 通过 key 删除
await s3StoragePlugin.delete("uploads/file-123.jpg");

// 通过 URL 删除
await s3StoragePlugin.delete("https://s3.amazonaws.com/mybucket/uploads/file-123.jpg");

配置方式

在环境变量中启用:

ENABLED_STORAGE=s3

并配置上述所有必需的环境变量。

文件名生成

自动生成唯一文件名:

const timestamp = Date.now();                          // 时间戳
const randomId = Math.random().toString(36).substring(2, 8);  // 随机 ID
const key = `${folder}/file-${timestamp}-${randomId}`;

URL 构造

标准 S3

const url = `https://s3.${region}.amazonaws.com/${bucket}/${key}`;

自定义 Endpoint

const url = `${endpoint}/${bucket}/${key}`;

安装依赖

使用此插件需要安装 AWS SDK:

npm install @aws-sdk/client-s3

注意事项

  1. 动态导入:AWS SDK 只在实际使用时加载
  2. 权限配置:确保 AWS 凭证有正确的 S3 权限(PutObject, DeleteObject)
  3. 公开访问:默认上传的文件可能需要额外的 ACL 或 Bucket Policy 才能公开访问
  4. CORS 配置:前端直传时需要配置 Bucket CORS
  5. forcePathStyle:使用自定义 endpoint 时启用路径样式 URL
← 返回目录