[JavaScript] 바닐라 자바스크립트로 SPA 구현하기 - html 파일 합치기, CSS 분리하기

suno·2022년 11월 21일
0

이번 프로젝트의 챌린지는 1) 바닐라 자바스크립트로 SPA 구현 2) Firebase로 CURD 구현이다.
인증, DB, 스토리지로 Firebase를 사용하고 배포는 AWS S3를 이용할 예정이다.


오늘 내가 맡은 부분은 팀원들이 만든 html 페이지를 모아서 SPA 라우팅을 구현하는 것이었다.

모든 페이지는 공통 컴포넌트로 네비게이션 바를 가지고, 링크를 클릭하면 각 페이지의 DOM 요소를 동적으로 추가하게 된다.
(첫 로딩 시 모든 페이지를 불러왔기 때문에 별도의 네트워크 요청이 필요하지 않고, HTTP 응답 코드로는 304가 나타난다.)

클라이언트 리디렉션 응답 코드 304 Not Modified 는 요청된 리소스를 재전송할 필요가 없음을 나타낸다. 캐시된 자원으로의 암묵적인 리디렉션이다.
MDN - 304 Not Modified

따라서 index.html 파일에는 내비게이션 바와 DOM 요소를 추가할 비어 있는 div가 존재한다!


팀원들이 각 페이지를 따로따로 html 파일로 작성했기 때문에, 병합할 때 고려해야 할 사항이 몇가지 있었다.

SPA 구현 고려사항

1. html 파일을 하나로 사용한다.

아래의 폴더 구조에서는 index.html 파일이 유일한 html 파일이 되고, pages/*.html 파일들은 index.html 페이지 내부의 DOM 요소로 추가된다.
따라서 pages/*.html 파일은 head와 body를 가지지 않아야 한다.

아래 코드는 html, head, body 태그가 두개씩 존재하므로 잘못된 예시이다!

변경 전 💩

<!-- index.html 시작 -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>
<body>
  <main id="main-page">
    <!-- home.html 시작 -->
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <div id="page-home">
          <h1>Hello World!</h1>
        </div>
      </body>
    </html>
    <!-- home.html 끝 -->
  </main>
</body>
</html>
<!-- index.html 끝 -->

변경 후 💫

<!-- index.html 시작 -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>
<body>
  <main id="main-page">
    <!-- home.html 시작 -->
    <div id="page-home">
      <h1>Hello World!</h1>
    </div>
    <!-- home.html 끝 -->
  </main>
</body>
</html>
<!-- index.html 끝 -->

2. CSS 셀렉터(class, id)의 충돌을 고려해야 한다.

만약 main 페이지와 login 페이지에 둘다 title이라는 클래스명을 가진 태그가 존재한다면, css 충돌이 일어날 수 있다.
이를 방지하기 위해 webpack 등 모듈 번들러를 사용하거나, 코드 스플릿팅으로 해결하는 방법이 있다고 한다.

우리 팀은 임시방편으로 각 페이지의 요소에 루트 id를 줘서 class 셀렉터를 좁혀주는 방법을 사용했다.

변경 전 💩

/* main.html */
.title {
  color: black;
}
/* login.html */
.title {
  color: white;
}

변경 후 💫

#page-main .title {
  color: black;
}
#page-login .title {
  color: white;
}




프로젝트를 진행하면서 또 알게 되는 것이 있다면 추가해야겠다.
내일은 alert 창 대신 사용할 모달 창과, (가능하다면) 댓글 CRUD를 구현해볼 예정이다.

아직까지는 프로젝트가 순조로워서 마음이 편하다. 다음주까지 또 파이팅!!! 💪

profile
Software Engineer 🍊

0개의 댓글