<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>hs.log</title>
    <link>https://hslog.today</link>
    <description>Journey To Solution — 권형석의 기술 블로그</description>
    <language>ko</language>
    <item>
      <title><![CDATA[같은 Figma를 보고도 매번 다른 코드가 나오는 문제 줄이기]]></title>
      <link>https://hslog.today/blog/142</link>
      <guid isPermaLink="true">https://hslog.today/blog/142</guid>
      <pubDate>Mon, 24 Aug 2026 02:17:14 GMT</pubDate>
      <category><![CDATA[AI Agent]]></category>
      <description><![CDATA[![86a81755-86d6-4f87-add9-98465f0d0394 _1_](https://d38ach2syxq6se.cloudfront.net/blog/1787546477927-1f958752-959f-4932-8a85-54ad8cfe0ded.png)

## figma-design-to-code 스킬에 검증 절차를 붙인 과정

### 1. 도입 배경

]]></description>
    </item>
    <item>
      <title><![CDATA[사용자가 페이지 로딩을 눈치채지 못하게 만들기 - 블로그 상세 페이지 RSC 적용기]]></title>
      <link>https://hslog.today/blog/140</link>
      <guid isPermaLink="true">https://hslog.today/blog/140</guid>
      <pubDate>Thu, 26 Mar 2026 05:39:26 GMT</pubDate>
      <category><![CDATA[최적화]]></category>
      <description><![CDATA[이 글은 Next.js의 App Router 환경에서 RSC(React Server Components)와 TanStack Query의 `HydrationBoundary`를 활용하여 블로그 상세 페이지의 초기 렌더링 속도를 높이고 사용자 경험을 개선하는 과정을 상세하게 설명합니다. 기존에는 서버에서 데이터를 별도로 요청한 뒤 클라이언트에서 다시 렌더링하는 흐름 때문에 콘텐츠 로드 지연과 레이아웃 이동이 발생했으나, 서버에서 데이터를 먼저 조회하여 Query Cache에 넣고 `dehydrate` 후 클라이언트에 전달하는 방식을 채택함으로써 초기 콘텐츠 노출을 빠르게 하였습니다. 이를 위해 서버 컴포넌트와 `HydrationBoundary`를 조합하는 구조를 설계했고, 구체적인 구현 방법과 코드 예시도 포함되어 있습니다. 개선 효과로는 페이지의 본문과 핵심 UI가 더 빠르게 나타나며, LCP와 FCP 등의 성능 지표가 유의미하게 개선되었으며, SEO 측면에서도 유리하다는 점이 강조됩니다. 또한, 이러한 방식을 모든 페이지에 무조건 적용하기보다는, 사용자 비중과 페이지의 특성에 따라 선택적으로 적용하는 전략을 제시하며, 기존 구조를 크게 훼손하지 않으면서 경험을 향상시키는 방법을 소개합니다.]]></description>
    </item>
    <item>
      <title><![CDATA[Tanstack Query의 효율적인 추상화 : queryOptions 활용]]></title>
      <link>https://hslog.today/blog/139</link>
      <guid isPermaLink="true">https://hslog.today/blog/139</guid>
      <pubDate>Wed, 25 Mar 2026 05:55:58 GMT</pubDate>
      <category><![CDATA[Tanstack Query]]></category>
      <description><![CDATA[이 글은 Tanstack Query를 사용하는 프로젝트에서 흔히 겪는 쿼리 로직의 추상화 문제를 다루고 있다. 현재 커스텀 훅 방식은 타입 추론의 복잡성, React 훅 규칙 제약, 그리고 관리의 어려움 같은 한계가 있음을 지적한다. 이를 해결하기 위해, queryOptions라는 설정 객체 또는 함수를 활용하여 쿼리의 실행과 설정을 분리하는 전략을 소개한다. queryOptions는 컴포넌트 내 데이터 조회, prefetching, 캐시 확인 등 다양한 활용이 가능하며, 타입 안정성과 재사용성을 높이는 데 도움을 준다. 이러한 접근법은 React의 생명주기와 결합된 복잡한 로직과 달리, 낮은 수준의 설정 데이터로써 더 높은 유연성과 안전성을 제공하는 장점이 있다. 마지막으로, 커스텀 훅과 queryOptions의 적절한 병행 사용 방안을 제시하며, 과도한 추상화와 유연성 간의 균형을 맞추는 중요성을 강조한다.]]></description>
    </item>
    <item>
      <title><![CDATA[Tanstack Query의 Query Key 관리 - Enum 관리에서부터 query-key-factory 라이브러리 도입까지]]></title>
      <link>https://hslog.today/blog/138</link>
      <guid isPermaLink="true">https://hslog.today/blog/138</guid>
      <pubDate>Thu, 14 Aug 2025 06:24:27 GMT</pubDate>
      <category><![CDATA[Tanstack Query]]></category>
      <description><![CDATA[이 글은 Tanstack Query에서 queryKey를 문자열로 직접 관리할 때 발생하는 문제점과 한계점에 대해 설명하고 있습니다. 특히, 일관성 없는 queryKey 사용과 리팩토링 시 오류 발생 가능성을 지적하며, 이를 해결하는 방법으로 Enum을 활용한 타입 안전성 확보 방안을 제안합니다. 구체적으로 queryKey를 Enum으로 만들어 관리하는 방식과, 하위 쿼리키와 관련된 객체 구조를 구성하는 예시를 통해 구조화된 관리 방법을 소개합니다. 또한, useQuery나 invalidateQueries 등에서 Enum을 활용하여 안전하게 쿼리 키를 사용하는 방법도 설명하면서, 이러한 방식이 프로젝트의 유지보수성과 규칙 준수에 큰 도움이 됨을 강조합니다. 전체적으로, 타입 안정성과 일관성을 높이고 오류를 방지하는 구조적 쿼리 키 관리법을 제시하는 내용입니다.]]></description>
    </item>
    <item>
      <title><![CDATA[크로미움 기반 브라우저와 사파리 브라우저에서의 Date 객체 처리 방식]]></title>
      <link>https://hslog.today/blog/105</link>
      <guid isPermaLink="true">https://hslog.today/blog/105</guid>
      <pubDate>Mon, 11 Aug 2025 07:59:39 GMT</pubDate>
      <category><![CDATA[크로스 브라우징]]></category>
      <description><![CDATA[이 글은 프론트엔드 개발에서 백엔드로부터 받은 날짜 데이터를 다룰 때 발생하는 브라우저별 호환성 문제를 설명합니다. 특히, `new Date()` 생성자가 브라우저마다 다르게 동작하는 원인을 분석하며, 크롬은 비표준 형식을 유연하게 처리하는 반면 사파리는 엄격하게 표준만 준수한다고 설명합니다. 이를 해결하기 위해선 항상 표준인 ISO 8601 형식(예: `YYYY-MM-DDTHH:mm:ssZ`)으로 날짜 문자열을 받아서 `new Date()`에 전달하는 것이 중요하다고 조언합니다. 이후, 생성된 `Date` 객체를 디자인에 맞게 포매팅하는 방법도 제시하며, 날짜 처리의 안정성과 일관성을 확보하는 방법을 안내합니다.]]></description>
    </item>
    <item>
      <title><![CDATA[TailwindCSS V4에서 다크 모드가 적용되지 않는 이슈]]></title>
      <link>https://hslog.today/blog/97</link>
      <guid isPermaLink="true">https://hslog.today/blog/97</guid>
      <pubDate>Wed, 09 Jul 2025 08:06:41 GMT</pubDate>
      <category><![CDATA[TailwindCSS]]></category>
      <description><![CDATA[TailwindCSS V4로 업그레이드하면서 기존의 `tailwind.config.ts` 파일을 통한 다크모드 설정 방식이 제거되고, `@custom-variant`를 사용해야 하는 새로운 방법이 도입되었습니다. V3 이하 버전에서는 `darkMode: 'class'` 옵션으로 다크모드를 활성화했지만, V4에서는 글로벌 CSS 파일에 직접 `@custom-variant`를 선언하는 방식으로 변경되었습니다. 이 방법은 `dark` 클래스가 넣어진 요소와 그 하위 모든 요소에 대해 `dark:` 변형 클래스를 올바르게 적용하게 해줍니다. 이 과정에서 `:where()` 가상 클래스를 활용하여 선택자 명시도를 낮추고, 유연하게 다크모드 스타일을 제어할 수 있습니다. 결론적으로, 쉽게 다크모드 기능을 활성화하려면 `globals.css`에 `@custom-variant dark (&:where(.dark, .dark *));` 구문을 추가하는 것이 핵심이며, 이를 통해 별도의 `tailwind.config.ts` 수정 없이 간단히 다크모드 설정이 가능해졌음을 알 수 있습니다. 이번 경험에서도 공식 문서를 꼼꼼히 읽는 것이 중요하다는 교훈이 담겨 있습니다.]]></description>
    </item>
    <item>
      <title><![CDATA[Biome - 차세대 Linter & Formatter]]></title>
      <link>https://hslog.today/blog/95</link>
      <guid isPermaLink="true">https://hslog.today/blog/95</guid>
      <pubDate>Wed, 04 Jun 2025 04:46:19 GMT</pubDate>
      <category><![CDATA[Biome]]></category>
      <description><![CDATA[이 글은 기존에 ESLint와 Prettier를 조합하여 사용하는 방식과 달리, 훨씬 빠른 성능과 간편한 설정이 가능한 Biome에 대해 소개합니다. Biome은 JavaScript, TypeScript, JSX, JSON 등 다양한 언어를 지원하며, 하나의 도구로 포매터와 린터 기능을 동시에 수행할 수 있습니다. 설치와 환경 설정 방법, 그리고 프로젝트에 적용하는 방법 등을 상세히 설명하며, Biome의 우수한 속도와 사용 편의성을 강조합니다. 또한, Biome이 제공하는 규칙, 확장성, IDE와의 연동성 등 장점들을 소개하고, 기존 도구와의 비교를 통해 즉각적인 효과와 앞으로의 기대감을 전달합니다. 마지막으로, 아직 지원하지 않는 언어와 레퍼런스 부족 등의 단점도 함께 살펴봅니다.]]></description>
    </item>
    <item>
      <title><![CDATA[반응형 웹을 위한 Tailwind CSS와 rem 단위 활용하기]]></title>
      <link>https://hslog.today/blog/86</link>
      <guid isPermaLink="true">https://hslog.today/blog/86</guid>
      <pubDate>Fri, 11 Apr 2025 01:19:26 GMT</pubDate>
      <category><![CDATA[CSS]]></category>
      <description><![CDATA[픽셀(px)은 절대 단위로, 다양한 화면 크기와 사용자의 폰트 크기 변경에 유연하게 대응하지 못하는 한계가 있습니다. 반면, rem은 루트 폰트 크기를 기준으로 하는 상대적 단위로, 모든 요소가 비례하여 조정되어 반응형 웹 구현에 적합합니다. 피그마에서 설계된 모바일 디자인 기준 너비인 360px을 기준으로 폰트 크기를 계산하는 방법도 설명하며, 이를 적용하면 다양한 디바이스 크기에서도 일관된 비율을 유지할 수 있습니다. Tailwind CSS는 rem 기반으로 설계되어 있어 반응형 디자인에 유리하며, 필요시 px을 rem으로 변경하는 방법도 안내되어 있습니다. 이러한 방식을 통해 더욱 유연하고 유지보수하기 쉬운 반응형 웹 디자인을 구현할 수 있습니다.]]></description>
    </item>
    <item>
      <title><![CDATA[서버에서 prefetch를 할 경우 Suspense는 불필요한 것일까]]></title>
      <link>https://hslog.today/blog/85</link>
      <guid isPermaLink="true">https://hslog.today/blog/85</guid>
      <pubDate>Thu, 10 Apr 2025 13:35:38 GMT</pubDate>
      <category><![CDATA[Tanstack Query]]></category>
      <description><![CDATA[서버 컴포넌트에서 데이터를 미리 불러오고(pre-fetch) 이를 클라이언트에 전달하는 패턴이 있지만, 이 방식이 클라이언트 데이터 갱신과 별개로 작동한다는 점이 핵심이에요. 서버에서 prefetch된 데이터는 초기 로드 시에는 별다른 fallback 없이 바로 보여지지만, 클라이언트에서 staleTime 이후 다시 데이터를 요청할 때는 Suspense의 fallback UI가 필요하죠. useSuspenseQuery는 로딩과 에러 관리를 선언적으로 처리하며, 이를 Suspense와 함께 사용하면 더 간단하게 UI 상태를 제어할 수 있어요. 결론적으로, 서버 prefetch와 클라이언트의 데이터 refetch는 별개이기 때문에, 클라이언트 갱신 시에는 Suspense fallback이 필요하며, useSuspenseQuery는 이를 더욱 쉽게 구현할 수 있게 도와준다는 내용입니다.]]></description>
    </item>
    <item>
      <title><![CDATA[rsc에서 Prefetch한 데이터 사용하기]]></title>
      <link>https://hslog.today/blog/66</link>
      <guid isPermaLink="true">https://hslog.today/blog/66</guid>
      <pubDate>Thu, 13 Mar 2025 08:19:17 GMT</pubDate>
      <category><![CDATA[Tanstack Query]]></category>
      <description><![CDATA[이 글은 기존에 서버에서 fetch한 데이터를 initialData로 넘기는 방식의 문제점과 React Query의 hydration API를 활용한 개선 방안을 설명합니다. 서버 컴포넌트에서 prefetch와 dehydrate로 데이터를 캐시하고, 클라이언트에서 hydrate로 복원하는 방법을 소개하며, 이를 통해 props drilling을 줄이고 캐시 일관성을 높일 수 있음을 강조합니다. 또한, Next.js의 정적 페이지 캐싱으로 인한 데이터 갱신 문제와 그 해결책으로 서버 액션과 revalidatePath를 사용하는 방안을 제시합니다. 마지막으로, revalidate = 0 설정과 서버 액션 호출로 클라이언트와 서버 캐시를 동시에 무효화하는 전략을 설명하며, 실시간 데이터 반영과 SSR 최적화의 균형을 모색하는 중요성을 전달합니다.]]></description>
    </item>
    <item>
      <title><![CDATA[프론트엔드 개발자의 동일한 개발 환경 구축]]></title>
      <link>https://hslog.today/blog/65</link>
      <guid isPermaLink="true">https://hslog.today/blog/65</guid>
      <pubDate>Thu, 13 Mar 2025 04:08:51 GMT</pubDate>
      <category><![CDATA[Frontend]]></category>
      <description><![CDATA[새로운 프로젝트 또는 협업에서 개발 환경을 통일하는 이유와 중요성을 설명합니다. 코드 일관성을 유지하면 가독성과 유지보수가 쉬워지고, 불필요한 변경 기록을 방지할 수 있습니다. 또한, 패키지 버전과 도구 확장을 통일하여 프로젝트 간 차이로 인한 문제를 예방할 수 있습니다. 이를 위해 VSCode 환경설정 파일, Git 관련 속성, ESLint, 패키지 매니저 버전 통일 등 구체적인 설정 방법을 제시합니다. 마지막으로, 코딩 스타일을 강제하는 다양한 설정 파일들에 대한 예시도 포함되어 있습니다.]]></description>
    </item>
    <item>
      <title><![CDATA[Execution Context (실행 컨텍스트) & 호이스팅]]></title>
      <link>https://hslog.today/blog/58</link>
      <guid isPermaLink="true">https://hslog.today/blog/58</guid>
      <pubDate>Tue, 14 Jan 2025 06:01:02 GMT</pubDate>
      <category><![CDATA[JavaScript]]></category>
      <description><![CDATA[실행 컨텍스트는 자바스크립트 코드 실행 환경과 순서를 관리하는 객체로, 콜스택에 쌓여 코드의 흐름을 제어합니다. 각각의 컨텍스트는 Lexical Environment, Variable Environment, This Binding으로 구성되어 있으며, 이를 통해 변수와 함수, 스코프를 관리합니다. Lexical Environment는 식별자와 상위 스코프 참조를 담당하고, Variable Environment는 var 변수와 함수 선언 등을 저장하며, This Binding은 함수 호출 시의 this 값을 결정합니다. 실행 컨텍스트 생성 과정에서는 환경 정보들이 수집되어 콜스택에 쌓이고, 함수 종료 시 제거됩니다. 또한, 호이스팅은 자바스크립트가 코드 실행 전에 변수와 함수 선언을 미리 끌어올려 검색 가능하게 하는 현상으로, 이를 통해 변수 선언문의 위치와 상관없이 사용할 수 있게 됩니다.]]></description>
    </item>
  </channel>
</rss>