[넘블 챌린지] vanillaJS로 신년메시지 주고받는 SPA 사이트 만들기

할거면제대로·2023년 2월 9일
0

프로젝트

목록 보기
1/1
post-thumbnail

챌린지 진행 기간은 1월 6일부터 1월 19일까지였지만, 추가 공부를 하다가 이제 회고록을 쓰게 되었다

📌 챌린지 소개

넘블측에서 제공하는 백엔드 API를 이용하여 바닐라 자바스크립트로 SPA사이트를 만드는 챌린지이다.
와이어프레임을 제공해주고, 주어지는 요구사항에 맞게 챌린지를 진행하면 된다.
챌린지 가이드라인

요구사항

  • 구현
    • ES6 문법 사용
    • 상태관리 library 사용 불가
    • 사용 가능한 library
      • 정적 파일 제공을 위한 express 사용 가능
      • axios 및 HTTP 관련 library 사용 가능
      • CSS 전처리기 자율적으로 사용 가능하며, 이에 따라 필요한 library 사용 가능
      • 이미지 업로드는 아래에서 추가 설명
    • 디자인
      • 기본적인 가이드라인은 지켜야 함 (단 색상, 폰트 등은 제약 없음)
      • 모바일 기준으로, 가로 넓이는 최대 640px
    • 이미지 업로드는 URL 만 가능함
  • 코드 버전 관리에 대해서
    • Git 을 이용해 코드 버전 관리하기
  • 배포에 대해서
    • AWS, 네이버 클라우드 등을 이용하여 배포

와이어프레임

🎯 참여 동기

2022년 9월부터 자바스크립트 공부를 시작해서 알고리즘 문제로 공부를 해왔다. 그리고 dom을 다루는 연습을 하기 위해서 10월 말부터는 우아한테크코스 프리코스에 참여하게 되었는데, 이번 기수에는 콘솔 환경에서 미션이 진행되었다.

그래서 올해부터는 웹개발을 중심으로 공부를 하기로 마음먹었고, 우연히 개발 관련 오픈채팅방을 통해 넘블이라는 챌린지 사이트를 알게되었다.
그리고 때마침 네카라쿠배 개발자와 함께 VanillaJS 활용하기 챌린지가 1월 6일부터 시작된다고 하여서 신청을 하게 되었다.

내가 이번 챌린지를 신청한 이유는 다음과 같다.

  1. 기초를 제대로 다지기 위해 프레임워크나 라이브러리 없이 바닐라 자바스크립트로 웹 개발을 시작하려고 했었다.
    -> 챌린지는 바닐라 자바스크립트로 진행된다.
  2. 나는 공부를 같이 하는 사람이 주변에 없다. 그래서 같이 공부하고 도움을 주고 받을 수 있는 사람이 있음면 좋겠다고 생각하였다.
    -> 팀빌딩을 제공한다.

이러한 이유들 때문에 이번 챌린지가 나에게는 매력적으로 느껴져서 신청하게 되었다.

이 때까지만 해도 나를 위해서 이 챌린지가 만들어진 것 같다는 생각이 들었다...

😥 뒤늦게 알게된 SPA의 존재

챌린지를 신청하고 시작하기 전까지만 해도 나는 SPA가 무엇인지 몰랐다.
사이트 만들기니까 자바스크립트로 뚝딱뚝딱 만들면되겠다라고만 생각했었는데, 일반 사이트만들기가 아니었다.
검색해보니까 Sigle Page Application....
index.html 뼈대를 이용하여 js를 갈아끼우는 형태로 사이트를 만드는 것이었다...
일반 웹사이트 만드는 것도 제대로 해본적 없는데 SPA를 만들라고 하니까 정말 쉽지 않을 것 같다는 생각이 들었다.
하지만 그래도 해내야지라고 생각하고, 공부하면서 구현해 나갔다.

🎯 결과물

깃허브 링크
배포 사이트

메인페이지

-> 게시글 작성페이지와 상세 게시물로 이동할 수 있다.

게시글 작성 페이지

-> 이미지와 텍스트를 입력하면 글 작성하기 버튼이 활성화 되면서 글을 작성할 수 있다.

상세 게시물 페이지

-> 댓글을 작성하고 삭제할 수 있다.

-> 글을 수정할 수 있다.

-> 글을 삭제할 수 있다.

📁파일 구조

📦src
 ┣ 📂css  
 ┃ ┣ 📜detail.css      ----------------------------------- 상세 게시물 페이지 css 관리
 ┃ ┣ 📜edit.css        ----------------------------------- 게시물 수정 페이지 css 관리
 ┃ ┣ 📜home.css        ----------------------------------- 메인 페이지 css 관리
 ┃ ┣ 📜navbar.css      ----------------------------------- 중복되는 네비게이션 바 css 관리
 ┃ ┣ 📜style.css       ----------------------------------- css 통합 관리 css 관리
 ┃ ┗ 📜upload.css      ----------------------------------- 게시물 추가 페이지 css 관리
 ┣ 📂images
 ┃ ┗ 📜left-arrow.png  ----------------------------------- 뒤로가기 아이콘 
 ┗ 📂js
   ┣ 📂api
   ┃ ┣ 📜commentApi.js ----------------------------------- 댓글 관련 api 관리
   ┃ ┣ 📜imageApi.js   ----------------------------------- 랜덤 이미지 api 관리
   ┃ ┗ 📜postApi.js    ----------------------------------- 게시물 관련 api 관리
   ┣ 📂handler
   ┃ ┣ 📜detailPostHandler.js  --------------------------- 상세 게시물 페이지 핸들러
   ┃ ┣ 📜editHandler.js        --------------------------- 게시물 수정 페이지 핸들러
   ┃ ┗ 📜uploadHandler.js      --------------------------- 게시물 추가 페이지 핸들러
   ┣ 📂utils
   ┃ ┣ 📜dom.js                --------------------------- dom 관리
   ┃ ┗ 📜url.js                --------------------------- url 관리
   ┣ 📂views
   ┃ ┣ 📜404.js                --------------------------- 404 페이지 렌더링
   ┃ ┣ 📜detailPost.js         --------------------------- 상세 게시물 페이지 렌더링
   ┃ ┣ 📜editPost.js           --------------------------- 게시물 수정 페이지 렌더링
   ┃ ┣ 📜header.js             --------------------------- 네비게이션 바 렌더링
   ┃ ┣ 📜home.js               --------------------------- 메인 페이지 렌더링
   ┃ ┗ 📜uploadPost.js         --------------------------- 게시물 추가 페이지 렌더링
   ┣ 📜index.js                --------------------------- index.js
   ┗ 📜router.js               --------------------------- 각 페이지 라우팅 관리
📜index.html                   --------------------------- html 뼈대 
📜_redirects                   --------------------------- 배포 리다이렉팅 파일
📜server.js                    --------------------------- 로컬 서버 파일

파일 구조를 이렇게 구성한 이유

우아한테크코스 프리코스를 하면서 클린코드를 짜는 것과 역할 분리의 중요성을 배웠었다.
하지만 경험이 부족해서 그런지 아무리 고민을 해도 어떻게 짜야될 지 감이 오지 않았다. 그래서 프로젝트 생성과 삭제를 엄청 많이 했던 것 같다.
결국 결론은 이런 부분은 경험을 통해 배우는 것이라고 생각하고 그냥 생각나는대로 구성하였다. 기본적으로 모든 파일들이 소스코드라고 생각했기 때문에 src폴더를 만들고, 그 안에서 크게 css, image, js로 나눴다.

  • css : 각 페이지별로 css를 따로 만들고, style.css에서 통합관리 하였다.
  • image : 이미지 파일을 관리하였다.
  • js
    - api : 게시물 관련 api와 댓글 관련 api, 이미지 api를 나누었다.
    • handler : 페이지 별로 구성한 핸들러이다. 이 파일을 통해서 이벤트 처리 등을 한다.
    • utils : 공통적으로 많이 쓰이는 파일들을 utils로 묶었다.
    • views : 각 페이지별로 렌더링 파일을 묶어두었다.
    • index.js : 사이트를 열거나 새로고침할 때 이벤트를 통해 라우터 파일을 연결하고, 클릭 등의 이벤트를 발생시켜 핸들러와 연결하여 각 페이지를 렌더링 할 수 있게한다.
    • router.js : 각 페이지로 연결될 수 있게 하는 파일이다.

🎯 핵심 로직

function App() {
  const route = new Route();
  document.addEventListener("DOMContentLoaded", route.loadPage);

  document.addEventListener("click", e => {
    e.preventDefault();
    if (e.target.dataset.href === "/") return route.routePage(e);
    if (window.location.pathname === "/") return route.routePage(e);
    if (window.location.pathname === "/upload") return handleUpload(e);
    if (window.location.pathname.includes("post")) return handleDetailPost(e);
    if (window.location.pathname.includes("edit")) return handleEdit(e);
  });

  document.addEventListener("keyup", e => {
    if (e.target === $("#input-title") || e.target === $("#textarea-content")) {
      handleUpload(e);
    }
  });

  addEventListener("popstate", route.loadPage);
}

처음에는 각 연결부분들에 이벤트 리스너를 따로 작성할까 싶었는데 이벤트 리스너가 많아지면 웹사이트가 느려질 수도 있다고 하였다. 그래서 그 부분을 생각해서 이벤트를 유형으로만 나누었다. 유형별로 살펴보자면

  • DOMContentLoaded
    먼저 페이지가 처음 로드될 때와 새로고침을 했을 경우를 생각해서 DOMContentLoaded를 하나의 이벤트리스너로 사용하였다.
    이 부분에서는 현재의 url주소를 판단하여 router.js의 라우터를 통해 각 페이지를 연결한다.
  • click
    클릭으로 연결되는 부분이 많아서 하나의 클릭이벤트를 통해 연결되도록 만들었다. 먼저 preventDefault는 기본 수행 동작을 막기 위해 사용하였다.
    처음 if문 부분은 뒤로가기("<")아이콘과 HPNY2023문구를 클릭하면 이동되게 하려고 a태그의 href를 이용려 했으나 뒤로가기아이콘과 preventDefault()때문에 위 방식으로는 target이 잡히지 않아 이 방식을 사용하였다. (이 부분은 추후에 공부를 통해 더 좋은 방법을 찾아봐야겠다.)
    각 부분의 pathname을 이용하여 루트경로 이후의 경로를 확인한다. 그리고 마지막 includes 부분도 일관성 있게 사용하고 싶었으나 post/:id, edit/:id 형식으로 경로가 지정되어 방법이 떠오르지 않아 이런 방식으로 코드를 작성하였다.
  • keyup
    게시글 작성 페이지에서 이미지가 들어가고 제목과 내용이 작성 되었을 때, 글 작성하기를 활성화되게 하려 하였다. 그래서 제목과 내용의 텍스트를 확인하기 위하여 keyup 이벤트를 사용하였다.
  • popstate
    SPA사이트에서 뒤로가기를 구현하기 위하여 popstate이벤트를 사용하였다.

click 이벤트에서 각 부분을 모두 if문으로 구성한 이유는 이 방식이 리턴하는 사이클이 짧아서 가독성이 좋기 때문에 바로 리턴하는 방식을 채택하였다.

function Route() {
  this.loadPage = async () => {
    let location = window.location.pathname;
    if (/\/post\/[0-9]+$/.test(location)) {
      const detailPost = new DetailPost(location);
      await detailPost.render(location);
    } else if (/\/edit\/[0-9]+$/.test(location)) {
      const postApi = new PostApi();
      const { post } = await postApi.getPost("/post/" + location.split("/").at(-1));
      const editPost = new EditPost();
      editPost.render(post.title, post.content, post.image);
    } else if (location === "/") {
      const home = new Home();
      home.render();
    } else if (location === "/upload") {
      const uploadPost = new UploadPost();
      uploadPost.render();
    } else {
      PageNotFound();
    }
  };

  this.routePage = e => {
    const renderButton = e.target.closest("a");
    if (!renderButton) return;
    window.history.pushState({}, "", renderButton.href);
    this.loadPage();
  };
}

Route 함수는 각 페이지를 렌더링하기 위해 연결해주는 함수이다.
loadPage 함수는 각 페이지로 연결해주는 함수이고, routePage는 a태그로 되어있는 네비게이션바(뒤로가기(<)와 HPNY2023)를 누를 때 이동되게 하기 위해 구성하였다. App함수에서 썼던 preventDefault()와 안에 있는 img태그 때문에 href가 잡히지 않아 이 방식을 선택했다.

원래 loadPage함수는 따로 객체로 구성하여 href를 객체 키로 연결되는 방식을 사용했는데 게시물을 불러오고 수정하는 부분의 pathname이 post/:id, edit/:id 형식으로 되어 있어서 사용할 수 없었다. 그래서 일관성을 갖추기 위해 모두 if문으로 사용하였다.

일관성을 갖춘다고는 했지만 전반적으로 코드들이 일관성이 없어보이는게 보이고, 난잡해 보이는 코드가 된 것 같아서 아쉽다. 이 부분은 마음에 담아두고 다음 프로젝트를 할 때 더 신경써서 구성해 보아야겠다.

💣어려웠던 점

솔직히 모든 부분이 어려웠다. 처음해보는 것이라서 그런지 쉬운 게 하나도 없었고, 정말 고민의 연속이었다.
그래도 그 중에서 가장 어려웠던 점은 상세 게시물 페이지에서 새로고침할 때 생기는 오류, netlify 배포 시 생기는 오류를 뽑을 수 있겠다. 하나씩 차례대로 살펴보자

1. 상세 게시물 페이지 새로고침

이 부분은 정말 나에게 큰 스트레스를 주었다. 어느 부분이 문제인지 전혀 알 수가 없었다. 애초에 잘못된 페이지라고 한다면 404페이지로 연결되도록 했는데 상세 게시물 페이지에서는 계속 아래와 같은 오류가 발생하였다.

찾아보니 오류의 원인은 js 파일이나 css 파일 등의 리소스 파일 사용시 접근을 못하는 에러라고 하였다. 그러나 왜 접근을 못하는지는 찾을 수가 없었다.

임시방편으로 해결했다 !

그래서 나는 원인을 찾아보다가 정상적으로 열리는 페이지와 에러가 생기는 정상적으로 열리는 페이지의 차이점을 발견했다.
pathname이 "/"인 메인 페이지와 "/upload"인 게시물 추가 페이지는 정상적으로 새로고침 되었고, "/post/:id"형식으로 된 상세 게시물 페이지와 "edit/:id"로 된 게시물 수정페이지는 오류가 발생했다.
혹시 슬래쉬를 두번써서 들어가면 오류가 생기는 것인가 싶어서 두 페이지 모두 "/:id"형식으로 수정하였다. 그랬더니 오류가 감쪽같이 사라졌다. 그래서 마지막 스터디날에 이 부분을 해결하지 못하고 있던 팀원분들에게도 알려드렸다.

근본적인 문제 해결!!

하지만 이 방식으로 해결하는 것은 근본적인 해결책이 아니었기 때문에 찝찝함이 계속 남아 있어서 해결책을 찾기 위해 온갖 방법을 다써봤다. 구글로 검색해서 구석구석까지 훑어보고, 나의 유일한 선생님이었던 chatGPT에게도 물어보고.... 하지만 답은 찾을 수 없었다.
이렇게 모든 시간을 여기에 쏟기에는 너무 시간 낭비라는 시간이 들어서 매일 몇시간씩만 찾아보았다. 그렇게 일주일 정도가 지나고 이제 포기하고 성장한 미래의 나에게 맡기려고 마음먹었던 찰나에 이유를 알게 되었다.
우연히 경로에 관해서 검색을 하게 되었는데 설마? 라는 생각이 머릿속을 스쳐가면서 동시에 오류의 원인이 리소스 파일에 접근을 못하는 것이라는 생각이 같이 스쳐지나갔다. 그래서 index.html을 확인했는데 스크립트의 경로부분이 상대경로로 되어있어서 절대경로로 바꿨다.

그리고 기도를 하며 새로고침을 해봤는데 해결되었다.. 너무 기뻤지만 생각보다 너무 간단하게 해결되어서 허탈하였다.

그 후 이유를 찾아보니 스크립트에 상대경로를 사용할 경우 브라우저를 거치면서 서버가 잘못된 MIME 타입으로 응답하기 때문에 오류가 발생한다는 것을 알았다.

이렇게 원인을 알아보고 다른분들의 결과물 코드를 봤는데 다들 절대경로로 쓰거나 절대경로로 수정한 흔적이 보였다.. 전혀 경로의 문제라고 생각하지 못해서 이렇게 오래 걸린 것 같다.
그래도 결과적으로 원인을 알게 되어서 뭔가 기분이 좋았고, 챌린지 팀원들에게도 원인을 알려주었다. 뿌듯!
그런데 어떤 메커니즘 때문에 상대경로를 쓰면 오류가 생기는 걸까? 이건 차차 공부하면서 알아봐야겠다.

2. netlify 배포 오류

위의 상대경로 문제를 해결하고 나서 배포까지 빨리 하고 해치워버리고 싶었다. 하지만 끝까지 나를 곱게 보내주지 않았다..
먼저 완성된 결과물을 그냥 배포를하면 다음과 같은 오류가 발생한다.

이 오류는 https사이트에서 http를 통해서 리소스를 요청할 때 생기는 오류이다. netlify는 https 사이트인데 api들이 http이기 때문에 발생한 오류로 였던것이었다.
이 오류 자체는 챌린지 디스코드 채널을 통해서 먼저 오류를 겪으신 분이 관련 자료를 올려주셔서 쉽게 해결할 수 있었다.
_redirects 라는 파일을 만들어서 아래와 같이 코드를 작성해주고,

/api/* http://43.201.103.199/:splat 200
/api/* http://43.201.103.199/:splat 201
/* / 200

api 주소를 아래와 같이 바꿔주면 해결된다.

ex)
before >http://43.201.103.199/posts
after > api/posts

http와 https를 연결해줘야하기 때문에 리다이렉팅이 필요하다.
netlify에서 리다이렉팅을 하는 방법은 _redirects파일을 확장자 없이 쓰는 방법과 netlify.toml 파일에 규칙을 처리하는 방식으로 두가지가 있다.
내가 한 방법은 두 가지 방법중에서 확장자 없이 쓰는 방법을 사용하였다.
위 예시로 간단하게 설명하자면 api는 http://43.201.103.199에 대응되고 *부터는 :splat에 대응된다.
자세한 부분은 공식문서, 공식문서, 참고 링크를 통해 확인할 수 있다.
하지만 이상하게도 배포하고나서 상세 게시물 페이지가 들어가지지 않았다.

일단 해결한 방법

이 부분도 챌린지 팀원분이 이미 겪은 문제라서 바로 해결할 수 있었다.
위에서 사용했던 _redirects 코드를 다음과 같이 수정하면 해결이 된다.

/api/* http://43.201.103.199/:splat 200
/api/* http://43.201.103.199/:splat 201

/post/api/* http://43.201.103.199/:splat 200
/post/api/* http://43.201.103.199/:splat 201

/edit/api/* http://43.201.103.199/:splat 200
/edit/api/* http://43.201.103.199/:splat 201
/* / 200

이 부분은 혼자 생각해보려 했지만 상세 게시물 새로고침에 모든 힘을 다 사용하여 더이상 생각하는 것이 힘들어서 이 코드를 사용하였던 팀원분께 물어봤고 이유를 알 수 있었다.

메인 페이지
메인페이지에서 불러오는 게시글 api는 요청 url이 ~/api/posts로 되어있기 때문에 리다이렉트 부분의 윗 두줄로만 해도 해결이 된다. 게시글 불러오는 api는 baseurl/posts 형식이기 때문에 올바르게 대응되어 리다이렉팅이 가능해지기 때문이다.

상세 게시물 페이지
상세 게시물 페이지에서 게시물 하나를 불러오는 api를 요청할 때, 요청 url이 ~/post/api/post/117로 나온다.
이 상태에서는 윗 두줄이 대응이 되지 않기 때문에 리다이렉팅이 불가능하다.
가운데 줄을 추가해서 적용해보면 /post/api 가 http://43.201.103.199/로 대응되고 그 이후의 코드는 /post/117에 대응이 된다. 상세 게시물 api는 baseurl/post/:postId 형식이기 때문에 제대로 불러올 수 있게 된다.

이렇게 해결법은 알게 되었지만 한가지 의문이 있었다. 나는 api 처리를 fetch로 하였는데 메인 페이지의 게시글 api는 fetch("api/posts")로 되어 있어서 ~/api/posts가 되는 것은 납득을 했다.
그러나 상세 게시물 페이지에서는 fetch("api/post/postNumber") (postNumber는 변수) 이런 형식으로 되어 있어서 ~/post/117/api/post/117이 될 줄 알았는데 ~/post/api/post/117이 돼서 혼란이 왔다.

그래서 이 부분에 대해서도 팀원분과 고민을 해보다가 결국 원인을 알게 되었다.

문제 해결 완료!

문제의 답은 경로에 있었다.
fetch를 사용할 때 첫 부분을 슬래쉬 없이 사용하면 그 경로는 상대경로로 취급한다.
예를 들자면 fetch("abcde")로 사용한다면 fetch("./abcde")로 처리된다.
그렇기 때문에 상세 게시물 페이지의 url이 "~/post/117"이고 fetch("api/post/117")이라면 fetch는
fetch("./api/post/117")로 처리하여 117을 갖고 있는 post에서 api/post/117을 붙이는 것이다. 그래서 ~/post/api/post/117이 되는 것이었다.

이렇게 원인을 알고나서 절대 경로로 실험을 해보았다.

위와 같은 방식으로 루트 주소를 기준으로 하기 때문에 기본 주소 옆에 바로 fetch에 사용한 주소가 붙는다.
그래서 이 방식을 사용하여 코드를 다음과 같이 수정하였다.

"/"로 절대주소로 만들어주고 BASE_URL(api) postNumber(post/111)로 각각 대응되어 해결되었다.
(postNumber를 통해 post/:postId 를 넘겨 받는다. 상세 게시물 페이지에서 설명한 부분과는 별개로 생각하면 될 것 같다.
지금 보니까 변수명을 적절하게 사용하지 못한 것 같다...)

🎯느낀점

먼저 상위 5명까지 코드리뷰를 해주신다고 하셨는데 챌린지를 시작하기 전에는 무슨 자신감이었는지 모르겠지만, 5명 안에 들 수 있을 줄 알았다.
아무래도 나는 내가 재능충인 줄 알았나보다... 결론은 전혀 아니었다ㅋㅋㅋㅋㅋ

챌린지를 진행하며 어려움을 많이 겪었는데 처음 시작할 때는 SPA 때문에 쉽지 않겠다고 생각했었고, 진행중에는 코드를 어떤 식으로 작성해 나갈지에 대한 고민, 마지막은 배포 부분과 페이지 새로고침 부분의 경로에서 시련이 찾아왔었다.
거의 이 챌린지에만 한달을 매달렸던 것 같은데 이 챌린지에 이렇게 매달려서 한 사람은 나 밖에 없을 것 같다.
챌린지 호스트분께서 난이도가 있는 챌린지라서 2주라는 시간이 괜찮을지 고민을 많이 했다고 하셨었다. 어려운 챌린지였는데 아무것도 몰랐던 백지상태에서 시작했던 터라 나에게는 더욱더 어려웠던 챌린지로 느껴졌었던 것 같다.
게다가 나는 의문이 드는 부분이 있을 때 그냥 넘어가면 계속 신경 쓰이고 원리를 알고 싶어지는 스타일이라서 더 힘겨웠던 것 같다.

하지만 이번에 느낀 것이 이해가 안되면 고민을 해보고 알아보는 것이 좋지만 아무리 해도 이해가 안되면 일단 알아만 두고 넘어가는 것이 좋은 것 같다는 생각이 들었다. 결국은 이해가 안된다는 것은 관련 지식이 부족하다는 것인데 다른 부분을 공부하고 와서 경험치가 쌓이면 이해될 수도 있다는 생각이 들었기 때문이다.
또 이제 공부를 시작하는 시점에서 사소한 부분까지 전부 신경쓰고 넘어가기에는 채워야 할 점이 많기 때문에 차라리 그 시간에 다른 부분을 공부하는 것이 더 효율적이라는 생각이 들었다. 하지만 위에서 겪었던 문제들은 사소한 부분은 아니라고 생각한다. 중요한 부분이니까 고민했던 시간들이 의미가 있었다!! 앞으로 다가올 사소한 부분들에 대해서만 방금 말한 것처럼 대처해야겠다.

그리고 팀원들과 스터디를 할 때 아는 것이 없어서 말도 제대로 못하고, 도움만 받은 것 같아서 죄송하다는 생각이 많이 들었는데 이렇게 마지막에 팀원분들을 도울 수 있어서 뿌듯했다. 또 팀장님께서 팀을 잘 이끌어주신 것 같아서 완전 든든했다. 나도 이런 리더가 되어야겠다는 생각이 들었다.
(문제점에 대해 같이 고민해봤던 팀원님, 팀을 잘 이끌어주신 팀장님, 도움을 줬던 팀원님 정말 감사합니다.)

이번 챌린지를 통해 사이트 만들기부터 api활용, 배포까지 다 해보았는데 처음 부터 끝까지 다 만들어 보았기 때문에 뭔가 자신감이 조금 생긴 것 같다. 그래도 아쉬운 점이 있는데 챌린지 기간안에 제대로 완성하지 못한 것과 리팩토링을 한다고 했는데 아직도 코드가 중구난방인 점이다. 리팩토링에 더 시간을 쏟고 싶었지만 api를 곧 닫는다고 하시고, 한 프로젝트를 계속 끌고 가니까 의욕이 떨어지고 심적으로 쳐지는 느낌이 든다. 그렇기 때문에 리팩토링 부분은 이제 접어두고, 다음 프로젝트를 할 때 이 부분을 염두에 두고 진행해야겠다.
더불어 다음 프로젝트에는

  1. 글을 읽듯이 읽을 수 있는 코드를 만들려고 노력하기
  2. 사용자 입장에서 생각하면서 만들기
  3. 에러 처리같은 방어적인 코드 작성
  4. css를 css스럽게 사용하고 js를 js스럽게 사용하기

등을 생각하면서 진행해야겠다.

또 이번 챌린지를 하면서 위에서 작성했던 어려웠던 점 말고도 고민해보고 공부해야 할 것들을 따로 적어뒀는데 그 부분에 대해서는 TIL 느낌으로 따로 포스팅 해봐야겠다.

그리고 마지막으로 가벼운 마음으로 신청했던 챌린지에서 이렇게 많은 고민들과 배움들을 얻을 수 있어 뜻깊은 시간이었다는 말을 전하며 회고록을 마치겠다.

0개의 댓글