[Webpack] hash, chunkhash 그리고 contenthash (캐싱전략)

jiseong·2022년 5월 21일
5

T I Learned

목록 보기
251/291

개발환경에서는 style 태그에 삽입,
배포환경에서는 css를 분리하여 배포하고 있다.

하지만 재배포하는 과정에서 css의 캐싱문제로 올바르게 적용되지 않았던 문제점이 발생하였다. 문제의 원인은 빌드시마다 css파일의 내용이 수정되어도 항상 동일한 파일명(main.css)으로 생성되기 때문에 브라우저에서 동일한 파일로 인식하여 캐싱된 css파일을 불러오기 때문이였다. 그래서 캐싱문제를 해결하기 위해 번들 결과시에 생성되는 파일명을 수정하는 방향으로 문제를 해결하고자 하였다.

다음과 같이 src 디렉토리에 3개의 파일이 있다고 가정해보자. (index.js, index.css,vendors.js)

Entry Points를 활용하여 index와 vendors라는 이름을 가진 두 개의 chunk로 분리하고자 설정하였으며 css파일의 경우 따로 파일을 분리하고자 MiniCssExtractPlugin를 사용하였지만 index.js 와 index.css는 동일한 chunk라는 것을 알고 시작하면 좋을 것 같다.

// webpack 설정 내용
entry: {
  index: ["./src/index.js", "./src/index.css"],
  vendors: ["./src/vendors.js"]
},
output: {
  filename: "[name].[어떤옵션일지].js"
}
plugins: [
  new MiniCssExtractPlugin({
    filename: "[name].[어떤옵션일지].css"
  })
]

Chunk란 번들러에 의해 생성되는 하나의 코드 덩어리를 Dynamic Import나 Entry Points 등을 활용하여 분리된 파일들을 의미한다.

(어떤옵션일지의 부분은 동일한 옵션을 사용한다고 가정)

hash를 사용하는 경우

hash 값은 빌드할 때마다 생성되며 번들된 모든 Chunk의 hash 값은 동일하게 생성된다.

세 Chunk 모두 동일한 hash값을 가지는 것을 볼 수 있고 어느 Chunk 하나라도 수정하지 않을 경우 매번 빌드해도 동일한 hash값을 가지지만 하나의 Chunk라도 수정된다면 모든 Chunk의 hash값이 변경된다.

그런데 Webpack5부터는 hash는 deprecated 된 것 같다.

hash as hash for the full compilation is now deprecated

chunkhash를 사용하는 경우

chunkhash는 webpack entry를 기반으로 생성되며 각 chunk별로 hash값이 다르다.

따라서 index chunk와 vendors chunk의 hash 값이 다른것을 볼 수 있다.

만약 vendors 파일의 수정이 일어난다면, vendors 파일의 hash 값만 변경된다. 즉, 변경이 일어난 entry의 hash값만 변경된다.

index.js 파일의 경우에는 수정이 일어나면 index.css를 참조하기 있기 때문에 index.css 또한 hash값이 변경된다.(entry 기반으로 변경되기 때문)

contenthash를 사용하는 경우

contenthash는 각 파일의 내용을 기반으로 hash값을 생성한다. 따라서 chunkhash와 동일하게 모든 Chunk에 대해 hash값을 생성하지만 차이점으로는 chunkhash는 entry를 기반으로 해시를 생성한다는 점이다.

따라서 chunkhash와는 조금 다르게 css 파일 또한 분리되어 개별적인 파일로 보아 다른 hash값을 가지는 것을 볼 수 있다.

만약 main.js 파일의 수정이 일어난다면 chunkhash와 다르게 main.js의 hash 값만 바뀌게 된다. (entry기반이 아니기 때문)

그렇다면 분리된 css파일의 캐싱전략은?

그렇다면 MiniCssExtractPlugin를 사용해서 css로 분리한 경우 어떤 캐싱전략이 좋을까?

contenthash일 경우

처음에 빌드된 경우에는 다음과 같다.

이후에 개발자가 js코드를 수정하게 되면 분리된 css의 hash값은 그대로인 것을 확인할 수 있다.

chunkhash일 경우

처음에 빌드된 경우에는 다음과 같다.

이후에 개발자가 js코드를 수정하게 되면 분리된 css의 hash값까지 변경된 것을 확인할 수 있다.

따라서 브라우저의 캐싱을 효과적으로 사용하여 로딩 속도를 높이기위해서 분리하여 사용하는 css의 경우에는 contenthash을 사용하는 것이 좋아보인다.

#### Propro 프로젝트로 테스트한 경우

- 둘다 contenthash
js css 다른 hash값
js만 수정: js만 변경
css만 수정: css만 변경

- entry output만 chunkhash extract은 contenthash
js css 다른 hash값
js만 수정: js만 변경
css만 수정: css, js 변경

- entry output만 contenthash extract은 chunkhash
js css 다른 hash값
js만 수정: js, css 변경
css만 수정: css만 변경

- 둘다 chunkhash
js css 동일한 hash값
js만 수정: js, css 변경
css만 수정: js, css 변경


Reference

0개의 댓글