You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Next.js中使用AWS SDK上传S3时如何减小包体积?

减小Next.js中AWS SDK包体积的方案

针对你在Next.js中使用AWS SDK上传文件到S3时遇到的包体积过大问题,以下是几个实用的解决方法:

1. 迁移到AWS SDK for JavaScript v3(推荐)

AWS SDK v3采用模块化设计,支持按需导入所需的服务和功能,能大幅减少打包体积。你只需要引入S3客户端和上传相关的模块即可:

首先安装依赖:

npm install @aws-sdk/client-s3 @aws-sdk/lib-storage

替换后的上传代码示例:

import { S3Client } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";

export const uploadS3 = async (file: File) => {
  const type = file.name.split('.').pop()?.toLowerCase();
  const allowedTypes = ['jpg', 'png', 'gif', 'svg', 'jpeg', 'webp'];

  if (type && allowedTypes.includes(type)) {
    const fileName = `content-images/dobda-${Date.now().toString()}.${type}`;
    const s3Client = new S3Client({
      region: process.env.NEXT_PUBLIC_REGION,
      credentials: {
        accessKeyId: process.env.NEXT_PUBLIC_AWS_ACCESS_KEY_ID!,
        secretAccessKey: process.env.NEXT_PUBLIC_AWS_SECRET_ACCESS_KEY!,
      },
    });

    const upload = new Upload({
      client: s3Client,
      params: {
        Bucket: process.env.NEXT_PUBLIC_BUKET!,
        Key: fileName,
        Body: file,
        ContentType: file.type,
        // ACL: 'public-read',
      },
    });

    return await upload.done();
  }
};

2. 将上传逻辑移至Next.js API路由(更安全+降体积)

重要提醒:你当前将AWS密钥放在NEXT_PUBLIC_前缀的环境变量中,会直接暴露给前端用户,存在严重的安全风险。将上传逻辑移到后端API路由,既能彻底避免前端打包AWS SDK,又能保护密钥:

步骤1:创建API路由(pages/api/upload-to-s3.ts)

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import type { NextApiRequest, NextApiResponse } from 'next';
import { createReadStream } from 'fs';
import formidable from 'formidable';

export const config = {
  api: {
    bodyParser: false,
  },
};

const s3Client = new S3Client({
  region: process.env.AWS_REGION!,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  },
});

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method Not Allowed' });
  }

  const form = formidable({});
  const [fields, files] = await form.parse(req);
  
  const file = files.file?.[0];
  if (!file) {
    return res.status(400).json({ message: 'No file uploaded' });
  }

  const type = file.originalFilename?.split('.').pop()?.toLowerCase();
  const allowedTypes = ['jpg', 'png', 'gif', 'svg', 'jpeg', 'webp'];
  if (!type || !allowedTypes.includes(type)) {
    return res.status(400).json({ message: 'Invalid file type' });
  }

  const fileName = `content-images/dobda-${Date.now().toString()}.${type}`;
  
  try {
    await s3Client.send(new PutObjectCommand({
      Bucket: process.env.AWS_BUCKET!,
      Key: fileName,
      Body: createReadStream(file.filepath),
      ContentType: file.mimetype || undefined,
      // ACL: 'public-read',
    }));

    res.status(200).json({ url: `https://${process.env.AWS_BUCKET!}.s3.${process.env.AWS_REGION!}.amazonaws.com/${fileName}` });
  } catch (error) {
    res.status(500).json({ message: 'Upload failed', error });
  }
}

步骤2:前端调用API上传文件

export const uploadS3 = async (file: File) => {
  const formData = new FormData();
  formData.append('file', file);

  const response = await fetch('/api/upload-to-s3', {
    method: 'POST',
    body: formData,
  });

  return await response.json();
};

注意:此方法需要安装formidable处理表单数据:

npm install formidable @types/formidable

3. 优化AWS SDK v2的导入(临时方案)

如果你暂时不想升级到v3,确保只导入S3客户端而非整个SDK(你已经这么做了),同时可以在next.config.js中配置tree shaking:

module.exports = {
  webpack: (config) => {
    config.optimization.minimize = true;
    config.optimization.splitChunks = {
      chunks: 'all',
    };
    return config;
  },
};

但此方法的优化效果远不如v3或后端处理方案。

内容的提问来源于stack exchange,提问作者bootoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:35:19