Skip to content

Leo-Xee/github-graph

Repository files navigation

GitHub-Graph

GitHub ์œ ์ €์˜ ์ •๋ณด๋ฅผ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋กœ ์ œ๊ณตํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๐ŸŒ

template version

github-graph

๐Ÿ”ฅ ์†Œ๊ฐœ ( Demo )

GitHub Graph๋Š” GitHub API๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ฒ€์ƒ‰ํ•œ GitHub ์œ ์ €์˜ ์ •๋ณด๋ฅผ ๋ฆฌ์ŠคํŠธ์™€ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ๋Š” ์ œ๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ์•ฑ์ธ Obsidian์˜ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋ฅผ ๋ณด๊ณ  ์ธ์ƒ ๊นŠ๊ฒŒ ๋А๊ปด์„œ ์ด๋ฅผ ์ ์šฉํ•ด ๋ณผ ์•„์ดํ…œ์„ ๊ณ ๋ฏผํ•ด๋ณด๋‹ค๊ฐ€ GitHub์— ์ ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ƒˆ๋กœ์šด ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์„œ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ดˆ๊ธฐ์—๋Š” GitHub์—์„œ ์ œ๊ณตํ•˜๋Š” REST API๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•˜๋‹ค๊ฐ€ Over-Fetching ๋ฌธ์ œ๋ฅผ ๊ฒช์–ด๋ณด๊ณ ๋Š” ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์„œ GraphQL๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ GraphQL ์‚ฌ์šฉ์ด ์ฒ˜์Œ์ด๋‹ค๋ณด๋‹ˆ ์ „๋ฐ˜์ ์ธ ๋™์ž‘ ๋ฐฉ์‹์„ ์ตํž ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ ๊ณต์‹ ๋ฌธ์„œ์™€ ๊ฐ„๋‹จํ•œ ๊ฐ•์˜๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์˜ํ™” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•ด๋ณธ ๋’ค ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์‹œ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ API ํƒ€์ž… ์„ ์–ธ์˜ ์ž๋™ํ™”๋ฅผ ์œ„ํ•ด์„œ GraphQL Code Generateor๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ ์ด๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ํƒ€์ž… ์„ ์–ธ ํŒŒ์ผ(generated.ts)์€ ํฐ ์šฉ๋Ÿ‰ ๋•Œ๋ฌธ์— Git์— ํฌํ•จํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.


๐Ÿš€ ์‹คํ–‰ ๋ฐฉ๋ฒ•

ํ”„๋กœ์ ํŠธ ํด๋ก  ๋ฐ ์˜์กด์„ฑ ์„ค์น˜

$ git clone https://github.com/Leo-Xee/github-graph.git
$ npm install
# or
$ yarn install

GitHub API Token ์ƒ์„ฑ ๋ฐ ์ ์šฉ

GitHub API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ GitHub API Docs๋ฅผ ์ฐธ๊ณ ํ•ด์„œ Personal Token์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์•„๋ž˜์˜ ํ•ญ๋ชฉ์„ ํ•„์ˆ˜๋กœ ์ฒดํฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

  • repo
  • admin:repo_hook
  • user
  • project

Personal Token ์ƒ์„ฑ์„ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด ๋ฃจํŠธ ์œ„์น˜์— .env.example์„ ์ฐธ๊ณ ํ•ด์„œ .env๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Token๊ฐ’์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

GraphQL Code Generator ์‹คํ–‰

ํ˜„์žฌ API ํƒ€์ž… ์ •๋ณด๊ฐ€ ํ”„๋กœ์ ํŠธ์— ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ์ƒ์„ฑํ•˜๋ฉด ํƒ€์ž… ์ •๋ณด๋ฅผ ๊ฐ€์ง„ src/graphql/generated.ts ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

$ npm run generate
# or
$ yarn generate

ํ”„๋กœ์ ํŠธ ์‹คํ–‰

$ npm run dev
# or
$ yarn dev

๐Ÿ“š ๊ธฐ์ˆ  ์Šคํƒ

Typescript React.js Emotion GraphQL
Apollo-Client D3.js Zustand

๐ŸŒฒ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ

.
โ”œโ”€โ”€ public
โ””โ”€โ”€ src
    โ”œโ”€โ”€ assets      // ์ •์  ํŒŒ์ผ
    โ”œโ”€โ”€ components
    โ”‚   โ””โ”€โ”€ common  // ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ
    โ”œโ”€โ”€ graphql     // graphQL ์ฟผ๋ฆฌ
    โ”œโ”€โ”€ hooks       // ์ปค์Šคํ…€ Hooks
    โ”œโ”€โ”€ pages       // Page ์ปดํฌ๋„ŒํŠธ
    โ”œโ”€โ”€ shared
    โ”‚   โ””โ”€โ”€ utils   // ์œ ํ‹ธ ํ•จ์ˆ˜
    โ”œโ”€โ”€ styles
    โ””โ”€โ”€ types       // ํƒ€์ž…

โš™๏ธ ์ฃผ์š” ๋‚ด์šฉ

โœ… GitHub ์œ ์ € ๊ฒ€์ƒ‰์–ด ์ถ”์ฒœ ๋ฐ ์ž๋™์™„์„ฑ

search

GitHub ์œ ์ € ๊ฒ€์ƒ‰ ์‹œ์— ๊ฒ€์ƒ‰ ๋ฐ ๋กœ๋”ฉ ์•„์ด์ฝ˜์ด ํ™œ์„ฑํ™”๋˜๊ณ  ์ตœ๋Œ€ 5๊ฐœ์˜ ์ถ”์ฒœ ๊ฒ€์ƒ‰์–ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ถ”์ฒœ ๊ฒ€์ƒ‰์–ด๋ฅผ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ ๊ฒ€์ƒ‰์ฐฝ์— ์ž…๋ ฅํ•œ ์•„์ด๋””๋กœ ์œ ์ €๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ถ”์ฒœ ๊ฒ€์ƒ‰์–ด๋ฅผ ์œ„ํ•œ API ์š”์ฒญ์ด ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ ์ž ๊ด€๋ จ ํ•จ์ˆ˜์— ๋””๋ฐ”์šด์Šค๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

โœ… Tab ๋ณ„ ๋ฆฌ์ŠคํŠธ ๋ทฐ์™€ ๋ฌดํ•œ์Šคํฌ๋กค

list

์œ ์ € ๊ฒ€์ƒ‰์ด ์‹คํ–‰๋˜๋ฉด ์ž ์‹œ ์Šค์ผˆ๋ ˆํ†ค UI๋ฅผ ๋ณด์—ฌ์ค€ ํ›„์— ๊ฒ€์ƒ‰ํ•œ ์œ ์ €์˜ ๊ธฐ๋ณธ ์ •๋ณด์™€ Followings, Followers, Repositories, StarredRepositories ๋ฆฌ์ŠคํŠธ๋ฅผ Tab ๋ณ„๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฐ ๋ฆฌ์ŠคํŠธ๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•ด์„œ ์ตœ์ดˆ์—๋Š” 20๊ฐœ๋งŒ ๋ณด์—ฌ์ฃผ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กค ํ•˜๋‹ค๊ฐ€ ๋ฆฌ์ŠคํŠธ์˜ ์ค‘๊ฐ„์— ๋„๋‹ฌํ•˜๋Š” ๊ฒƒ์„ Intersection Observer๋กœ ๊ฐ์ง€ํ•ด์„œ ๊ทธ ๋‹ค์Œ 20๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ๋ฌดํ•œ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฆฌ์ŠคํŠธ์˜ ์•„์ดํ…œ์„ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ์œ ์ €๋‚˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ GitHub ์ฃผ์†Œ๋กœ ์ด๋™ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

Tab ๋ณ€๊ฒฝ ์‹œ์—๋Š” Tab ์ƒํƒœ๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋งŒ ๋ฆฌ๋ Œ๋”๋ง๋˜๊ธฐ๋ฅผ ์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ํ•˜๋‚˜์ธ Zustand๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

โœ… D3.js๋ฅผ ์‚ฌ์šฉํ•œ ๊ทธ๋ž˜ํ”„ ๋ทฐ

view

D3.js๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ DOM์„ ์กฐ์ž‘ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ ๋‹ค์–‘ํ•œ ๋ชจ๋“ˆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ค‘์— Force, Selections, Zoom ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ด์„œ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋ฉฐ Tab์˜ ์ƒํƒœ์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ตœ๋Œ€ 100๊ฐœ์˜ ๋…ธ๋“œ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๊ทธ๋ž˜ํ”„ ๋ทฐ์˜ ๋™์ž‘์€ runForceGraph ํ•จ์ˆ˜๊ฐ€ ๋‹ด๋‹นํ•˜๋ฉฐ ๋‹ค์Œ ๊ณผ์ •์„ ํ†ตํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. ๋ฐ์ดํ„ฐ ํ•„ํ„ฐ๋ง

    • GitHub Graph์˜ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋Š” Tab์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ƒํƒœ๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•ด์„œ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์ด ํ•„์š”๋กœํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ์ž‘์—…์„ FilterData ํ•จ์ˆ˜์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฒ€์ƒ‰๋œ ์‚ฌ์šฉ์ž ๋…ธ๋“œ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ทธ๋ž˜ํ”„ ๋ทฐ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธธ ์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— FilterData ํ•จ์ˆ˜์—์„œ ๊ฒ€์ƒ‰๋œ ์œ ์ €์˜ ์ •๋ณด์ธ userData๋ฅผ ์ฒซ ์š”์†Œ๋กœ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
  2. ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ์ƒ์„ฑ ๋ฐ ๋…ธ๋“œ์™€ ๊ฐ„์„  ๋“ฑ๋ก

    • ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ํ•„ํ„ฐ๋งํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋…ธ๋“œ(Nodes), ๊ฐ„์„ (Links)์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
    • svg ์š”์†Œ ๋‚ด๋ถ€์— ๋…ธ๋“œ์™€ ๊ฐ„์„ ์„ g ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋”ฐ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ๋…ธ๋“œ๋“ค ์ค‘์— ๊ฒ€์ƒ‰๋œ ์‚ฌ์šฉ์ž ๋…ธ๋“œ์™€ ๊ทธ ์™ธ์˜ ๋…ธ๋“œ๋“ค์„ class ์†์„ฑ์œผ๋กœ ๊ตฌ๋ถ„ํ•œ ๋’ค ์„œ๋กœ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ์ดํ„ฐ๊ฐ€ Followings๋‚˜ Followers์ธ ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹น ์œ ์ €์˜ Followers์˜ ์ˆ˜์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ Repositories๋‚˜ StarredRepositories์ธ ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹น ๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ Star ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  3. Zoom ์ƒ์„ฑ ๋ฐ ๋“ฑ๋ก

    • Zoom ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ Zoom ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  svg ์š”์†Œ์— ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
    • Zoom์˜ scale์ด ๋„ˆ๋ฌด ์ปค์ง€๊ฑฐ๋‚˜ ์ž‘์•„์ง€๋ฉด ์‚ฌ์šฉ์„ฑ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ ์ ˆํ•œ ์ตœ์†Œ๊ฐ’๊ณผ ์ตœ๋Œ€๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  4. Drag ์ƒ์„ฑ ๋ฐ ๋“ฑ๋ก

    • Drag ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ Drag ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  svg ์š”์†Œ์— ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  5. Graph ์ปดํฌ๋„ŒํŠธ๊ฐ€ Unmount๋  ๋•Œ, ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ์ •์ง€ ๋ฐ DOM ์ œ๊ฑฐ

    • D3.js๋Š” DOM์„ ์ง์ ‘ ์กฐ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ ๊ธฐ๋ฐ˜์œผ๋กœ DOM์„ ์กฐ์ž‘ํ•˜๋Š” React.js์—์„œ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๋ฌด์กฐ๊ฑด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ Unmount ๋  ๋•Œ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์˜ ๊ณ„์‚ฐ์„ ์ •์ง€ํ•˜๊ณ  ์ถ”๊ฐ€ํ•œ DOM ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ runForceGraph ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์ž‘์„ฑํ–ˆ๊ณ  ์ด๋ฅผ Unmount ์‹œ์— ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

โœ… ๋‹คํฌ๋ชจ๋“œ

dark

์šฐ์ธก ์ƒ๋‹จ์˜ ๋‹คํฌ๋ชจ๋“œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ…Œ๋งˆ๋ฅผ ๋‹ค๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ Emotion์˜ ํ…Œ๋งˆ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด์„œ ํ…Œ๋งˆ๋ณ„ ๋ณ€์ˆ˜์™€ ์Šคํƒ€์ผ์„ theme.ts์—์„œ ๋”ฐ๋กœ ์ง€์ •ํ–ˆ๊ณ  Zustand๋ฅผ ํ†ตํ•ด์„œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.


โ‰๏ธ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…๊ณผ ๊ณ ๋ฏผ

๐Ÿค” Router๊ฐ€ ํ•„์š”ํ• ๊นŒ?

  • ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ์—๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋งŽ์ง€ ์•Š๋‹ค๋ณด๋‹ˆ ๋ผ์šฐํ„ฐ์˜ ํ•„์š”์„ฑ์„ ๋А๋ผ์ง€ ๋ชปํ–ˆ๋Š”๋ฐ ๊ฒ€์ƒ‰๋œ ์œ ์ €์˜ ์ฃผ์†Œ๋กœ ์ง์ ‘ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ๊ฒ€์ƒ‰๋œ ํŽ˜์ด์ง€๋ฅผ ๊ณต์œ ํ•  ๋•Œ ์œ ์šฉํ•  ๊ฒƒ ๊ฐ™์•„์„œ ๋ผ์šฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ๊ทธ ๋•๋ถ„์— username์„ URL์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ค‘๋ณต๋˜๋Š” ๋กœ์ง์„ ์กฐ๊ธˆ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿค” ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”ํ• ๊นŒ?

  • UserDetail ํŽ˜์ด์ง€ ๋‚ด๋ถ€์—์„œ Search์™€ Profile ์ปดํฌ๋„ŒํŠธ ๋ฅผ ์ œ์™ธํ•œ Graph, ListContainer, Tab ์ปดํฌ๋„ŒํŠธ๊ฐ€ Tab์˜ ์ƒํƒœ์— ๋”ฐ๋ผ์„œ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ–ˆ์—ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ Context API๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ Tab ์ƒํƒœ์— ๋”ฐ๋ผ์„œ ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•˜๊ธธ ์›ํ–ˆ๊ณ  ์ „์—ญ์œผ๋กœ ๊ด€๋ฆฌํ•ด์•ผํ•  ์ƒํƒœ๊ฐ€ ๋งŽ์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ›„๋ณด ์ค‘ ๊ฐ€์žฅ ๊ฐ€๋ฒผ์šด Zustand๋ฅผ ์„ ํƒํ–ˆ๋‹ค.

  • ๋ฌผ๋ก  Context API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ ์ตœ์ ํ™” ์ž‘์—…์„ ํ•ด์ค€๋‹ค๋ฉด ๋™์ผํ•  ํšจ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ๊นŒ์ง€ ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•  ์ด์œ ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ๋•ํŠธ์˜ ์Šค์ผ€์ผ์ด ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰์œผ๋กœ ์ปค์ง„๋‹ค๋ฉด ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์˜์กด์„ฑ์€ ์ฝ”๋“œ์˜ ๋ณต์žก๋„๋ฅผ ์œ ๋ฐœํ•˜๊ธฐ ๋•Œ๋ฌธ์— Context API๋‚˜ ์ œ๋Œ€๋กœ๋œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ๋‚˜์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ๋„ ๋“ค์—ˆ๋‹ค.

๐Ÿค” ๊ฒ€์ƒ‰ํ•œ ์œ ์ € ๋ฐ์ดํ„ฐ์™€ Tab๋ณ„ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์–ธ์ œ ์–ผ๋งˆ๋‚˜ ํŒจ์นญํ•ด์•ผํ• ๊นŒ?

  • GitHub Graph์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ข…๋ฅ˜๋Š” ํฌ๊ฒŒ ๊ฒ€์ƒ‰ํ•œ ์œ ์ € ๋ฐ์ดํ„ฐ์™€ Tab ์ƒํƒœ๋ณ„ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋กœ 2๊ฐ€์ง€์ด๋‹ค. ํ•˜์ง€๋งŒ GraphQL ์ฟผ๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•ด์„œ ์–ธ์ œ ์–ผ๋งˆ๋‚˜ ํŒจ์นญํ•ด์•ผํ•  ์ง€์— ๋Œ€ํ•ด์„œ ๊ณ ๋ฏผ์ด ๋งŽ์•˜๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ๊ฒ€์ƒ‰ํ•œ ์œ ์ € ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ์—๋Š” ์œ ์ €์˜ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ์™€ followings, followers, repositories, starredRepositories์˜ count๋งŒ ์ฟผ๋ฆฌํ•˜๊ณ  UserDetail ํŽ˜์ด์ง€๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ํŒจ์นญํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Tab๋ณ„ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋Š” ๋ฌดํ•œ์Šคํฌ๋กค๋กœ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Tab ๋ณ„๋กœ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•ด์„œ ํŒจ์นญํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

  • ํ•˜์ง€๋งŒ ListContainer ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ๊ฐ์˜ Tab ๋ณ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ํšจ์œจ์ ์œผ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์„์ง€์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ๊ณ ๋ฏผ์ด ์ƒ๊ฒผ๋‹ค. ๊ทธ๋ž˜์„œ ์ดˆ๊ธฐ์—๋Š” Tab ๋ณ„๋กœ ์•„์ดํ…œ์˜ ๋ทฐ๊ฐ€ ๋น„์Šทํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜์„œ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ณ ์ž ListContainer ์ปดํฌ๋„ŒํŠธ์—์„œ Tab ๋ณ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•ด์ฃผ๋ ค๊ณ  ํ–ˆ๋‹ค๊ฐ€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ๋งค์šฐ ๋–จ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค. ๊ทธ๋ž˜์„œ ์ฝ”๋“œ์˜ ๋ฐ˜๋ณต์ด ์กฐ๊ธˆ ์ƒ๊ธฐ๋”๋ผ๋„ ๋ถ„๋ฆฌํ•˜๋Š” ํŽธ์ด ๋‚˜์„ ๊ฑฐ๋ผ๊ณ  ํŒ๋‹จํ•˜๊ณ  ๊ฐ๊ฐ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋”ฐ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค. ์ฝ”๋“œ ๊ฐ€๋…์„ฑ๊ณผ ๋ฐ˜๋ณต ์ œ๊ฑฐ๋Š” ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„ ๊ด€๊ณ„์— ์žˆ๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ์ ์ ˆํ•œ ๊ท ํ˜•์„ ์žก๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋А๊ผˆ๋‹ค.

๐Ÿค” Apollo-Client์—์„œ๋Š” ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”๊ฑธ๊นŒ?

  • ํŽ˜์ด์ง€๋„ค์ด์…˜๊ณผ ๋ฌดํ•œ์Šคํฌ๋กค ๊ธฐ๋Šฅ์„ ์ฒ˜์Œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์ด๋ฅผ GraphQL๊ณผ Apollo-Client ๊ธฐ๋ฐ˜์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์ฒ˜์Œ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ณต์‹๋ฌธ์„œ์™€ ๊ฒ€์ƒ‰ํ•˜๋‹ค ์ฐพ์€ ์˜์ƒ์„ ๋ณด๊ณ  ๊ตฌํ˜„ํ•˜๋‹ค๊ฐ€ fetchMore ์ธ์ž๋กœ updateQuery๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ™์—ฌ์ค„ ๋•Œ ์ •์ƒ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค. ๊ทธ๋ž˜์„œ ๊ตฌ๊ธ€๋งํ•˜๋˜ ์ค‘ ๋”์ด์ƒ updateQuery๋กœ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค๋Š” ๊ธ€์„ ๋ณด๊ณ  apollo.ts์˜ InMemoryCache์˜ ๊ด€๋ จ ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋‹ˆ ์ž˜ ๋™์ž‘ํ–ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ํŽ˜์ด์ง€๋„ค์ด์…˜์—๋Š” ํŽ˜์ด์ง€ ๊ธฐ๋ฐ˜๊ณผ ์ปค์„œ ๊ธฐ๋ฐ˜์ด ์žˆ๋Š”๋ฐ ์ปค์„œ ๊ธฐ๋ฐ˜์ด ์กฐํšŒ ์‹œ์— ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๊ณ  GitHub API๊ฐ€ Relay ์Šคํƒ€์ผ์˜ ์ปค์„œ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปค์„œ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

  • ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ „๋žต์—๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. offset ๊ธฐ๋ฐ˜๊ณผ ์ปค์„œ ๊ธฐ๋ฐ˜์ด๋‹ค. ๋ฌดํ•œ ์Šคํฌ๋กค์— ์œ ์šฉํ•œ ์ปค์„œ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ์œ ์ €์˜ followings, followers, repos, stars์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ๊ฐ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋ฐ ์บ์‹œ ๊ด€๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ๋”ฐ๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ๊ด€๋ฆฌํ• ์ง€๊ฐ€ ๊ณ ๋ฏผ์ด์˜€๋‹ค.

๐Ÿค” D3.js๋Š” ๋Œ€์ฒด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฑธ๊นŒ?

  • D3.js์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๊ธฐ๊นŒ์ง€๋Š” ๊ฝค ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ GitHub Graph์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋Š” Force ๋ชจ๋“ˆ์€ ๋‹ค๋ฅธ ๋ชจ๋“ˆ๊ณผ ๋™์ž‘๋ฐฉ์‹์ด ๋งค์šฐ ๋‹ฌ๋ž๊ณ  ๋ ˆํผ๋Ÿฐ์Šค๋„ ๋งŽ์ง€ ์•Š์•˜์œผ๋ฉฐ SVG์— ์ต์ˆ™ํ•œ ํŽธ๋„ ์•„๋‹ˆ์˜€๋‹ค. ๊ทธ๋ž˜์„œ ์ž‘์€ ํ”„๋กœ์ ํŠธ๋ฅผ ํด๋ก ํ•ด๋ณด๋ฉฐ ์ตํ˜€๋ณผ ํ•„์š”์„ฑ์„ ๋А๋ผ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์ด ์˜ˆ์ œ์™€ ๊ณต์‹๋ฌธ์„œ ๋ฐ ๋ฒˆ์—ญ๋œ ๋ฌธ์„œ๊ฐ€ D3.js๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ํฐ ๋„์›€์ด ๋˜์—ˆ๊ณ  SVG๋Š” MDN์˜ ๋‚ด์šฉ์„ ์ˆ˜์‹œ๋กœ ๋ณด๋ฉด์„œ ์ง„ํ–‰ํ•ด๋‚˜๊ฐ”๋‹ค.

โš ๏ธ ๊ฒ€์ƒ‰์ฐฝ์— ๋””๋ฐ”์šด์Šค๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ

  • ๊ฒ€์ƒ‰์ฐฝ์˜ ๊ฒ€์ƒ‰์ถ”์ฒœ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’๋งˆ๋‹ค API ์š”์ฒญํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฟŒ๋ ค์ค˜์•ผํ–ˆ๋Š”๋ฐ ๊ฐœ๋ณ„ ํƒ€์ดํ•‘๋งˆ๋‹ค ์š”์ฒญํ•˜๊ธฐ์—๋Š” ์„ฑ๋Šฅ์ƒ ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— lodash์˜ ๋””๋ฐ”์šด์Šค๋ฅผ ์ ์šฉํ–ˆ๋Š”๋ฐ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋Ÿฌ๋‹ค ์ƒ๊ฐํ•ด๋ณด๋‹ˆ useCallback์œผ๋กœ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ์ฃผ์ง€ ์•Š์•„์„œ ๋ฆฌ๋ Œ๋”๋ง ์‹œ๋งˆ๋‹ค ํ•ญ์ƒ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋กœ ์ธ์‹ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ ์˜€๋‹ค. ๊ทธ๋ž˜์„œ useCallback์œผ๋กœ ๊ฐ์‹ธ์ฃผ๋‹ˆ ์ •์ƒ ๋™์ž‘ํ–ˆ์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ์ƒ๊ฐ๋ณด๋‹ค ๊น”๋”ํ•˜์ง€ ๋ชปํ•ด์„œ ์ฐพ์•„๋ณด๋‹ˆ ์ปค๋ง์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์–ด์„œ ์ถ”ํ›„์— ์ปค๋ง์„ ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ๋ฆฌํŒฉํ† ๋ง ํ•ด๋ด์•ผ๊ฒ ๋‹ค๊ณ  ๋А๊ผˆ๋‹ค.

โš ๏ธ ๊ฒ€์ƒ‰๋œ ์œ ์ €๋ฅผ ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ๊ณ ์นจํ•  ๋•Œ ํ”Œ๋ฆฌ์ปค ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

  • UserDetail ํŽ˜์ด์ง€์—์„œ๋Š” ์œ ์ €๊ฐ€ ์ด๋ฏธ ๊ฒ€์ƒ‰๋œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฒ€์ƒ‰์ฐฝ์— ๊ฒ€์ƒ‰๋œ ์œ ์ € ์•„์ด๋””๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๋Š”๋ฐ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ฑฐ๋‚˜ ํ•ด๋‹น ํŽ˜์ด์ง€๋กœ ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ์— ๊ฒ€์ƒ‰์ฐฝ์˜ ์œ ์ € ์•„์ด๋””๊ฐ€ ์ž ๊น ๋น„์–ด์žˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋˜๋Š” ๋ฌธ์ œ์ธ ์ผ๋ช… ํ”Œ๋ฆฌ์ปค ํ˜„์ƒ์ด ์ƒ๊ฒผ๋‹ค. ์›์ธ์„ ์ฐพ์•„๋ณด๋‹ˆ ๊ฒ€์ƒ‰์ฐฝ์˜ input์„ URL๋กœ๋ถ€ํ„ฐ useParams๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ›์•„์™€์„œ useEffect ๋‚ด๋ถ€์—์„œ setInput์„ ํ†ตํ•ด์„œ ๋ณ€๊ฒฝํ•ด์คฌ๊ธฐ ๋•Œ๋ฌธ์ด์˜€๋‹ค. ์ด๋Ÿฌ๋ฉด ๋งˆ์šดํŠธ ์ดํ›„์— ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜๋Š”๋ฐ ๊ทธ ์‚ฌ์ด์— ๊ฒ€์ƒ‰์ฐฝ์— ๋นˆ๊ฐ’์ด ๋ณด์—ฌ์ง€๋‹ˆ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ์„ ์œ„ํ•ด์„œ ๋งˆ์šดํŠธ ์ด์ „์— ์‹คํ–‰๋˜๋Š” useLayoutEffect๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ˆ˜์ •ํ–ˆ๋‹ค๊ฐ€ URL์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ๊ฐ’์„ input ์ƒํƒœ๊ฐ’์˜ ๋””ํดํŠธ๋กœ ์ฃผ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•  ๊ฒƒ ๊ฐ™์•„์„œ ์žฌ์ˆ˜์ •ํ–ˆ๋‹ค.

โš ๏ธ GraphQL ์œ ๋‹ˆ์˜จํƒ€์ž…์— map ์‚ฌ์šฉ ์‹œ์— ํƒ€์ž… ๋ฌธ์ œ

  • GraphQL์„ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ผ์„œ Inline Fragment๋ผ๋Š” ๊ฐœ๋…์„ ์•Œ์ง€ ๋ชปํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์˜ ๋ฐฐ์—ด๋กœ ์ด๋ฃจ์–ด์ง„ ์ถ”์ฒœ ๊ฒ€์ƒ‰์–ด ๋ฐ์ดํ„ฐ์˜ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ์™€ ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ map์œผ๋กœ ๋ฟŒ๋ ค์ค„ ๋•Œ ์‹œํ–‰์ฐฉ์˜ค๊ฐ€ ์žˆ์—ˆ๋‹ค. ํ•ด๊ฒฐ์„ ์œ„ํ•ด ๊ณต์‹๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋‹ˆ ์ฟผ๋ฆฌ๋ฅผ ์œ„ํ•ด ์œ ๋‹ˆ์˜จ ํƒ€์ž…์— ์ ‘๊ทผํ•  ๋•Œ๋Š” Inline Fragment๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๋‚ด์šฉ์ด ์žˆ์–ด์„œ ์ด๋ฅผ ์ฐธ๊ณ  ํ–ˆ๊ณ  map ์‚ฌ์šฉ ์‹œ์—๋Š” ํƒ€์ž… ๊ฐ€๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค.

โš ๏ธ Apollo-Client์˜ ์บ์‹œ๊ฐ€ ๋ฎ์–ด์จ์ง€๋Š” ๋ฌธ์ œ

  • ์‚ฌ์šฉ์ž์˜ ๋ฆฌ์ŠคํŠธ ๋ทฐ์™€ ๊ทธ๋ž˜ํ”„ ๋ทฐ๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์„ฑ์š”์†Œ์™€ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ฌ๋ž๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ๊ฐ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋™์ผํ•œ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์š”์ฒญ์ด๊ธฐ ๋•Œ๋ฌธ์— Apollo-Client๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋“ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์ผํ•œ ํ•„๋“œ๋กœ ๊ฐ„์ฃผํ•ด์„œ ์บ์‹œ๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์บ์‹œ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ ๊ณต์‹๋ฌธ์„œ์˜ keyArgs๋ถ€๋ถ„์„ ์ฝ์–ด๋ณด๋‹ˆ keyArgs ๋ผ๋Š” ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์„œ ๋™์ผํ•œ ํ•„๋“œ์˜ ์บ์‹œ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ–ˆ๋‹ค. ๋‚˜์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฆฌ์ŠคํŠธ ๋ทฐ์™€ ๊ทธ๋ž˜ํ”„ ๋ทฐ๊ฐ€ ์š”์ฒญํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฐœ์ˆ˜์— ๋Œ€ํ•œ ์ธ์ž๊ฐ€ ๋‹ฌ๋ผ์„œ key๊ฐ’์œผ๋กœ first ๋ผ๋Š” ์ธ์ž๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ—€๋‹ค.

โš ๏ธ ํŠน์ • ๋…ธ๋“œ์— ์ด๋ฏธ์ง€ ์‚ฝ์ž… ๋ฐ ์Šคํƒ€์ผ๋ง์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ

  • ๊ทธ๋ž˜ํ”„ ๋ทฐ์—์„œ ๊ฒ€์ƒ‰๋œ ์‚ฌ์šฉ์ž์˜ ์•„๋ฐ”ํƒ€๋ฅผ ์œ„ํ•ด svg์— ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  border-radius๋กœ ์Šคํƒ€์ผ์„ ์ฃผ๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ์ ์šฉ๋˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ž˜์„œ ๊ตฌ๊ธ€๋ง์„ ํ•œ์ฐธํ•˜๋‹ค๊ฐ€ ์ด ๊ธ€์„ ๋ณด๊ณ  foreignObject๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๊ณ  ํ•ด๋‹น ํƒœ๊ทธ์•ˆ์— img ํƒœ๊ทธ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์Šคํƒ€์ผ์„ ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค.

โš ๏ธ ํฌ๋กœ์Šค ๋ธŒ๋ผ์šฐ์ง• ๋ฌธ์ œ

  • ํŒŒ์ด์–ดํญ์Šค์—์„œ ๋…ธ๋“œ์˜ alignment-baseline ์†์„ฑ์ด ๋™์ž‘ํ•˜์ง€ ์•Š์•„์„œ ๋…ธ๋“œ ์•ˆ์— ์žˆ๋Š” ํ…์ŠคํŠธ์˜ ๋ ˆ์•„์ด์›ƒ์ด ๊นจ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ณต์‹๋ฌธ์„œ์™€ ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ alignment-base ๋Œ€์‹  dominant-baseline์˜ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๋Š” ๋‚ด์šฉ์„ ๋ณด๊ณ ๋Š” ์ˆ˜์ •ํ•ด์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค.

  • ์‚ฌํŒŒ๋ฆฌ์—์„œ ๊ฒ€์ƒ‰๋œ ์‚ฌ์šฉ์ž์˜ ๋…ธ๋“œ ์ด๋ฏธ์ง€์— border-radius ์†์„ฑ์ด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๊ธฐ์กด์—๋Š” ํ•ด๋‹น ์†์„ฑ์ด ์ด๋ฏธ์ง€์˜ ์ƒ์œ„ ์—˜๋ฆฌ๋จผํŠธ์ธ foreignObject์— ์ ์šฉ๋˜์–ด ์žˆ์—ˆ๋Š”๋ฐ ์ด๋ฅผ xhtml:img ์—˜๋ฆฌ๋จผํŠธ์— ์ง์ ‘ ์ ์šฉํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค.


๐ŸŒ ๋งํฌ

About

A tool to visualize GitHub user data using graphs ๐ŸŒ

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published