마스터정
337
2019-07-31 00:10:18 작성 2019-08-11 03:04:22 수정됨
47
9686

[React] 최종 프로젝트 평가 부탁드립니다. (비전공자 학원 고민 하시는 분들도 보시면 좋겠네요)


안녕하세요.

okky에서 많은 도움을 받은 신입 개발자 입니다.

비전공자이지만, 누구보다 노력을 많이 했고, 저처럼 진입 장벽이 두려운 비전공자분들이 더 힘내시라고,

이번에 진행한 최종 프로젝트를 소개할까 합니다.(오늘 수료했습니다..ㅠㅠ 6개월 순삭)

개발기간은 2달이지만, 실질적으로 코드를 작성한 기간은 45일 정도 되는 거 같습니다.

(그 전에는 주제 선정, 설계 등..)

 물론 소개 동영상은 FLEX하게 만들다 보니깐, "우린 달라, 우린 특별해, 너넨 우릴 못 따라잡아"라곤 하긴 했지만, 개인적인 생각은 정말 열심히 하기 나름인거 같습니다. 저희 팀은 매 주말 만나서 스터디를 6시간씩하고, 새벽에도 보면 항상 슬렉에 팀원들이 가득했거든요.  

모두들 파이팅이고, 조장으로서 팀원 모두 잘됐으면 좋겠습니다^^

아래 소개를 잘봐주세요!

감사합니다.




0. 특이점이라고 하면, 저희는 기술 위주의 프로젝트 입니다.

 프로젝트 시연 때도 기술 위주로 진행하였지만, 이미 프로젝트 주제는 더 나올 것이 없을 정도로 많다고 생각이 들어서 특이한 주제나 특정 기능에 초점을 맞추지 않고, 오로지 페이지를 구현하는 기술에 초점을 맞췄습니다. 소개 동영상을 보시더라도, 기존에 사이트를 소개하는 영상들과는 달리, 우리는 무슨 기술을 사용했다에 초점을 두었습니다. 이 점 참고 부탁드립니다.


1. 사이트 소개( http://www.team-ability.com )

 우리 프로젝트는 한국형 Stack overflow를 지향하고 있습니다. 여러가지 트랜드를 반영한 최신 기술과 고급 기술들을 많이 적용해서 만든 기술 중심형 프로젝트입니다. 사용자들은 질문을 통해 개발에 대한 해결방안을 얻고, 답변을 통해 일정한 포인트(능력치)를 얻을 수 있는 사이트 입니다. 또한 사용자들은 페이지를 통해 구인을 원하는 기업에 지원할 수 있고, 사용자 간의 채팅도 가능하며, 본인이 만든 프로젝트 영상을 다른 사용자들에게 보여줄 수 있는 공간을 제공합니다.


 사이트 접속시 메인 페이지에 한해서 서버사이드 렌더링을 구현했습니다. 물론 데이터만 서버사이트 렌더링을 구현했기 때문에, 접속시 순간적으로 css 깨짐에 대해서는 알고 있습니다. => 2019/08/11 수정 배포 했습니다. styled-components SSR 적용 완료 git-issues closed

 리액트를 학원이 아닌, 스터디로 별도로 공부하면서 프로젝트를 했던거라, 처음에 설계 미흡으로, 전체에 대해 서버사이드 렌더링을 적용할 수 없습니다. 그래서 맨 마지막에 만들었던 메인 페이지를 서버사이드 렌더링을 적용한 것입니다. 


 질문 답변 사이트인만큼, 헬멧 라이브러리를 이용해서 검색 최적화에도 신경을 써, 이후 더 나은 서비스가 제공될 예정입니다. => 2019/08/11 수정 배포 했습니다. 메인 페이지에 한해 SEO 및 Helmet SSR 적용 완료 git-issues closed


마지막으로 저희 사이트는 실제로 배포했기 때문에(gz 압축, 데몬 사용 - PM2 ) 확인하실 수는 있으나, 

돈을 벌 수 없는 상황에서 구성한 거라, 커넥션 풀이 모자를 수 있습니다.(AWS-RDS-t2.micro는 마스터 전용 풀1개를 제외한 65개의 커넥션풀이 제공됩니다. 메모리 1mb당 66개의 커넥션 풀이 제공된다고 보시면 됩니다. 자세한 사항은 AWS-RDS api문서를 정독하시면 좋을거 같습니다.)

혹시라도 오류로 서버가 종료된다면 정말 죄송합니다. 빠른 시일 내에 돈을 모아서 스케일 아웃을 진행 하겠습니다.


(혹시 사이트 이용중 오류를 발견하신다면, 깃허브 이슈에 남겨주시면 감사하겠습니다. 메인 배너 2번째에 링크가 걸려있습니다. 로컬 환경에서는 잘 되고, 빌드도 성공했지만, 오류가 있더라고요.. 많이 수정했는데, 혹시 보이면 말씀해 주세요!)

 이건 여담이지만, 메인 배너를 클릭하면, 그 클릭 수와 날짜, ip 정보 등을 수집합니다. 그리고 운영자 페이지에서 CPC 방식으로 1클릭당 1원의 비용을 계산해서 보여줍니다...;;)


2. 소개 동영상 

소개 동영상은 두 가지 주제로 구성 되어있습니다.

"어빌리티의 탄생", "어빌리티의 기술" 입니다.(소리o)


3. 


 왜 하나의 데이터 베이스에 두 개의 서버로 접근 하냐는 질문이 있을 수도 있겠는데요.

솔직히 노드로만 mysql에 접근해도 됐었고, 스프링 부트로만 접근해도 됐었습니다.

그럼에도 불구하고 두 나눈 이유는 2가지 입니다.


첫번째 이유 AWS에 t2.micro를 이용하기 때문에 스케일 아웃이나, 로드밸러싱을 구현하지 못합니다(취준생에 아품입니다...돈..). 그래서 서버로 가는 부하를 최대한 분산시키기 위함입니다.


두번째 이유는 "그럼 왜 노드랑 스프링 부트로 나눴나?" 하는 질문에 대한 답변이기도 한데요, 저희가 배운게 스프링/자바 위주이어서 사실 스프링으로만 구현하는게 좋으나, Node.js로도 서버를 구축할 수 있다는걸 보여드리고 싶었습니다. (물론 스프링 부트도 학원에서 안 배운거긴 하나, 스프링을 배우고 부트를 만지니깐 쫌 더  빠른 설정이 가능하더라고요... 시간이 부족에서 순수 스프링으로는 구현하지 않았습니다.)



4.



 배포환경에서는 익스프레스 서버는 pm2 모듈을 사용해서 무중단 배포 및 ssh 연결을 끊었을 경우에도 서버가 돌 수 있도록 구성해 두었습니다. tomcat8의 경우 우분투에서 한번 작동하면 꺼지지 않기 때문에 별도의 설정을 하지 않았고요.



5. ABILITY 프론트엔드 사이트 로드맵



6. ABILITY 백엔드 사이트 로드맵


7. 제이쿼리와 jsp도 사용했어요.

회원가입 페이지와 비밀번호 찾기는 JSP로 구현했는데요, 벨류 데이션 및 이벤트는 jQuery로 구현했고요.

이유는 별거 없습니다. 리액트로만 하면 혹시 JSP 나 제이쿼리를 못한다고 오해하실까봐 구현해 놨습니다. 커뮤니티라는 아이디어가 아닌, 기술로 많이 보여드리고 싶었어요.

(물론 제이쿼리는 리액트에서는 사용하지 않았습니다.)


8. SSR (Server-side-Rendering) 구현

검색 기반의 질문 & 답변 사이트이므로 서버 사이드 렌더링은 선택이 아니라 필수였습니다. 하지만, 초기 검색 최적화(SEO)를 위한 SSR 에 대해서 잘 알지 못했고, 초기 설계 단계에서 고려하지 못해 모든 페이지에는 적용하지 못했습니다. 그래서 가장 마지막에 개발한 페이지에만 적용하였습니다.

 현재 서버 사이드 렌더링이 적용된 페이지는 메인 페이지(index)입니다.


9. CSS 적용방식

메인 페이지와 일부 컴포넌트에서는 styled-components를 사용했고 나머지 컴포넌트에서는 css-in-js를 사용했습니다. 이렇게 나눠서 사용된 이유는 실제 프로젝트 완성 당시에는 시간이 부족하여 바로 적용할 수 있는 css-in-js방법을 선택했고, 학원 수료후 평소 배우고 싶던 styled-components를 익혀 기존 프로젝트를 수정했습니다.


10. 저희 홈페이지는 로봇배제표준을 따릅니다.

검색 기반의 질문 & 답변 사이트이므로 모든 봇에 대해서 접근은 가능하나, 일부 URL에 대해서는 접근을 불허했습니다.


11. 배포시 번들 사이즈에 대한 고찰 및 개선

 배포를 위해 파일을 빌드하였을 때, 일부 번들이 1MB가 넘게 나왔었습니다. 한국이 인터넷 속도가 빠르지만, 좀 더 나은 서비스와 t2.micro 서버이기 때문에 접속이 몰려 팬딩이 발생할 때를 대비해 최대한 가볍게 1MB 아래로만 구성하고 싶었습니다. 1MB가 넘는 파일에 대해서 처음에는 트리쉐이킹을 통해 개선할려고 했으나, 아직 해당 라이브러리들에 트리쉐이킹 이슈가 closed되지 않아, 다른 방법을 강구 하였고, 빌드시 웹팩 커스텀을 통하여 .gz 방식으로 압축하는 선택했습니다.


12. 조금 더 자세한 내용은 깃 허브 주소(리드미) 참고 부탁드립니다.

(https://github.com/JungKyuHyun/ABILITY-PUBLIC/blob/master/README.md)


 프로젝트 중간에 보안에 대한 부분도 알아보고, DOTENV를 이용해서 프론트 익스프레스 서버와 백엔드 익스프레스 서버에는 적용은 해놨으나, 이전 커밋을 보면 개인 설정 내용이 있기 때문에 깃에 있는 실제 프로젝트는 private 입니다. node.js 도 별도의 공부를 통해서 배운거라, 초기 설정에 넣지 못한 점이 있습니다; (리드미에 이전 프로젝트 총 커밋 회수 등은 적어놨습니다. 7/31 기준 커밋이 1780번이 넘네요..ㅎ). 


13. 댓글로 남겨주신 사항들은 수정하고 있으며 비록 학원은 수료했지만,

사이트 수정 및 추가 배포는 계속 진행 중이며 관련 내용은 깃허브 이슈란을 참고 부탁드립니다.

13
6
  • 댓글 47

  • moonti
    2k
    2019-07-31 00:28:55

    소개 영상부터 프로젝트까지 잘 봤습니다.
    저라면 실제 떠있는 서비스 링크를 가장 위로 올리고, 간단히 어떤 서비스인지 소개 할 것 같습니다.

  • 마스터정
    337
    2019-07-31 01:07:48

    moonti 감사합니다, 바로 수정했습니다!

  • 익진
    87
    2019-07-31 01:25:31

    본인이 작성한 코드는 언제쯤 업데이트 되나여 단순 외형만 보고는 알 수 없지않나싶네여

  • 웨어하우스
    72
    2019-07-31 08:40:20

    로그인 후 개발자들 게시판에서 페이징처리가 잘못된 것 같습니다~

    포폴용으로 참 좋겠네요 잘봤습니다.



  • owwem
    879
    2019-07-31 11:25:51 작성 2019-07-31 11:45:59 수정됨

    전체 검색이 안되네요. 프론트 부분은 훌륭한거같은데 백엔드 부분이 약간

    여기저기 완성도가 부족한 부분이 있는거같습니다. 그거만 다듬으면 정말 훌륭하겠네요

  • Yuu2
    2019-07-31 11:31:18

    고생많으셨어요 ㅎㅎ... 규모를 보면 신입이아닌거같네요 멋집니다 ㅎㅎ

  • 마스터정
    337
    2019-07-31 13:31:46

    익진  포트폴리오 만들면서 코드 부분도 정리 예정입니다..ㅎ 중복된 일은 한번만 하는게 좋으니깐요!! 조금만 기달려주세요~!!


    웨어하우스 앗... 감사합니다..ㅠ 20~21 개로 넘어갈때가 한 개가 크네요.. 


    owwem 감사합니다 ㅠ 로컬에서 잘 되던 부분인데 흑.. 


    Yuu 어차피 회사에서도 신입이지만 중고신입의 능력을 원하는거 같아서, 저희는 불평하지 않고 애초에 신입처럼 만들지 말자고 열심히 만들었습니다.  배포전 번들 사이즈 분석,  검색 최적화, 서버사이드 렌더링, 코딩 스타일의 통일(ESLINT), 디자인패턴 적용(ATOMIC), REST-API, POSTMAN을 통한 단위 테스트, 프로시저-트리거-스케줄러 구현, WEB-PACK 커스텀, 트리 쉐이킹(CLOSED 된 이슈가 아니라서 빌드 옵션을 gz 으로 수정하여 1mb 아래로만 빌드 파일 구성) 등 최대한 많은 것을 보려드릴려고 했어요! 잘 봐주셨다니 감사합니다 ㅎㅎ 

  • 웃어라포도
    2019-07-31 15:27:16

    오 멋지네요. 

    한가지 궁금한게 , 메인페이지에서 리액트를 사용하셨으면 클라이언트에서 렌더링 해준거 아닌가요? 

  • 테리야스
    10
    2019-07-31 17:18:14

    완성도는 더 있어야겠지만

    신입으로 취업을 원하신다면

    그 수준이상은 되는것같습니다. 열심히 고생하셧네요 ^^

  • 마스터정
    337
    2019-07-31 17:37:22 작성 2019-07-31 17:57:59 수정됨

    웃어라포도 

    리액트의 경우 SPA이면서, 클라이언트 사이드 렌더링이 기본이 맞지만, 저희는 메인 페이지의 경우 saga를 이용해서 데이터 부분만 서버사이드 렌더링을 구현했습니다 ㅎㅎ 

    사실 전체 페이지를 서버사이드 렌더링으로 구현하고 싶었지만, 리액트가 처음인지라, 초기 설계를 전부 뒤엎을 수가 없더라고요..ㅠ 그리고 저희가 질문/답변 중심의 검색 사이트인만큼, 클라이언트 사이드 렌더링으로 페이지를 구현해 버리면, 구글은 봇이 똑똑해서 상관없다지만, 네이버나 다음에서 검색이 안되기 때문에 서버사이드 렌더링을 구현했어요^^


    아, 그리고 회원가입/ 기업회원가입 / 비밀번호 찾기 이외의 모든 페이지는 리액트로 구성하였습니다.

    그리고 리액트 부분은 정확하게는 react, react-redux, react-hooks, javascript(es6 ++), redux-saga, next.js 정도가 대표적인 기술이 될거 같아요.


    테리야스 

    감사합니다!!ㅎㅎ 더 열심히 해야겠어요!!

  • 삼이
    1k
    2019-07-31 18:11:07

    저도 코드를 한번 보고 싶네요

  • 그림일기
    70
    2019-07-31 18:12:46 작성 2019-07-31 18:22:26 수정됨

    안녕하세요.  신입의 프로젝트라고는 믿기지 않네요. 궁금한것들이 있어서 질문드립니다.

    저도 개인적으로 리액트 프로젝트를 하는지라 궁금한점 아주많네요..


    1. redux 쓰셨다고 나와서 질문 바꿀게요. 혹시 Redux 를 특별히 채용한 이유가있나요? Mobx 라던지를 거르고..

    2.컴포넌트의 스타일은 어떤방식으로 주셨나요? ( css, sass, styled-component 등)

    3. 테스트 라이브러리,혹은 프레임워크 사용해서 테스트 해보셨나요?

    4.컴포넌트 형식은 class 형식으로 되어있나요 functional 형식으로 되어있나요? ( 통일되어있지않으면 대부분의겅우.)

    5.프로젝트 내의 GIT 브랜치나 커밋메세지의 컨벤션이 정해져있었나요?

    6. slack 을 제외한 협업툴이 있었나요? (ex trello)

    7.리액트 부분에서 타입스크립트를 적용하자는 의견이 나왔었나요?

    8.IDE 나 Editor 는 무엇을 사용하셨나요?

    9.노드 진영 vs 스프링부트 진영어떤게 더 마음에 드셨나요?

    10. 비전공자라 하셨는데 전공공부를 시작하신지 얼마나되셨나요?

    11. 다른 조의 프로젝트도 비슷한 수준인가요?


    저도 국비들어서 취업한지 1년정도 지났는데 진취적인 마인드 멋지네요.

  • 마스터정
    337
    2019-07-31 19:12:04 작성 2019-08-06 07:00:15 수정됨


    삼이  코드는 조금만 기달려 주세요..ㅠ 어제 프로젝트가 끝나서요..ㅠ 최대한 빨리 올려보겠습니다.


    그림일기 

    1-1. 리덕스를 사용한 이유는 상태 값을 처음에는 상위 컴포넌트로 올렸는데, 간단한 페이지의 경우 괜찮지만, 컴포넌트가 많고 깊어질수록 상태값 관리가 어려웠습니다. 그래서 리덕스를 사용했습니다.


    1-2. 모백스를 사용하지 않은 이유는, 솔직히 말씀드리면, 이 프로젝트를 시작할 당시 모백스를 몰랐습니다. 대부분의 책들에도 리액트와 리덕스 중심으로 설명했기 때문에 제가 자료를 많이 얻거나 공부할 수 있는 것도 리덕스였습니다. 


    2. 스타일 방식은 js in css 방식을 주로 사용했습니다. 전역 css의 경우 index 페이지에서 스타일 태그를 사용했고요. styled-component 를 사용하고 싶었지만, 사용하지 않은 이유는 전 조원이 리액트가 처음이기도 하고 각기 다른 실력 차이를 가지고 있었기 때문에 순수 리액트로 페이지를 구성하는데에도 많은 시간과 노력이 필요했습니다. 그래서 가장 러닝커브가 적은 js in css 방법을 사용했고, 반응형은 부트스트랩을 최대한 활용하여 sass의 직접 구현을 자제했습니다. 


    3-1. 테스트 라이브러리는 따로 사용해 보지 않았습니다. 포스트맨과 크롬에서 제공되는 리덕스데브툴, 리액트툴, 리액트분석툴을 최대한 활용했습니다. 


    3-2. 프레임워크는 NEXT.JS를 사용했습니다. 처음부터 사용한건 아니고, 7월 초쯤에 많은 레퍼런스를 찾아보고 서버사이드 렌더링에 관심이 생기면서 중간에 프로젝트를 엎고 다시 넥스트를 얹었습니다.


    4. 컴포넌트 형식은 사실 혼재되어있습니다. 

    이유는 중간에 저와 진호군은 같이 REACT HOOKS를 추가적으로 공부하여, 함수형의 컴포넌트를 사용했지만, 나머지 팀원은 클래스형 컴포넌트를 사용했습니다. 둘 다 할줄알기 때문에 코드 리뷰해줄때는 딱히 어려움은 없었고요. 

    그렇다고 모든 팀원의 스타일을 변경하기에는 시간적 여유가 부족했습니다. 한 가지로 통일하지 못한 이부분은 아쉬운 부분에 속합니다. 


    5. 커밋 메시지의 컨벤션도 정했습니다.

    A. 동사로 시작하며, 명령문이다.

    B. 첫줄에 제목을 적고 그 다음 한 칸 띄고 본문을 적는다.

    C. 첫줄은 영어로 적되(git log --oneline 했을때 통일되게 보일려고요.) 본문은 한글로 적어도 된다(영어로 본문을 적으라고 하면 아무도 본문을 안적을꺼 같더라고요... ..ㅎㅎ)

     - 위 내용은 커밋 메시지 컨벤션을 통일하기 위해 찾아봤더니 있더라고요. 

     - 브랜치는 마스터 브랜치 하나로 갔습니다. release 브런치나 각자 작업한 부분을 나눌려고 생각도 했지만, 모든 팀원의 git 사용실력이 동일하지 않고, 기본적인 checkout 부터 merge나 merge tool을 사용하는 방법을 모두 알려주기에는 리액트로도 벅찼던게 사실입니다. 


    6. 슬랙으로 통일했습니다. 트랠로는 이전 프로젝트에서 사용해봤지만, 저 포함하여 6명의 팀원이 굳이 툴을 추가하여 소통의 공간을 분산 시키는 것이 더 비효율적이었습니다. 그래서 이번 프로젝트에는 slack으로 통일하고, 슬랙에서 필요한 채널을 나눠 채널별로 일정-공지-작업내역-특이사항을 관리했습니다.


    7. 안나왔습니다...


    8. 메인으로는 VSCODE를 사용했습니다. 스프링부트의 경우 STS를 사용했고요. 우분투에서는 vim과 nano를 사용했어요.


    9. Node.js 가 더 좋았습니다. 이유는 더 직관적이고 추상적인 부분이 적다고 할까요? 

    스프링의 경우 너무 커져버린 덩치탓에 다루기가 무겁고 복잡했고요, 스프링 부트는 간소화 됐지만, 노드보다는 여전히 다루기가 까다러웠습니다.(스프링 시큐리티를 적용해서 그런거일 수도 있고요..)

    pom.xml에 의존성을 추가하는 것보다 패키지 매니저를 통해 모듈을 설치하는게 더 좋았고요.

    npm에서 관리가 되기 때문에 모듈별 레퍼런스를 찾기에 너무 편리했습니다. (더 좋다고 하는 얀도 있지만 둘다 사용해봤을 때는  굳이 npm에서 얀으로 넘어가야될 이유는 못 찾겠네요.)


    10. 본격적인 시작은 아무래도 자바 일텐데 학원 들어오기 1달 전부터 했습니다. Do it java 책으로 예습하고 왔던게 생각나네요..

    그 전에도 경험이 없진 않앗습니다. 이제부터는 TMI 이니, 아래글은 안보셔도 무관합니다.

    원래는 평범한 문과생이었고 회사에서 온라인 영업 관련 일을 해었습니다. 2년 전 쯤인가요. 근데 사무직이라는게 엑셀이 반이고, 중복되는 일이 엄청 많았습니다. 그리고 너무 짜증이 났던거는, 제가 막내여서 이것저것 취합을 엑셀로 받았는데, 중복되는 날짜를 취합 받으면 안되는데, 자꾸 중복되는 날짜를 넣어놓는 것이었습니다. 저보다 직급이 높았기 때문에 제가 모라고 할 수가 없었어요. 그래서 방법을 고심하다가  엑셀로 매크로를 만들고 중복되는 날짜가 입력이 안되게 해버렸습니다.

     이게 완전한 프로그래밍 이라고는 할 수없겠지만, VBA로 나름 프로그래밍에 입문하게 된 계기입니다. 그리고 봤더니, 모든 일이 귀찮아졌습니다. 네이버 쇼핑 가격조사를 하는게 있었는데, 문득 생각이 든게 이걸 왜 내가 하고 있지라는 것이었어요. 그래서 1년 전쯤인가요, python을 배웠습니다. 그리고는 크롤링 기술을 배워서 엑셀로 뽑는거까지 자동화했어요. (이 프로그램의 중간 단계의 모습을 제 유튜브에 있습니다. 최종단계는 찍지는 않았는데 좀더 세밀해 졌을뿐 큰 변화는 없어요.). 그리고 온라인 영업이 내 길이 아니고 난 개발자가 천직인거 같은데 하고 온게 이제 학원입니다. 어제 수료했던요..ㅎ


    엑셀 VBA를 배운게 전공공부의 시작이라고 하면 2년전이 될것이고, python을 접한게 시작이라면 1년 전이 될꺼 같습니다. 자바를 처음시작한게 프로그래밍의 시작이면 7개월 전이고요. 학원 다니고 부터는 거의 매일 밤을 새며, 눈 뜨면 컴퓨터만 잡았던거 같아요. 


    11. 다른 조의 프로젝트도 비슷한 수준인가는 잘 모르겠습니다. 이전 기수의 프로젝트는 분석했어도 같은 동료의 프로젝트를 이유없이 분석하고 싶진 않았습니다. 각기 특색이 있어요. 이후에 비트캠프 수료 영상에 업로드 될 예정이니, 보시면 아실꺼 같습니다. 죄송해요;;




    질문이 11가지나 되서 깜짝 놀랐습니다...

    하지만 제가 지금 포트폴리오를 만들고 있었는데, 충분히 고려해보고 넣었어야 될 내용들인거 같아 감사드립니다. 11가지건 110가지건 질문 달아주시면 답변드리겠습니다.(110가지는 대신 답변 달아드릴려면 110일 기달려주세요 ㅎㅎ)

    감사합니다.

  • 그림일기
    70
    2019-07-31 20:22:39

    마스터정 

    대단하시네요. 저도 개인 프로젝트를 진행중이여서 너무 궁금한게 많아서요.

    저는 실력이 저와 비슷한 친구랑 해당 프로젝트에 많은 기술을 섞고 싶은데,

    이게 서로 욕심이 많다보니까 끝이 없더라구요..

    그래서 프로젝트를 마친 분으로써 궁금한게 너무 많았네요 ㅋㅋ 아쉬운점이라든지.. 그런 부분들요.

    제가 신입때 이 실력 이였으면 참 좋았을텐데 ㅋㅋㅋ..

    본인의 직종을 아주 잘찾으신것같으시네요.

    7개월만에 진짜 많은걸 배우신것같아요 그 열정 진짜 부럽습니다.

    코드 올려주시면 꼭 답글달아주세욥!


  • 마스터정
    337
    2019-07-31 21:42:39 작성 2019-07-31 21:49:26 수정됨

    그림일기 

    실력이 비슷하시고 욕심이 많다고 하시면, 제가 아쉬웠던걸 말씀드릴께요.

    리액트라고 하시면,

    컴포넌트는 기본적으로 리액트에서 채택한 react-hooks로 만드시고, 

    리덕스와 리덕스-사가를 미리 공부하신 후 서버와 통신하는 기능을 만드시면 좋을거 같아요.

    전 기본적으로 요청-성공-실패의 패턴으로 리듀서를 설계했었습니다.

    export const LOG_IN_MAINTAIN_REQUEST = 'LOG_IN_MAINTAIN_REQUEST';
    export const LOG_IN_MAINTAIN_SUCCESS = 'LOG_IN_MAINTAIN_SUCCESS';
    export const LOG_IN_MAINTAIN_FAILURE = 'LOG_IN_MAINTAIN_FAILURE';

    이런식으로요.

    그리고 설계한 패턴의 사가를 구현하면 됩니다.

    function loginMaintainToken(){
        if ( localStorage.getItem('token')=== "null" || localStorage.getItem('token')  === null ){
            return;
        } 
        return axios.get("요청 주소",
         {params:{
             token:localStorage.getItem('token'),
            }
         })
         .catch((res)=>{console.log(res)});
     }
    
    function* loginMaintainAPI(){
        const result = yield call(loginMaintainToken);
        if(result.data === "success"){
            return {
                token:localStorage.getItem('token'),
                user:{
                    userid:localStorage.getItem('userid'),
                    role_name:localStorage.getItem('role_name'),
                    nick_name:localStorage.getItem('nick_name'),
                    isLogin:localStorage.getItem('isLogin'),
                    email:localStorage.getItem('email'),
                    user_image:localStorage.getItem('user_image'),
                    reputation:localStorage.getItem('reputation'),
                }
            }
        }else{
            Router.push('/user/login');
        }
    }
    
    function* loginMaintain(){
        try {
            const result = yield call(loginMaintainAPI); 
            if(result === undefined || result===null || result === "null"){
                return;
            }
            yield put({
                type:LOG_IN_MAINTAIN_SUCCESS,
                data:result,
            })
        } catch (e) {
            console.error(e);
            yield put({
                type:LOG_IN_MAINTAIN_FAILURE,
            })
        }
    }
    
    function* watchLoginCheck(){
        yield takeLatest(LOG_IN_MAINTAIN_REQUEST, loginMaintain)
    }
    export default function* userSaga(){
        yield all(    
            fork(watchLoginCheck),
        ]);
    }

    위 코드에서는 제가 처음 서버사이드 렌더링을 고려하지 않은 살짝의 문제가 있는 코드입니다.

    이게 제일 아쉬운데요. css 서버사이드 렌더링이야 하면 되긴데는데, 자세히 저희 사이트를 보시면, 로그인 후 맨 위 로그인 데이터는 css와 함께 늦게 들어와요. 로그인은 클라이언트 사이드 렌더링이거든요. 

    이걸 서버 사이드로 바꾸지 못한 이유는 바로 로컬 스토리지 값을 읽어와서 그런건데, 이런 부분도 아쉽습니다. 새로 고침시마다 로컬 스토리지가 아닌, 서버에 있는 레디스의 값을 읽어와서 로그인 유지 처리 및 데이터를 받아왔으면, 조금 더 완벽한 서버사이드 렌더링이 됬을꺼 같은데 말이죠..ㅠ

    (로그인 유지 기능만 2주일이 걸린거 같아요.. jsp에선 문제가 아니던게 리액트에선 문제더라고요)


    그래서 사가와 리덕스 페이지를 미리 설계 후, 서버사이드 렌더링을 같이 구현하시는걸 추천드립니다! 

    next.js를 사용안했다면 꼭 사용하세요, 서버사이드 렌더링이 구현이 매우 어렵습니다. 


    + 로컬스토리지는 서버사이드 렌더링시 참조 되서는 안됩니다. 왜냐하면 이건 생성 시점의 문제입니다. 서버사이드 렌더링이 먼저 된 이후에 클라이언트 측 웹이 생성되기 때문에, 생성시점이 더 늦은 로컬스토리지는 확인 할 수 없다는 에러만 나올 뿐입니다. (<-- 제가 겪었던 문제들이에요. 똑같은 걸로 고민하지 마세요!) 


    리액트로 뷰 꾸미거나 state 값 올리고 내리고 하는건 하다보면 할만 합니다. 하지만 초기 설계단계에서 고려하지 않으면, 그거의 몇 배로 시간이 듭니다. 저처럼 기간이 정해져 있다면 프로젝트를 수정할 수 없을 단계가 되버리는거죠.. 매우 아쉽습니다.


    혹시 sns 가 아닌 검색을 통한 유입이 많은 사이트라면, 헬멧 라이브러리를 통해, 검색 최적화 해주는 것도 했으면 좋겠습니다 .


    아쉬운건 많지만, 이건 특히나 초기에 잡지 않으면 나중에 서버사이드 렌더링은 잡기 힘든 부분입니다. 리액트로 프로젝트를 하신다고 하니 아쉬운 점을 넘겨드립니다. 꼭 좋은 프로젝트 만들어주세요! 

    나중에 깃 올려주시면 보고 많이 배워가겠습니다.


    감사합니다.

  • owwem
    879
    2019-07-31 22:41:03 작성 2019-07-31 22:45:45 수정됨

    아 페이지 넘어가는 문제 생각해보니까 아마도 (총 게시글 수 /  페이지당 글 수) + 1 로

    페이지 숫자를 계산하셔서 페이지가 딱 찼을때 한페이지가 더 생기는 버그가 발생하는거같은데

    math.ceil 함수를 이용해서 해결할 수 있습니다. 가우스 기호 반대로 해주는 함수거든요.


    페이지 수 = ceil( (double )총 게시글 수 /  (double) 페이지당 글 수), (더블로 캐스팅이 필요합니다)

    총 게시글 수가 0일때는 1

  • 삼이
    1k
    2019-08-01 10:27:29

    마스터정 로컬스토리지에 저렇게 많은 값을 저장할 필요가 있나요?

    토큰만 가지고 처리해도 될문제 같은데

    토큰으로 리덕스에 유저 정보 담구요

  • 마스터정
    337
    2019-08-01 12:12:19 작성 2019-08-01 14:30:08 수정됨

    owwem +

    그 문제 이전에 퀴리문부터 잘못됐더라고요.. 제가 확인했어야 했는데 시간 없다는 핑계로 테스트가 잘못됐네요.. 수정할게요! 


    삼이

    네 저렇게 많은 정보 사용도 필요도 없습니다, 처음에 경험부족으로 혹시 필요할까 하는 생각으로 죄다 넣어놨는데, 수정할게요!!  

    아 그리고 로컬스토리지에 담은 이유는 스토어에 담아봤자 새로고침 하면 다 날라가 버립니다!

    토큰만 가지고 처리하는 것 하겠는데, 혹시 서버사이드 렌더링시 로그인을 유지 시킬 수 있는 방법이 있을까요? 이부분이 제일 애매합니다. 혹시 방법을 아신다면 조금만 도움 부탁드립니다.


    프로젝트는 끝났지만, 현재 오류 수정을 계속  진행하고 있습니다. 혹시라도 또 오류가 있다면 빠른 시일 내에 수정하겠습니다. 감사합니다

  • 삼이
    1k
    2019-08-01 17:05:18

     마스터정 수정 하시라는 뜻은 아니었구요, 왜 그렇게 한건지 여쭤본거에요.

    저도 요새 리액트를 공부하고 있어서

    저 같은 경운 토큰으로 서버에 요청해서 사용자 정보를 리덕스 담고 있습니다.

    컴포넌트를 감싸고 있는 최상위 컴포넌트에서 확인하고 있어요

    헤더, 라우터 앞.. 머 이런식이요

    # velopert님리액트를 다루는 기술 책 참조해보세요

    # veloper님 github 코드 확인하셔도 되구요


  • 마스터정
    337
    2019-08-01 17:46:27 작성 2019-08-01 17:53:03 수정됨

    삼이 

    아하.. 리덕스 스토어에 열심히 담아도 새로고침 하면 삭제되는 부분은 어떻게 하셨나요? 

    저는 최상위 컴포넌트에서


    로컬스토리지에 토큰값이 존재하면 ? 로그인 유지 사가를 디스패치 시키고 : 아니면 이벤트 없이, 

    (그럼 레디스 서버에서 저장된 토큰 값을 비교하구요, 일치하면 response로 "성공" , "실패 )

    하는 방식으로 현재 로그인을 유지하고 있거든요.


    근데 문제는 이 방식을 서버사이드 렌더링에서는 할 수가 없다는 거죠. 솔직히 위 로직도 생각해 내는데 2주나 걸렸지만,

    더 문제는 서버사이드 렌더링시

    1. 로컬스토리지 값을 참조할 수 없다 

    2. 리덕스 스토어는 초기화 되어 있다


    잖아요. 그럼 대체 무슨 기준의 데이터로 서버로 부터 로그인한 사용자의 자격증명을 해서 기존 로그인 정보를 보내지게 할 수 있을까요ㅠ 벨로퍼트님도 존경하는 분이긴 하지만, 이 부분에 대한 해답을 찾지는 못했습니다.


    화면 새로고침시 마다 로딩바를 띄우는게 최선인 걸까요. ㅠㅠ

    로그인 유지 기능에는 성공했으나 새로고침시 유저정보가 없는것처럼 보이는 약간의 딜레이를 지워서 유저 경험을 향상 시키고 싶었으나, 아직까지 미제 입니다. .. 혹시 답을 알고 계시다면 힌트라도 주시면 감사하겠습니다. ㅠ

  • 삼이
    1k
    2019-08-01 23:37:35

     마스터정 음..서버사이드 렌더링이랑 무슨 상관이 있는지 모르겠지만

    제가 말씀드린건 최상위 컴포넌트에서 렌더링 될시에 서버쪽에 토큰으로 유저정보를 확인하고

    리턴 받은 유저정보를 리덕스에 너어두는 것인데

    성공 ? 실패로 리턴을 받는게 아니라, 그 토큰에 해당하는 유저정보를 받으면 리덕스에 저장하고 있습니다

    토큰이 유효하지 않다면 나머지 정보들이 렌더링 안되거나 리다이렉팅 시키는것이구요

    답변이 되었을지 모르겟네요

    아.. 그리고 제가 말씀드리는건 해답이 아닙니다.

    그냥 단지 같은 기능을 어떻게 만드는지 비교 해보고 싶을뿐입니다.


  • 마스터정
    337
    2019-08-01 23:46:41

    삼이  


    서버 사이드 렌더링으로 구현을 하지 않았다면, 로그인 정보는 최상위 컴포넌트가 렌더링 될시 클라이언트 사이드 렌더링으로 구현되자나요? 혹시 그때 화면에 데이터가 비었다가, 혹은 로그인이 안된 상태가 살짝 보이는데,


    그걸 막고 싶어서 서버사이드 렌더링으로 로그인 유지를 구현할려고 했고, 그 점에대해서 도움을 요청드렸던 겁니다 ㅎㅎ

    혹시 컴퓨터가 너무 좋다면 크롬 디버그 툴을 이용해서 천천히 사이드를 렌더링 해보시면, 데이터가 없다가 들어오지 않으신가요?ㅠ 

  • 삼이
    1k
    2019-08-01 23:50:50 작성 2019-08-01 23:52:06 수정됨
  • 마스터정
    337
    2019-08-02 00:01:29 작성 2019-08-02 00:09:28 수정됨

    삼이 

    그 시간은 오래 걸리진 않지만, 순간적으로 깜박임이 있지 않으신가요?ㅠ

    F5키로 새로고침 할때 모습이에요!

  • 삼이
    1k
    2019-08-02 00:14:08

     

    마스터정 낼 오전중에 확인하고 말씀드릴게요!
  • 마스터정
    337
    2019-08-02 00:18:53

    삼이 

    앗, 감사합니다!! ㅎㅎ 굿나잇하세요!!

  • 삼이
    1k
    2019-08-02 11:24:11
    마스터정 스샸을 찍어서 보여드릴순 없지만, 저는 그런 문제가 마스터정님처럼 보이진 않네요






    나중에 코드 공개하시면 코드를 한번 볼게요!

  • 마스터정
    337
    2019-08-02 14:25:14
  • Sosu
    543
    2019-08-05 12:27:11

    여기서 redis랑 spring boot는 무슨 역할로 있는거죠?

  • 남쪽행운
    64
    2019-08-05 12:54:29

    퍼블리셔로써,

    개발 관련 프로젝트이니 그쪽에 집중하셨을터라 제가 왈가왈부 할 내용은 아닌 듯 하지만..

    화면 구성은 어떻게 진행됐는지 궁금하네요.

    현재 소스로는 front 쪽 html / css 쪽만 보자면 손볼게 엄~~~~~청 많아서요.

    불필요하거나, 마크업 오류로 잡히는 부분도 많구요. (w3c validation 으로 해보니 메인만 경고 포함 오류 55개 나오네요)





  • ilovepc
    69
    2019-08-05 17:21:33

    제 이메일에 언더바(_)가 들어가는데 ... 올바른 이메일 형식이 아니라고 떠요 ㅠㅠ

  • 마스터정
    337
    2019-08-05 17:38:03 작성 2019-08-05 18:13:35 수정됨

    김성민  spring-boot는 톰캣 서버를 이용하여, 요청을 보내고 그 요청에 대한 여러 서비스 로직을 처리 합니다. 노드로만 구성해도 되고 스프링으로만 구성해도 되나, 취업시 스프링이나 자바 관련 부분도 많이 보시길래 서버를 두 가지 만들어, 데이터를 주고 받고 있습니다. redis의 경우 로그인 토큰 값 저장 용도로 쓰입니다. 캐시는 1일로 설정해 두었으며, 인메모리 방식으로 속도도 더 빠르고요! 그리고 성능이 낮은 DB를 사용하다 보니, DB로 보내는 요청을 최소화 해야됐습니다.(고가역성의 DB는 현재 저희 팀이 모두 취준생이고 많은 돈을 지불할 수 있는 여건이 되지 않습니다.)


    남쪽행운 화면 구성은 스택오버 플러우와 오키 등을 참고하며, 한땀한땀 부트스트랩을 이용해서 만들었습니다. 불필요하거나 마크업 오류도 많은 것은 알고는 있으나, 45일 동안 리액트를 공부하면서, 퍼플리싱까지 완벽하게 할 수는 없었기 때문에 선택과 집중을 하게되었습니다. 기능적인 부분에 더 신경을 쓰고 있습니다. 죄송합니다 ㅠ

    왜 템플릿을 안썼냐고도 질문하실 수 있겠지만 안쓴게 아니라, 저희가 원하는 템플릿이 없기도 했고, 일반 템플릿을 리엑트로 변경할려면 직접 필요한 부분만 만드는게 훨씬 시간이 적게 들었습니다.


    ilovepc  바로 수정 수정하여 추가 배포 하겠습니다. (https://github.com/JungKyuHyun/ABILITY-PUBLIC/issues/27) 일정은 깃허브 이슈를 통해 공유하겠습니다~!


  • 남쪽행운
    64
    2019-08-05 17:59:38

    @마스터정 

    아니에요~^^. 그냥 개발공부 하시는 분들이 그 영역을 어떻게 시도하시는지 궁금했었습니다.

    개발하는 것만으로도 시간이 부족하셨을텐데 노력한 것들이 잘 보이는 사이트인 것 같아요.

    추후 개발을 전문적으로 하시게 되면 퍼블 영역에 대한 관심도 가져주세요~


  • 마스터정
    337
    2019-08-05 18:09:44

    남쪽행운 

    넵, 퍼블리싱은 해보니깐 정말 힘들고 어렵다는 것을 알았어요.

    왜 css 속성을 주면 제 마음대로 움직이질 않던지... 제일 힘들었습니다. 정말 존경합니다..

    앞으로 퍼블 영역(?)도 신경 많이 쓰겠습니다^^

  • 마스터정
    337
    2019-08-06 04:19:32 작성 2019-08-06 04:30:18 수정됨

    ilovepc 안녕하세요 어빌리티 개발자입니다.

    테스트 및 관련 내용 검토 결과 이메일 관련 벨류데이션에는 _(언더바)는 사용 가능하며, _이외에 다른 문자나 공백 등에서 오류가 난거 같습니다. 이메일 주소를 알려주시면 재 확인해보겠습니다. 일단 해당 이슈는 closed 하였습니다.

  • ISA
    2k
    2019-08-06 09:03:37

    화이팅

  • Mommoo
    937
    2019-08-06 09:33:48

    최근본 신입 포트폴리오 중 에서는 제일 좋은거 같습니다. 고생하셨어요!!

    여담으로, 다른 신입개발자 분들에게 당부드리고 싶은점은 부트스트랩으로 단순히 페이지만 꾸며서는 경쟁력이 없다는 점을 알려드리고 싶네요. 본 포트폴리오가 좋은 예시인거 같습니다.

  • 마스터정
    337
    2019-08-06 11:37:11

    ISA . Mommoo 

    감사합니다, 저 열심히 하겠습니다!ㅎㅎ

  • 기분전환
    1k
    2019-08-06 15:05:22

    오류 하나 제보 합니다~

    중앙 최상단 검색 창 버튼 돋보기 누른후

    좌측 최상단 배너(홈버튼) 누르면 400 오류 페이지 나옵니다.

  • 마스터정
    337
    2019-08-06 18:50:49

    기분전환  감사합니다! 

    이슈에 추가하고 수정하도록 하겠습니다!

    깃이슈 #34

  • 익진
    87
    2019-08-10 15:36:47

    자바코드도 작성자님이 담당하신건가요??

  • 마스터정
    337
    2019-08-10 22:06:23

    익진 

    기본적인 서버 구성은 제가 했으나, 나머지 부분은 (컨트롤러, 매퍼 등) 실제 api 통신과 그와 관련된 로직은 각 게시판 담당자(팀원 모두)가 맡았습니다. 물론 저도 있습니다.

  • 익진
    87
    2019-08-10 23:13:13 작성 2019-08-10 23:14:31 수정됨

    마스터정

    주석에 코드담당자가 적혀 있어서 마스터정님이 작성하신 코드를 살짝 봤는데

    몇가지 묻고싶은게 있습니다 

    첫번째는 RestController쓰신것으로 보아 rest로 설계된 api같은데 결과 상태를 담아 리턴 안하는 이유가 있으신건가요?? 프로젝트 내 다른 부분에서 따로 처리해주는 부분이 있는건가요???

    두번째는 CommunityController에 insertReply()은 무조건 성공적인 결과만 가져오는게 맞는지 다시 생각해보는게 어떨까 싶습니다 답글작성시 원문글이 삭제 되는 경우라던가 예외 발생에 대한 대책이 보이지 않네요(트랜잭션,예외처리 등) 

    세번째는 CommunityController에postRecommand() 에서 result는 String보다는 boolean이 더 적절한 타입이지 않나요????? 굳이 String으로 하시는 이유가 궁굼합니다 유지보수시 result에 값은 2가지가 아니라 무한가지로 변경이 가능한데 혹시 result에 결과값이 추후에 추가될 가능성이 있어서 그런건가요??

    네번째는 파라미터로 받는 seq는 뭔가요,,,,???????? 저렇게 명명하신 이유가 따로 있는건가요??

    다섯번째는 RequestParam으로 많이 받는 것보다는 Vo나 Dto를 활용하시는거에 어떻게 생각하는지 궁굼합니다 dto와 vo까지 설계하셨는데 컨트롤러에서 하나하나 다 받는 것에 어떤 이유가 있는지 묻고싶습니다

    마지막으로 중복되는 코드,중복되는 vo,dto가 보입니다 이것들 고려하지 않고 각각 따로따로 두신 이유가 무엇인지 궁굼합니다


  • 마스터정
    337
    2019-08-11 01:16:22 작성 2019-08-11 01:18:51 수정됨

    코드 리뷰를 해주신거에 대해 정말 감사드립니다.

    사실 신입 개발자로서는 정말 나의 코드를 보여준다는게 너무 민망하고 쪽팔렸지만, 그럼에도 불구하고 지금처럼 피드백 받고 고치는 편에 백배 낫다고 생각이 들었었는데 역시나 매우 민망하고 부끄럽지만, 감사한 마음으로 답변드리겠습니다.


    1. 이 부분은 어떤 부분인지 알려주세요! 

    2. 이 부분은 제가 간과했던 부분입니다. 바로 깃 이슈에 올려놨고, 이 후 개발에서도 잊지 않고 꼭 처리하겠습니다. 정말 감사합니다!! (깃 이슈는 현재 선 작업 중인게 있어, 이슈가 많이 밀려있는 상황입니다. 이점 죄송합니다.)

    (일부 컴포넌트 CSS SSR 적용 및 SEO를 위한 Helmet SSR 적용(현재) -> https로 전환 -> 일부 테스트 코드 작성 -> CI/CD (jenkins or travis) -> 이슈 수정 처리) - 물론 그 전에 서버는 닫을 수 있습니다. 취준생의 신분으로 AWS 비용이 너무 부담이 되서요. 저번달에만 130달라가 청구된.. 예약 인스턴스를 구매할 것인지도 고민했지만, 유지기간이 이슈와 여기서도 또 금액적인 이슈가 발생해서요. 

    3. dev와 prod환경에서 약간 달라진 점이 있어서 그렇습니다. 최초 구현한 기능에는 한 가지 경우의 수가 더 있었습니다. 총 3가지로 발생하여, boolean 보다는 String 으로 했었습니다. 

    4. seq는 글번호 입니다. 시퀀스의 약자이며, 처음에 변수명에 대한 명명을 했었는데, 이 부분이 빠져있어, 최초로 사용한 팀원의 변수명으로 통일했습니다.

    5.  일부에서만 vo, DTO로 받고 있습니다만, 이유는 "딱히 클라이언트에게 노출되어도 상관 없는 로직이다, 받는 데이터가 많지 않다. 그렇다고 모든 걸 vo, DTO로 받는다면 나는 성능상 이점을 누릴 수 있는가?에 대한 고민" 입니다. 그렇다고 DTO로 받은 모든 데이터가 위에 경우에 해당이 되지 않나?라는 질문을 하실 수도 있겠지만, 사용 중 그때 그때 더 맞다는 방법으로 생각되는 방식을 했습니다. 


    보시면 아시겠지만, 여러 부분에서 비효율적인 부분과 리펙토링 책을 1장만 보고 오더라도 수정해야 될 부분이 많습니다. 사실 저희가 이번 프로젝트에 적용한 리액트는 45일 동안 정말 고군분투하며, 별도의 스터디를 병행하면서 프로젝트를 만들었던 부분이라, 시간이 많이 부족하고 미리 정했던 코딩컨벤션이 잘 지켜지지 않는 것이 사실입니다.

     그래서 프로젝트도 사실상 종료되고, 학원도 수료했지만 미흡했던 부분들은 말씀해 주시면 이슈관리하며 수정중에 있습니다. 만약 수정하지 못하더라도 저희 프로젝트에 대한 지적 한번에 대한 부분은 꼭 생각하며, 이후 더 나은 개발자가 되겠습니다.

    다시 한번 모든분께 코드 리뷰 정말 감사드립니다.

  • 코쟁이놈
    142
    2020-01-02 23:04:18

    몇명이서 진행한 프로젝트인가요?

  • bbikko
    2
    2020-06-19 15:43:06

    와 진짜 대단하세용

  • sinnan
    61
    2020-08-12 14:19:38
    혹시 국비학원 이름 알 수 있을까요?
  • 로그인을 하시면 댓글 을 등록할 수 있습니다.