들어가기에 앞서, 프론트엔드에 많은 양의 이미지를 저장하는 것은 유지보수가 어렵고, 권장되지 않습니다.많은 이미지를 수반한다면 CDN 서비스를 사용하는 것이 좋습니다.이 포스팅은 프론트엔드 서버를 사용하지 않는 정적 배포를 기준으로 작성합니다 !!1. 이미지 파일을 어떻게 관리할까?NextJS 환경에서 이미지 저장 경로는 크게 2종류로 나눌 수 있습니다.public 폴더src 폴더 하위 경로You can store static files, like images and fonts, under a folder called public in the root directory. Files inside public can then be referenced by your code starting from the b..
리액트의 조건부 렌더링 방식에는 여러가지가 있습니다.가장 많이 쓰이는 얼리 리턴, 삼항 연산자, 논리 AND 연산자(&&) 패턴을 정리했습니다.얼리 리턴 (Early Return)조건에 만족하면 즉시 컴포넌트를 반환합니다.export default function SingleSeat({ clusterUser, seatNumber,}: { clusterUser?: ActiveClusterUser; seatNumber: number;}) { const { user } = useUserStore(); if (!clusterUser) // 해당 Seat 컴포넌트에 전달받은 유저가 없다면 빈 자리를 리턴합니다. return ( {seatNumber} ..
JWT, access token, refresh token에 대한 설명은 생략합니다.평소처럼 비동기 API 콜을 사용하여 데이터를 받아오고 있었습니다.액세스 토큰이 손상, 만료될 경우를 대비해 axios 인터셉터에 만료 로직을 추가하여 관리하고 있는 상황이었는데..기존의 재발급 처리 방식axios.interceptors.response.use( async (response) => response, async (error) => { // API 요청 중 401 unauthorized 에러가 발생한 경우 (토큰 만료 등) if (error.response && error.response.status === 401) { try { // reissue 요청을 하고 실패한 요..
리액트의 useMemo 훅은 결과값을 저장해놓고 디펜던시 배열에 있는 값이 바뀌지 않는 한 재연산을 하지 않아도 되는, 캐싱 역할을 합니다. 실제로 useMemo를 프로덕션에 적용하여 볼까요?export default function AnnouncementItem({ announcementType, title, date, currDate, isLast,}: { announcementType: string; title: string; date: string; currDate: Date; isLast?: boolean;}) { // useMemo를 쓰지 않을 때 const diffTime = currDate.getTime() - new Date(date).getTime(); const ..
어느때부터 개발이 너무 편해졌다 싶었는데 ESLint가 적용되지 않고 있었습니다.다시 환경설정을 해보자 싶어 또 무한 구글링에 돌입하여 ESLint 공식 문서도 열심히 읽고, 블로그도 조사하였으나.. 아무것도 문제를 해결해주지 않았습니다. 크아아악~~제 문제는 다음과 같았습니다.터미널에서 lint를 실행했을 때는 잘 되지만, vscode에서만 적용되지 않음. (빨간 줄로 경고가 나타나지 않음)이 경우는 vscode만의 문제라고 보면 되니, 이 안에서 해결해야 합니다.워크 스페이스 설정, eslintrc 등을 고쳐보았지만 전혀 진전이 없던 찰나 vscode 하단의 OUTPUT 탭을 확인하여 ESLint의 출력을 볼 수가 있었는데, 다음과 같은 출력이 나오고 있었습니다.the language client r..
import MyComponent from "../../../../../components/MyComponent";import ADifferentFile from "../../../some/other/dir/ADifferentFile";import PageMeta from "@components/PageMeta";import RecentPostList from "@components/RecentPostList";import SocialCards from "@components/SocialCards";1. tsconfig 설정{ "compilerOptions": { ... "paths": { "@/*": ["./src/*"] }, ... }}tsconfig의 컴파일러 옵션..
이전에 팀원분들과 프로젝트 구조에 관해 논의하던 중 이런 이야기가 나왔습니다.백엔드: 그런데 사실 저는 프론트 서버가 왜 필요한지 모르겠습니다.어차피 백엔드 서버가 있는데 왜 프론트 서버가 따로 필요한건가요?프론트 서버를 거쳐서 백엔드 서버에 접근할 거라면 애초에 백엔드 서버에 접근하는게 더 빠르지 않나요?저는 당시 쉽사리 답변을 해드리지 못했습니다. 저 말만 놓고 보면 틀린 말이 아니니까요.그럼 결국 프론트엔드 서버는 필요 없는걸까요? 1. 전통적인 프론트엔드 개발 방식 (정적 배포)근본적으로 웹 프론트엔드는 HTML, JS, CSS의 세 가지 요소로 이루어져있습니다.브라우저는 위 요소만을 가지고 웹을 구성하게 되죠. 전통적인 프론트엔드의 배포 과정은 아래와 같습니다.리액트 등의 라이브러리, 프레임워크..
일괄적인 컬러 적용을 위해 테일윈드 :root 클래스에 darkblue 프로퍼티를 선언하여 사용하고 있었습니다.하지만 크롬에서는 작동하고 사파리에선 작동하지 않는 이슈가 터지고 말았습니다!! 아아~크롬만 보고 테스트해서 이미 메인 서비스까지 올려놨는데 말이죠~ 새벽에 확인하고 허겁지겁 롤백했다 아입니꺼~처음에 추정한 원인은 테일윈드CSS 클래스 관련해서 사파리엔 아직 지원하지 않는게 있나? 싶었지만,결국 원인은 오타였습니다. 사진에서 --darkblue를 선언할 때 중간에 쉼표가 들어간 게 보이시나요?--darkblue: 215, 56%, 17% // 이렇게 쉼표를 모두 붙이거나,--darkblue: 215 56% 17% // 이렇게 모두 없애야 합니다.사파리가 이상한 게 아니고, 크롬 브라우저의 CSS..