08/31 - personal portfolio(1)

Ian·2020년 8월 31일
0

Today I Learned

목록 보기
13/40
post-thumbnail

나만의 포트폴리오를 만들어 보는 시간이다. 서버와 클라이언트 전부!


Getting Started

  1. 클라이언트 사이드 셋업

    • create-react-app 을 이용해서 리액트 프로젝트를 만듭니다.
    • react router를 yarn 또는 npm을 이용하여 설치합니다.
    • react router의 Quick Start의 예제 코드를 참고하여, 기본적인 라우팅이 제대로 작동하는지 확인합니다.
  2. 서버 사이드 셋업

    • create-react-app의 build 기능을 이용해 리액트 프로젝트를 빌드합니다.
      • 그런데, 빌드는 왜 하는 걸까요? 각자 고민해보세요!
    • 새로운 폴더에서 서버 프로젝트를 하나 만듭니다. (npm init -y)
    • express를 설치합니다.
    • 클라이언트에서 빌드한 파일들을 적당한 폴더에 복사해 넣습니다. (보통 폴더 이름을 public 이라고 짓습니다.)
    • 서버 코드를 작성하여, https://localhost:8080/static 과 같은 URL로 접근할 때 클라이언트 파일들이 접근 가능하도록 만듭니다. (다시한번 말씀드리지만, create-react-app의 yarn start를 이용하는 것이 아닙니다)
  3. 페이지 설계

    • 위의 프로젝트 셋업이 완료된 후, 실질적인 페이지 설계에 들어가도록 합니다. 앞서 recast.ly 스프린트에서 컴포넌트 구조를 짰을 때 처럼 간단한 그림을 먼저 그리고 시작합시다.

Bare Minimum Requirements

클라이언트 사이드

  • React를 사용해야 합니다.
  • SPA(Single Page App)로 만들어야 합니다.
  • 클라이언트 상에서 페이지 라우팅을 적용하십시오.
    • React Router를 사용해봅시다
  • Stateful한 컴포넌트를 두 개 이상 만드세요. (다음 예시를 참조하세요. 라이브러리를 사용하지 마세요.)
    • 메뉴 선택 (selected/deselected) 컴포넌트
    • Toggle해서 내용이 가려지고 보여지는 컴포넌트
    • 모달 창 컴포넌트

서버 사이드

  • React 빌드 결과물을 담는 폴더를 만들어서, 웹 서버를 통해 사이트를 제공하게끔 만듭니다.
    • create-react-app의 build 기능 (yarn build)을 이용합니다.
  • node.js 및 express를 이용해서 웹 서버를 만듭니다.
  • 서버를 라우팅한 후, 동일한 주소의 클라이언트 라우팅에 맞춰 렌더링되어야 합니다.
    • 이게 무슨 말인지는 Routing lesson을 통해서 알아봅시다

해결전략

일단은 클라이언트부터 먼저 잡고가려고 한다. 그 이유는 요구사항을 보았을 때 클라이언트에서 해야 할 일들이 더욱 많기 때문이다. 클라이언트는 SPA 나 Stateful Component 의 구현, 클라이언트 단에서의 페이지 라우팅(React Router 를 사용해서) 등등 해야 할 부분들이 많다.

그에 비해 서버는 클라이언트에 맞추어서 "일단은" 간략하게만 구현해도 내 포트폴리오를 보여주는 데에는 큰 손색이 없기 때문이다. (물론, 서버가 중요하지 않다는 이야기는 절대로 아니다)


Client Side

Client Page Routing, 그리고 React Router 란 무엇인가

Client Routing and Server Routing

Routing, 즉 URL 조건에 따른 분기이다. 그리고, 이 라우팅을 서버사이드에서 처리해주느냐, 혹은 클라이언트 사이드에서 처리해주느냐에 대한 방법론들도 존재한다. 전자는 server side routing, 후자는 client side routing 이라고 한다.

SPA(Single Page Application)

웹페이지를 그려낼 때 업데이트가 필요한 부분이 생기면, 업데이트가 필요한 "부분만" 업데이트를 한다. 서버와는 달리 DOM을 필요한 부분만 그려주는 방식으로 업데이트한다. 그렇지만 DOM 만 바뀌는 것이 아니다. 실제로 URL 도 바뀌고, back/front 버튼을 누르면 작동한다.

이는 어떤 원리에 기반해서 만들어졌는가

위에 적은 Client Side Routing 이 되는 SPA 앱은 HTML5History API 를 사용해서, 그 중에서도 pushState() 라는 메서드를 이용해서 만들어졌다. pushState() 메서드는 내가 입력한대로 브라우저에 기록을 저장한다. 그렇게 만든다면 브라우저 상에서 back/front 버튼을 통해 왔다갔다 할 수 있다.

코드로 이해해보자, 내가 만약 "google.com" 에 접속해 있는 상태에서, 개발자 도구를 통해

const state = { 'page_id': 1, 'user_id': 5 }
const title = ''
const url = '/inseob'

history.pushState(state, title, url)

다음과 같은 pushState 코드를 실행해 주었다면, 현재 내 URL 은 "google.com/inseob" 으로 바뀌고, 저 endpoint 에는 내 state 가 추가된다. 위에 적은 대로, back/front 버튼이 전부 잘 작동한다.

그러나 이 상태는 실제로 서버에 기록되진 않는다. 그저 브라우저 상에만 저장되고 있다. 새로고침을 해서 "google.com/inseob" 이라는 페이지에 접속을 요청하면 404 에러가 뜬다. 즉 브라우저 안에서 왔다갔다 할 때만 의미가 있는 주소라는 것이다.

What is the benefit of Client Side Rendering?

서버에서 클라이언트에 맞추어 라우팅처리를 할 필요가 없이 클라이언트를 개발하면서 렌더링을 해 주면 되니 작업과정이 줄어들어 오류가 생길 확률이 적어진다.

Client Side Rendering With Server

물론 client side routing "만" 으로 routing 을 걸어준 endpoint 를 server 에서 routing 해주지 않으면, 브라우저 내부에서 접근하는 과정에선 문제가 없지만 그 endpoint 로 직접 접근하는 방식 자체는 안 된다. 왜냐면, 서버에서 해당 url 에 대한 요청의 routing 이 되어있지 않기 때문이다. cannot /GET request 같은 메시지가 뜰 것이다.

이렇게 클라이언트 단에서도, 서버 단에서도 렌더링을 해 주는 경우에서 이득을 볼 수 있는 경우는 두 가지이다.

  1. 사용자 경험을 조금 더 좋게 만들고 싶은 경우 (URL 로 직접 접속요청을 날리는 사용자도, 클라이언트에서 GUI를 통해 접근해주는 사용자도 모두 만족할 수 있도록)
  2. 검색 엔진 최적화를 고려하는 경우

Plus - Server side rendering?

이제는 client side rendering + routing 을 넘어서서, 그냥 서버에서 해당 과정들을 모두 처리해버리자는 server side rendering 이라는 방법론도 고개를 드는 중이다. server side rendering 에서 가장 유명한 라이브러리는 Next.js 이다.


간단한 React Router 구현

먼저, npm install react-router-dom 을 통해 react-router-dom 을 사용한다. 그 중에서도 BrowserRouter, Switch, Route, Link 를 활용해 Routing 을 해주면 된다. 이렇게 하면 client side routing 이 가능해진다. 다시 한 번 말하지만, 물론 서버에는 구현되어있지 않다.

참고 문서 :

React Router: Declarative Routing for React

import React from 'react'
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom'

export default function App() {
  return (
    // router section 
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  )
}

function Home() {
  return <h2>Home</h2>
}

function About() {
  return <h2>About</h2>
}

function Users() {
  return <h2>Users</h2>
}

사이트의 간단한 그림 그려보기

"어떤 배치가 이쁠까?" 를 잘 모르겠어서, Redux 페이지를 참고하였다. 일단 초안은 이런 식인데, 계속 만들면서 바꿔나가야겠다.

https://www.figma.com/embed?embed_host=notion&url=https%3A%2F%2Fwww.figma.com%2Ffile%2F4FowLYQhTt6Qpoe6V3Ckr1%2Fpersonal-portfolio%3Fnode-id%3D0%253A1


Toggle 만들기

다크모드를 Toggle 로 구현해보고자 생각보다 간단해 보이는 기능이었는데, 뜯어보니 상당히 복잡해서 놀랐다. CSS 가 정말 많이 들어갔었다.

/* The switch - the box around the slider */
.switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 34px;
  }
  
  /* Hide default HTML checkbox */
  .switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }
  
  /* The slider */
  .slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  .slider:before {
    position: absolute;
    content: "";
    height: 26px;
    width: 26px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  input:checked + .slider {
    background-color: #2196F3;
  }
  
  input:focus + .slider {
    box-shadow: 0 0 1px #2196F3;
  }
  
  input:checked + .slider:before {
    -webkit-transform: translateX(26px);
    -ms-transform: translateX(26px);
    transform: translateX(26px);
  }
  
  /* Rounded sliders */
  .slider.round {
    border-radius: 34px;
  }
  
  .slider.round:before {
    border-radius: 50%;
  }

사실 W3S 의 toggle 예제를 그대로 복붙했다. 다행히 작동은 잘 된다.


오늘은 사실상 CSS 만 한 듯 하다. CSS 를 하나도 안 했더니, 꽤나 고생을 많이 했다. padding 이나 flex 등등의 작업들, React Routing 을 통한 client side routing 정도를 했다. 오늘은 뭔가 남해개발자한달살기 모임들의 사람들이 오고, 오리엔테이션도 하는 등등 이런저런 일들이 많아서 제대로 공부를 하지 못 했다. 내일부터는 공부하는 것들을 다시 제대로 적어보려고 한다.

profile
правда и красота, truth and beauty

0개의 댓글