SPA Framework의 Router 구현해보기 - (3)

박춘화·2022년 3월 9일
0

지금까지 History Web API의 History.pushState를 활용하여 Router를 구현했다. 그런데 이 방법 외에도 SPA Framework의 Router를 구현할 수 있는 방법이 있다. 바로 hash를 활용하는 방법이다.

Vue Router - Hash mode

대표적인 SPA Framework인 Vue의 Router 기능을 담당하는 Vue Router에서는 두 가지 모드를 지원하는데, hash 모드와 history 모드를 지원한다. 공식 문서에서 각각의 모드에 대한 차이점을 다음과 같이 설명한다.

  • hash 모드는 실제 URL의 앞에 # 문자를 추가하여 사용한다. # 문자는 서버로 전송되지 않으므로 서버에서 특별히 처리해야하는 작업이 없지만, 검색 엔진 최적화(SEO)에 적절하지 않다.
  • history 모드는 실제 URL과 동일하게 사용한다. 하지만, SPA 특성상 메인 페이지를 통한 페이지 이동이 아니라 사용자가 직접 특정 페이지의 URL을 입력하여 페이지를 이동하는 경우에는 404 Not Found 에러를 받게 된다. 이러한 문제를 방지하기 위해 서버 측에서 문서로 존재하지 않는 경로를 받은 경우에는 index.html 문서를 반환하도록 처리를 해야한다.

Hash - #

이제 hash에 대해 알아보자. hash는 <a> 태그로 사용되는 Anchor Element와 함께 사용되어 동일한 문서 내에서 특정 위치로 이동할 때 주로 사용된다.

hash Router를 구현하기 전에 알아야할 중요한 두 가지 개념은 다음과 같다.

  • hash는 동일한 문서 내에서 특정 위치로 이동할 때 사용한다. 그러므로 hash를 사용한 URL 변경은 다른 문서를 불러올 필요가 없다.
  • hash 값이 변경되면 hashchange 이벤트가 발생한다.

위의 두 가지 개념을 활용하여 이전에 History Web API를 활용하여 구현했던 Router를 hash를 사용하도록 변경해보자.

Router.js

class Router {
  constructor(routes) {
    this.routes = routes;
    this.routeList = Object.keys(this.routes);
  }

  registerListener(listener) {
    // hashchange 이벤트에 리스너 함수를 등록하도록 변경
    window.addEventListener("hashchange", listener);
  }

  go(path) {
    // hash 값이 변경되면 hashchange 이벤트가 발생하므로 URL을 hash를 붙여 변경해주면 된다.
    window.location = `/#${path}`;
  }
}

App.js

...

this.render = () => {
    this.initApp();

    const { hash } = location;

    // hash 값이 없는 경우
    if (!hash.startsWith("#")) {
      if (location.pathname === "/") {
        router.go("/");
      } else {
        router.go("/404");
      }
    } else {
      const pathname = hash.replace("#", "");
      if (!router.routeList.includes(pathname)) {
        window.location = `/#/404`;
        new router.routes["/404"]({ $parent });
      } else {
        new router.routes[pathname]({ $parent });
      }
    }
  };

...

hash를 활용하여 SPA Framework의 Router를 구현했다. 예제를 통해 제대로 작동하는지 확인해보자.

예제

https://vlxtbq.csb.app/#/

참고 자료

profile
함께 성장하는 개발자

0개의 댓글