Webpack dev server 메모리 누수

문제 재현

  • Webpack-dev-server를 실행하고 코드 작성 중, Javascript heap out of memory가 발생

  • heap size를 늘리는 해결책이 있지만, 다른 방법이 있을 거라고 생각해 찾아보던 중

  • 이 분의 링크를 보고, 참고링크

  • 직접 내부를 살펴보자는 방식으로 찾아보게 되었습니다.

yarn pnp 관련 오류 발생

  • yarn pnp 이전과 같은 명령어를 사용할 시 나올 수 있는 에러

이 에러 참고 링크

  • yarn workspaces, lerna를 함께 사용하면서, yarn install 시, 따로 관리되는 부분이 존재하였습니다.
  • 그래서 직접 yarn cache 내에서 파일을 찾아 check script에 webpack-dev-server 경로를 추가해주었습니다.

관련 repo info

yarn berry에서 찾아서 봐야할 info

yarn pnp에서 node inspect를 어떻게 활용하는가

  • pnp 경로를 node --inspect --inspect-brk 옵션에 명시해주는 것으로 해결했습니다
"scripts": {
    "install": "yarn install",
    "test": "webpack",![](https://media.vlpt.us/images/39ghwjd/post/4762d06a-3b90-4f1f-b0bb-7e060c66299b/node-inspector%20error.PNG)
    "dev": "webpack serve",
    "check": "node --inspect --inspect-brk .yarn/cache/webpack-dev-server-npm-4.7.3-fa508b7d1a-6062db1ba6.zip/node_modules/webpack-dev-server/bin/webpack-dev-server.js"
  }
  • inspect-brk 옵션을 통해 실행 전 멈춘상태로 디버거가 실행됩니다.

  • 아래와 같이 보이는 화면에서 일시정지 버튼 대신 play 버튼이 떠있을텐데, 그 버튼을 눌러서 디버거를 붙이고 프로그램을 실행시킵니다.

테스트 진행

// webpack.config.js
    filename: '[name].[contenthash].client-bundle.js',
    path:PUBLIC_PATH,
    clean: true
  • 파일을 수정해 번들링을 새로할 때마다 contenthash 값이 새롭게 생성되며, 번들이 쌓이는 것으로 보인다는 생각이 들었습니다.

  • 그래서 webpack-dev-server를 켜놓고 일부분 코드를 수정해 번들을 새롭게 생성해서 디버거에서 확인해보았습니다.

  • 번들링 전, 되고 난 후에 heap snapshot을 여러 번 찍어서 용량이 늘어나고 있는지를 확인하였습니다.

  • 새롭게 늘어나는 것들이 매우 많았지만, 검색 옵션 중에 Object allocated between Snapshot2 and Snapshot3 옵션을 이용해서

    	- 스냅샷들 사이에 새롭게 생성된 리소스들만 조사했습니다. 

    - 이 순간, 이것들을 보면서 더 알아보고 싶다는 생각도....(정말 끝이 없는 거 같습니다 ㅠ)


  • 계속해서 코드가 수정될 때마다 번들링이 새로 되어 바뀌는 hash값들이 object 안에 저장되어 있는 것을 보고 heap이 터지는 것을 확인할 수 있었습니다.

해결책

  • webpack-dev-server를 사용하면서, 제가 웹팩설정에서 output설정을 다음과 같이 했습니다.

  • devMode 변수에 따라 생성되는 번들 파일의 이름을 고정했습니다.

output: {
        //filename: '[name].[contenthash].client-bundle.js => ',
  		filename: devMode ? '[name].js' : '[name].[contenthash].js',
        path:PUBLIC_PATH,
        clean: true

  • 같은 방법으로 테스트를 해보니, heap 용량 증가도 거의 없었고, 번들링된 파일들의 이름도 새로운 hash값으로 수정되지 않는 것을 알 수 있었습니다.

  • 무작정 heap-size를 늘리려고만 시도했다면, 더 멀리, 깊게 볼 수 없었다고 생각합니다.

    • 항상 지금의 해결책이 최선이라고 생각하지 말고, 더 나은 개선점이 있는지 찾도록 노력해야 합니다!

찾아보면서 더 공부해보고 싶은 부분!

  • webpack 내부에서 memory-fs 대신 memfs를 사용하고 있다는 것을 알게 됨 : 링크
  • performance 객체에 대한 설명 : 링크

좋은 웹페이지 즐겨찾기