ABOUT ME

-

Today
-
Total
-
  • 블록체인 스타트업 프론트엔드 개발자의 입사 1주년 회고
    Record/daily 2023. 2. 22. 13:17
    반응형

    중국어통번역학과를 졸업한 내가 어느덧 2년 차 개발자가 됐다!! 🥳

    하지만 개발자로 지내면서 학습 내용은 틈틈이 개인 노션이나 블로그에 작성해 왔지만, 나를 돌아볼 시간은 없었던 것 같다.

    그래서 이번 회고를 통해서 내가 1년 동안 무엇을 했고 어떤 걸 배웠는지, 그리고 앞으로 해야 할 일들을 정리하고자 한다.

    개발자로서 작성하는 첫 번째 회고의 주제는 블록체인 스타트업 프론트엔드 개발자의 입사 1주년이다.

     

    1. 프리랜서 개발자로 시작하다

    현재 다니는 회사에 오기 전 어떤 경험을 쌓았는지부터 시작해야 할 것 같아서 이야기를 한 번 풀어본다.

    개발자로서의 내 첫 커리어는 상주 프리랜서 프론트엔드 개발자로 시작을 했다.

    개발 공부를 병행하며 YAPP 동아리 활동을 마치고 취업 준비를 하려던 즈음에, 노마드코더 커뮤니티에서 많은 도움을 주시던 Flynn님께서 리액트 프리랜서 개발자 채용 공고를 공유해 주셨다. 지원할 당시 개발 공부한 지 1년도 안된 초보 였기 때문에 프리랜서는 전혀 생각지 못한 선택지였다. 하지만 채용 공고의 기술 스택이 굉장히 매력적이었고, 업무 경험을 하루빨리 쌓아 보고 싶다는 욕구가 강했다.

    그래서 개인 프로젝트 하나와 동아리에서 진행한 팀 프로젝트 하나를 포트폴리오에 담고 면접을 보러 갔다.

    개발자로서 첫 면접이었는데, 정말 떨렸던 기억이 난다. 주로 개인 프로젝트의 기술 사용에 대해 많은 질문을 하셨고, 최선을 다해 답변했다.

    그 결과 개발자로서 첫 면접에 첫 합격 통보를 받게 됐고, 프론트엔드 개발자로서의 첫 발걸음을 내딛게 되었다.

     

    채용 공고 내용 일부

    프리랜서로 참여하게 된 프로젝트는 LG 생활건강에서 발주한 미국 온라인 쇼핑몰 리뉴얼 작업이었다.

    꽤나 대형 프로젝트였던걸로 기억하는데, 구현해야 하는 페이지가 130여 개였고, 페이지마다 구현해야 할 기능도 다양했다.

    투입 초기에는 프론트엔드 개발자 1명, 퍼블리셔 1명이 전부여서 지레 겁을 먹었지만, 몇 달 후에 프론트엔드 개발자가 3명이 더 채용돼서 안도의 한숨을 내쉬었던 기억이 있다. 이렇게 큰 프로젝트에 실무자로 투입되자마자 트렌디했던 기술 스택은 다 사용해 본 것 같다.

    (React, Redux, Redux-Saga, Redux-Thunk, Storybook, TypeScript, styled-components)

    물론 학습하면서 바로 바로 실무에 사용해야 해서 꽤나 버겁긴 했지만, 좋은 기회였고 짧은 시간 내에 많은 걸 배울 수 있었다. 그리고 함께 일하는 백엔드 개발자들 뿐만 아니라 LG CNS 직원분들과도 협업해야 해서 다양한 포지션의 분들과 끊임없이 소통하며 개발해야 했다.

    첫 직장에서 기술적으로도 성장했지만 협업을 하는 부분에 있어서도 많은 성장을 이룬 것 같다.

    (이와 관련해서 더 자세한 얘기는 추가적으로 글을 쓸 시간이 되면 다른 포스팅에서 다뤄보고 싶다.)

     

    경험이라고는 팀 프로젝트 하나 있는 비전공자 신입 개발자를 믿고 채용해 준 것에 대해 감사했고, 이에 보답하기 위해 약 7개월 동안 개인적인 성장과 동시에 팀 내에서 1인분을 하기 위해 정말 고군분투했다. 

    하지만, 시작을 프리랜서로 시작했던 나는 프리랜서보다는 좀 더 안정적인 정규직을 구하고 싶었고 다시 취업 준비를 시작했다.

     

     

    2. 취업 준비, 그리고 블록체인 스타트업으로 입사

    첫 번째 취업을 단 한 번의 면접으로 하게 됐기 때문에 사실상 제대로 취업 준비를 해본 경험이 없었다. 그래서 두 번째 취업 준비를 할 땐 많은 준비가 필요했다. 알고리즘 공부, 과제 전형 준비, 기술 면접 공부 등 다양한 준비를 하며 약 6개월을 보냈다.

    코딩테스트는 자바스크립트로 준비했고 여러 인터넷 강의를 시청하고 문제는 프로그래머스에서 주로 풀었다.

    과제 전형은 주로 바닐라 자바스크립트로 구현하는 것이 나와서 이에 따른 공부를 추가적으로 했고,

    기술 면접은 인터넷 강의, 유튜브, 블로그 자료들을 참고해서 노션에 따로 정리해서 질의응답 리스트를 만들어서 준비했다.

    실제로 받았던 프론트엔드 개발 면접 질문은 따로 포스팅을 했는데, 생각보다 많은 유입이 들어와서 놀랐다.

    그리고 취업 준비를 하면서 백수인 상태로 지낼 수 없었기에 크몽에서 간단한 퍼블리싱 작업을 통해 지속적인 수입을 창출해 냈다.

    퍼블리싱 의뢰를 받으면서 HTML, CSS에 대한 이해도를 끌어올려 나가는 동시에, 좋은 작업물로 의뢰인들에게 만족감을 줘서 뿌듯했다.

     

    (좌)면접 질문/답변 노션 정리 (우)판매한 크몽 서비스 리뷰

     

    개발자로 취업 준비를 하기 이전에도 수많은 낙방을 경험했기에 🥲 많은 기업에 지원하고 탈락의 고배를 마셔도 크게 좌절하진 않았던 것 같다. 대기업의 신입 전형 코딩테스트는 정말 대부분 어려웠고, 합격하는 게 나에게는 하늘의 별따기였다.

    그래도 포기하지 않고 여기저기 문을 두드려본 결과 면접까지 가게 된 회사들이 있었고 최선을 다해 면접에 임했다.

     

    그 결과 운 좋게 현재 다니고 있는 회사를 알게 됐고 블록체인에 관심이 많았던 나는 입사를 결심하게 됐다.

    사실 내가 개발자의 꿈을 가지게 된 건 이전에 다녔던 블록체인 회사에서 블록체인 공부를 개발자들과 함께 하면서부터였던 것 같다.

    블록체인이라는 기술이 탄생하게 된 스토리텔링부터가 굉장히 신선했고, 공부할수록 흥미가 생겼다. 그래서 원래는 블록체인 개발자가 되는걸 꿈꿨는데, 비록 지금은 그 꿈과는 약간은 멀어졌지만 그래도 DApp 개발자로 일을 할 수 있다는 게 입사 당시에는 정말 기뻤다.

     

     

    3. 패럴랙스 스크롤링으로 한 편의 애니메이션을 만들다

    출근 첫날, 여러 층을 둘러보며 감탄을 금치 못했던 기억이 난다.

    아무것도 없는 곳에서 일하다가 17층 건물을 통째로 쓰는 회사로 입사를 하다니... 성공했다 나 자신😂

    상주 프리랜서로 근무할 때는 복지라고는 1도 없었고, 장비 지원도 없고, 심지어 모니터도 내 돈으로 샀었는데..

    최신 장비 지원! 간식 무제한 지원! 맛있는 밥 제공! 코인 노래방, 당구, 포켓볼, 탁구대 구비!

    너무 회사 홍보 글 같은데🧐

     

    입사 당시 회사 내부

     

    아무튼 입사하고 일주일 정도는 비즈니스에 대한 설명과 블록체인에 대한 이해도를 높이는 시간을 가졌다. 그리고 나는 입사한 지 일주일 만에 바로 비즈니스와 관련된 티저 페이지와 랜딩 페이지 개발을 해야 했다. 당시 개발 인력은 컨트랙트 개발자 1명과 나, 총 2명이 전부였다. 

     

    랜딩페이지에 패럴랙스 스크롤링을 사용한 이유

    원래는 패럴랙스 스크롤링 말고 서비스를 소개하는 애니메이션 영상을 띄우기로 했었다. 하지만 회사 측에서 한 패럴랙스 스크롤 사이트를 접하게 되면서 이 기법에 완전히 빠져들어버렸다. 하지만 나는 랜딩페이지를 패럴랙스 스크롤링 기법으로 구현하는 것에 처음에는 반대하는 입장이었다. 왜냐하면 애니메이션으로도 이미 충분히 영상이 잘 뽑혔는데, 이걸 굳이 다시 각 scene마다 리소스를 따서 패럴랙스 스크롤링으로 만든다는 것이 이해되지 않았다. 그리고 랜딩 페이지라는 것은 서비스를 소개하기 위한 것인데, 서비스를 파악하기 위해 사용자가 상당히 긴 스크롤을 내려가면서 꽤나 상당한 노력을 들여야 한다니.

    그러나 당시 블록체인 서비스의 소개 사이트들을 대부분 둘러봤을 때 인터랙티브한 사이트는 많이 없었기 때문에 화려한 인터랙션이 들어간 랜딩 페이지 하나만으로도 눈길을 끌 수 있을 거라는 의견이 강했고, 나도 이에 설득당했다..🙃

    예상되는 씬이 생각보다는 많지 않았고 스크롤 길이가 엄청나게 길지는 않아서 조금의 노력으로 화려한 인터랙티브 효과를 볼 수 있었다. 이를 통해 다른 사이트보다 좀 더 차별화를 두고 관심을 끌 수 있었던 것 같다.

     

    입사하자마자 만들게 된 티저 페이지를 구현할 때도 svg 파일의 path를 이용해서 애니메이션을 구현하며 신기한 애니메이션의 세계로 진입하게 됐는데, 랜딩 페이지는 패럴랙스 스크롤링을 구현해야 한다니! 입사하자마자 처음 시도하는 것들의 연속이었다.

    하지만 프론트 개발자는 나 하나..! 반드시 구현해야 한다는 일념 하나로 열심히 서칭하고 강의도 들어보고 했다.

    그 결과, 빠른 시일 내에 익히고 도입할 수 있는 GSAP의 Scroll Trigger 라이브러리를 사용하는 것을 선택했다.

    스크롤 트리거는 말 그대로 스크롤 기반으로 애니메이션을 구현하는 건데,  트리거 엘리먼트를 지정하고 뷰포트에 트리거 엘리먼트가 등장하면 지정한 엘리먼트의 애니메이션이 작동된다. 사용법도 익히기 쉽고 성능도 좋아서 처음 시도한 것 치고 금방 구현할 수 있었다.

    패럴랙스 스크롤 랜딩 페이지 개발에 대한 자세한 이야기는 아래 포스팅에서 확인할 수 있다.

     

     

    애플처럼 화려한 Parallax Scroll 랜딩 페이지 개발해보기

    Parallax scrolling is a web site trend where the background content (i.e. an image) is moved at a different speed than the foreground content while scrolling. 패럴랙스 스크롤링 기법을 간단히 말하면 스크롤에 따른 애니메이션 효

    xiubindev.tistory.com

     

     

    4.  설레이는 첫 DApp 개발 

    디앱(DApp)이란 블록체인을 기반으로 돌아가는 탈중앙화 분산 애플리케이션을 말한다. 쉽게 말해서 이더리움 기반 디앱이면, 디앱에서 상호작용하는 데이터들이 이더리움 블록체인에 기록되고 불러내어지는 애플리케이션이라고 이해하면 된다.

     

    입사하고 랜딩페이지를 만들었던 시간을 제외하고 약 한 달 정도는 블록체인과 DApp 개발 강의를 많이 보고 기초를 다졌다. 이전 직장에서 기본 개념은 익혔고, 퇴사 이후에도 판교에서 블록체인 강의도 듣고 멋사에서 진행했던 프로젝트도 진행해봤기 때문에 다행히도 배우는 데 진입 장벽은 그나마 높지 않았던 것 같았다. 혼자 스터디하는 데 도움이 됐던 링크들을 공유한다.

    1. 유튜브
    https://www.youtube.com/@DappUniversity
    https://www.youtube.com/@stone_chain
    https://www.youtube.com/@jaeyuntv
    2. 깃허브
    https://github.com/ConsenSys/ethereum-developer-tools-list/blob/master/README_Korean.md
    3. 문서
    https://academy.binance.com/en 

     

    하지만... 공부를 하는 것과 실무에 적용하는 것은 천지 차이라는 것을...😭

    그래서 참고할 만한 DeFi 오픈소스 프로젝트가 있는지 열심히 찾아보다가 PancakeSwap 이라는 프로젝트를 발견했다. 정말 사막의 오아시스 같은 존재였고, 실무에서 사용하기 위해 필요한 부분만 골라서 분석하기 시작했다. 모든 소스 코드를 다 분석하기에는 나 혼자서는 역부족이었기에... 모듈 위주로 분석하고 차용하기로 결정했다. 그래도 이 오픈소스 하나만 분석해도 어떤 방향으로 나아가야 할지 명확해졌고 정말 큰 도움이 됐다🫶

     

    4-1. DApp 프론트엔드 개발 환경 구축하기

    일반 App과 DApp의 가장 큰 차이점은 서버와 데이터베이스가 중앙화되어있는지 여부이다.

    예를 들어, 일반 애플리케이션은 서버에서 아이디와 비밀번호를 관리하고 유저가 이를 애플리케이션과 상호작용하는 데 사용하지만, DApp은 별도로 아이디와 비밀번호를 위한 서버를 구축하지 않고, 블록체인에서 스마트 컨트랙트와 상호작용할 수 있는 Address(EOA)와 Private key를 유저가 직접 가지고 있는 상태에서 서비스를 이용하게 된다.

    즉, 서버가 아닌 프론트엔드에서 유저가 블록체인과 상호작용하도록 하는 기능을 구현해야 한다. 이를 위해서는 Address(EOA)와 Private key가 필요한데 상용화된 블록체인 지갑을 사용할 수 있다. DApp 개발에서 프론트엔드의 핵심적인 역할은 유저가 블록체인 지갑을 애플리케이션에서 사용할 수 있도록 연동해주고 스마트 컨트랙트와 상호작용할 수 있도록 해주는 것이다.

     

    우리는 블록체인 메인넷 중에 BNB 스마트체인 위에서 DApp 개발을 진행하기로 했고, 블록체인 지갑 연동은 메타마스크(Metamask) 지원하기로 했다. 개발환경은 기존에 익숙한 React 개발 환경에 PancakeSwap을 참고하여 Web3 관련 개발 환경까지 구축하기로 결정했다. 개발 시작 당시 프론트엔드는 나 혼자여서 기술 스택을 함께 상의할 팀원이 없어서 아쉽긴 했다. 그래도 약 한 달 후에 시니어 개발자 분이 오셔서 천만다행이었지만!! 역시 시니어 개발자시라 빠르게 기술 습득을 하고 적용하시는 게 멋졌다😎

    아무튼 내가 제로베이스에서 구축한 DApp 프론트엔드 개발 환경은 아래와 같다. 

    • Yarn, Webpack, React.js, TypeScript, SWR, Emotion, ESLint
    • Ethers.js 
      이더리움 블록체인과 상호 작용하기 위한 라이브러리이며, 유용한 유틸리티가 많다. BNB 스마트체인은 EVM과 호환되기 때문에 이더리움 관련 개발 도구를 사용할 수 있다.
    • bignumber.js
      블록체인에서 많은 작업은 JavaScript에서 사용할 수 있는 안전한 값의 범위를 벗어난 숫자에서 작동한다. 이 라이브러리는 모든 크기의 숫자에 대해서 연산을 안전하게 할 수 있도록 도와준다. Ethers.js 라이브러리에도 BigNumber 관련 유틸리티가 있지만, bignumber.js 라이브러리가 더 정교하게 다룰 수 있고 유틸리티도 훨씬 많아서 좋은 것 같다.
    • web3-react  
      디앱 빌딩 프레임워크로, 블록체인 지갑 연동뿐만 아니라 스마트컨트랙트와 상호작용에 사용할 수 있다.

     

    2021년 12월, 노션에 정리해뒀던 메타마스크 사용 코드

    원래 web3-react 라이브러리를 몰랐을 때는 Metamask 공식 문서를 참고해서 블록체인 연동 관련 코드를 다 짜놨었다. 노션에 개발 기능 정의, 코드 예제 등 다 작성했었는데, PancakeSwap 오픈소스를 알게 되고 나서 코드를 다시 새로 다 짰다🤣 어쨌든 메타마스크 지갑을 연결하는 원리는 같지만 web3-react는 DApp과 관련된 데이터의 상태들을 쉽게 관리할 수 있어서 편리해서 사용하게 됐다. 그리고 메타마스크 외에 다른 지갑들도 쉽게 연동할 수 있는 것이 큰 장점이다.

    web3-react 사용 방법에 대해서는 간단하게 포스팅을 한 번 해서 아래 글에서 확인해 볼 수 있다.

     

    web3-react로 DApp에 지갑 연동 구현하기

    이더리움 DApp을 개발하기 위해서 블록체인 지갑 연동은 필수라고 할 수 있다. 이더리움 기반 블록체인 지갑에는 여러 종류가 있는데 레저 나노, 트레저원, 메타마스크, 마이이더월렛, 트러스트

    xiubindev.tistory.com

     

    4-2. ESLint를 자동화해보자

    커밋하기 전에 lint 에러가 있는 경우 커밋을 하지 못하도록 하기 위해 git hook을 활용했다. 이를 위해 husky와 lint-staged를 사용했고 커밋 전 staging area에 있는 파일들을 lint로 검사했다. 이와 관련해서 ESLint를 자동화해보자 라는 제목으로 포스팅을 했고, 아래 글에서 확인할 수 있다. 함께 작업하는 동료가 늘어날 때 굉장히 유용한 것 같다. commit 외에 다른 hook을 활용해서 프로젝트에 적용해 봐도 좋을 것 같다.

     

    ESLint를 자동화해보자 (feat. husky & lint-staged)

    Lint 코드의 오류나 버그, 스타일 등을 점검하는 것을 lint라고 부른다. 린트는 코드의 가독성을 높이는 것뿐만 아니라 자바스크립트와 같은 동적 언어의 특성인 런타임 버그를 예방하는 역할도

    xiubindev.tistory.com

     

    4-3. 웹팩 성능 최적화를 통해 개발 효율성을 극대화해보자

    사실 예전에는 웹팩으로 큰 사이즈의 프로젝트를 번들링 해본 적이 없어서 빌드 속도가 느릴 수 있다는 것을 인지하지 못했다. 그리고 입사해서 m1 맥북 13 프로를 지원받았기 때문에 더더욱 성능 이슈를 겪을 일이 없었다. 하지만 동료 개발자분이 들어오시고 이전에 사용하셨던 윈도우 노트북으로 개발을 하시는데 내 개발환경 성능과 비교했을 때 상당히 느리다는 것을 알게 되었다.

    첫 빌드가 30초 걸리고 dev server를 첫 구동하는데 90초라니...😱 이게 2022년도에 있을 수 있는 일인가!! 심지어 프로젝트 사이즈가 엄청나게 큰 시점도 아니었는데 말이다. 이를 계기로 동료 개발자분이 먼저 최적화를 조금 하시다가, 내가 이어받아서 최대한의 성능 최적화는 다 하게 됐다. 웹팩을 최적화한 결과, 성능을 5배 ~ 18배 개선할 수 있었다. 최적화와 관련된 자세한 사항은 아래 글에 작성했다.

     

    웹팩 성능 최적화를 통해 개발 효율성을 극대화 해보자 ✨

    🚧 이 글은 윈도우로 개발하는 동료로부터 시작되었습니다..! 사실 m1 맥북 13 프로를 쓰는 나로서는 개발하는데 성능의 문제성을 크게 느끼지 못했다. 서버 사양도 나쁘지 않아서 배포하는데도

    xiubindev.tistory.com

     

    4-4. DApp 개발 트러블 슈팅

    메타마스크 지갑 연결, 네트워크 감지 및 변경, Token 조회/전송, Token 추가, DeFi(staking, unstaking, approve, claim) 등 다양한 기능을 개발하면서 정말 많은 이슈가 있었지만 해결하면서 뿌듯함을 느꼈고 재미있었다!

     

      1. 일반 애플리케이션을 개발할 때도 개발 서버와 운영 서버를 나눠서 개발하듯이 블록체인도 마찬가지로 테스트넷과 메인넷의 개념이 있다. 그래서 개발할 때 테스트넷과 메인넷을 구별해서 환경 설정을 해야 한다. 아래 코드를 참고하면 좋을 것 같다.
    그리고 테스트넷 환경에서 스마트컨트랙트를 실행시키려면 tBNB 토큰이 있어야 하는데, 이 토큰을 얻기 위해서는 faucet이라는 것을 활용해야 한다. 여기서 캡차를 풀고 개발용으로 개인 메타마스크 지갑을 생성하고 지갑 주소를 넣으면 무료로 들어오는데, 24시간 기준 1번 가능하다.

    export const RPC_URL = isDevelopment
      ? 'https://data-seed-prebsc-1-s1.binance.org:8545'
      : 'https://bsc-dataseed.binance.org';
    export const BASE_BSC_SCAN_URL = isDevelopment ? 'https://testnet.bscscan.com' : 'https://bscscan.com';
    export const SNAPSHOT_BASE_URL = isDevelopment ? 'https://testnet.snapshot.org' : 'https://hub.snapshot.org';
    export const CHAIN_ID = isDevelopment ? 97 : 56;
    export const CHAIN_NAME = isDevelopment ? 'BNB Smart Chain Testnet' : 'BNB Smart Chain';
    export const TOKEN_ADDRESS = isDevelopment
      ? '0x12346'
      : '0x12345';

     

      2. 메타마스크 연결을 시도할 때 웹은 익스텐션, 모바일은 앱이 설치 돼있는지 먼저 확인을 해야한다. 온보딩 예제는 메타마스크 공식 문서에 친절하게 나와있어서 그대로 따라 하면 된다. 온보딩 외에 마주했던 이슈는 메타마스크가 잠금 상태일 때 연결 시도를 요청하면 아무 반응이 없었던 것이다. 그래서 이를 해결하기 위한 방법을 공식 문서에서 찾게 됐다. 개발을 하면 할수록 문서를 꼼꼼하게 읽어야겠다는 생각이 든다. 해결법은 여기서 확인할 수 있다.

    실험적 API라고 적혀서 언제 없어질지는 모르는 메소드이긴 하지만 ethereum._metamask.isUnlocked() 를 호출하면 잠금상태인지 아닌지 boolean 값을 리턴해준다. 잠금상태이면 지갑 잠금을 풀어야 한다는 팝업을 띄워주고 잠금이 해제된 상태에서 지갑 연결을 시도하면 된다.

     

      3. 블록체인에서 많은 작업은 JavaScript에서 사용할 수 있는 안전한 값의 범위를 벗어난 숫자에서 작동한다. 따라서 안전한 값을 벗어난 숫자에 대해서 연산을 할 수 있도록 개발하는 것이 가장 중요하다. 최대한 number 연산자는 쓰지 않고 모든 크기의 숫자를 다룰 수 있는 라이브러리를 활용해서 정교하게 연산을 하는 것이 좋다. 그리고 메타마스크에서 트랜잭션을 보낼 때 대부분 Hex string으로 변환해서 보내야 한다. 예를 들어 BNB 토큰을 전송할 때는 ethers.utils.parseUnits 유틸리티 함수를 통해 input에 입력된 value를 토큰 decimals에 맞게 BigNumber로 변환한 후, ethers.utils.hexValue 유틸리티 함수를 통해 이를 Hex string으로 변환하면 된다.

     

     

    5. Next.js로 풀스택 개발 도전

    스타트업에게 홈페이지가 왜 중요할까? 당연한 얘기지만 스타트업은 인재 채용에 있어서 정말 많은 어려움을 겪는다. 그중에 가장 큰 이유는 회사에 대한 정보가 많이 부족하기 때문일 것이다. 알려진 것이 많이 없으니 지원자 입장에서는 채용 공고를 보더라도 스타트업에 지원하기가 쉽지 않다. 그래서 회사가 추구하는 비전, 문화, 복지 등을 회사 홈페이지에서 잘 노출해야 할 필요성이 있다. 채용 공고에 회사에 대한 내용을 구구절절 써놓는 것보다 제대로 된 회사 홈페이지 하나만 있어도 지원자의 눈길을 끌 수 있기 때문이다.

    우리 회사 진짜 좋은데... 어떻게 말로 표현할 방법이 없네...

    우리도 채용에 있어서 난관을 겪고 있는 상황이었어서 리브랜딩을 하는 것과 동시에 회사 소개 및 채용 홈페이지를 개발하기로 결정했다.

     

    5-1. 개발 환경 구축하기

    회사 홈페이지를 개발하는 데 사용한 기술 스택은 다음과 같다.

    Next.js, TypeScript, SWR, emotion.js, prisma, SQLite, jsonwebtoken, gsap

    Next.js를 선택한 가장 큰 이유는 SSR, SEO 등 다양한 장점을 가지고 있지만, 그중에서도 Next.js 하나로 풀스택 개발을 할 수 있기 때문이었다. 정적인 페이지가 아니라 어드민 기능(로그인, 로그아웃, 채용공고 CRUD, 팀원 CRUD, 아티클 CRUD)까지 있어야 했기 때문에 풀스택 프레임워크인 Next.js를 사용했다. 당시 개발 리소스가 넉넉하지 않았고 채용을 위해서는 빠른 시일 내에 개발을 완료해야 했기 때문에 혼자 개발하기에는 적절한 프레임워크라고 판단했다.

    그리고 데이터베이스는 팀원이 추천해 준 SQLite를 사용했다. SQLite가 프로젝트에 적합한 이유는 다음과 같다. 가볍고, db 파일 하나로 데이터베이스 정보를 관리하기 때문에 간편하고, 초기 설정이 거의 없기 때문에 빠른 개발이 가능하다. 큰 단점 중에 하나는 동시성이 제한되는 점이 있는데, 동시 쓰기 작업이 거의 이뤄지지 않을 것이라는 판단하에 이 단점은 제쳐두고 사용하기로 결정했다.

    그리고 ORM으로는 Prisma를 사용했다. Prisma는 Node.js와 TypeScript 환경에서 데이터베이스에 쉽게 접근할 수 있도록 해주는데, 직접 사용해 보면서 이렇게 편할 수가 있나 싶을 정도로 개발 생산성이 무척 뛰어났다. 실무에서 백엔드를 다뤄보는 건 처음이었는데도 불구하고 개발 편의성이 높은 도구들을 활용해서 빠른 시일 내에 개발할 수 있었다.

     

    5-2. 트러블 슈팅

    1. Next.js Middleware로 토큰 검증 및 리다이렉트하기

    채용 홈페이지를 만들면서 어드민 기능도 추가해야 해서, 서브 도메인을 별도로 생성하지 않고 같은 도메인에 /admin 경로를 추가하여 작업하기로 했다. 어드민 경로만 알고 있으면 누구나 어드민 페이지에 접근은 할 수 있는 상황이었다. 따라서 어드민 경로로 접근하면 로그인하지 않았을 때는 로그인 화면을 보여주고, 로그인을 했을 때는 어드민 세부 페이지로 리다이렉트 해줘야 했다.

     

    처음에 생각했던 방법은 _app.tsx 파일에서 useEffect를 사용해서 pathname이 어드민 경로일 경우 토큰 검증을 해서 리디렉션 조건을 걸고자 했다. 그런데 이렇게 하면 접근 불가한 페이지로 바로 진입했을 경우 해당 페이지 화면이 잠깐 보였다가 리다이렉트가 되는 문제가 있었다. 이 문제는 토큰 검증이 끝나기 전에는 로딩 화면을 렌더링 하고 검증이 끝난 후 해당 페이지를 렌더링 하면 된다. 하지만 로그아웃 상태에서 모든 어드민 경로 페이지에 접근했을 때 로딩 화면을 보여주지 않고 바로 /signin 페이지로 리다이렉트 해주고 싶었다.

    그래서 두 번째로 적용해 본 방법은 모든 어드민 페이지가 서버 사이드 렌더링이었기 때문에 getServerSideProps를 활용해 redirect 객체를 리턴하는 것이었다. 서버에서 토큰을 검증하고 원하는 페이지를 바로 렌더링 해주기 때문에 로딩 화면이나 접근 불가 페이지가 노출되지 않는 장점이 있다. 하지만 이 방식은 모든 어드민 페이지에 동일한 코드를 넣어줘야 한다는 단점이 있었다. 

     

    Middleware allows you to run code before a request is completed, then based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.

    마지막으로 적용한 방법은 Next.js의 Middleware를 사용하는 것이었다.

    미들웨어를 사용하면 request를 기반으로 response를 직접 제어할 수 있다. 쉽게 말해 요청이 들어오면 요청이 완료되기 전에Authentication, Bot protection, Redirects and rewrites 등의 작업을 할 수 있다. 

    미들웨어에서 쿠키에 토큰이 있으면 토큰 검증해서 성공한 경우 어드민 컨텐츠 페이지로 리다이렉트를 해주고, 만약 토큰이 없거나 유효하지 않은 토큰일 경우 /signin 페이지로 리다이렉트를 해줬다. 그리고 미들웨어에서 jsonwebtoken 라이브러리를 사용하지 못해서 찾아보니까 미들웨어가 Edge runtime에서 작동하기 때문에 라이브러리가 동작하지 않는 것이었다. 그래서 Edge runtime에서도 작동하는 jose 라이브러리의 jwtVerify 메소드를 활용해서 토큰을 검증해 줬다. 그리고 /admin 경로에서만 미들웨어를 실행할 수 있도록 config에 matcher를 어드민 경로로 작성해 줬다.

    import { NextRequest } from 'next/server'
    import { NextResponse } from 'next/server'
    import { jwtVerify } from 'jose'
    
    export async function middleware(request: NextRequest) {
      const token = request.cookies.get('token') ?? ''
      const JWT_TOKEN_KEY = process.env.JWT_TOKEN_KEY ?? ''
    
      try {
        if (token) {
          const { payload } = await jwtVerify(token, new TextEncoder().encode(JWT_TOKEN_KEY))
          if (!request.nextUrl.pathname.startsWith('/admin/signin') && !payload?.loginId) {
            return NextResponse.redirect(new URL('/admin/signin', request.url))
          }
        } else {
          return NextResponse.rewrite(new URL('/admin/signin', request.url))
        }
      } catch (error) {
        return NextResponse.rewrite(new URL('/admin/signin', request.url))
      }
    
      if (request.nextUrl.pathname === '/admin') {
        return NextResponse.rewrite(new URL('/admin/careers', request.url))
      }
    }
    export const config = {
      matcher: '/admin/:path*',
    }

     

    2. Prisma와 SQLite 활용해서 DB 구축하기

    Prisma is an open source next-generation ORM.
    - Prisma Client: Auto-generated and type-safe query builder for Node.js & TypeScript
    - Prisma Migrate: Migration system
    - Prisma Studio: GUI to view and edit data in your database.

    Prisma를 처음 사용해 보면서 타입스크립트와 정말 잘 맞는 ORM이라고 생각했다. type-safe 쿼리를 통해 데이터를 안전하게 관리할 수 있고, 데이터베이스에 접근할 때 에디터에서 자동완성이 제공되는 게 정말 편리했다.

    prisma를 셋업 하면 가장 중요한 게 prisma schema인데, 이 스키마를 베이스로 직관적인 데이터 모델링을 할 수 있다. schema 파일에 데이터베이스 연결 및 generator를 정의하고, 데이터베이스에 사용할 모델을 생성하면 된다.

    나는 SQLite를 사용했기 때문에 prisma 폴더 내에 db 파일을 생성해서 서버에 업로드하는 방식을 채택했다. 

     

    generator client {
      provider        = "prisma-client-js"
      previewFeatures = ["referentialIntegrity"]
    }
    
    datasource db {
      provider             = "sqlite"
      url                  = env("DATABASE_URL")
      referentialIntegrity = "prisma"
    }
    
    model User {
      id        Int      @id @default(autoincrement())
      role      Int      @default(1)
      loginId   String   @unique
      password  String
      createdAt DateTime @default(now())
      updatedAt DateTime @updatedAt
    }
    ...생략

     

    prisma는 기본적으로 환경변수를 사용하기 위해 prisma를 셋업 하면 루트 디렉토리에 생기는 .env 파일을 불러온다. 그래서 .env 파일에 DATABASE_URL 환경변수를 저장하고 url에 불러와서 사용했다. 하지만 데이터베이스를 개발용과 프로덕션용으로 구분하기 위해 .env.development, .env.production 으로 구분지어서 파일명을 변경했더니, prisma cli를 사용할 때 환경변수를 찾지 못한다는 에러가 발생했다.

    공식 문서를 찾아보니 개발 환경에 따라 여러 env 파일을 사용하는 방법이 나와있었다. dotenv-cli 패키지를 사용해서 prisma가 사용해야 하는 환경변수 파일을 지정할 수 있다. dotenv의 -e 옵션으로 env 파일을 지정할 수 있다. 

    그리고 데이터베이스를 파일 하나로 관리하고 있기 때문에, 로컬에 있는 프로덕션 DB와 서버에 있는 DB를 동기화하기 위해서는 추가적인 작업이 필요했다. 이를 위해 현재 DB 파일이 있는 우분투 서버에 접속해서 파일을 받아와서 동기화하는 작업을 migrate 스크립트에 추가했다.

     "migrate:dev": "dotenv -e .env.development -- npx prisma migrate dev --name sqlite-init",
     "migrate:prod": "scp -r -i '프라이빗키_경로' 서버_접속_경로 ./prisma && dotenv -e .env.production -- npx prisma migrate --name sqlite-init",

     

     

    6. DApp  교육 과정 수료 및 해커톤 참가, 그리고 수상까지

    블록체인 업계에서 일하는 건 처음이다 보니 아무래도 스스로 스터디를 많이 하려고 했다. 그래서 온라인 강의도 많이 듣고 무료 교육 과정이 있으면 찾아서 듣곤 했다. 교육 과정 중에 해커톤이 있는 과정도 있어서 교육을 수료하고 실제로 디앱을 만들어 해커톤에 참가해 보면서 실무에 도움이 될만한 기술을 많이 습득하게 됐다. 온라인 강의를 제외하고 교육 과정은 2번을 수료했고 해커톤은 총 3번을 참가했다.

     

    6-1. NFT 블록체인 마켓 앱 만들기 with 그라운드X

     

    회사에서 초창기에 Klaytn 기반으로 디앱을 만들 가능성이 있다고 해서 미리 스터디도 해둘 겸 멋쟁이사자처럼에서 진행하는 NFT 블록체인 마켓 앱 만들기라는 교육과정에 참여하게 됐다. 원래 회사 입사 전 취준생이었던 시절에도 같은 교육 과정을 잠깐 들었었는데 취준과 병행하다 보니 제대로 수료하지 못했었다. 심지어 그때는 유료 강의였는데 🥲 이번에는 무료 교육 과정으로 풀려서 한 번 더 참여하게 됐다.

    5주 동안 온라인 교육을 들으면서 클레이튼 기반 애플리케이션을 설계하고 개발하는 방법에 대해 익히고 3주 동안 해커톤을 진행했다. 해커톤은 서버 개발자2,기획자1,앱 개발자1 그리고 나까지 다섯 명이 팀을 이루게 됐다.

    스마트 컨트랙트와 프론트엔드 부분은 거의 내가 담당했는데, 스마트 컨트랙트는 레퍼런스가 많아서 개발에 엄청난 어려움은 없었지만, 프론트엔드에서 컨트랙트 호출을 연동하는 부분에 있어서 클레이튼 관련 레퍼런스가 생각보다 부족해서 어려움이 있었다. caver.js 버전에 따라 달라지는 부분도 많았고, caver.js 공식 문서를 정독해도 해결이 안됐던 부분은 클레이튼 개발자 포럼을 적극 활용했는데, 그래도 하루 이틀이면 답변이 달려서 다행이었다. 

    첫 디앱 개발 해커톤이어서 부족한 점도 많았지만, 팀원들도 바쁜 와중에 끝까지 포기하지 않고 참여해 준 결과 4위라는 값진 결과를 얻을 수 있었다! 개발과 관련된 문서나 코드는 아래 깃허브에서 확인할 수 있다. 지금 와서 보면 굉장히 부족하지만 5주간의 교육과 3주간의 작업물 치고는 나름 만족스럽다.

     

    BadgeMeal

    BadgeMeal has 3 repositories available. Follow their code on GitHub.

    github.com

     

    6-2. BNB 체인 해커톤

     

    Klaytn 해커톤은 회사에서 나 혼자 참여했는데, 이번 BNB 체인 해커톤은 회사 동료들이 모여서 참가하기로 했다. 동료 한 명이 새롭게 블록체인 개발 파트에 합류하게 돼서, 동료의 컨트랙트 개발 스터디 겸 다 같이 해커톤에 참여하기로 했다. 사실 상금이 목적에 조금 더 가깝긴 했는데..😏 아무튼 이번 교육은 지난번 멋사에서 진행했던 교육 과정보다 훨씬 알찬 내용이어서 유익했다. 기술적인 측면과 동시에 블록체인 프로젝트들의 현황도 알려주고 그에 따른 어떤 기술이 필요한지 파악하기 수월했다. 예를 들어 화이트리스트 수집 기능, 리빌 기능, 오픈제플린 적극 활용하기 등 실무에서 쓸법한 것들을 알게 돼서 좋았다. 

    첫 해커톤 보다 개발은 수월하게 진행됐다. 기능 구현하면서 서버 쪽 리소스가 필요 없어서 스마트 컨트랙트와 프론트에만 집중하면 됐다. 클레이튼 메인넷으로 개발할 때는 카이카스와 클립 모두 연동해야 웹,모바일 모두 실행할 수 있었는데, 이번에는 메타마스크 하나만 연동하면 되니 개발에 공수가 덜 들었다. 워들 게임비 BNB 송금, NFT 민팅/조회 등등 원했던 기능 대부분을 시간 내에 구현할 수 있었다.

    4주 간의 온라인 교육 과정이 끝나고 오프라인으로 해커톤 데모데이가 진행됐다. 팀별로 부스를 설치하고 팀 상호 평가 및 심사위원 평가가 진행됐다. 그 결과 우리 팀은 최우수상을 수상했다! 퇴근하고 며칠간 고생했던 보람이 있었다. 나중에 받은 상금으로 다 같이 회사 근처에서 때깔 좋은 소고기도 맛있게 먹었다ㅎㅎ

    아 그리고 지난번 온라인 교육과정에서 같은 팀원이었던 분을 이번 해커톤에서 오프라인으로 처음 뵙게 돼서 정말 반가웠다. 그분은 군대 전역 직전에 해커톤을 참여하러 휴가 중에 시간을 냈다고 하신다... 정말 리스펙! 

     

    BDDC

    BNB Chain Defi Degen Club. BDDC has 2 repositories available. Follow their code on GitHub.

    github.com

     

    6-3. BNB 체인 이노베이션 해커톤

     

    BNB 체인 해커톤에서 수상한 팀에게 BNB 체인 이노베이션 해커톤 참가 기회를 부여해 줘서 참가하게 됐다. 이전에 사용했던 소스에서 추가 기능을 덧붙여서 디벨롭시켰다. 우리는 디파이 프로토콜 부문에 지원했는데, 해당 부문에는 정말 잘 갖춰진 프로젝트들이 쟁쟁하게 지원했고 우리 프로젝트는 그에 비해 부족한 점이 많이 보였다😭 그래서 아쉽게도 수상은 하지 못했지만 좋은 경험이었고 좀 더 프로젝트를 디벨롭해 볼 수 있어서 좋았다. 나중에 회사에서 지원해 준다면 사이드 프로젝트로 이어나가고 싶은 마음도 크다!

     

     

    7. Notion 200% 활용하기

    회사에서 업무 협업툴로 노션을 사용하고 있다. 프로젝트 관리, 문서 아카이브 등 다양한 용도로 활용하고 있는데, 나는 회사에서 제공하는 템플릿 외에 개인적으로도 다양하게 사용하고 있다. 

     

    7-1. To Do List

     

    나는 항상 월요일에 할 일 목록을 쭉 적고 일주일을 시작하는 편이다. MBTI는 ESFP로 나왔지만 일할 때만큼은 J가 되는 나..🫢

    팀 스페이스에 각자 할 일 목록을 적는 공간이 있어서 나는 늘 그곳에 나의 업무 리스트를 늘 작성해 둔다. 템플릿은 각자 편한 대로 유연하게 하면 돼서, 나는 테이블 리스트에 이름은 통일하고 보기 편하도록 기간을 설정하고 최신 순으로 정렬을 해뒀다. 그리고 문서를 열면 현재 진행 중인 프로젝트마다 할 일 목록을 구분해서 체크리스트로 작성하고, 퇴근 전 마친 일들을 체크해 둔다.

    원래는 프로젝트마다 보드를 만들고 to do, doing, done 그리고 기간 이렇게 썼는데 한눈에 보기에 칸반 보드는 불편한 것 같아서, 그냥 개인적으로는 주 단위로 할 일 목록을 작성하고, 프로젝트 별 WBS는 회사에서 작성하는 것으로 파악하고 있다.

    아무튼 이렇게 할 일 목록을 작성하다 보면 WBS를 작성할 때 나의 개발 일정 산출이 조금 수월해지는 것 같다. 입사 초반에 개발 일정을 산출해 달라는 요청을 받았는데, 해당 업무에 내가 얼마나 시간이 소요될지 측정이 어려웠다. 하지만 할 일 목록을 작성하고 그것이 얼마나 걸렸는지 대략 파악하다 보니 이제는 개발 일정을 산출하는데 나름 요령이 생긴 것 같다.

     

    7-2. Study & Issues

    일하면서 스터디가 필요한 부분이 많아서 공부했던 내용들을 정리하기 위해 Study 페이지를 만들었다. 공부한 내용이 동료 개발자들에게 도움이 될 것 같으면 보기 좋게 한 번 더 정리해서 노션 링크를 공유하기도 했다. 노션에 공부한 내용을 정리한 것을 바탕으로 블로그에 포스팅하기도 편해서 정리만 잘해두면 좋은 글감이 되기도 한다.

    그리고 가장 유용하게 사용하고 있는 페이지는 Issues 페이지이다. 개발을 하다 보면 꼭 하루에 하나 이상 이슈를 접하게 된다. 해당 이슈를 바로 해결하더라도 다음에 또 똑같은 이슈를 마주할 확률은 꽤나 높다. 사람은 똑같은 실수를 반복하기 마련이기 때문에 이슈를 해결했더라도 해결 방안을 정확히 기억하기는 쉽지 않다. 그래서 나는 겪었던 이슈들과 해결방안을 정리해 두는 습관을 들여놨다. 물론 접했던 모든 에러나 이슈를 적는 것은 아니다. 나만의 기준에서 적어야 할 것만 필터링해서 작성하는 편이다.

    Issues 페이지에는 React,TypeScript,HTML,CSS 등 큰 카테고리로 분류를 해놓았다. 그리고 이슈에 해당하는 대략적인 내용을 제목으로 알아보기 쉽게 작성한다. 그리고 블럭 안 내용에는 발생한 이슈, 해결 방법과 참고했던 링크를 작성한다.

    이렇게 하면 나중에 다시 같은 이슈를 만났을 때 적었다는 사실만 기억해 내면 여기서 찾아볼 수도 있고, 블로그에도 좋은 글감으로 활용할 수 있다. 

     

     

    8. 통계로 보는 나의 1년

    (좌) 회사 깃랩    (우) 개인 깃헙

    회사 깃랩은 아주 파랑 파랑한 반면에! 나의 깃헙 잔디는 시멘트 바닥...😭

    그만큼 회사에 집중을 했다고 보면 되지 않을까...ㅎㅎ 사이드 프로젝트로 혼자 뭔가 디벨롭해보기엔 시간이 없었다...

    하지만 이제 집도 회사 근처로 옮겼으니 개인 시간이 거의 두 시간이 늘어났다!

    이 시간을 잘 활용해서 자기 계발에 좀 더 집중해 봐야겠다.

    나의 깃헙 시멘트 바닥을 영양가 가득한 잔디로 채우는 그날까지!

     

    티스토리 블로그 방문자 통계

    입사 후에도 시간이 날 때마다 블로그를 열심히 했다. 더 나은 양질의 정보를 공유하기 위해, 사람들에게 도움이 되는 글을 작성하기 위해 고민만 하다가 결국 글을 쓰지 못한 글감들도 많아서 아쉬움이 남기는 한다.

    물론 내가 작성하는 글들이 다 정답이 아닐 수도 있고, 누군가에게 큰 도움이 되지는 못할 수도 있지만 나는 글을 쓰며 내 생각을 공유하는 것을 오랫동안 좋아했다. 개발자가 되기 이전에도 네이버 블로그로 정보 공유하는 것을 즐겨했고 나름 파워 블로거(?) 였던 시절이 있었다ㅋㅋ

    어쨌든 앞으로도 내가 겪었던 일들과 다양한 정보들을 열심히 공유하는 개발자가 되고 싶다.

     

     


    개발자로서 첫 회고를 마치며.
    입사하고 1년 동안 내 나름대로 치열하게 살았지만,
    2023년에는 더 치열하게 살아보자!

     

    개발 블로그를 제대로 시작하고 나서, 내 블로그 타이틀을 "자라는 것을 잘하는 개발자"라고 명명했다.

    이 타이틀에 걸맞게 나는 계속해서 자라나고 싶고, 더 나은 개발자가 되고 싶다.

    이를 실현하기 위해 올해 목표는 다음과 같다.

    1. 다양한 개발 컨텐츠 접하기
      강의도 듣고, IT 아티클도 읽고, 책도 읽어서 최대한 다양한 지식을 접해보고 싶다. 지금은 너무 회사에 갇힌 우물 안의 개구리처럼 느껴진다. 물론 회사에서도 얻는 게 정말 많지만, 개발자로서 시야를 넓히는 노력을 하고자 한다. 그래서 일단 YES24 북클럽 정기결제를 했고, 한 달에 한 번 개발 서적 읽기를 도전해보고자 한다🧐
    2. 체력 증진하기
      입사 이후 나름 운동을 꾸준히 했다. 복싱도 하고, PT도 하고, 수영도 했다. 하지만 인바디 결과를 보거나 내가 느끼는 나의 체력 상태를 봤을 때 아직 한참 부족한 상태이다. 올해 운동은 수영과 헬스장 웨이트 2가지에 집중해보려고 한다. 웨이트 운동을 정말 싫어하는 나지만... 근육량이 남들보다 현저히 낮기 때문에 무조건 해야 한다.. 체력은 내가 개발자로서 오래오래가기 위한 초석을 다지는 중요한 요소 중 하나이기 때문에 소홀히 하지 않을 것이다.
    3. 대외 활동 시작하기
      취업 준비할 때는 정말 활발하게 대외 활동을 했던 것 같은데, 입사하고 나서부터 대외 활동에 시간을 투자하지를 못했다. 속해있는 커뮤니티도 간간히 눈팅만 하고🥲 대외 활동을 통해 다양한 사람들을 만나고 그들과 함께 소통하면서 시너지를 낼 수 있다는 게 얼마나 소중한 것인지 알고 있기 때문에, 올해는 조금 적극적으로 활동해보고 싶다.

     

    2023년에도 자라는 것을 잘하는 개발자가 되자!

     

    반응형

    'Record > daily' 카테고리의 다른 글

    문돌이의 개발자 도전 프로젝트 Start  (0) 2019.07.25

    댓글