본문 바로가기
Projects/Portfolio

[Portfolio] 웹퍼블리셔의 리액트(React.js) 기반 포트폴리오 (VScode Style) 만들기

by 박히밍 2022. 11. 21.
반응형

VScode style의 포트폴리오 메인

 

✍️ Intro.

리액트로 토이트로젝트를 끝마친 뒤, gsap와 three.js를 공부하던 와중에 기존 포트폴리오 사이트의 호스팅이 만료되면서 리액트를 기반으로 만든 포트폴리오를 제작하게 되었습니다. (사실 회사 퇴사하고 백수의 몸인지라, 포폴을 빨리 만들어야 하는 것도 한몫했습니다..ㅠㅠ)

 

VScode 스타일로 만들게 된 계기는 제가 디자인에 자신이 없기도 하지만 디자인을 구상하는데 많은 시간을 소요할 수가 없어서

웹퍼블리셔나 개발자라면 가장 친숙한 편집기인 VScode 스타일로 포트폴리오를 만들어서 인상적인 이미지를 남기고 싶기도 했고.

일반적인 포트폴리오 스타일이 스크롤 디자인인 것이 조금 진부하다고 느껴지고, 앞으로 개발에 관한 다양한 콘텐츠를 포트폴리오에 지속적으로 담고 싶어서 게시판 느낌으로 탭 메뉴 구성으로 만들게 되었습니다.

 

메인 화면의 경우 개발 공부를 시작하면 가장 첫 번째로 찍는 워딩이 Hello World! 였던걸 모티브 삼아서

저의 세상(포트폴리오)에 온 것을 환영하는 의미로 위와 같이 메인 화면을 기획하게 되었습니다.

 

 

💻 사용 기술

Design tool: Figma
Editor: VScode
Lang

  • css (CSS-module, Flex, Grid, --var)
  • React.js (Router, axios, open-API)

ETC: Github & Sourcetree 사용 / Mac Os 환경에서 개발

배포: Github.io

 



📅 개발 기간

총 15일 소요 


 

🗂 폴더 구조

 

VScode 포트폴리오 폴더 구조

 

📁 public / images

- 이미지를 담아 놓은 폴더입니다.

 

📁 components

- 화면을 구성하는 작은 요소 단위의 컴포넌트들을 담아 놓은 폴더입니다.

 

📁 components /  icons

- SVG 아이콘들을 함수형 컴포넌트로 제작하여 담아 놓은 폴더입니다.

 

📁 pages

- 각 라우터 페이지들을 담아 놓은 폴더입니다.

 

📁 styles

- 전역 style과 변수, module.css를 담아 놓은 폴더입니다.




🕹 구현 기능

- CSS-module을 사용해볼 것

- Router로 SPA탭메뉴 구성을 만들어 볼 것

- 하드코딩을 지양하고 json 파일을 만들고, axios로 데이터들을 받아와서 화면에 뿌려줄 것

- SVG는 함수형 컴포넌트로 만들어 확장성 있게 사용할 것

- 변수 기능을 활용하여 테마 변경 기능을 넣을 것(localstorage)

- 이메일 API를 이용하여 포트폴리오 페이지 내에서 바로 이메일 발송을 가능하게 할 것

 

 

 

 

 




1. CSS-module

 

ProjectCard 컴포넌트와 module.css

 

기존에 CSS와 SCSS를 이용한 프로젝트를 많이 경험해봤고, 리액트 토이프로젝트인 Simple-note app 프로젝트를 진행하면서 styled-components까지도 경험해봤기 때문에 이번에는 CSS-module을 기반으로 스타일 작업을 진행하고 싶었습니다.
스타일시트의 변천사를 찾아보고 검색해보니, CSS-module의 경우 클래스가 겹치지 않고 컴포넌트 단위의 스타일이 적용 가능하기 때문에 더욱 진화된 스타일 작성법으로 평가가 되고 있음을 알게 되어서 더욱 사용해보고 싶었던 것 같습니다.
클래스 지정의 고민이 사라지고 전역스타일과 분리해서 작업이 가능하니 확실히 효율이 올라가는 느낌이 들었습니다.

또한 컴포넌트/라우터 페이지별로 CSS-module을 지정할 수 있다 보니 반응형 작업에도 좀 더 수월했으며 파일 구조 파악이 직관적이어서 편리하다고 느꼈습니다.





2. Router Tab menu

 

Router로 구현한 Tab 메뉴
Tabsbar 컴포넌트에서 path를 props로 전달하는 모습
Tabsbar 컴포넌트에서 props를 전달받은 Tab 컴포넌트

 

3단 레이아웃 디자인을 구성하되 일반적인 홈페이지 이동 느낌을 느끼지 않도록 하고, 라우터를 이용하며 SPA의 효과를 극대화할 수 있는 탭 메뉴 구성을 만들고 싶었습니다.

각 페이지의 Tab을 감싸고 있는 Tabsbar로부터 props를 전달받은 Tab들은 props.pathuseLocation을 사용하여 현재 페이지의 path를 비교하여 탭을 활성화시킵니다.




3. JSON / AXIOS

 

axios를 이용하여 json 데이터를 동적으로 받아오는 project 페이지
RSS API와 axios를 이용하여 최신 블로그 포스팅을 동적으로 받아오는 blog 페이지
깃허브에 올라간 project 페이지의 custom json
axios를 이용하여 json 데이터를 받아오고있는 Projects page

 

리액트를 배우기 전에는 모든 요소들을 하드코딩했었습니다.
유지보수가 번거로웠고, 새로운 무언가를 추가하기에 까다로웠죠.

그래서 이번 포트폴리오를 만들 땐 하드코딩을 지양하고 JSON 데이터를 만들어서 axios를 이용하여 받아온 뒤 
동적으로 컴포넌트들이 생성되도록 만들어, 다양한 콘텐츠들을 쉽고 빠르게 채워 넣고 싶었습니다.

깃허브에 project에 관련된 json 파일을 생성하여 커밋한 뒤, 새로운 프로젝트가 업데이트될 때마다 배열을 추가하고 커밋해주면 ProjectCard 컴포넌트들이 .map() 메서드를 통해 자동으로 생성되도록 하였습니다.


또한 blog 페이지의 경우 RSS XML 데이터를 > JSON 데이터로 변환하는 API를 이용하여 데이터를 받아온 뒤
최근 게시물을 최대 10개까지 뿌려지도록 하였습니다.



 

4. SVG ICON Components

 

SVG 아이콘을 함수형 componet로 만든 모습
Side바의 경우 SVG components를 Import하여 배열에 담아 뿌려줍니다.

 

SVG 아이콘의 재사용성을 높이고 이미지의 최적화를 위하여 함수형 컴포넌트로 만들기로 하였습니다.
함수형 컴포넌트로 만든 뒤 props를 전달받도록 하여, className / CSS-module / width / height / path 등을 동적으로 전달받게 하였습니다.

Aside bar와 Explorer bar의 경우 각 아이콘 컴포넌트를 import 하여 배열에 추가한 뒤,
각 아이콘의 import name, path, title에 따라 동적으로 컴포넌트를 생성합니다.

 

 

 

5. --var를 이용한 Theme 기능

 

테마에 따라 전체 컬러들이 변경되는 모습

 

css 전역 변수와 localstorage를 이용하여 VScode의 테마가 변경되듯이, 사이트 내 모든 컬러들이 일괄적으로 변경되도록 만들었습니다. default 컬러는 Github Dark 테마이고, set theme 버튼을 클릭할 때마다 각 테마가 적용되도록 개발하였고
동시에 localstorage로 해당 테마의 데이터가 저장되어 웹사이트에 재접속 시에도 해당 테마가 그대로 적용되도록 구현했습니다.




 

6. Email API

이메일이 전송되는 모습
이메일이 정상적으로 도착한 모습

Email API를 이용하여 포트폴리오 사이트 내에서 이메일이 전송되도록 구현했습니다.
이메일이 발송 중일 때 Sending mail로 버튼이 변경되며,
정상적으로 발송이 되었을 경우 Succese 문구가 1초가량 노출된 뒤 본래의 Send 버튼으로 변경됩니다.
또한 input과 textarea에 있던 value를 초기화시킵니다.







 


🌱 회고록

회고록은 혼잣말처럼 반말로 작성하겠습니다 👀!

 

 

 

프로젝트 진행 전 👶

리액트 토이프로젝트를 끝내고 인터랙티브 웹에 대해서 공부하던 중에 기존 포트폴리오 사이트가 만료됨에 따라

조금 불안한 마음이 들기 시작하다 보니 공부를 진행하기 어려워졌고, 결국 마음 편히 공부하고자 포트폴리오를 먼저 만들자! 하고 마음먹게 되었다.

 

하지만 디자인엔 자신이 없고, 많은 시간을 투자하고 싶지도 않았다. 포트폴리오는 첫인상이 매우 중요하기 때문에 인상적인 디자인을 만들고 싶은데 아이디어가 떠오르지 않던 와중에

VScode가 개발자들에게 매우 친숙한 디자인이지만 포트폴리오로 만들 경우 신선할 것 같아서 VScode 스타일로 개발하기로 마음먹고 

각종 래퍼런스와 만들어야 할 기능들을 정리하기 시작했다.

 

이번 포트폴리오는 그저 프로젝트 소개 사이트로 끝날 것이 아니라, 제2의 블로그처럼 만들고 싶었기 때문에

동적으로 컴포넌트들을 생성하는 것에 초점을 맞추고 개발하였고, 그 외에도 이메일 발송 기능과 티스토리 포스팅을 받아오는 기능은 반드시 추가하는 것이 목표였다.




 

프로젝트 진행하면서 어려웠던 점 🥺

일단 토이프로젝트와는 다르게 만들어야 하는 컴포넌트의 양과 라우터 페이지의 양이 어마어마해서 초기 세팅이 오래 걸렸던 것 같다.

또한 json 데이터를 axios를 이용하여 받아오는 것이 익숙지 않다 보니 많이 버벅거렸던 것 같고 포트폴리오 제작 외에도 안에 들어가야 하는 콘텐츠들도 취합하고 정리해야 하다 보니 꽤나 오래 걸렸던 것 같다.

 



json 데이터와 RSS 데이터를 async await / 그리고 axios를 이용하여 받아오려고 하니 비동기 방식 문법이 잘 이해가지 않고

받아왔다 하더라도 Promise <pending> 상태로 반환되어 정상적으로 받아온 데이터에 접근이 불가능해서 하루 종일 헤맸다.

결국 스스로 해결하지 못하여 ㅠㅠ 인스타에 다른 개발자분들에게 질문을 올렸고, 여러 답변을 통해 문제를 알게 되어 데이터에 접근할 수 있는 방법을 알게 되었다.

요약하자면, axios는 promise 기반 http client이고 promise 객체의 resolve를 해체할 수 있는 방법이 then이나 async-await이다.

그런데 나는 async를 사용하면서 await을 promise 앞에 사용하지 않아서 Promise <pending> 값이 반환되었던 것이었다.

이번을 통해 axios의 사용 방법을 조금은 이해하게 되었고 async-await은 한 쌍으로 사용해야 한다는 것을 알게 되었다.

 



의외로 복병이었던 것이 set theme 버튼이었다.

두 개의 버튼 중 하나를 선택하면 셀렉트 표시가 되고, localstorage에 데이터가 저장되면 페이지 재접속 시에도 해당 버튼의 셀렉트 상태를 유지하도록 해주어야 하는데 useRef() 문법을 통해 className을 제어하려 했지만 쉽지가 않았다.

결국 해결 방안으로는 해당 버튼을 radio 버튼으로 만들고 defaultChecked 상태의 조건값을    localStorage.getItem("theme") ===item.theme  일 때 설정되도록 하였다.

 




그 외에도 API key값은 보안 문제로 숨겨야 하는데, 그 방법을 몰랐고 깃허브에 그대로 업로드할 뻔했다.

하지만 .env 문서를 통해 API key 은닉화 방법을 알게 되었고 깃허브에 커밋되지 않도록 잘 숨겨 놓았다. 👀 헿

 


 

리액트 프로젝트 배포 후 알게 된 것인데, 깃허브 페이지는 SPA을 지원하지 않아서.

라우터로 이동 후 새로고침 하면 404 에러가 뜬다는 것이다.. 여러 가지 방법을 시도하였지만 아직 이 부분은 해결하지 못하였다.

(2022.11.22 기준 해결 완료)

가장 유력한 방법은 HashRouter를 이용할 생각인데 이 부분은 차차 해결하려 한다.

(혹시 좋은 방법 있으면 알려주시면 감사하겠습니다..! 🙇‍♀️)

 

Github page (Github.io) SPA Reload 404 page error 해결 방법 업데이트 [2022.11.22 추가]
깃허브 페이지(Github.io) 새로고침 / 뒤로가기시 404 페이지 에러 해결 방법 업데이트


packgage.json에 homepage 링크를 추가한 뒤,
<BrowserRouter> 이 부분을
<HashRouter basename={process.env.PUBLIC_URL}> 하면 됩니다.

 

프로젝트 진행 후 얻은 것 🙌

이 또한 소소한 자신감을 얻은 것이 가장 기쁘다.

만들고 배포하고 나서 돌이켜보면 그래도 조금이나마 성장했구나. 하고 느낄 수 있는 것들이 눈에 보이니 부족하더라도 큰 애착을 갖게 되는 것이다.

이번에는 하드코딩이 아닌 axios를 통해 데이터를 동적으로 핸들링해볼 수 있어서 좀 더 뜻깊은 프로젝트였던 것 같고

그 외에도 내 손으로 API라는 것을 붙여서 사용했다는 것에 가장 큰 의의를 두고 싶다.

 



더 공부해야 할 것 ✍️

이전에도 다짐했듯이 비동기 처리 방식에 대해서 좀 더 깊은 공부가 필요할 것 같다. 
그리고 리액트 DOM에 접근할 수 있는 useRef에 대해서도 공부해서 좀 더 DOM을 핸들링하는 것에 익숙해질 필요가 있을 것 같다.

 

 

🙇‍♀️ End 🙇‍♀️

부족한 긴 글 봐주셔서 감사합니다 :D !!







#웹퍼블리셔 포트폴리오 #웹퍼블리셔 #웹퍼블리싱 #포트폴리오 #프론트엔드 #리액트

반응형