프로젝트

    file, blob 객체의 차이점

    최근 사내 프로젝트를 진행하던 도중, ai 인식을 위해 키오스크 기기에서 촬영한 이미지 파일을 서버로 보내야 하는 상황이 있었다. 이미지 파일을 blob 형식으로 보냈는데, 서버에서 정상 인식이 되지 않는 상황이 발생해 디깅을 하다, File 형식으로 보내야 한다는 것을 깨닫고... 두 형식의 차이점이 무엇인지 궁금해졌다. 결론부터 말하자면, File 객체는 Blob 의 확장이다. 만약 input 을 통해 file 을 업로드 하면, 이 데이터의 형식이 바로 File 형식이다. 테스트를 위해 임시로 input 을 통해 file 을 받아 업로드 했을 때 정상 동작했던게 바로 이런 차이가 있기 때문이다... 그렇다면 Blob 객체란 무엇이냐? Blob 은 Binary Large Object 의 약자로, 이진 ..

    프론트엔드 e2e 테스트 도입기: 구조화가 필요해..! (feat. cypress)

    프론트엔드 e2e 테스트 도입기: 구조화가 필요해..! (feat. cypress)

    배경 기존에 서비스중이던 프로젝트 구조를 변경에 대응하기 쉽도록 리팩토링하는 작업을 맡게 되었다. 그 중 가장 시급했던 부분은 로그인/인증 파트였는데, 기존에도 이상하게 에러가 많이 발생하는 파트였지만... 에러를 잡기 위해서 고치면 고칠수록 다른 부분에서 또 다른 이슈가 발생하는 상황이 있었다. 규모가 규모인지라, 별도의 QA 팀도 없어서 이슈를 고쳤을 때 또 다른 이슈는 없는지, 또 어느 범위까지 영향을 미치는 것인지 충분히 파악이 되지 않은 상태에서 배포를 하다보니 미흡한 부분이 그대로 유저에게 노출이 되었고... 비슷한 이슈에 대한 반복적인 대응에 나를 포함한 다른 여러 유관부서 팀원들의 리소스를 낭비하게 되는 현상이 있었다. 😢 분명 나는 개선하려고 리팩토링을 시작했던 건데... 가독성도 좋아지..

    CRA to Vite 마이그레이션 및 테스트환경 세팅하기

    CRA to Vite 마이그레이션 및 테스트환경 세팅하기

    배경 CRA 기반으로 세팅된 사내 프로젝트 중 하나를 Vite 로 마이그레이션을 진행하게 되었다. CRA 는 최신 번들러에 비해 크기가 크고 속도가 느린 편이고, 현재 리액트에서 공식적으로 deprecated 된 상태라 변경이 필요했다. 공식적으로는 Next.js, Remix, Gatsby 등으로 새 프로젝트를 시작하라고 하는데, 그러면 전체 구조가 바뀌어야 하니까 가장 현실적이고 사례가 많은 Vite 를 도입하기로 함. 성과 빌드 타임과 로컬 컴파일 타임이 무진장진장 거의 3배 정도 줄어들었다. CRA : 빌드 타임 58.68s. Vite : 빌드 타임 19.61s. 기존에는 빌드를 하고 앱을 시작하기 까지 한 세월이 걸렸는데, 거의 시간이 거의 3배 정도 단축되어 DX 가 무척 향상되었다. 번들 사이..

    Notion API 를 연동해 블로그를 만들어보자 -2

    Notion API 를 연동해 블로그를 만들어보자 -2

    주의! 정보성 글 보다는 삽질 기록에 가깝습니다. API를 연동한 뒤에 데이터를 불러오고, 화면에 표현하는 작업을 했다. 내용 자체는 간단한데 Next13 공식문서도 읽으면서 찾아보고, 또 여러가지 적용 방법을 고민하다보니 생각보다 시간이 오래걸렸다. 우선 글 목록을 불러오는데에는 성공했기 때문에, 이 블로그 아이템을 클릭했을 때 상세 페이지로 이동할 수 있도록 Link 컴포넌트를 적용해주었다. 원래 하고 싶었던 것은 예전에 Next12에 있는 getStaticPaths 처럼 미리 static paths 를 slug 로 만들어 둔 뒤 이를 통해 각 상세 페이지를 만드는 것이었는데, 나는 글 상세 페이지에서 데이터 요청을 위해 id 값이 필요했기 때문에 Notion DB 상에 설정해두었던 slug 문자열과..

    Notion API 를 연동해 블로그를 만들어보자 -1

    Notion API 를 연동해 블로그를 만들어보자 -1

    지금까지 개발을 하면서 꼭 해보고 싶었던 것이 바로 직접 기술 블로그를 만드는 일이었다. (매우 멋져...!) Tistory 나 벨로그처럼 이미 만들어진 서비스가 확실히 사용하기도 편하고 또 노출도 많이 되지만, 실제로 내가 운영을 하면서 꾸준히 유지보수를 할만한 프로덕트를 하나 만들고 싶었다. 내가 제일 좋아하고 자주 하는게 기록 남기는 일이기도 하니까, 그러면 블로그가 딱 적당하다고 생각해 진행하게 되었다. 기술 스택 선정 Next.js 먼저 SEO에 유리한 Next.js 를 사용하기로 했다. 하꼬 블로그지만 많이 노출이 되면 좋은거니까..! 그리고 이번에 Notion API를 연동하면서 알았는데, Next.js 에서 제공하는 api 디렉토리를 통해 엔드포인트를 만들 수 있어서 유용하게 쓸 수 있었다..

    # 작업 일지 21 / code splitting with named export components

    # 작업 일지 21 / code splitting with named export components

    성능 최적화를 위해 코드 스플리팅을 적용하려고 한다. React 에서는 Suspense 와 Lazy import를 지원하기 때문에, 별도 모듈로 분리했던 Router 에 적용해보자. https://reactjs.org/docs/code-splitting.html#named-exports 이 링크를 보면 React.lazy의 경우 export defaul 만을 지원한다고 한다. 별도의 처리를 해주어야 하는데, 여기서는 아래와 같은 방법을 추천하고 있다. 이렇게 변경할 경우 모든 컴포넌트에 대해서 이런 처리를 해주어야 하는데.. 다른 방법은 없을까? https://github.com/facebook/react/issues/14603#issuecomment-726551598 이 글에 나온 코드를 적용하여 해결..

    # 작업일지 20 / SSE 알림 기능 상태관리, 화면 렌더링!

    # 작업일지 20 / SSE 알림 기능 상태관리, 화면 렌더링!

    1. 현재는 실시간 알림 데이터를 쿼리 데이터로 직접, 즉시 업데이트 하도록 하고, 이를 getQueryData로 가져오고 있다. useQuery를 사용해 가져온 데이터의 경우 이전 쿼리데이터와 현재 쿼리데이터를 비교해서 변경시에 화면에 자동으로 리렌더링이 일어난다. 하지만 위와 같이 가져온 데이터에 대해서는 적용되지 않는다. 이를 수정하기 위한 방법은 useNotification에서 가져오는 notifications 데이터를 useQuery를 사용해서 가져와야 한다. 전체 알림을 조회하는 API가 있으면, 먼저 useQuery로 해당 데이터를 가져오고, setQueryData로 쿼리데이터를 직접 업데이트 하게 된다. 위와 같이 api를 호출하고 성공시 업데이트 하도록 메서드를 사용해주었다. 그런데 이상..

    # 작업일지 19 / SSE 연결하여 알림 기능 구현하기

    # 작업일지 19 / SSE 연결하여 알림 기능 구현하기

    오늘은 지난 시간 다 하지 못한 SSE로 알림 기능 구현하기- 를 진행했다. 1. 알림을 어떤 컴포넌트가 마운트 되었을때 연결하지 말고, 전체 앱에서 전역으로 관리할 수 있도록 호출 위치를 변경해주었다. 그렇게 해야 어떤 페이지에서든 접근이 가능하고, 중복 연결을 방지할 수 있음! 최초로 페이지가 마운트 될 때 SSE라는 컴포넌트가 마운트 되도록 하면서 로그인이 되어있는 경우 SSE를 연결한다. 2. 알림 데이터를 어떻게 관리할까. 우선 알림 데이터는 전역으로 관리하려고 한다. 이유는 먼저 알림 연결 지점은 SSE라는 최상단 컴포넌트이고, 실제로 이 데이터를 사용하는 지점은 메인 헤더와 알림 페이지 두 곳이다. 우선은 fetchSSE 함수를 실행하면 아래와 같은 코드가 실행된다. EventSource 객..

    # 작업일지 18 / 조건에 따른 데이터 refetch, 검색 기능 로직 수정

    # 작업일지 18 / 조건에 따른 데이터 refetch, 검색 기능 로직 수정

    이틀간 SSE와 싸워 지쳤던 나는, 나머지 마무리 하지 못한 기능을 마저 완성하기로 했다. 1. queryClient.refetchQueries(key) 메서드로 실시간 데이터가 업데이트 될 때마다 refetch 되도록 했다. 상품 상세페이지에서 입찰 후 실시간 데이터가 변경이 될 때, 웹소켓으로 받아오지 않는 나머지 데이터에 대해서도 업데이트 되도록 했다. 이제 훨씬 자연스럽고 더 실시간으로 변경되는 느낌이 난다. 위와 같이 key값을 넘기면 간단하게 사용이 가능하다. option에 enabled 라는 속성에 boolean 값을 넣으면 평가에 따라 refetch 하도록 할 수 있는데, 나의 경우 response 데이터가 변경될때마다 상태를 처리하는 것보다 refetchQueries 라는 메서드를 쓰는게..

    # 작업일지 17 / SSE 야! 이미 연결 되어있는데 왜 자꾸 끼어들어!

    # 작업일지 17 / SSE 야! 이미 연결 되어있는데 왜 자꾸 끼어들어!

    SSE를 활용한 알림 기능을 구현하고 있다. 계속 서버가 다운되는 문제가 있었는데, SSE 연결이 되어있는 상태에서 연결이 끊어지지 않고 계속 되어서 스레드 풀을 잡아먹고, 사용 가능한 스레드 풀을 다 채워서 서버가 자꾸 죽는 것이었다. 이미 SSE가 연결된 상태에서 끊어지지 않는 이유가 뭘까? 클라이언트 측에서는 아래와 같이 EventStrem을 생성한 후 특정 시점에 연결을 종료하려고 하였다. 현재는 EventStream이 메인 헤더 컴포넌트에 종속적이어서, 이 컴포넌트가 마운트 될 때 event를 연결하고, 언마운트될 때 연결을 끊고자 하였다. 그런데 이상하게 서버 로그를 확인해도 그 어디에서도 연결이 끊어진 것을 볼 수가 없고, 컴포넌트가 새롭게 마운트 될 때마다 연결만 가중되는 현상이 있었다. ..