React의 배포
SSR를 사용하지 않는 CSR React 라이브러리 및 React 기반 프레임워크들은 빌드하면 아래와 같은 파일이 산출물로 나오기 때문에 정적 배포가 가능하다.
assets/
scripts/
ㄴ index.js
ㄴ index_ABCD.js
ㄴ ...
index.html
따라서 AWS의 S3와 같은 서비스를 사용하여 정적 배포를 하기도 하고, CDN을 사용하기 위해 앞단에 cloudFront 서비스를 붙여 사용하기도 한다.
CloudFront의 캐시 기능
cloudFront는 캐시기능을 제공한다, 아래 사진과 같이
Cloudfront → 배포 ID 선택 → 작업 → 동작 → 편집
에서 캐시가 걸려있는것을 확인할 수 있다. (이 경우는 비용절감을 위해 캐시를 직접 설정했다)
{
"type": "mediaSingle",
"attrs": {
"layout": "center",
"width": 760,
"widthType": "pixel"
},
"content": [
{
"type": "media",
"attrs": {
"width": 1657,
"alt": "image-20250908-073835.png",
"id": "8a5a9e5a-b383-47dc-99e1-1cedc1a555a9",
"collection": "contentId-127631386",
"type": "file",
"height": 809
}
}
]
}
cloudFront의 캐싱은 파일경로와 파일명이 똑같으면 hit했다고 판단하는 방식이다. 파일 내부 내용이 바뀐것은 캐시히트에 들어가지 않는다.
React의 요청과정
그렇다면 React가 어떻게 파일을 요청하는지 살펴보자면.. 먼저 index.html을 불러오고, 해당 파일 내에는 빌드시 만들어진 javascript파일들을 요청하도록 되어 있다.
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<script src="index_ABCD.js" />
...
</body>
</html>
다만 문제는 빌드 시 마다 생성되는 javascript파일명이 계속 바뀐다는것이고, index.html의 파일명은 바뀌지 않는다.
따라서. cloudFront는 index.html을 요청받으면, 파일명이 변하지 않았으므로 캐시가 히트 되어 이전 빌드의 index.html을 전달한다. 하지만, 이미 scripts/
내의 자바스크립트는 새로 빌드된 파일만이 들어있다. 물론 해당 파일들도 캐시가 되어 있으면 불러올 수 있겠으나, 업데이트된 버전으로는 불러올 수 없다. 하물며 최적화를 위해 javascript파일을 전부 불러오지 않고 특정 path에서만 불러오도록 설정되어있으면 아예 페이지가 로드되지 않는다.
따라서 배포시마다 페이지가 작동하지 않거나, 업데이트가 되지 않는 현상이 발생한다.
CloudFront Cache Invalidate
따라서 배포시, cache를 invalidate해주는 과정이 필요하다.
cache를 강제로 invalidate 시켜 가장 최근에 빌드된 파일을 불러올 수 있도록 한다.
배포방식에 따라 다양한 방식이 있으니 참고하여 사용하면 된다.
YOUR_DISTRIBUTION_ID는 cache를 invalidate할 cloudfront id를 적어준다.
AWS-CLI
# aws-cli
aws cloudfront create-invalidation \
--distribution-id <YOUR_DISTRIBUTION_ID> \
--paths "/*"
Lambda
import boto3
def lambda_handler(event, context):
client = boto3.client('cloudfront')
response = client.create_invalidation(
DistributionId='YOUR_DISTRIBUTION_ID',
InvalidationBatch={
'Paths': {'Quantity': 1, 'Items': ['/*']},
'CallerReference': str(context.aws_request_id)
}
)
return response
CodePipeline - CodeBuild (build.yaml)
version: 0.2
phases:
build:
commands:
- echo "Deploying to S3..."
- {s3배포...}
- aws cloudfront create-invalidation \
--distribution-id $YOUR_DISTRIBUTION_ID \
--paths "/*"
IAM 권한
또한 강제 invalidate에는 아래의 권한이 필요하다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": "*"
}
]
}