<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>news-thing</title>
    <link>https://news-thing.tistory.com/</link>
    <description>news-thing 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 16 Jun 2026 06:31:09 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>danny-shim</managingEditor>
    <item>
      <title>Argc: Bash CLI 프레임워크로 CLI 개발을 간단하게!</title>
      <link>https://news-thing.tistory.com/24</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Argc란 무엇일까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argc는 Bash 기반의 CLI 프레임워크이자 커맨드 러너로, CLI를 구축할 때 발생하는 지루한 작업(인수 파싱, 사용법 텍스트 생성, 에러 메시지 처리 등)을 자동화해줍니다. 핵심 아이디어는 &lt;b&gt;주석으로 CLI 인터페이스를 정의&lt;/b&gt;하는 거예요. 코드를 작성하면서 &lt;code&gt;@&lt;/code&gt;로 시작하는 주석만 달아주면, Argc가 나머지를 처리해주죠. 게다가 크로스플랫폼 지원(macOS, Linux, Windows, BSD)으로 어디서든 동작합니다. 라이선스는 Apache-2.0 또는 MIT로 자유롭게 사용할 수 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 매력은 단순함에 있어요. 복잡한 파서 라이브러리를 배우지 않아도, 기존 Bash 스킬만으로 풀페처 CLI를 만들 수 있답니다. 게다가 Argcfile.sh를 통해 태스크 자동화도 가능하니, 스크립트 애호가들에게 딱 맞아요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Argc의 주요 기능&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argc가 왜 특별한지, 핵심 기능을 나열해볼게요:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;쉬운 인수 파싱&lt;/b&gt;: 플래그, 옵션, 위치 인수, 서브커맨드를 자동 처리. 입력 유효성 검사와 사용법 텍스트 생성까지!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;독립 실행 스크립트 생성&lt;/b&gt;: Argc에 의존하지 않는 standalone Bash 스크립트를 빌드할 수 있어요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 완성 지원&lt;/b&gt;: Bash, Zsh, Fish, PowerShell 등 다양한 쉘에서 자동 완성 기능 제공.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Man 페이지 자동 생성&lt;/b&gt;: CLI의 상세 매뉴얼을 한 번에 만들어줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;환경 변수 통합&lt;/b&gt;: 옵션/인수와 환경 변수를 연결하고 검증.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;태스크 자동화&lt;/b&gt;: Argcfile.sh로 Bash + GNU 도구를 활용한 명령 실행.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;크로스플랫폼 호환&lt;/b&gt;: 플랫폼 간 이식성이 뛰어나요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능들 덕분에, CLI 개발 시간이 대폭 줄어요. 예를 들어, 기존에 수십 줄의 파싱 코드를 작성하던 걸 몇 줄의 주석으로 대체할 수 있죠.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치 방법: 5분 만에 시작하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argc 설치가 간단해서 좋습니다. 여러 방법을 지원하니, 환경에 맞게 선택하세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패키지 매니저 사용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Rust (Cargo)&lt;/b&gt;: &lt;code&gt;cargo install argc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Homebrew (macOS/Linux)&lt;/b&gt;: &lt;code&gt;brew install argc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Arch Linux (Pacman)&lt;/b&gt;: &lt;code&gt;yay -S argc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;바이너리 다운로드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub Releases에서 다운로드하거나, 한 줄 스크립트로 설치:&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;curl -fsSL https://raw.githubusercontent.com/sigoden/argc/main/install.sh | sh -s -- --to /usr/local/bin&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;GitHub Actions (CI/CD용)&lt;/h3&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;- uses: sigoden/install-binary@v1
  with:
    repo: sigoden/argc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;팁&lt;/b&gt;: macOS에서는 Bash 5와 GNU 도구를 설치하세요 (&lt;code&gt;brew install bash coreutils gawk gnu-sed grep&lt;/code&gt;). Windows에서는 Git Bash를 사용하고, PowerShell에서 &lt;code&gt;.sh&lt;/code&gt; 파일 실행을 위해 레지스트리 설정을 추가하면 돼요. (자세한 코드는 리포지토리 참조!)&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 사용 예시: 간단한 CLI 만들기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Argc의 마법을 느껴보죠. &lt;code&gt;example.sh&lt;/code&gt;라는 스크립트를 작성해봅시다. 주석으로 인터페이스를 정의한 후, &lt;code&gt;eval&lt;/code&gt;로 Argc를 호출하면 끝!&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;#!/usr/bin/env bash

# @flag -F --foo  Flag param
# @option --bar   Option param
# @option --baz*  Option param (multi-occurs)
# @arg val*       Positional param

eval &quot;$(argc --argc-eval &quot;$0&quot; &quot;$@&quot;)&quot;

echo foo: $argc_foo
echo bar: $argc_bar
echo baz: ${argc_baz[@]}
echo val: ${argc_val[@]}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 예시:&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;./example.sh -F --bar=xyz --baz a --baz b v1 v2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;foo: 1
bar: xyz
baz: a b
val: v1 v2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도움말도 자동 생성! &lt;code&gt;./example.sh --help&lt;/code&gt;를 치면:&lt;/p&gt;
&lt;pre class=&quot;http&quot;&gt;&lt;code&gt;USAGE: example [OPTIONS] [VAL]...

ARGS:
  [VAL]...  Positional param

OPTIONS:
  -F, --foo           Flag param
      --bar &amp;lt;BAR&amp;gt;     Option param
      --baz [BAZ]...  Option param (multi-occurs)
  -h, --help          Print help
  -V, --version       Print version&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 기능 활용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Standalone 빌드&lt;/b&gt;: &lt;code&gt;argc --argc-build ./example.sh build/&lt;/code&gt;로 Argc 없이 실행 가능한 스크립트 생성.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 완성&lt;/b&gt;: &lt;code&gt;source &amp;lt;(argc --argc-completions bash ./example.sh example --)&lt;/code&gt;로 쉘 완성 활성화.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Man 페이지&lt;/b&gt;: &lt;code&gt;argc --argc-mangen ./example.sh man/&lt;/code&gt;로 매뉴얼 생성 후 &lt;code&gt;man man/example.1&lt;/code&gt; 확인.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 복잡한 CLI는 &lt;code&gt;@describe&lt;/code&gt;, &lt;code&gt;@cmd&lt;/code&gt; (서브커맨드), &lt;code&gt;@env&lt;/code&gt; (환경 변수) 등의 태그를 활용하세요. Argcfile.sh로 태스크를 정의하면, Makefile 같은 자동화도 가능해요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 Argc를 추천할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argc는 Bash의 강점을 극대화하면서, 현대 CLI 도구의 편의성을 더해줍니다. 특히, Rust로 작성된 가벼운 바이너리라 성능도 우수해요. 벤치마크는 별도로 없지만, 간단한 파싱으로도 고속 동작을 보장하죠. 만약 여러분이 스크립트나 도구를 자주 만드신다면, Argc로 시간을 절약하고 더 프로페셔널한 CLI를 만들어보세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트를 더 탐구하고 싶으시면 &lt;a href=&quot;https://github.com/sigoden/argc&quot;&gt;GitHub 리포지토리&lt;/a&gt;를 방문하세요.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/24</guid>
      <comments>https://news-thing.tistory.com/24#entry24comment</comments>
      <pubDate>Fri, 31 Oct 2025 10:32:38 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 16의 혁신: 캐싱부터 개발자 경험까지, 미래 지향적인 업데이트</title>
      <link>https://news-thing.tistory.com/22</link>
      <description>&lt;p&gt;안녕하세요, 웹 개발자 여러분! Next.js가 또 한 번 업계를 흔들고 있습니다. 2025년 10월 21일, Vercel은 Next.js 16을 공식 발표하며, Next.js Conf 2025를 앞두고 개발자 커뮤니티를 흥분시켰습니다. 이 버전은 Turbopack의 안정화, 캐싱 아키텍처의 대대적 개편, React 19 통합 등으로 가득 차 있어요. 만약 여러분이 React 기반의 풀스택 앱을 개발 중이라면, 이 업데이트는 반드시 확인해야 할 내용입니다. 오늘은 이 블로그 포스트를 바탕으로 Next.js 16의 핵심 포인트를 간결하게 정리해 보겠습니다. 업그레이드 해보고 싶으신가요? 함께 살펴보죠!&lt;/p&gt;
&lt;h2&gt;1. 캐싱의 새 시대: Cache Components와 Partial Prerendering 완성&lt;/h2&gt;
&lt;p&gt;Next.js의 가장 큰 변화는 &lt;strong&gt;캐싱 모델&lt;/strong&gt;입니다. 이전 App Router의 암시적 캐싱에서 벗어나, 이제 &lt;strong&gt;명시적(opt-in) 캐싱&lt;/strong&gt;을 도입했습니다. &lt;code&gt;&amp;quot;use cache&amp;quot;&lt;/code&gt; 지시어를 사용해 페이지, 컴포넌트, 함수를 캐싱할 수 있으며, 컴파일러가 자동으로 캐시 키를 생성해 줍니다. 동적 코드는 기본적으로 요청 시 실행되며, 이는 풀스택 프레임워크의 기대와 맞아떨어집니다.&lt;/p&gt;
&lt;p&gt;이 변화의 하이라이트는 &lt;strong&gt;Partial Prerendering (PPR)&lt;/strong&gt; 의 완성입니다. 2023년에 도입된 PPR이 이제 안정화되어, Suspense를 통해 동적 부분을 정적 페이지에 선택적으로 포함할 수 있어요. 초기 로드 속도를 유지하면서도 동적 콘텐츠를 자유롭게 활용할 수 있게 됐죠. 활성화는 간단합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;// next.config.ts
const nextConfig = {
  cacheComponents: true,
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실험적 플래그(&lt;code&gt;experimental.ppr&lt;/code&gt;)는 제거되었으니, 이 설정으로 대체하세요. 더 자세한 내용은 Next.js Conf 2025에서 공개될 예정입니다.&lt;/p&gt;
&lt;p&gt;또한, 캐싱 API가 강화됐어요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;revalidateTag()&lt;/strong&gt;: 이제 &lt;code&gt;cacheLife&lt;/code&gt; 프로필(예: &amp;#39;max&amp;#39;)을 요구하며, stale-while-revalidate(SWR) 전략을 지원합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;updateTag()&lt;/strong&gt; (신규, Server Actions 전용): 즉시 캐시 만료 및 새로고침으로 read-your-writes를 구현.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;refresh()&lt;/strong&gt; (신규, Server Actions 전용): 캐시를 건드리지 않고 데이터만 새로고침.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이러한 변화로 앱의 성능이 크게 향상될 거예요. 예를 들어, 사용자 알림처럼 실시간 업데이트가 필요한 부분에서 유용하죠.&lt;/p&gt;
&lt;h2&gt;2. Turbopack의 안정화: 속도와 안정성의 정점&lt;/h2&gt;
&lt;p&gt;Turbopack이 이제 &lt;strong&gt;기본 번들러&lt;/strong&gt;로 자리 잡았습니다! 새 프로젝트에서는 자동으로 적용되며, 프로덕션 빌드가 2~5배, Fast Refresh가 최대 10배 빨라집니다. Next.js 15.3+ 사용자 중 50% 이상이 개발 세션에서, 20%가 프로덕션 빌드에서 이미 사용 중이에요. 커스텀 webpack 설정이 필요하다면 &lt;code&gt;--webpack&lt;/code&gt; 플래그로 옵트아웃하세요.&lt;/p&gt;
&lt;p&gt;베타 기능으로는 &lt;strong&gt;Turbopack File System Caching&lt;/strong&gt;이 추가됐습니다. 대형 프로젝트에서 컴파일러 아티팩트를 디스크에 저장해 재시작 속도를 높여줍니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;// next.config.ts
const nextConfig = {
  experimental: {
    turbopackFileSystemCacheForDev: true,
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 외에도 &lt;strong&gt;React Compiler 지원&lt;/strong&gt;이 안정화됐어요. &lt;code&gt;reactCompiler: true&lt;/code&gt; 설정으로 컴포넌트를 자동 메모이징해 재렌더링을 줄일 수 있지만, Babel 의존성으로 컴파일 시간이 길어질 수 있으니 주의하세요.&lt;/p&gt;
&lt;h2&gt;3. 개발자 경험(DX) 향상: 로그, 프록시, 그리고 AI 도구&lt;/h2&gt;
&lt;p&gt;개발 과정이 더 직관적으로 변했습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;로그 개선&lt;/strong&gt;: 개발 요청 로그에 컴파일/렌더링 시간 표시, 빌드 로그에 단계별 시간 출력으로 병목 현상을 쉽게 파악할 수 있어요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;proxy.ts 도입&lt;/strong&gt;: &lt;code&gt;middleware.ts&lt;/code&gt;를 대체하며, Node.js 런타임에서 실행됩니다. 단순히 파일과 함수 이름을 바꾸기만 하면 됩니다. Edge 런타임용으로는 더 이상 사용하지 마세요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next.js Devtools MCP&lt;/strong&gt;: AI 기반 디버깅 도구로, 라우팅/캐싱/렌더링 지식을 AI 에이전트에 제공합니다. 로그 통합과 오류 자동 접근으로 문제 진단이 수월해졌어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;또한, &lt;strong&gt;라우팅 및 네비게이션&lt;/strong&gt;이 최적화됐습니다. 공유 레이아웃 중복 다운로드를 줄이고, 증분 프리페칭으로 불필요한 요청을 최소화합니다. 뷰포트 이탈 시 취소, 호버 시 우선순위 부여 등으로 사용자 경험이 부드러워졌죠.&lt;/p&gt;
&lt;h2&gt;4. React 19 통합과 기타 하이라이트&lt;/h2&gt;
&lt;p&gt;Next.js 16은 &lt;strong&gt;React 19.2 Canary&lt;/strong&gt;를 App Router에 적용합니다. View Transitions로 업데이트 애니메이션, &lt;code&gt;useEffectEvent&lt;/code&gt;로 비반응 로직 처리, &lt;code&gt;Activity&lt;/code&gt;로 백그라운드 렌더링 지원 등이 포함됐어요. 브라우저 호환성도 강화: Node.js 20.9+, TypeScript 5.1+ 필수입니다.&lt;/p&gt;
&lt;p&gt;기타 개선:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;create-next-app&lt;/strong&gt; 재설계: App Router 기본, TypeScript 우선, Tailwind/ESLint 포함.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Adapters API&lt;/strong&gt; (알파): 배포 플랫폼 커스텀 훅 지원.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;주의할 점: Breaking Changes와 마이그레이션&lt;/h2&gt;
&lt;p&gt;좋은 소식만큼, 변화도 있어요. 주요 브레이킹 체인지:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AMP 지원 제거, &lt;code&gt;next lint&lt;/code&gt; 폐지 (ESLint/Biome 사용).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;middleware.ts&lt;/code&gt; → &lt;code&gt;proxy.ts&lt;/code&gt; 리네임.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;revalidateTag()&lt;/code&gt; 시그니처 변경, 동기 API → 비동기 전환.&lt;/li&gt;
&lt;li&gt;이미지 최적화 기본값 조정 (TTL 4시간, 품질 75 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;업그레이드는 CLI(&lt;code&gt;npx @next/codemod@canary upgrade latest&lt;/code&gt;)나 수동 설치로 쉽습니다. 자세한 가이드는 &lt;a href=&quot;https://nextjs.org/docs/app/guides/upgrading/version-16&quot;&gt;공식 업그레이드 문서&lt;/a&gt;를 확인하세요.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/22</guid>
      <comments>https://news-thing.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 28 Oct 2025 11:08:10 +0900</pubDate>
    </item>
    <item>
      <title>React Grab: React 앱 요소를 클릭 한 번으로 코딩 에이전트에게 전달하는 혁신적인 도구</title>
      <link>https://news-thing.tistory.com/21</link>
      <description>&lt;p&gt;안녕하세요, 개발자 여러분! React로 앱을 개발하다 보면, UI 요소를 수정하거나 디버깅할 때 코드 에이전트(예: Cursor, Claude Code, OpenCode)를 활용하고 싶어지는 순간이 많죠. 하지만 이 에이전트들은 페이지의 실제 요소에 직접 접근할 수 없어서, 매번 코드를 복사하거나 설명을 길게 적어야 하는 번거로움이 있었습니다. 오늘은 이런 문제를 간단히 해결해주는 오픈소스 도구 &lt;strong&gt;React Grab&lt;/strong&gt;을 소개해보려 해요. GitHub에서 &lt;a href=&quot;https://github.com/aidenybai/react-grab&quot;&gt;aidenybai/react-grab&lt;/a&gt; 저장소를 기반으로 한 이 도구는, 단 한 줄의 스크립트로 앱 내 요소를 &amp;quot;잡아&amp;quot; 에이전트에게 전달할 수 있게 해줍니다. 개발 생산성을 폭발적으로 높여줄 거예요!&lt;/p&gt;
&lt;h2&gt;React Grab이란?&lt;/h2&gt;
&lt;p&gt;React Grab은 React 앱에서 &lt;strong&gt;⌘C (Command + C)&lt;/strong&gt; 키를 누르고 클릭하는 것만으로, 원하는 DOM 요소를 복사해 코딩 에이전트에게 전달할 수 있는 라이브러리입니다. 예를 들어, Cursor나 Claude Code 같은 AI 도구에 &amp;quot;이 버튼의 스타일을 바꿔줘&amp;quot;라고 지시할 때, 단순한 텍스트 설명 대신 실제 요소의 HTML 구조와 스타일을 그대로 제공할 수 있어요. 이 도구는 순수 JavaScript로 구현되어 있어서 프레임워크 의존성이 낮고, 개발 모드에서만 활성화되도록 설계되어 프로덕션 환경에 영향을 주지 않습니다.&lt;/p&gt;
&lt;p&gt;왜 이게 유용할까요? &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI 에이전트가 페이지 컨텍스트를 이해하기 어려워서 발생하는 오해를 줄여줍니다.&lt;/li&gt;
&lt;li&gt;빠른 프로토타이핑과 버그 픽스에 딱! 클릭 한 번으로 요소를 &amp;quot;잡아&amp;quot; 클립보드에 저장해 에이전트 프롬프트에 붙여넣기만 하면 끝.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;저는 이 도구를 사용해보니, 기존 워크플로우가 훨씬 직관적으로 변했어요. 특히 복잡한 컴포넌트 트리를 다룰 때 빛을 발합니다.&lt;/p&gt;
&lt;h2&gt;주요 기능&lt;/h2&gt;
&lt;p&gt;React Grab의 핵심 기능은 간단하지만 강력합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;쉬운 요소 잡기&lt;/strong&gt;: 앱에서 ⌘C를 누르고 클릭하면, 해당 요소의 HTML, CSS, 그리고 React 컴포넌트 구조가 클립보드로 복사됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;호환성&lt;/strong&gt;: Cursor, Claude Code, OpenCode 등 주요 코딩 에이전트와 완벽 호환.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;경량 구현&lt;/strong&gt;: 단일 스크립트 태그로 추가 가능. 번들 크기는 &lt;a href=&quot;https://bundlephobia.com/package/react-grab&quot;&gt;Bundlephobia&lt;/a&gt;에서 확인할 수 있지만, 매우 가볍습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;개발 모드 전용&lt;/strong&gt;: &lt;code&gt;data-enabled=&amp;quot;true&amp;quot;&lt;/code&gt; 속성으로 쉽게 토글 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아래는 README에 포함된 데모 GIF로, 실제 작동 방식을 보여줍니다. (이미지: &lt;a href=&quot;https://react-grab.com/demo.gif&quot;&gt;데모 GIF&lt;/a&gt;) 클릭만으로 요소가 잡히는 게 보이시죠?  &lt;/p&gt;
&lt;h2&gt;설치 방법&lt;/h2&gt;
&lt;p&gt;설치는 프로젝트 유형에 따라 다르지만, 대부분 1-2분이면 끝납니다. &lt;strong&gt;주의: 개발 모드에서만 활성화하세요!&lt;/strong&gt; 프로덕션에서는 &lt;code&gt;process.env.NODE_ENV === &amp;quot;development&amp;quot;&lt;/code&gt; 조건을 사용해 비활성화하는 걸 추천해요.&lt;/p&gt;
&lt;h3&gt;1. 일반 HTML/JS 프로젝트 (프레임워크 없음)&lt;/h3&gt;
&lt;p&gt;HTML의 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;나 &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;에 스크립트 태그를 추가하세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;script
  src=&amp;quot;//unpkg.com/react-grab/dist/index.global.js&amp;quot;
  crossorigin=&amp;quot;anonymous&amp;quot;
  data-enabled=&amp;quot;true&amp;quot;
&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이게 전부! CDN을 통해 즉시 로드됩니다.&lt;/p&gt;
&lt;h3&gt;2. Next.js (App Router)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;app/layout.tsx&lt;/code&gt; 파일에 Next.js의 &lt;code&gt;Script&lt;/code&gt; 컴포넌트를 사용하세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-tsx&quot;&gt;import Script from &amp;quot;next/script&amp;quot;;

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    &amp;lt;html lang=&amp;quot;ko&amp;quot;&amp;gt;
      &amp;lt;head&amp;gt;
        {process.env.NODE_ENV === &amp;quot;development&amp;quot; &amp;amp;&amp;amp; (
          &amp;lt;Script
            src=&amp;quot;//unpkg.com/react-grab/dist/index.global.js&amp;quot;
            crossOrigin=&amp;quot;anonymous&amp;quot;
            strategy=&amp;quot;beforeInteractive&amp;quot;
            data-enabled=&amp;quot;true&amp;quot;
          /&amp;gt;
        )}
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;{children}&amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Next.js (Pages Router)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pages/_document.tsx&lt;/code&gt;에 추가:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-tsx&quot;&gt;import { Html, Head, Main, NextScript } from &amp;quot;next/document&amp;quot;;
import Script from &amp;quot;next/script&amp;quot;;

export default function Document() {
  return (
    &amp;lt;Html lang=&amp;quot;ko&amp;quot;&amp;gt;
      &amp;lt;Head&amp;gt;
        {process.env.NODE_ENV === &amp;quot;development&amp;quot; &amp;amp;&amp;amp; (
          &amp;lt;Script
            src=&amp;quot;//unpkg.com/react-grab/dist/index.global.js&amp;quot;
            crossOrigin=&amp;quot;anonymous&amp;quot;
            strategy=&amp;quot;beforeInteractive&amp;quot;
            data-enabled=&amp;quot;true&amp;quot;
          /&amp;gt;
        )}
      &amp;lt;/Head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;Main /&amp;gt;
        &amp;lt;NextScript /&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/Html&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. Vite 프로젝트&lt;/h3&gt;
&lt;p&gt;먼저 npm으로 설치:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm i react-grab@latest&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그 다음 &lt;code&gt;vite.config.ts&lt;/code&gt;에 플러그인을 추가:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { defineConfig } from &amp;#39;vite&amp;#39;;
import react from &amp;#39;@vitejs/plugin-react&amp;#39;;
import { reactGrab } from &amp;quot;react-grab/plugins/vite&amp;quot;;

export default defineConfig({
  plugins: [
    react(),
    reactGrab(),  // React Grab 플러그인 추가
  ],
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cursor 사용자라면, &lt;a href=&quot;https://cursor.com/link/prompt?text=1.+Search+in+this+codebase+for+the+project%0A2.+Determine+if+the+project+is+using+Next.js+app%2Fpages+router%2C+or+Vite%2C+or+something+else%0A3.+Scrape%3A+https%3A%2F%2Fraw.githubusercontent.com%2Faidenybai%2Freact-grab%2Frefs%2Fheads%2Fmain%2FREADME.md%0A4.+Find+the+installation+instructions+in+the+scraped+content+and+install+it+in+the+user%27s+project%0A.&quot;&gt;이 링크&lt;/a&gt;를 클릭해 자동 설치 프롬프트를 사용할 수 있어요. 편리하죠?&lt;/p&gt;
&lt;h2&gt;사용법&lt;/h2&gt;
&lt;p&gt;설치 후, 앱을 실행하고 &lt;strong&gt;⌘C를 누른 상태로 클릭&lt;/strong&gt;하세요. 선택한 요소의 상세 정보(HTML, 스타일 등)가 클립보드에 저장됩니다. 이제 Cursor나 Claude Code에 붙여넣기만 하면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;이 요소를 수정해줘&amp;quot; 같은 프롬프트가 훨씬 정확해집니다.&lt;/li&gt;
&lt;li&gt;React 컴포넌트의 props나 state도 함께 캡처되어 컨텍스트가 풍부해집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API는 별도로 노출되지 않지만, 스크립트가 자동으로 이벤트 리스너를 등록하니 추가 코드 없이 바로 써보세요. 더 자세한 예시는 &lt;a href=&quot;https://react-grab.com&quot;&gt;라이브 데모 사이트&lt;/a&gt;에서 체험할 수 있습니다.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/21</guid>
      <comments>https://news-thing.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 28 Oct 2025 11:03:11 +0900</pubDate>
    </item>
    <item>
      <title>Vitest 4.0 출시: 테스트 도구의 새로운 시대를 열다</title>
      <link>https://news-thing.tistory.com/20</link>
      <description>&lt;p&gt;안녕하세요, 개발자 여러분! 오늘은 JavaScript 테스트 라이브러리 &lt;strong&gt;Vitest&lt;/strong&gt;의 메이저 버전인 &lt;strong&gt;4.0&lt;/strong&gt;이 출시된 소식을 전해드리려 합니다. 2025년 10월 22일에 공식 발표된 이 릴리스는 Vitest의 브라우저 모드를 안정화시키고, 시각 회귀 테스트, 스키마 검증 등 혁신적인 기능을 도입하며, 개발자 경험을 한층 업그레이드합니다. Vitest 코어에 기여한 640명 이상의 커뮤니티 멤버들에게 깊은 감사를 표하며, 이번 포스트에서 주요 업데이트를 자세히 살펴보겠습니다.&lt;/p&gt;
&lt;p&gt;Vitest는 Vite의 빠른 빌드 시스템을 활용한 테스트 러너로, Jest와 유사한 API를 제공하면서도 더 가벼운 성능으로 사랑받고 있습니다. 만약 Vitest를 처음 사용한다면, &lt;a href=&quot;https://vitest.dev/guide/&quot;&gt;Getting Started 가이드&lt;/a&gt;부터 시작해보세요. 이제 본격적으로 Vitest 4.0의 하이라이트를 탐구해 보죠!&lt;/p&gt;
&lt;h2&gt;브라우저 모드의 안정화: 더 이상 실험적이지 않다&lt;/h2&gt;
&lt;p&gt;Vitest 4.0의 가장 큰 뉴스는 &lt;strong&gt;브라우저 모드(Browser Mode)&lt;/strong&gt; 가 안정 버전으로 전환된 점입니다. 이전에는 실험적 태그가 붙어 있었지만, 이제 완전한 프로덕션 레디 상태로 사용할 수 있어요. 이를 위해 브라우저 제공자(Provider)를 별도의 패키지로 분리했습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@vitest/browser-playwright&lt;/code&gt;: Playwright를 사용한 브라우저 테스트.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@vitest/browser-webdriverio&lt;/code&gt;: WebdriverIO를 위한 옵션.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@vitest/browser-preview&lt;/code&gt;: 미리보기 기능.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;설정 예시는 간단합니다. 예를 들어, Playwright의 경우 &lt;code&gt;vitest.config.ts&lt;/code&gt;에 다음과 같이 추가하세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { defineConfig } from &amp;#39;vitest/config&amp;#39;
import { browserProvider } from &amp;#39;@vitest/browser-playwright&amp;#39;

export default defineConfig({
  test: {
    browser: {
      provider: browserProvider,
      launchOptions: { headless: true }
    }
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;또한, &lt;code&gt;page&lt;/code&gt; 컨텍스트는 이제 &lt;code&gt;vitest/browser&lt;/code&gt;에서 직접 임포트할 수 있으며, 이전 버전과의 호환성을 위해 다음 메이저 릴리스까지는 기존 방식도 지원합니다. &lt;code&gt;@vitest/browser&lt;/code&gt; 패키지는 더 이상 필요 없으니 제거하세요. 이 변화로 브라우저 테스트가 더 모듈화되고 유지보수하기 쉬워졌습니다.&lt;/p&gt;
&lt;h2&gt;시각 회귀 테스트와 새로운 매처: UI 테스트의 혁명&lt;/h2&gt;
&lt;p&gt;브라우저 모드에서 &lt;strong&gt;시각 회귀 테스트(Visual Regression Testing)&lt;/strong&gt; 를 지원하는 &lt;code&gt;toMatchScreenshot&lt;/code&gt; 어설션이 추가되었습니다. UI 컴포넌트나 페이지의 스크린샷을 참조 이미지와 비교해 변화점을 자동으로 감지할 수 있어요. 예시:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { expect, test } from &amp;#39;vitest&amp;#39;
import { toMatchScreenshot } from &amp;#39;@vitest/expect&amp;#39;

test(&amp;#39;버튼 스크린샷 비교&amp;#39;, async ({ page }) =&amp;gt; {
  await page.goto(&amp;#39;/button&amp;#39;)
  await expect(page).toMatchScreenshot(&amp;#39;button-state&amp;#39;)
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;더불어, &lt;code&gt;toBeInViewport&lt;/code&gt; 매처가 도입되어 IntersectionObserver API를 활용해 요소가 뷰포트 내에 있는지 확인할 수 있습니다. 부분 가시성을 위한 &lt;code&gt;ratio&lt;/code&gt; 옵션(예: 0.5)도 지원하죠. 이 기능들은 E2E 테스트에서 UI 안정성을 크게 높여줄 거예요.&lt;/p&gt;
&lt;h2&gt;Playwright 트레이스와 로케이터 향상: 디버깅의 편의성 UP&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Playwright 트레이스 지원&lt;/strong&gt;이 추가되어 브라우저 테스트의 디버깅이 훨씬 수월해졌습니다. &lt;code&gt;trace&lt;/code&gt; 옵션을 &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;on-first-retry&lt;/code&gt; 등으로 설정하면 테스트 실패 시 트레이스 파일이 생성되며, HTML 리포터에서 직접 링크로 확인할 수 있어요. CLI 플래그 &lt;code&gt;--browser.trace=on&lt;/code&gt;으로도 활성화 가능합니다. Playwright Trace Viewer로 상세 분석이 가능하니, 복잡한 브라우저 상호작용을 추적하는 데 딱입니다.&lt;/p&gt;
&lt;p&gt;로케이터 측면에서는 Playwright 전용 &lt;code&gt;page.frameLocator&lt;/code&gt; API가 새로 추가되어 iframe 요소를 쉽게 다룰 수 있습니다. 모든 로케이터에 &lt;code&gt;length&lt;/code&gt; 속성이 노출되어 &lt;code&gt;toHaveLength&lt;/code&gt; 매처와 결합할 수 있어요.&lt;/p&gt;
&lt;h2&gt;타입 인식 훅과 expect 확장: 타입스크립트 개발자를 위한 선물&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;test.extend&lt;/code&gt;로 확장된 라이프사이클 훅(예: &lt;code&gt;beforeEach&lt;/code&gt;, &lt;code&gt;afterEach&lt;/code&gt;)이 이제 타입 인식(Type-Aware)을 지원합니다. 반환된 &lt;code&gt;test&lt;/code&gt; 객체에서 직접 컨텍스트 타입을 참조할 수 있어 타입 안전성이 강화됐습니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;expect&lt;/code&gt; 객체에 Chai의 &lt;code&gt;assert&lt;/code&gt; 메서드가 노출되어 타입 좁히기(Type Narrowing)가 용이해졌고, 새로운 &lt;code&gt;expect.schemaMatching&lt;/code&gt; 매처는 Standard Schema v1 객체로 값을 검증합니다. Zod, Valibot, ArkType 같은 스키마 라이브러리와 잘 어울리며, 이메일 유효성 검사 등에 유용해요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { z } from &amp;#39;zod&amp;#39;
import { expect, test } from &amp;#39;vitest&amp;#39;

const emailSchema = z.string().email()

test(&amp;#39;스키마 검증&amp;#39;, () =&amp;gt; {
  expect(&amp;#39;user@example.com&amp;#39;).toMatchSchema(emailSchema)
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 외에도 고급 공용 API 메서드가 추가되었으니, &lt;a href=&quot;https://vitest.dev/api/&quot;&gt;Vitest API 문서&lt;/a&gt;를 확인하세요.&lt;/p&gt;
&lt;h2&gt;리포터와 디버깅 개선: 일상 테스트가 더 스마트해지다&lt;/h2&gt;
&lt;p&gt;디버깅 측면에서 VSCode 확장 프로그램에 &amp;quot;Debug Test&amp;quot; 버튼이 브라우저 테스트를 위한 지원이 추가됐습니다. &lt;code&gt;--inspect&lt;/code&gt; 플래그로 수동 디버깅 시 DevTools 연결이 자동화되며, &lt;code&gt;trackUnhandledErrors&lt;/code&gt;가 비활성화되어 충돌을 방지합니다.&lt;/p&gt;
&lt;p&gt;리포터 업데이트:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;basic&lt;/code&gt; 리포터 제거: 대신 &lt;code&gt;default&lt;/code&gt; 리포터에 &lt;code&gt;summary: false&lt;/code&gt; 옵션 사용.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default&lt;/code&gt; 리포터: 단일 테스트 파일에서만 트리 형식 출력.&lt;/li&gt;
&lt;li&gt;새 &lt;code&gt;tree&lt;/code&gt; 리포터: 항상 트리 형식으로 테스트 출력.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;verbose&lt;/code&gt; 리포터: 이제 CI 외 환경에서도 테스트를 하나씩 출력 (이전 CI 전용 동작은 config로 조건부 적용).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;주의할 점: Breaking Changes와 마이그레이션 가이드&lt;/h2&gt;
&lt;p&gt;Vitest 4.0은 브라우저 모드의 패키지 분리와 임포트 변경 등 몇 가지 breaking changes를 포함합니다. 전체 목록은 &lt;a href=&quot;https://vitest.dev/changelog.html#vitest-40-2025-10-22&quot;&gt;Changelog&lt;/a&gt;을 참조하세요. 업그레이드 전에 반드시 &lt;a href=&quot;https://vitest.dev/guide/migration.html#vitest-40&quot;&gt;Migration Guide&lt;/a&gt;를 읽고, 브라우저 제공자 패키지 업데이트와 리포터 설정 조정을 확인하세요. 대부분의 경우 큰 이슈 없이 마이그레이션할 수 있지만, 안전을 위해 테스트를 먼저 실행해보는 걸 추천합니다.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/20</guid>
      <comments>https://news-thing.tistory.com/20#entry20comment</comments>
      <pubDate>Tue, 28 Oct 2025 08:34:15 +0900</pubDate>
    </item>
    <item>
      <title>Node.js가 이렇게 변했다? 2025년 현대 Node.js의 숨겨진 기능 5가지</title>
      <link>https://news-thing.tistory.com/19</link>
      <description>&lt;p&gt;안녕하세요, 개발자 여러분! Node.js를 사용하다 보면 &amp;quot;이걸 왜 패키지로 설치해야 하지?&amp;quot; 싶은 순간이 많죠? 2018년 이후 Node.js는 엄청난 변화를 겪었고, 이제는 nodemon이나 dotenv 같은 인기 패키지 없이도 많은 작업을 처리할 수 있어요. 이 포스트에서는 그 영상을 바탕으로 Node.js의 최신 기능 5가지를 자세히 살펴보겠습니다. AI 도구조차 이 기능들을 제대로 추천하지 않는다는 점이 재미있더군요.&lt;/p&gt;
&lt;p&gt;이 기능들은 Node.js 버전 15 이상(예: 25 버전)에서 지원되며, 간단한 &amp;quot;Hello World&amp;quot; 앱을 기반으로 실습할 수 있습니다. 각 기능별로 코드 예시를 포함했으니, 따라 해보세요. 준비됐나요? 시작해 볼까요!&lt;/p&gt;
&lt;h2&gt;1. Watch Mode: 파일 변경 시 자동 재시작, nodemon 없이!&lt;/h2&gt;
&lt;p&gt;과거에는 파일을 수정할 때마다 터미널에서 Ctrl+C로 중단하고 다시 실행해야 했죠? 이제 Node.js의 내장 Watch Mode로 그 번거로움을 끝낼 수 있습니다. (Node.js 18.11+ 지원)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;어떻게 사용하나요?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;명령어: &lt;code&gt;node --watch app.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;예시 코드 (&lt;code&gt;app.js&lt;/code&gt;):&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(&amp;#39;Hello World!&amp;#39;);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;파일을 수정하고 저장하면 자동으로 재시작되어 변경 사항이 즉시 반영됩니다. 예를 들어, &amp;quot;Hello World!&amp;quot;를 &amp;quot;Hello Node.js!&amp;quot;로 바꾸면 콘솔에 새 출력이 나타나요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 기능 하나로 nodemon 패키지를 설치할 필요가 없어집니다. 개발 속도가 훨씬 빨라지죠!&lt;/p&gt;
&lt;h2&gt;2. TypeScript 직접 실행: 컴파일 없이 타입 안전성 확보&lt;/h2&gt;
&lt;p&gt;TypeScript를 쓰려면 tsconfig.json 설정하고 tsc로 컴파일하는 게 기본이었어요. 하지만 Node.js 23+에서는 &lt;code&gt;.ts&lt;/code&gt; 파일을 직접 실행할 수 있습니다. 타입 어노테이션을 무시하거나 변환해 JavaScript로 동작하게 해요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;기본 사용법:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;명령어: &lt;code&gt;node app.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;예시 코드 (&lt;code&gt;app.ts&lt;/code&gt;):&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;let username: string = &amp;quot;Max&amp;quot;;
console.log(`Hello, ${username}!`);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;출력: &amp;quot;Hello, Max!&amp;quot; – 타입 체크 없이도 안전하게!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;고급 기능 (Enums 등):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;플래그 추가: &lt;code&gt;node --experimental-transform-types app.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;예시:&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;enum Role { Admin, User }
let role: Role = Role.Admin;
console.log(role); // 0 (Admin)&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;실용 스크립트 작성 시 컴파일 단계를 생략할 수 있어 생산성이 UP! 아직 실험적 기능이니 주의하세요.&lt;/p&gt;
&lt;h2&gt;3. 내장 SQLite: 가벼운 DB 없이 서버리스 데이터베이스&lt;/h2&gt;
&lt;p&gt;SQLite는 서버 없이 파일 기반으로 동작하는 가벼운 DB예요. Node.js 25+에서는 &lt;code&gt;sqlite&lt;/code&gt; 모듈로 바로 사용할 수 있어, better-sqlite3 같은 패키지가 필요 없어요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;사용 예시 (&lt;code&gt;app.js&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;import { DatabaseSync } from &amp;#39;sqlite&amp;#39;;
import { open } from &amp;#39;sqlite/slow-sqlite3&amp;#39;; // 필요 시

const db = await open({ filename: &amp;#39;test.db&amp;#39;, driver: DatabaseSync });
await db.exec(&amp;#39;CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)&amp;#39;);
await db.run(&amp;#39;INSERT INTO users (name) VALUES (?)&amp;#39;, &amp;#39;Max&amp;#39;);
const users = await db.all(&amp;#39;SELECT * FROM users&amp;#39;);
console.log(users); // [{ id: 1, name: &amp;#39;Max&amp;#39; }]&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;실행 후 &lt;code&gt;test.db&lt;/code&gt; 파일이 생성되고, VS Code 확장으로 테이블을 확인할 수 있어요.&lt;/li&gt;
&lt;li&gt;소규모 프로젝트나 유틸리티 스크립트에 딱!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. Promise-based Timers: async/await으로 타이머 간단히&lt;/h2&gt;
&lt;p&gt;setTimeout을 Promise로 감싸서 await 하던 시대는 끝났어요. Node.js 15+부터 &lt;code&gt;timers/promises&lt;/code&gt; 모듈로 네이티브 지원합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예시 코드 (&lt;code&gt;app.js&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;import { setTimeout } from &amp;#39;node:timers/promises&amp;#39;;

async function main() {
  console.log(&amp;#39;시작!&amp;#39;);
  await setTimeout(1000); // 1초 대기
  console.log(&amp;#39;1초 후 실행!&amp;#39;);
  await setTimeout(2000);
  console.log(&amp;#39;끝!&amp;#39;);
}

main();&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;출력: 순차적으로 지연된 로그가 찍혀요. async 코드가 훨씬 깔끔해집니다. setInterval이나 setImmediate도 동일하게 지원돼요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. .env 파일 네이티브 지원: dotenv 패키지 goodbye!&lt;/h2&gt;
&lt;p&gt;환경 변수를 .env 파일에서 로드하려면 dotenv가 필수였죠? 이제 &lt;code&gt;--env-file&lt;/code&gt; 플래그로 간단히 처리합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;설정:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.env&lt;/code&gt; 파일 생성:&lt;pre&gt;&lt;code&gt;BUCKET=demo&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;명령어: &lt;code&gt;node --env-file=.env app.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;예시 코드 (&lt;code&gt;app.js&lt;/code&gt;):&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(process.env.BUCKET); // &amp;quot;demo&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;로컬 개발 환경이 한결 수월해집니다. 유틸리티 스크립트에 특히 유용해요.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/19</guid>
      <comments>https://news-thing.tistory.com/19#entry19comment</comments>
      <pubDate>Sat, 25 Oct 2025 10:26:03 +0900</pubDate>
    </item>
    <item>
      <title>Jujutsu (jj): Git의 대안으로 떠오르는 혁신적인 VCS 도구 탐구</title>
      <link>https://news-thing.tistory.com/18</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, 개발자 여러분! 오늘은 버전 컨트롤 시스템(VCS) 세계에서 최근 주목받고 있는 &lt;b&gt;Jujutsu (jj)&lt;/b&gt; 에 대해 이야기해보려 합니다. Git을 사랑하지만, 더 직관적이고 강력한 도구를 찾고 계신가요? Git의 속도와 호환성을 유지하면서도 Mercurial이나 Darcs 같은 도구의 혁신적인 기능을 결합한 jj가 바로 그 해답일 수 있습니다. 이 포스트는 &lt;a href=&quot;https://github.com/jj-vcs/jj&quot;&gt;GitHub 저장소&lt;/a&gt;의 내용을 기반으로 jj의 매력을 자세히 살펴보겠습니다. 초보자부터 고급 사용자까지, 왜 jj를 시도해볼 만한지 알아보죠.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Jujutsu란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jujutsu는 소프트웨어 프로젝트를 위한 &lt;b&gt;Git 호환 VCS&lt;/b&gt;로, 코드 복사, 변경 추적, 배포를 간단하고 강력하게 처리합니다. 2019년에 Martin von Zweigbergk가 취미 프로젝트로 시작한 이 도구는 이제 Google에서 풀타임 개발 중이며, 핵심 개발자들이 GitHub에서 jj를 개발하는 데 실제로 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jj의 철학은 &lt;b&gt;사용자 인터페이스와 알고리즘을 저장소 백엔드와 분리&lt;/b&gt;하는 데 있습니다. 기본적으로 Git 저장소를 사용해 Git 도구와 완벽하게 호환되지만, Mercurial, Breezy, 또는 Google의 Piper/CitC 같은 하이브리드 시스템도 지원할 수 있습니다. 이름은 'Jujutsu'지만, 명령줄 도구는 간단히 &lt;code&gt;jj&lt;/code&gt;로 불립니다. 아직 젊고 실험적인 도구지만, Git의 속도, Mercurial의 revset 언어, Darcs의 충돌 객체 같은 장점을 흡수해 더 나은 경험을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금한 점이 있으신가요? &lt;a href=&quot;https://discord.gg/dkmfj3aGQN&quot;&gt;Discord&lt;/a&gt;나 &lt;a href=&quot;https://github.com/jj-vcs/jj/discussions&quot;&gt;GitHub Discussions&lt;/a&gt;에서 커뮤니티와 소통해보세요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주요 기능: 왜 jj가 특별할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jj는 Git의 안정성을 유지하면서도 혁신적인 기능을 더해 &quot;더 나은 VCS&quot;를 지향합니다. 아래는 핵심 기능입니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Git 완벽 호환&lt;/b&gt;: Gitoxide Rust 라이브러리를 통해 Git 저장소를 사용합니다. &lt;code&gt;jj fetch&lt;/code&gt;나 &lt;code&gt;jj push&lt;/code&gt;로 Git 리모트와 자유롭게 상호작용하며, jj 커밋은 일반 Git 커밋으로 보입니다. 심지어 jj와 Git을 같은 저장소에서 섞어 사용할 수 있어요!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;작업 복사본(Working Copy) as Commit&lt;/b&gt;: 변경 사항이 자동으로 커밋으로 기록되어 &quot;더러운 작업 복사본&quot; 오류가 사라집니다. 스태시(stash) 필요 없이, 작업 복사본을 다른 커밋처럼 다룰 수 있습니다. 예를 들어, &lt;code&gt;jj describe&lt;/code&gt;로 메시지를 수정하거나 &lt;code&gt;jj restore&lt;/code&gt;로 이전 상태로 되돌리기 쉽죠.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;저장소가 진실의 원천(Repo as Source of Truth)&lt;/b&gt;: 모든 명령어가 작업 복사본을 스냅샷으로 찍고 저장소를 업데이트한 후, 작업 복사본을 새로 고칩니다. 결과적으로 &lt;code&gt;jj undo&lt;/code&gt;로 특정 작업을 되돌리거나, 전체 저장소 상태를 쉽게 복원할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;충돌(Conflicts) as First-Class Objects&lt;/b&gt;: 충돌을 커밋에 기록해 작업을 중단하지 않고 계속 진행합니다. 나중에 통합된 워크플로우로 해결하며, 병합 커밋의 리베이스도 정확히 처리됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 리베이스(Automatic Rebase)&lt;/b&gt;: 커밋 수정 시 후손 커밋이 자동으로 리베이스되고, 북마크가 업데이트되며, 충돌은 투명하게 처리됩니다. Git의 &lt;code&gt;rebase --update-refs&lt;/code&gt;와 &lt;code&gt;rerere&lt;/code&gt;를 합친 듯한 느낌!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포괄적인 히스토리 재작성&lt;/b&gt;: &lt;code&gt;jj rebase&lt;/code&gt;, &lt;code&gt;jj split&lt;/code&gt;(커밋 분할), &lt;code&gt;jj squash&lt;/code&gt;(변경 이동), &lt;code&gt;jj diffedit&lt;/code&gt;(체크아웃 없이 변경 편집) 등으로 히스토리를 자유롭게 다듬습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험적 기능&lt;/b&gt;: Dropbox, S3, rsync 같은 비원자적 파일 시스템에서 안전한 동시 복제를 지원합니다. (충돌 발생 시 해결 필요)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능들은 Git의 단점을 보완하며, 대규모 팀이나 복잡한 히스토리 프로젝트에 이상적입니다. 자세한 Git 비교는 &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/git-comparison&quot;&gt;여기&lt;/a&gt;를 확인하세요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치와 기본 사용법: 5분 만에 시작하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jj를 설치하는 건 간단합니다. 공식 &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/install-and-setup&quot;&gt;설치 가이드&lt;/a&gt;를 따르세요. (프리릴리스 버전은 &lt;a href=&quot;https://jj-vcs.github.io/jj/prerelease/&quot;&gt;여기&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 사용 예시:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;저장소 클론&lt;/b&gt;: &lt;code&gt;jj git clone https://github.com/example/repo&lt;/code&gt; (Git 리모트 지원).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;변경 작업&lt;/b&gt;: 파일 수정 후 자동 커밋. &lt;code&gt;jj describe -m &quot;My changes&quot;&lt;/code&gt;로 메시지 설정.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;히스토리 보기&lt;/b&gt;: &lt;code&gt;jj log&lt;/code&gt;로 그래프와 함께 로그 확인.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리베이스&lt;/b&gt;: &lt;code&gt;jj rebase -d main&lt;/code&gt;으로 메인 브랜치에 리베이스.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;언두&lt;/b&gt;: &lt;code&gt;jj undo&lt;/code&gt;로 최근 작업 취소.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;튜토리얼은 &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/tutorial&quot;&gt;여기&lt;/a&gt;에서 상세히 다뤄집니다. &lt;code&gt;jj help&lt;/code&gt; 명령어로 언제든 도움말을 불러보세요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;최근 업데이트와 로드맵&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jj는 활발히 개발 중입니다. 2024년 11월 v0.24에서 &lt;code&gt;jj file annotate&lt;/code&gt; (Git blame 비슷)가 추가되었고, 12월에 jj-vcs 조직으로 이동했습니다. Git Merge 2024에서 발표된 &lt;a href=&quot;https://www.youtube.com/watch?v=LV0JzI8IcCY&quot;&gt;비디오&lt;/a&gt;도 흥미로워요. 로드맵은 &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/roadmap&quot;&gt;여기&lt;/a&gt;에서 확인 가능하며, v1.0.0 이전에 호환성 변경이 있을 수 있습니다. (라이선스: Apache 2.0)&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리: jj로 VCS를 재발견하세요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jujutsu는 Git의 진화를 상징합니다. 실험적이라 버그가 있을 수 있지만, 그만큼 혁신적입니다. Git에 지치셨다면, 오늘 jj를 설치해보세요. 작업 복사본이 커밋처럼 느껴지는 순간, VCS의 새로운 세계가 열릴 거예요. 여러분의 경험 공유 부탁드려요 &amp;ndash; 댓글로 알려주세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 궁금한 점? &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/FAQ&quot;&gt;FAQ&lt;/a&gt;나 &lt;a href=&quot;https://jj-vcs.github.io/jj/latest/glossary&quot;&gt;글로사리&lt;/a&gt;를 추천합니다.&lt;/p&gt;</description>
      <category>Utils</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/18</guid>
      <comments>https://news-thing.tistory.com/18#entry18comment</comments>
      <pubDate>Fri, 24 Oct 2025 09:24:46 +0900</pubDate>
    </item>
    <item>
      <title>Claude Skills 탐험: AI 워크플로를 업그레이드하는 마법 같은 확장 기능들</title>
      <link>https://news-thing.tistory.com/17</link>
      <description>&lt;p&gt;안녕하세요, AI 애호가 여러분! 오늘은 Anthropic의 Claude AI를 더 강력하게 만들어주는 &lt;strong&gt;Claude Skills&lt;/strong&gt;에 대해 이야기해보려 해요. 만약 당신이 Claude를 일상적으로 사용한다면, 이 스킬들이 당신의 생산성을 폭발적으로 높여줄 거예요. 최근 발견한 멋진 사이트, &lt;a href=&quot;https://claudeskills.info/&quot;&gt;Claude Skills Hub&lt;/a&gt;를 기반으로 한 이 포스트에서, Claude Skills가 뭔지부터 설치 팁, 심지어 직접 만드는 방법까지 자세히 풀어볼게요. 이 사이트는 26개 이상의 스킬을 모아놓은 서드파티 마켓플레이스로, 공식 및 커뮤니티 기여물을 한눈에 볼 수 있게 해줘요. 자, 시작해볼까요?&lt;/p&gt;
&lt;h2&gt;Claude Skills란 무엇일까?&lt;/h2&gt;
&lt;p&gt;Claude Skills는 Claude AI의 기능을 확장하는 모듈러 확장 기능이에요. 단순한 챗봇을 넘어, 전문 지식, 도구, 워크플로를 추가해 문서 처리나 창의적 디자인 같은 구체적인 작업을 가능하게 하죠. 예를 들어, PDF를 분석하거나 엑셀 데이터를 처리하는 데 특화된 스킬이 있어요. 이 사이트의 FAQ에 따르면, 스킬은 Claude의 성능을 의미 있게 강화하면서도 보안 경계를 유지해 안전하게 작동해요.&lt;/p&gt;
&lt;p&gt;왜 Claude Skills가 중요한가요? AI가 점점 더 우리 일상에 스며들고 있지만, 기본 기능만으로는 한계가 있잖아요. 스킬은 그런 한계를 넘어, 개발자부터 크리에이터까지 누구나 맞춤형 AI를 만들 수 있게 해줘요. Claude Skills Hub는 이런 스킬을 &lt;strong&gt;Featured(인기)&lt;/strong&gt;, &lt;strong&gt;Latest(최신)&lt;/strong&gt;, &lt;strong&gt;All Skills(전체)&lt;/strong&gt;, &lt;strong&gt;Hosted(클라우드 기반)&lt;/strong&gt;, &lt;strong&gt;Official(공식)&lt;/strong&gt; 카테고리로 분류해 쉽게 탐색할 수 있어요. 검색 기능(⌘K 단축키)도 지원하니, 바로 원하는 걸 찾을 수 있죠.&lt;/p&gt;
&lt;h2&gt;Claude Skills는 어떻게 작동하나요?&lt;/h2&gt;
&lt;p&gt;설치 후 Claude와의 대화에 자연스럽게 통합돼요. 스킬이 제공하는 지침, 템플릿, 리소스를 따라가면 돼요. 예를 들어, 문서 처리 스킬을 사용하면 Claude가 자동으로 파일을 분석하고 요약해줄 거예요. 이 과정은 간단하지만 강력해요 – AI가 당신의 워크플로를 이해하고 보완해주는 거죠.&lt;/p&gt;
&lt;h2&gt;어디서 Claude Skills를 찾을 수 있을까?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;공식 Anthropic GitHub 저장소&lt;/strong&gt;: Anthropic에서 직접 제공하는 스킬의 원천.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Skills Hub&lt;/strong&gt;: 이 사이트처럼 커뮤니티가 큐레이션한 컬렉션. 26개 이상의 스킬을 한 곳에 모아놓아 탐색이 편해요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;커뮤니티 플랫폼&lt;/strong&gt;: Reddit이나 GitHub에서 추가 스킬을 발견할 수 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hub 사이트를 방문하면 스킬 카드를 클릭해 GitHub 상세 페이지로 이동할 수 있어요. 카테고리별로 정리되어 있으니, 당신의 필요에 딱 맞는 걸 골라보세요!&lt;/p&gt;
&lt;h2&gt;Claude Skills 설치: 초보자도 쉽게 따라하기&lt;/h2&gt;
&lt;p&gt;설치가 제일 궁금하시죠? 간단해요:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Claude Skills Hub에서 원하는 스킬을 찾아 카드를 클릭하세요.&lt;/li&gt;
&lt;li&gt;GitHub 저장소로 이동해 설치 지침을 따르세요.&lt;/li&gt;
&lt;li&gt;Claude Code나 Claude.ai에서 스킬을 활성화하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;대부분의 스킬이 오픈소스라 무료로 사용할 수 있어요. 하지만 공식 스킬은 Apache 2.0 라이선스, 커뮤니티 스킬은 다양하니 프로덕션 사용 전에 라이선스를 확인하세요. 팁: 처음엔 Featured 탭부터 시작해 인기 스킬을 테스트해보는 게 좋아요!&lt;/p&gt;
&lt;h2&gt;무료인가요? 라이선스 이야기&lt;/h2&gt;
&lt;p&gt;네, 대부분 무료예요! Anthropic의 공식 스킬은 Apache 2.0 같은 오픈 라이선스를 따르고, 커뮤니티 스킬도 비슷해요. 하지만 상업적 사용 시 라이선스를 꼭 체크하세요. 이 사이트의 FAQ가 이 부분을 명확히 설명해주니, 참고하면 실수 없을 거예요.&lt;/p&gt;
&lt;h2&gt;직접 Claude Skills 만들기: 당신의 창의력을 더하세요&lt;/h2&gt;
&lt;p&gt;누구나 만들 수 있어요! Anthropic의 공식 스킬 크리에이터 가이드를 따라 GitHub 저장소에 업로드하면 돼요. 개발 도구부터 창의적 앱(예: 생성 아트)까지, 당신의 아이디어를 스킬로 구현해보세요. 커뮤니티에 기여하면 더 재미있을 거예요 – AI 생태계를 함께 키우는 거니까요.&lt;/p&gt;
&lt;h2&gt;Claude Skills의 유형: 어떤 게 있을까?&lt;/h2&gt;
&lt;p&gt;다양한 카테고리가 매력 포인트예요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;개발 도구&lt;/strong&gt;: 코드 생성, 디버깅.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문서 프로세서&lt;/strong&gt;: PDF, Word, Excel 처리.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;창의적 앱&lt;/strong&gt;: 생성 아트, 디자인 워크플로.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;커뮤니케이션 도구&lt;/strong&gt;: 이메일 작성, 프레젠테이션 지원.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hub 사이트에서 카테고리별로 필터링해 보세요. 당신의 직업이나 취미에 맞는 스킬을 찾기 딱 좋아요.&lt;/p&gt;
&lt;h2&gt;제출하고 공유하기: 커뮤니티에 기여하세요&lt;/h2&gt;
&lt;p&gt;스킬을 만들었나요? Claude Skills Hub의 Submit 페이지를 통해 제출하세요. 이름, 설명, GitHub URL만 입력하면 검토 후 추가돼요. 품질과 호환성을 확인하니, 가이드라인을 따르세요. 이렇게 하면 더 많은 사람들이 당신의 스킬을 활용할 수 있어요!&lt;/p&gt;
&lt;h2&gt;마무리: Claude Skills로 AI를 재발견하세요&lt;/h2&gt;
&lt;p&gt;Claude Skills는 AI를 단순한 도우미에서 강력한 파트너로 바꿔줘요. Claude Skills Hub 덕분에 26개 이상의 스킬을 쉽게 탐험할 수 있고, 설치부터 생성까지 모든 게 문서화되어 있어요. 지금 사이트를 방문해 Featured 스킬 하나를 설치해보세요 – 당신의 워크플로가 어떻게 변할지 기대돼요!&lt;/p&gt;</description>
      <category>A.I</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/17</guid>
      <comments>https://news-thing.tistory.com/17#entry17comment</comments>
      <pubDate>Thu, 23 Oct 2025 13:52:25 +0900</pubDate>
    </item>
    <item>
      <title>Graffle.js: JavaScript 개발자를 위한 간단하고 타입 안전한 GraphQL 클라이언트</title>
      <link>https://news-thing.tistory.com/16</link>
      <description>&lt;p&gt;안녕하세요, 개발자 여러분! GraphQL을 다루다 보면 클라이언트 라이브러리의 복잡함에 지치신 적이 있나요? 오늘은 그런 고민을 싹 날려줄 수 있는 새로운 도구, &lt;strong&gt;Graffle.js&lt;/strong&gt;를 소개하려고 합니다. 이 라이브러리는 최소주의적 설계와 완벽한 타입 안전성을 강조하며, JavaScript 환경에서 GraphQL 쿼리를 더 쉽게 실행할 수 있게 해줍니다. 아직 개발 중인 프로젝트지만, 이미 강력한 잠재력을 보여주고 있어요. 이 포스트에서는 Graffle.js의 주요 기능, 설치 방법, 그리고 실제 사용 예제를 중심으로 살펴보겠습니다. &lt;/p&gt;
&lt;h2&gt;Graffle.js란 무엇일까?&lt;/h2&gt;
&lt;p&gt;Graffle.js는 Jason Kuhrt가 개발한 GraphQL 클라이언트로, Prisma와 Nexus 같은 프로젝트로 유명한 개발자의 손에서 탄생했습니다. 이 라이브러리의 핵심 철학은 &lt;strong&gt;단순함(minimal)&lt;/strong&gt;, &lt;strong&gt;확장성(extensible)&lt;/strong&gt;, &lt;strong&gt;타입 안전성(type-safe)&lt;/strong&gt; 입니다. 어디서나 동작할 수 있도록 설계되었으며, HTTP 엔드포인트나 인메모리 스키마에 대한 실행을 지원합니다. &lt;/p&gt;
&lt;p&gt;현재는 pre-release 버전으로, 안정화되지 않았지만 최신 기능을 체험하기에 딱입니다. MIT 라이선스 하에 공개되어 있어 자유롭게 사용할 수 있어요. GraphQL 쿼리를 작성할 때 타입 추론을 통해 실수 없이 코드를 작성할 수 있고, 필요에 따라 TypeScript API를 생성해 더 강력한 개발 경험을 제공합니다. &lt;/p&gt;
&lt;h2&gt;왜 Graffle.js를 써야 할까? 주요 기능&lt;/h2&gt;
&lt;p&gt;Graffle.js의 매력은 복잡한 설정 없이도 타입 안전한 쿼리를 실행할 수 있다는 점입니다. 주요 기능을 간단히 나열해 보죠:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;완벽한 타입 안전성&lt;/strong&gt;: GraphQL 문법에 대한 전체 타입 추론과, 옵션으로 Document Builder를 통해 생성된 TypeScript API를 제공합니다. 변수와 결과에 대한 정적 타입 체크로 런타임 오류를 최소화해요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;유연성&lt;/strong&gt;: 기본 설정으로 시작해 점진적으로 타입 안전 기능을 추가할 수 있습니다. GraphQL 문자열을 직접 작성하거나, 타입 안전한 빌더 API를 선택할 수 있어요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;확장성&lt;/strong&gt;: 미들웨어 같은 확장 시스템을 통해 OpenTelemetry(관찰성), 스키마 오류 처리, 커스텀 스칼라 등을 쉽게 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;다중 전송 지원&lt;/strong&gt;: HTTP URL이나 인메모리 스키마에 쿼리를 실행할 수 있어, 서버사이드나 클라이언트사이드 모두 유연합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;커스텀 스칼라 지원&lt;/strong&gt;: Date나 BigInt 같은 커스텀 타입을 위한 코덱을 등록해 인코딩/디코딩을 자동화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 기능들은 Apollo Client나 Relay 같은 기존 라이브러리와 비교해도 가볍고 직관적입니다. 특히, 타입 안전성을 추구하는 TypeScript 개발자에게 추천해요.&lt;/p&gt;
&lt;h2&gt;설치와 기본 사용법&lt;/h2&gt;
&lt;p&gt;설치는 간단합니다. 아직 개발 중이니 pre-release 버전을 설치하세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install graffle@next graphql&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;기본적으로 &lt;code&gt;Graffle.create()&lt;/code&gt;로 인스턴스를 생성하고, 전송(transport), 확장(extensions), 스칼라(scalars)를 체이닝으로 설정합니다. 쿼리는 &lt;code&gt;gql&lt;/code&gt; 템플릿 리터럴이나 Document Builder로 실행할 수 있어요.&lt;/p&gt;
&lt;h3&gt;빠른 시작 예제&lt;/h3&gt;
&lt;p&gt;간단한 국가 쿼리를 HTTP 엔드포인트에 실행해 보죠. (countries.trevorblades.com 스키마 사용)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { Graffle } from &amp;#39;graffle&amp;#39;

const graffle = Graffle
  .create()
  .transport({ url: &amp;#39;https://countries.trevorblades.com/graphql&amp;#39; })

const data = await graffle.gql`
  query {
    countries(filter: { name: { in: [&amp;quot;Canada&amp;quot;, &amp;quot;Germany&amp;quot;, &amp;quot;Japan&amp;quot;] } }) {
      name
      capital
      emoji
    }
  }
`.send()

console.log(data)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드로 캐나다, 독일, 일본의 국가 이름, 수도, 이모지를 출력할 수 있습니다. 타입 추론 덕분에 &lt;code&gt;data&lt;/code&gt;의 타입이 자동으로 알려져 편리해요.&lt;/p&gt;
&lt;h3&gt;Document Builder 사용: 타입 안전 쿼리&lt;/h3&gt;
&lt;p&gt;옵션으로 TypeScript API를 생성하면, 문자열 없이 IntelliSense를 활용한 쿼리를 작성할 수 있습니다. (포켓몬 스키마 예제)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;const pokemons = await graffle.query.pokemons({
  $: { filter: { name: { in: [&amp;#39;Pikachu&amp;#39;, &amp;#39;Charizard&amp;#39;] } } },
  name: true,
  hp: true,
})&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GraphQL 문자열 + 타입 추론&lt;/h3&gt;
&lt;p&gt;전통적인 GraphQL 문법을 좋아한다면 이 방식이 딱입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;const data = await graffle.gql(`
  query pokemonByName($name: String!) {
    pokemonByName(name: $name) {
      name
      hp
    }
  }
`).pokemonByName({ name: &amp;#39;Pikachu&amp;#39; })&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;확장과 커스텀 스칼라 추가&lt;/h3&gt;
&lt;p&gt;OpenTelemetry를 추가하거나, Date 스칼라를 처리하는 예제입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;const graffle = Graffle
  .create()
  .use(OpenTelemetry())
  .use(SchemaErrors)
  .scalar(&amp;#39;Date&amp;#39;, {
    decode: (value: string) =&amp;gt; new Date(value),
    encode: (value: Date) =&amp;gt; value.toISOString(),
  })

const pokemons = await graffle.query.pokemons({
  $: { filter: { birthday: { lte: new Date(&amp;#39;1987-01-13&amp;#39;) } } },
  birthday: true, // JavaScript Date로 반환
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이처럼 확장은 체이닝으로 쉽게 적용됩니다.&lt;/p&gt;
&lt;h2&gt;지원 요소와 한계&lt;/h2&gt;
&lt;p&gt;Graffle.js는 표준 GraphQL 요소(쿼리, 변수, 필터, 스칼라)를 지원하며, mutations도 유사하게 사용할 수 있습니다. 하지만 아직 개발 중이라 일부 기능(예: 스타일링이나 내보내기)은 없어요. 대신, 강력한 확장 시스템으로 커스터마이징이 가능합니다.&lt;/p&gt;
&lt;h2&gt;마무리: Graffle.js를 지금 써보세요!&lt;/h2&gt;
&lt;p&gt;Graffle.js는 GraphQL 클라이언트의 미래를 보여주는 프로젝트입니다. 타입 안전성과 유연성을 동시에 잡아, 초보자부터 고급 사용자까지 만족시킬 거예요. 아직 pre-release지만, npm으로 쉽게 설치해 테스트해 보세요. 더 자세한 문서는 &lt;a href=&quot;https://graffle.js.org/&quot;&gt;공식 사이트&lt;/a&gt;에서 확인하세요. &lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/16</guid>
      <comments>https://news-thing.tistory.com/16#entry16comment</comments>
      <pubDate>Wed, 22 Oct 2025 14:05:22 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL 18 릴리스: 개발자들을 위한 성능 혁명과 새로운 기능 탐구</title>
      <link>https://news-thing.tistory.com/15</link>
      <description>&lt;p&gt;안녕하세요, 데이터베이스 애호가 여러분! PostgreSQL 커뮤니티가 또 한 번의 대박을 터뜨렸습니다. 2025년 9월 25일, PostgreSQL Global Development Group이 &lt;strong&gt;PostgreSQL 18&lt;/strong&gt;을 공식 릴리스했습니다. 이 릴리스는 거의 30년의 오픈 소스 여정을 바탕으로 성능 최적화, 업그레이드 간소화, 개발자 도구 강화에 초점을 맞췄어요. 만약 여러분이 PostgreSQL을 사용 중이거나 도입을 고려 중이라면, 이 업데이트는 절대 놓칠 수 없는 소식입니다. 오늘은 이 릴리스의 핵심 하이라이트를 중심으로, 개발자 관점에서 블로그를 풀어보겠습니다. (출처: &lt;a href=&quot;https://www.postgresql.org/about/news/postgresql-18-released-3142/&quot;&gt;PostgreSQL 공식 발표&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;왜 PostgreSQL 18인가? 간단한 개요&lt;/h2&gt;
&lt;p&gt;PostgreSQL은 항상 안정성과 확장성을 자랑해왔지만, 이번 버전은 특히 &lt;strong&gt;비동기 I/O&lt;/strong&gt;와 &lt;strong&gt;인덱스 최적화&lt;/strong&gt; 같은 실전적인 성능 향상을 강조합니다. 데이터베이스 워크로드를 3배 빠르게 만들 수 있는 잠재력이 있어요. 게다가 보안과 사용성 측면에서도 큰 도약을 이루었죠. 이 포스트를 통해 주요 기능을 탐구하고, 실제 적용 팁을 공유할게요.&lt;/p&gt;
&lt;h2&gt;주요 새로운 기능: 개발 생산성 폭발&lt;/h2&gt;
&lt;p&gt;PostgreSQL 18은 개발자들이 더 쉽게 코드를 작성하고, 데이터를 다룰 수 있도록 돕는 기능을 쏟아냈습니다. 아래는 블로그에서 강조할 만한 포인트들입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;비동기 I/O (AIO) 서브시스템&lt;/strong&gt;: 순차 스캔, 비트맵 힙 스캔, VACUUM 작업에서 동시 I/O 요청을 지원합니다. OS의 readahead에 의존하지 않아 데이터베이스 특화 성능이 크게 향상되죠. &lt;code&gt;io_method&lt;/code&gt; 파라미터로 &lt;code&gt;worker&lt;/code&gt;, &lt;code&gt;io_uring&lt;/code&gt;, &lt;code&gt;sync&lt;/code&gt; 중 선택 가능 – 고성능 스토리지 환경에서 필수!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;가상 생성 열 (Virtual Generated Columns)&lt;/strong&gt;: 쿼리 실행 시 값 계산 (비저장) 기본 동작으로 전환. 저장 생성 열은 이제 논리적 복제 지원. 복잡한 계산 로직을 테이블에 내장해 쿼리 단순화에 딱입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UUIDv7 함수&lt;/strong&gt;: 타임스탬프 기반 UUID 생성으로 인덱싱과 읽기 성능이 업그레이드. &lt;code&gt;uuidv4()&lt;/code&gt;는 &lt;code&gt;gen_random_uuid()&lt;/code&gt;의 별칭으로 편의성 UP.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;시간적 제약 (Temporal Constraints)&lt;/strong&gt;: 범위에 대한 &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; PRIMARY KEY/UNIQUE 제약과 &lt;code&gt;PERIOD&lt;/code&gt; 외래 키 지원. 시간 기반 데이터 (예: 이벤트 스케줄링)에서 충돌 방지 로직이 훨씬 수월해집니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OAuth 2.0 인증&lt;/strong&gt;: SSO 시스템 통합을 위한 확장 지원. 보안과 편의성을 동시에 잡은 기능으로, 클라우드 환경 개발자들에게 환영받을 거예요.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CREATE FOREIGN TABLE ... LIKE&lt;/strong&gt;: 로컬 테이블에서 외래 테이블 스키마 복사로 설정이 간편. 분산 데이터베이스 작업이 빨라집니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RETURNING 절 확장&lt;/strong&gt;: INSERT, UPDATE, DELETE, MERGE에서 OLD와 NEW 값 모두 접근 가능. 트리거나 감사 로직 작성 시 게임 체인저!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 기능들은 PostgreSQL의 확장성을 한층 강화해, 마이크로 서비스나 빅데이터 프로젝트에서 빛을 발할 거예요.&lt;/p&gt;
&lt;h2&gt;성능 개선: 속도와 효율의 대박 업그레이드&lt;/h2&gt;
&lt;p&gt;성능은 PostgreSQL의 생명줄이죠. 18 버전에서 I/O 처리부터 인덱스, 조인까지 모든 게 빨라졌습니다. 실제 벤치마크에서 읽기 속도가 &lt;strong&gt;3배&lt;/strong&gt; 향상된 사례가 보고됐어요. 주요 개선 사항:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I/O 처리 최적화&lt;/strong&gt;: AIO 덕분에 스토리지 읽기 속도 폭발. 특히 대용량 테이블 스캔에서 효과적입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;인덱스 혁신&lt;/strong&gt;: 다중 열 B-tree 인덱스에서 접두사 조건 생략 시 스킵 스캔 지원. WHERE 절의 OR 조건 인덱스 활용, GIN/B-tree/BRIN 병렬 빌드. 쿼리 플래너가 똑똑해졌어요!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;조인 성능&lt;/strong&gt;: 해시 조인 속도 향상, 병합 조인에 증분 정렬 적용. 대규모 데이터 조합 작업이 부드러워집니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;하드웨어 가속&lt;/strong&gt;: ARM NEON/SVE 지원으로 &lt;code&gt;popcount&lt;/code&gt; 함수가 빨라짐. 비트 연산이 많은 애플리케이션 (예: 검색 엔진)에 좋습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;텍스트 처리&lt;/strong&gt;: &lt;code&gt;PG_UNICODE_FAST&lt;/code&gt; 콜레이션으로 upper/lower/casefold 함수 속도 UP. LIKE 패턴 매칭이 비결정적 콜레이션 지원. 풀텍스트 검색은 클러스터 기본 콜레이션 사용 (업그레이드 후 재인덱싱 주의!).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;복제 개선&lt;/strong&gt;: CREATE SUBSCRIPTION 기본 병렬 스트리밍, pg_createsubscriber의 --all 플래그로 멀티 DB 복제 간편.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 개선으로 인해, 기존 워크로드에서 20-50% 성능 향상을 기대할 수 있어요. ARM 서버나 클라우드 인스턴스 사용자라면 바로 테스트해보세요!&lt;/p&gt;
&lt;h2&gt;보안 강화: 안전한 데이터 세상을 위해&lt;/h2&gt;
&lt;p&gt;보안은 선택이 아닌 필수. PostgreSQL 18은 이를 명확히 인지하고 업데이트했습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OAuth 2.0 지원&lt;/strong&gt;: 안전한 SSO 통합으로 사용자 인증 강화.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;FIPS 모드 검증&lt;/strong&gt;: pgcrypto에서 준수성 UP.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TLS 설정&lt;/strong&gt;: &lt;code&gt;ssl_tls13_ciphers&lt;/code&gt; 파라미터로 서버 측 TLS 1.3 암호화 세트 제어.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;비밀번호 인증 변화&lt;/strong&gt;: MD5 폐기 (미래 제거 예정), SCRAM 우선. postgres_fdw와 dblink에 패스스루 지원, pgcrypto에 SHA-2 해싱 추가.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 변화로 인해, 규제 준수 (예: GDPR)가 필요한 프로젝트에서 더 안심할 수 있습니다. MD5 사용자라면 지금 SCRAM으로 마이그레이션하세요!&lt;/p&gt;
&lt;h2&gt;사용성 향상: 개발자 삶을 편하게&lt;/h2&gt;
&lt;p&gt;개발자 도구가 업그레이드되어 디버깅과 유지보수가 쉬워졌습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EXPLAIN ANALYZE 강화&lt;/strong&gt;: 버퍼 접근, 인덱스 조회, CPU/WAL/읽기 통계 표시 (VERBOSE 옵션). 쿼리 튜닝의 필수 도구!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;유지보수&lt;/strong&gt;: VACUUM에서 사전 페이지 동결로 오버헤드 감소. 유휴 복제 슬롯 자동 드롭 (&lt;code&gt;idle_replication_slot_timeout&lt;/code&gt;), 논리적 복제 충돌 로그/통계 보고.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;쿼리 처리&lt;/strong&gt;: 비결정적 LIKE 패턴 매칭, 조인/인덱스 쿼리 플래닝 개선.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;pg_stat_all_tables에 VACUUM 시간과 연결별 I/O/WAL 통계가 추가되어 모니터링이 한결 수월해졌어요.&lt;/p&gt;
&lt;h2&gt;마이그레이션 팁: 업그레이드의 함정 피하기&lt;/h2&gt;
&lt;p&gt;새 버전으로 옮기는 건 항상 조심스럽죠. PostgreSQL 18의 pg_upgrade는 더 똑똑해졌습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;속도 향상&lt;/strong&gt;: 대규모 객체 DB에서 처리 빨라짐. &lt;code&gt;--jobs&lt;/code&gt;로 병렬 체크, &lt;code&gt;--swap&lt;/code&gt;으로 디렉토리 스왑 (복사/링크 대신).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;통계 이식&lt;/strong&gt;: 플래너 통계 자동 이월로 업그레이드 후 즉시 성능 유지 (ANALYZE 불필요).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;주의 사항&lt;/strong&gt;: 풀텍스트 검색 재인덱싱 필수 (콜레이션 변경). 페이지 체크섬 기본 활성화 – 기존 클러스터 업그레이드 시 &lt;code&gt;--no-data-checksums&lt;/code&gt; 사용.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;폐기&lt;/strong&gt;: MD5 인증 전환 권장.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;전체 릴리스 노트는 &lt;a href=&quot;https://www.postgresql.org/docs/18/release-18.html&quot;&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/p&gt;
&lt;h2&gt;마무리: 지금 다운로드하고 실험해보세요!&lt;/h2&gt;
&lt;p&gt;PostgreSQL 18은 단순한 업데이트가 아니라, 개발자 생산성과 시스템 신뢰성을 재정의하는 릴리스입니다. 특히 AIO와 인덱스 개선으로 빅데이터나 실시간 애플리케이션에서 차별화될 거예요. 공식 사이트에서 &lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;다운로드&lt;/a&gt;하고, &lt;a href=&quot;https://www.postgresql.org/about/press/&quot;&gt;프레스 키트&lt;/a&gt;로 더 알아보세요.&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/15</guid>
      <comments>https://news-thing.tistory.com/15#entry15comment</comments>
      <pubDate>Wed, 22 Oct 2025 10:28:11 +0900</pubDate>
    </item>
    <item>
      <title>웹 보안의 필수 무기: DOMPurify로 XSS 공격을 막아보자!</title>
      <link>https://news-thing.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, 개발자 여러분! 웹 애플리케이션을 만들다 보면 사용자 입력을 처리할 때마다 떠오르는 그 익숙한 걱정거리, &lt;b&gt;XSS(Cross-Site Scripting) 공격&lt;/b&gt;. 악의적인 스크립트가 HTML에 주입되어 사용자 데이터를 훔치거나 사이트를 망가뜨리는 그 끔찍한 시나리오 말입니다. 오늘은 이런 문제를 간단하고 효과적으로 해결해주는 오픈소스 라이브러리, &lt;b&gt;DOMPurify&lt;/b&gt;를 소개할게요. 이 글은 GitHub 리포지토리(&lt;a href=&quot;https://github.com/cure53/DOMPurify)%EC%9D%98&quot;&gt;https://github.com/cure53/DOMPurify)&lt;/a&gt;의 내용을 바탕으로 작성되었으니, 함께 탐구하며 실제로 어떻게 적용할 수 있는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOMPurify는 2014년부터 개발된 JavaScript 라이브러리로, HTML, MathML, SVG 같은 콘텐츠를 안전하게 정화(sanitize)해주는 도구예요. 브라우저의 DOM을 직접 다루며, 초고속으로 작동하면서도 높은 보안성을 자랑하죠. 만약 당신의 프로젝트에서 사용자 입력을 HTML로 렌더링해야 한다면, 이 라이브러리를 빼놓을 수 없어요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DOMPurify가 왜 특별할까? 주요 기능 탐구&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOMPurify의 매력은 단순함과 강력함의 조화에 있어요. 기본 설정만으로도 안전하게 작동하지만, 필요에 따라 세밀한 커스터마이징이 가능하답니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;XSS 방어의 핵심&lt;/b&gt;: HTML, SVG, MathML을 필터링해 위험한 태그나 속성을 제거합니다. 예를 들어, &lt;code&gt;&amp;lt;script&amp;gt;alert('hacked!')&amp;lt;/script&amp;gt;&lt;/code&gt; 같은 코드는 완전히 무해하게 변신하죠.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;브라우저 호환성 최고&lt;/b&gt;: Safari 10+, Chrome, Firefox 등 현대 브라우저를 모두 지원해요. 구형 IE(Internet Explorer)에서는 동작하지 않지만, 2.x 브랜치로 보안 업데이트를 받을 수 있어요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;훅(Hooks)으로 확장성 UP&lt;/b&gt;: &lt;code&gt;beforeSanitizeElements&lt;/code&gt;나 &lt;code&gt;uponSanitizeAttribute&lt;/code&gt; 같은 훅을 통해 커스텀 로직을 추가할 수 있습니다. 예를 들어, 특정 속성을 검사하거나 로그를 남기고 싶을 때 유용하죠.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버사이드 지원&lt;/b&gt;: Node.js 환경에서도 jsdom 같은 DOM 구현체와 함께 사용 가능. 다만, happy-dom은 XSS 취약점이 있어 피하세요!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 철저&lt;/b&gt;: 28개 브라우저와 Node.js 버전(v18~v23)에서 자동 테스트를 거칩니다. 안정성에 자신 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능들 덕분에 jQuery나 Angular 같은 프레임워크와도 잘 어울려요. 데모 사이트(&lt;a href=&quot;https://cure53.de/purify)%EC%97%90%EC%84%9C&quot;&gt;https://cure53.de/purify)&lt;/a&gt;에서 직접 테스트해보세요 &amp;ndash; 클릭 한 번으로 XSS 공격 시뮬레이션을 볼 수 있어요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치: 5분 만에 시작하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치는 간단해요. 브라우저나 Node.js 환경에 따라 선택하세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;브라우저에서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML에 스크립트 태그로 불러오면 끝!&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;!-- 개발용 (소스맵 포함) --&amp;gt;
&amp;lt;script src=&quot;dist/purify.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;!-- 프로덕션용 (미니파이드) --&amp;gt;
&amp;lt;script src=&quot;dist/purify.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Node.js에서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm으로 설치 후, jsdom과 함께 사용:&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;npm install dompurify jsdom&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');

const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

// 또는 ES 모듈
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';

const window = new JSDOM('').window;
const purify = DOMPurify(window);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버사이드 이슈가 걱정되시면 &lt;code&gt;isomorphic-dompurify&lt;/code&gt;를 추천해요. 클라이언트/서버 공통으로 동작하죠!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 사용 예시: 코드로 배우기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 사용법은 한 줄이면 돼요. 더티한 입력을 깨끗하게 정화하는 거죠.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기본 정화&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const dirty = '&amp;lt;img src=x onerror=alert(1)//&amp;gt;';  // 악성 코드
const clean = DOMPurify.sanitize(dirty);
console.log(clean);  // &amp;lt;img src=&quot;x&quot;&amp;gt; (안전하게 변환)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTML 프로필만 사용&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;고급: 훅 추가로 로그 남기기&lt;/h3&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;DOMPurify.addHook('uponSanitizeAttribute', function(currentNode, hookEvent) {
  console.log('제거된 속성:', hookEvent.attrName);  // 커스텀 로직
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SVG/MathML 예시&lt;/h3&gt;
&lt;pre class=&quot;dust&quot;&gt;&lt;code&gt;DOMPurify.sanitize('&amp;lt;svg&amp;gt;&amp;lt;g/onload=alert(2)//&amp;lt;p&amp;gt;', { USE_PROFILES: { svg: true } });  // &amp;lt;svg&amp;gt;&amp;lt;g&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;/svg&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 사용자 입력(예: 댓글, 포스트 콘텐츠)을 처리하면 보안이 한층 강화돼요. 더 많은 예시는 GitHub의 &lt;code&gt;/demos&lt;/code&gt; 폴더를 확인하세요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설정 옵션: 보안과 유연성의 균형&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOMPurify는 20개 이상의 옵션으로 세밀한 제어가 가능해요. 하지만 보안을 최우선으로 하세요!&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;옵션 카테고리&lt;/th&gt;
&lt;th&gt;주요 옵션&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;주의점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;태그/속성 허용&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALLOWED_TAGS: ['b', 'i']&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;특정 태그만 허용&lt;/td&gt;
&lt;td&gt;기본값으로 충분한 경우가 많음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;URI 안전&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ADD_URI_SAFE_ATTR: ['my-link']&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;URI 속성 추가&lt;/td&gt;
&lt;td&gt;XSS 위험 증가 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;반환 타입&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RETURN_DOM: true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DOM 노드 반환&lt;/td&gt;
&lt;td&gt;성능 최적화에 유용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기타&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SAFE_FOR_TEMPLATES: true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;템플릿 문법 제거&lt;/td&gt;
&lt;td&gt;프로덕션에서 비추천 (취약점 유발)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, ARIA 속성을 막고 싶다면 &lt;code&gt;ALLOW_ARIA_ATTR: false&lt;/code&gt;를 설정하세요. 자세한 옵션은 문서를 참고!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming</category>
      <author>danny-shim</author>
      <guid isPermaLink="true">https://news-thing.tistory.com/14</guid>
      <comments>https://news-thing.tistory.com/14#entry14comment</comments>
      <pubDate>Wed, 22 Oct 2025 10:18:57 +0900</pubDate>
    </item>
  </channel>
</rss>