Skip to content

historyApiFallback 옵션을 설정했는데도 가끔 빈 화면이 나타나는 문제 해결

keeep-runnning edited this page Mar 17, 2023 · 1 revision

상황

서버에 존재하지 않는 주소를 웹브라우저 주소창에 입력하고 요청하더라도 index.html을 응답하도록, webpack dev server의 historyApiFallback 옵션을 설정했다.

devServer: {
  historyApiFallback: true,
},

문제

  • 웹브라우저의 주소창에 localhost:3000/posts/1을 입력하고 요청한다.

  • 번호가 1인 블로그 포스트 상세 정보가 표시되지 않고, 빈 화면이 표시된다.

원인

  • 개발자 도구의 네트워크 탭을 열었더니 bundle 파일(main.js), 파비콘 등을 제대로 가져오지 못했다.

  • 주소창에 localhost:3000/posts/1을 입력했을 때, historyApiFallback 옵션이 설정되어 있으므로 개발 서버는 해당 주소가 개발 서버에 없어도 index.html을 응답해 주었다.

  • 응답받은 index.html에 bundle 파일과 파비콘 등의 주소가 상대주소로 적혀있었다.

    <link rel="icon" href="favicon.ico">
    <script defer src="main.js"></script>
  • /main.js, /favicon.ico으로 요청해야 제대로 리소스를 가져올 수 있는데, 상대주소 때문에(현재 /posts/*에 있기 때문에) /posts/main.js, /posts/favicon.ico와 같이 잘못된 주소로 요청해 리소스를 못 가져와 빈 화면이 나타났다.

해결

HtmlWebpackPlugin을 사용해 output 폴더에 index.html을 생성하고 있으므로 index.html을 생성할 때, 리소스 요청 주소를 절대주소로 변경하고 싶었다.

  • webpack의 output.publicPath 옵션을 사용하면 된다.

  • webpack이 생성하는 url에 붙일 prefix를 설정하는 옵션이다.

  • output.publicPath/으로 설정한다.

    output: {
      publicPath: "/",
    },
  • 이제 index.html의 리소스를 요청하는 url에 /라는 prefix가 붙어서, 상대주소에서 절대주소로 변경된다.

  • output.publicPath를 설정하기 전

    <link rel="icon" href="favicon.ico">
    <script defer src="main.js"></script>
  • output.publicPath/으로 설정한 후

    <link rel="icon" href="/favicon.ico">
    <script defer src="/main.js"></script>
  • 이제 웹브라우저 주소창에 localhost:3000/posts/1을 입력했을 때, 필요한 리소스들을 잘 가져오고 문제가 해결되었다.