Webpack 빌드 파일은 어떻게 캐시되는가 (+ Nginx)

2023년 11월 08일
5

들어가며

우리가 React.js 로 작성한 웹사이트를 클라이언트에서 public하게 접속할 수 있게 하려면
프로젝트를 build하여 웹 서버를 통해 배포해야 한다. (주로 webpack으로 build)

그러나 코드가 변경되었을 때마다
모든 파일을 새롭게 빌드하여 배포하는 것은 리소스 혹은 네트워크 측면에서 매우 비효율적일 것이다.

이 과정을 최대한 효율적으로 관리하기 위해
번들러(webpack)는 파일명에 해시값을 부여하고, 웹서버(Nginx)는 빌드된 파일을 캐시하여 제공한다.

이 과정이 어떻게 이루어지는지 살펴보자.

필요성

위 과정이 필요한 이유는 크게 다음과 같다.

  1. 버전 관리 및 캐싱 효율성
    • 각 빌드 파일에 해시가 포함되면 파일 내용이 변경될 때마다 파일 이름이 변경된다.
    • 브라우저와 CDN(Contents Delivery Network)에서 새 파일을 캐시하도록 강제할 수 있다.
    • 새로운 버전의 애플리케이션을 배포할 때, 오래된 캐시를 사용자에게 제공해도 문제가 발생하지 않는다.
  2. 클라이언트 성능 향상
    • 클라이언트가 빌드 파일을 다운로드한 후 브라우저에서 캐시한다.
    • 재방문시 동일 파일을 재다운로드하지 않고 캐시된 파일을 사용하여 페이지 로드 시간을 줄일 수 있다.
  3. 보안 강화 및 디버깅 용이
    • 파일이 변조되거나 손상된 경우 브라우저에서 감지하고 로드하지 않도록 할 수 있다.
    • 특정 버전의 소스 코드와 연결된 해시를 사용하여 문제를 식별하고 해결할 수 있다.

Webpack : Hash Filename

webpack에서는 build 결과 생성된 chunk 이름에 해시값을 부여한다.

webpack.config.js 파일 내 hash 로직webpack.config.js 파일 내 hash 로직

정말 변경이 있는 파일만 해시값이 바뀔까?
파일 확장자에 따라서 그 전략이 다를 것 같은데,
실제 파일 변경 후 빌드를 해서 전후 차이를 살펴보도록 하자.

파일 변경 전후 빌드파일 해시값 비교표. 초록 음영은 css 파일파일 변경 전후 빌드파일 해시값 비교표. 초록 음영은 css 파일

파일 수정 전후 빌드 디렉토리 내 파일명을 비교하여 표로 정리해 보았다.

특징은 아래와 같았다.

  • 파일 수정과 상관없이 파일 번호는 유지된다.
  • 수정된 js 파일에 한해, 해시 값이 변경된다.
  • css 파일의 경우 항상 변경된다.

Nginx : Cache Setting

  • 기본적으로 gitlab의 ci/cd 배포 환경에서는 사용자의 cache를 활용하지 않음
  • 다만, nginx 기반 배포 환경에서는 설정을 수정하여 캐시 활성화 가능
  • 캐시를 위한 설정 로직을 .nginx.conf 에 추가
location ^~ /static/ {
  gzip_static on;
  # Set a far future Expires header
  expires max;
  # Serve up the file from cache if possible.
  add_header Cache-cControl public;
}

캐시 응답 여부 확인

네트워크 탭에서 확인 결과, 변경된 파일을 실제로 새롭게 제공하는 것을 확인할 수 있었다.

변경되지 않은 파일 (위 도표의 main.js)변경되지 않은 파일 (위 도표의 main.js)

변경된 파일 (위 도표의 59번 js 파일)변경된 파일 (위 도표의 59번 js 파일)

정리

  • 빌드 파일에 해시값이 부여되고, 파일 내용에 수정이 있는 경우에만 해시값이 갱신된다.
  • 해시값이 동일한 경우, 빌드 파일은 서버에 영구적으로 캐시된다.