개인 블로그에 있는 내용 중 project 페이지에서 사용될 이미지는 AWS S3에 저장 후 페이지로 가져오는 방법을 선택해 해당 방법에 대해 정리해보았다.
AWS SDK 사용법
S3 서비스만 필요함으로 @aws-sdk/client-s3를 설치했다.
개별 서비스 클래스를 바로 import 하면 메모리를 절약할 수 있다는 장점이 있다.
npm
// 개별 서비스
npm i @aws-sdk/client-s3
const { S3Client } = require("@aws-sdk/client-s3");
AWS Credentials : aws region 및 자격증명 설정
AWS 서비스와 연동하기 위해선 자격증명(Credentials)인 accessKeyId와 secretAccessKey가 필요하다. 해당 키들은 .env에 저장 후 불러온다.
관련글 : https://minsun309.tistory.com/entry/S3-%EA%B6%8C%ED%95%9C-%EC%84%A4%EC%A0%95-IAM
//aws s3 image
const credentials = {
accessKeyId: AWS_KEY,
secretAccessKey: AWS_SECRET_KEY,
};
const s3Client = new S3Client({
region: AWS_REG,
credentials: credentials,
});
객체 목록 : ListObjectsV2Command()
ListObjectsV2Command() 를 통해 S3에 저장된 폴더 내 객체 목록을 가져오는 요청 설정하고 S3클라이언트를 사용하여 폴더 내 객체 목록을 가져온다.
import { AWS_KEY, AWS_REG, AWS_SECRET_KEY } from "libs/config";
const { S3Client, ListObjectsV2Command } = require("@aws-sdk/client-s3");
export default function Project({ projects }: ProjectistObject) {
//...
const bucketName = "s3.personalblog";
const folderPrefixImages = "images/";
const [awsImages, setAwsImages] = useState<string[] | null>(null);
const getObjectsInFolder = async () => {
try {
// 폴더 내 객체 목록을 가져오는 요청 설정
const commandInput = {
Bucket: bucketName,
Prefix: folderPrefixImages,
};
const command = new ListObjectsV2Command(commandInput);
// S3 클라이언트를 사용하여 폴더 내 객체 목록을 가져옴
const data = await s3Client.send(command);
let objectlists = [];
for (let object of data.Contents) {
// 폴더 객체인 경우 리스트에 추가하지 않음
if (!object.Key.endsWith("/")) {
objectlists.push(object.Key);
}
}
return objectlists;
} catch (error) {
console.error(error);
}
};
return <></>;
}
getObjectsInFolder() 이 함수를 페이지 진입 시 실행 하도록 useEffect를 통해 setAwsImages에 저장한다.
useEffect(() => {
const fetchObjects = async () => {
try {
const res = await getObjectsInFolder();
if (res) {
const removeFolder = res.map((r: string) => r.split("/")[1]);
setAwsImages(removeFolder);
}
} catch (error) {
console.error("Error fetching objects:", error);
}
};
fetchObjects();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
해당 파일 명을 cloudfrontBaseUrl에 이어서 붙이면 S3에 저장된 이미지가 나온다.
{
awsImages?.map((imagePath: any) => (
<Image
src={`${cloudfrontBaseUrl}/images/${imagePath}`}
alt="image"
width={300}
height={300}
priority
placeholder="blur"
blurDataURL={blurDataURL}
key={imagePath}
/>
));
}
전체 코드
아래 코드에서는 aws 이미지들을 <Post /> 컴포넌트로 보내고 있다.
import { AWS_KEY, AWS_REG, AWS_SECRET_KEY } from "libs/config";
const { S3Client, ListObjectsV2Command } = require("@aws-sdk/client-s3");
export default function Project({ projects }: ProjectistObject) {
// AWS S3 설정
const credentials = {
accessKeyId: AWS_KEY,
secretAccessKey: AWS_SECRET_KEY,
};
const s3Client = new S3Client({
region: AWS_REG,
credentials: credentials,
});
const bucketName = "s3.personalblog";
const folderPrefixImages = "images/";
const [awsImages, setAwsImages] = useState<string[] | null>(null);
const getObjectsInFolder = async () => {
try {
// 폴더 내 객체 목록을 가져오는 요청 설정
const commandInput = {
Bucket: bucketName,
Prefix: folderPrefixImages,
};
const command = new ListObjectsV2Command(commandInput);
// S3 클라이언트를 사용하여 폴더 내 객체 목록을 가져옴
const data = await s3Client.send(command);
let objectlists: string[] = [];
for (let object of data.Contents) {
// 폴더 객체인 경우 리스트에 추가하지 않음
if (!object.Key.endsWith("/")) {
objectlists.push(object.Key);
}
}
return objectlists;
} catch (error) {
console.error(error);
}
};
useEffect(() => {
const fetchObjects = async () => {
try {
const res = await getObjectsInFolder();
if (res) {
const removeFolder = res.map((r: string) => r.split("/")[1]);
setAwsImages(removeFolder);
}
} catch (error) {
console.error("Error fetching objects:", error);
}
};
fetchObjects();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<Seo
title={`MinSun's Blog | Projects`}
url={BASE_URL + "/project"}
desc={"진행했던 프로젝트들을 기록합니다."}
/>
{mounted && (
<div className="laptop-max-width">
<Title
title={"Projects"}
subMent={"진행했던 프로젝트들을 기록합니다."}
/>
<div className="post-content-area">
{/* .... */}
<div
className={cls(
viewStyle === "gallery"
? "page-gallery-style grid-rows-3"
: "page-list-style",
"w-full min-h-[912px] lg:min-h-[904px]"
)}
>
{useSortedData(
filteredList.map((item: ListResults) => (
<Post
key={item.id}
item={item}
viewStyle={viewStyle}
tagCategory={tagCategory}
awsImages={awsImages}
/>
)),
sortedContent
).slice(indexOfFirst, indexOfLast)}
</div>
</div>
{/* .... */}
</div>
)}
</>
);
}
참고
https://inpa.tistory.com/entry/AWS-SDK-👨🏻💻-Nodejs-연동-및-SDK-기본-사용법
https://inpa.tistory.com/entry/AWS-SDK-👨🏻💻-Node-S3-메소드-예제-정리
'Dev' 카테고리의 다른 글
Next.js에 Prettier 적용하기 (0) | 2024.10.14 |
---|---|
React Developer Tools 설치(크롬 확장프로그램) (1) | 2024.09.10 |
S3 권한 설정 (IAM) (0) | 2024.09.10 |
AWS S3와 CloudFront 연동 (0) | 2024.09.06 |
AWS S3 버킷 만들기 (0) | 2024.09.06 |