사용 기술
front-end
react / typescript / styled-components / framer-motion / recoil / react-query / react-router-dom / spotify-web-api-node / react-spotify-web-playback
back-end
express / babel / nodemon / spotify-web-api-node
배포
front-end: netlify
back-end: fly.io
부제: 사이드 프로젝트로 크롬 모멘텀 클론 코딩하기
사이드 프로젝트 진행 4일차 (~2022.11.04)
부지런하게 한달 살기 챌린지를 하면서 진행할 사이드 프로젝트에 대해서 블로그 글을 쓰기로 했다. 진행하기 전, 무엇을 사용할 건지 계획하고 싶어서 나름대로 생각을 해봤고, 결론부터 말하면, 리액트와 노드를 사용했다.
처음에는 자바스크립트로만 만들까 했는데, 이미 만들어본 경험이 있고 이걸 리액트로 다시 만들어보는 것도 공부가 될 것 같았다. 더불어 api를 사용하려고 하기 때문에 리액트 쿼리의 도움을 받아도 좋을 것 같다는 생각도 있었다. 리액트 라이브러리는 좋은 게 많으니 그곳의 도움도 조금 받을 생각이다.
실제 크롬의 모멘텀에는 뮤직 플레이가 없다. 그럼에도 불구하고 spotify api를 사용하는 이유는 백그라운드로 음악을 들을 수 있으면 좋을 것 같아서 추가해줬다. 단순히 내가 사용하고 있어서 그런 것도 있지만 spotify에는 asmr이나 해외/국내 음악이 들어있어 포괄적이어서 선택했다. ...액세스 토큰을 얻기 까다롭다는 말을 들었지만 일단 시도했는데... 확실히 주니어는 어렵다...
오늘은 액세스 토큰을 얻는 방법을 작성해볼 것이다. 1일차 ~ 3일차까지 시도했는데, 투자한 시간에 비해 꽤 오래걸렸다. 에러도 자주 나고... 이것저것 시도하면서 구글링도 하다보니 지나간 시간인 거 같다. 지금보다 더 빠르게 일을 처리했으면 좋겠지만 이상하게 에러도 잡고 하다보면 시간이 너무 빠르게 지나간다. 하루에 대략 3 ~ 4시간만 투자해서 그런걸까.
다른 분들은 더 오랜 시간을 투자하는 것 같기도 한데... 나도 재고해봐야겠다. 그렇지만 지금까지 코딩하면서 느낀 점은 에러가 났을 때 바로 고치는 것도 좋은데 그 상황에서 보이지 않는 부분이 조금 쉬고, 다음날이 되면 보이게 되어서 고치는 경우가 대다수였다.
어쨌든 하고 싶은 것이 꽤 있으니... 부지런히 사이드 프로젝트를 진행해야겠다. 자바스크립트로 구현한 것을 리액트로 옮기는 건 엄청 쉽다고는 말할 수 없지만 이미 한번 해본 거니 수월하게 할 수 있을 거라 생각한다.
모멘텀의 background image를 따라하는 것은 unsplash API를 이용할 생각이다. 무료 이미지가 많고, 생각보다 이미지의 퀄리티도 좋다. API의 난이도는 듣지 못했지만 랜덤으로 이미지를 바꿔주는 것에 적절한 것 같다. 그런데 작성하는 지금 아는 것이지만 실제 크롬 모멘텀도 unsplash에서 이미지를 가져오는 것 같다.
새로고침을 했을 때 이미지가 변경되지 않는 것을 보아 아마 날짜가 바뀌면 변경하도록 구현한 거라고 생각한다. 이것도 따라해봐야겠다.
사이드 프로젝트 진행 8일차 (~2022.11.08)
날짜가 바뀌면 bg 이미지가 변경되는 기능을 추가하려고 했으나 생각한 모든 로직이 실패했다. 날짜가 바뀌었다는 걸 어떻게 컴퓨터에게 알려주어야 할까?
우선, 여기에 묶여있지 않고 다른 것부터 하기로 했다. 새로고침을 하면 여전히 bg 이미지가 바뀌었지만 이 정도면 그래도 괜찮다.
스포티파이 access token를 가져오는 것에 어려움을 겪었는데, access token을 가져오는 것만 어렵지 나머지는 수월했다. 다만, uri라고 한번도 보지 못했던 거라 조금 끙끙거렸다.
player를 만들어서 재생/멈춤을 재현하고 싶은데 src에 사용할 소스가, 아무리 봐도 data에 없었다. 원래 사용할 수 없는 걸까? 싶어졌는데... 이걸로만 계속 고민한 거 같다.
답은 생각보다 가까이 있었고, spotify login 을 구현하는 유튜브 영상을 끝까지 다 보니 알 수 있었다. 오픈 소스를 다운받아서 uri를 넘겨주면 되더라... 그 뒤로는 css를 건드리거나 간단한 내용들이라 진도가 빠르게 넘어가서 지금은 거의 다했다.
이번주까지는 완성시키고 싶으니 서둘러야겠다. css가 제일 시간을 잡아먹는다...
todo list도 원하는 방식으로 구현했다. 이걸 좀 더 다듬고 싶은데, 우선 완성부터 시키고 후에 정리하는 걸로 하자. 누더기 코드라도 일단! 돌아가게 만들고! 정리하는 게! 좋다고 배웠다.
사이드 프로젝트 진행 12일차 (~2022.11.12)
setting button을 만들었다. 이걸 클릭하면, background images가 변경되고, 변경된 value가 local에 저장되어 다음에 브라우저를 틀었을 때 value의 값이 유지된다. 이건 모멘텀에 있는 기능은 아니지만 그렇게 만들어보고 싶어서 추가로 구현해보았다.
모멘텀에는 토글 버튼으로 각 기능들을 화면에서 hide할 수 있는데, 그것 또한 따라해보았다. 토글 버튼의 값을 local에 저장하는데, 이걸 다 별도의 값으로 저장해야 될 지 고민을 했던 것 같다. 하나의 객체에 몰아 넣어 관리하고 싶었으나 그렇게 하려면 값을 어떻게 변경해야할지 어려웠다. 그래서 우선, 별도의 key로 전부 빼서 저장했다.
저장을 하고나서 변경된 값을 실시간으로 렌더링해야 하는데 local 값을 변경해도 리렌더링 되지는 않았다. 값이 변경될 때마다 리렌더링 하고 싶으면 state에 넣어야 했다. 그러면 또 state가 여러개로 늘어날 것 같았고... state에 넣지 않았는데도 불구하고 값이 변경되는 것이 있어 의문을 가졌다.
처음에는 state에 넣지 않아도 잘 변경이 되었었는데, 코드를 떼어서 컴포넌트로 정리하고 나서부터는 몇몇의 기능은 작동하지 않았다. 그래서 떼어낸 컴포넌트를 살펴보니 훅으로 사용한 기능에 현재 타이머를 가져오는 것이 있었다. 그러니까...
현재의 시간 값을 수시로 가져오면서 local의 값도 실시간으로 계속 가져오는 것이 되어 state를 사용하지 않았으나 리렌더링 되는 것처럼 보이는 것이었다. (local의 값으로 리렌더링 되는 것이 아닌 다른 값으로 리렌더링 되면서 local값도 가져오는...)
state를 사용하고 싶지 않았으니 그대로 두었고, 대략적인 기능은 전부 구현한 것 같아 css를 만졌다. framer-motion으로 애니메이션을 만들고, 배포에 돌입했다.
백엔드에 넣은 코드는 얼마 없어서 (스포티파이 로그인, express 코드밖에 없음) 배포는 오래 걸리지 않을 거라 생각했는데 오산이었다. 온갖 에러를 맛본 것 같다... 구글링도 했지만, 문제가 해결되지 않았다.
프론트는 react+typescript, 백으로는 node.js(babel)를 사용하고 배포는 heroku를 통해 한다. 이런저런 내용을 검색하다가 유튜브에도 있을까 싶어 찾아보니 다행히 누군가 올려주신 내용이 있었다.
배포 영상을 보며 많은 도움을 얻었다. 나는 어디로 접속하든 리액트로 만든 사이트를 보내주는 형식으로 구현했기에 추가적으로 경로를 달리 했다. 물론, 영상을 보고도 맞이한 에러도 있다.
영상을 따라하며 맞이한 첫 에러이다.
정확하게 첫 에러는 아니고 시도하면서 여러가지 에러가 있었으나 구글링도 해보고 도저히 안돼서 영상을 보며 다시 시도했다. 그 뒤로 나온 에러이다.
바벨을 사용해서 컴파일을 하는데, 컴파일에는 성공했지만 그 뒤로 권한 거부가 나와 빌드에 실패했다. 대체 이게 뭐지 구글링을 해보았는데 마땅히 건진 게 없었고, 헤로쿠에서 이를 다루는 내용이 있었다.
영상에서 보면 scripts에 ci를 넣는다. 이게 npm install과 비슷한 양상을 띄는 것 같은데, npm 버전이 높으면(사이트에서 말하는 버전보다) ci 버그가 발생하는 것 같았다. 그래서 버전도 낮게 잡아봤지만 달라지는 건 없었고 ci를 삭제하게 되면 바벨을 못찾았다고 에러가 났다.
해결은 간단하게 했다. 단순히 내가 경로를 잘못 잡고 있었다. scripts를 작성하면서 백엔드 경로에서 빌드를 했으면 다시 root로 나와 프론트로 들어가야 했는데, root로 나오지도 않고 프론트 빌드를 시작했으니 오류가 난 것 같다.
경로 수정을 하고 다시 빌드를 시도해보니 다음과 같은 에러가 나타났다.
이거는 영상에서도 나오는 에러인데, 헤로쿠는 빌드를 할 때 60초를 넘기면 에러가 나온다. 그래서 60초가 지나기 전에 빌드를 다 해주어야 한다. 만약 빌드 전에 해야할 것이 많으면 heroku-prebuild
를 이용하자.
그렇다면 왜 60초를 넘겼는가에 대해 이야기 해봐야하는데, 이유는 단순하다. PORT를 못 찾았기 때문이다. 헤로쿠는 PORT를 매순간 랜덤으로 전해주는데 내가 PORT 설정을 안했기 때문.
정확하게는 잘못 설정했다.
개발을 할 때, 5000번 PORT에서 사용했다. 그러니까, 해당 번호의 포트는 항상 존재하는 개념이라 process.env.PORT
가 나올 일이 없는 거다. 앞에 있는 value가 false가 아니니... 뒤에 값이 나올 리가 없지. 그래서 순서를 바꿔 써주었다.
이렇게 하면 process.env.PORT
가 없을 때 포트 5000으로 실행된다. 이렇게 작업하고 나니 배포가 잘 되었다. 물론, 어디로 접속하든 리액트에서 만든 페이지를 넘겨주는 코드의 경로가 잘못 되어서 Not Found.
가 떴는데, 경로를 수정해주니 멀쩡히 잘 나왔다.
그 뒤로, 간단히 css를 수정해주고 완성했다. 조금 더 빠르게 끝내고 싶었는데 배포로 하루를 보내버리니... 결국 2주를 채우고 완성했다. 배포가 잘 되었나 이것저것 만져보며 알아차린 버그가 하나 있어서 이것도 후에 수정해주어야겠다.
그래도 열심히 작업했고 꽤 즐겁게 만들었다. 물론 고민하고 힘들어한 상황은 즐겁지 않았지만 어쨌든 해결을 했고, 만들었으니까! 이제 내가 코드를 어떻게 짰는 지에 대한 블로그 글을 올려야겠다.
heroku 에서 무료 플랜이 끝나 fly.io, netlify로 이전하여 배포하였습니다. 배포하는 것을 작성한 게시글은 아래의 링크를 봐주세요.
heroku에서 fly.io로 이전하여 배포하기