์ „์ฒด ๊ธ€

๊ฐœ๋ฐœ์ผ์ง€ ๋ฐ ์ •๋ณด ๊ณต์œ 
๐Ÿ“ก WebView Bridge ํ†ต์‹ ์ด๋ž€?React Native ←→ WebView (์›น ํŽ˜์ด์ง€)๋‘ ํ™˜๊ฒฝ์ด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ํ†ต์‹  ๊ตฌ์กฐ๋ฅผ ๋งํ•œ๋‹ค. ์ง์ ‘์ ์œผ๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ,์ค‘๊ฐ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” "๋ฉ”์‹œ์ง€ ๋ธŒ๋ฆฟ์ง€(message bridge)"๋ฅผ ๋งŒ๋“ค์–ด์„œ ์„œ๋กœ ์†Œํ†ตํ•œ๋‹ค. ๐Ÿค” ์™œ ๋ธŒ๋ฆฟ์ง€๊ฐ€ ํ•„์š”ํ•œ๋ฐ?โœ… ๋„ค์ดํ‹ฐ๋ธŒ ๊ธฐ๋Šฅ์„ ์›น์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œโˆ™ WebView ์•ˆ์—์„œ ์‚ฌ์ง„ ์—…๋กœ๋“œ ๋ฒ„ํŠผ →๋„ค์ดํ‹ฐ๋ธŒ ์นด๋ฉ”๋ผ ์‹คํ–‰์›น๋งŒ์œผ๋กœ๋Š” ์นด๋ฉ”๋ผ๋ฅผ ์ผค ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ๋Œ€์‹  ์‹คํ–‰ํ•ด์•ผํ•œ๋‹ค. โœ… ์›น์—์„œ ํ† ํฐ / ์‚ฌ์šฉ์ž ์ •๋ณด ๊ณต์œ โˆ™ ์›น๋ทฐ ๋กœ๊ทธ์ธ ์„ฑ๊ณต → RN ์•ฑ์— accessToken ์ „๋‹ฌ์•ฑ์€ ํ•ด๋‹น ํ† ํฐ์„ ์ €์žฅํ•˜๊ณ  API ์š”์ฒญ์— ์‚ฌ์šฉ.(๋‹จ, ๋„ค์ดํ‹ฐ๋ธŒ์—์„œ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์—๋Š” ๋”ฐ๋กœ ์ €์žฅ์„..
์‹ค์‹œ๊ฐ„ ๊ธฐ๋Šฅ (์ฑ„ํŒ…, ์•Œ๋ฆผ, ์„ผ์„œ ๋ฐ์ดํ„ฐ, ๋Œ€์‹œ๋ณด๋“œ ์—…๋ฐ์ดํŠธ ๋“ฑ)์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์›น์†Œ์ผ“ (WebSocket) ๊ธฐ์ˆ ์ด ํ•„์š”ํ•˜๋‹ค.NestJS๋Š” ์ด๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Gateway(๊ฒŒ์ดํŠธ์›จ์ด)๋ผ๋Š” ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๐Ÿ“ก WebSocketWebSocket์€ ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๊ฐ€ ์ง€์†์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์„œ๋กœ ์ž์œ ๋กญ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์–‘๋ฐฉํ–ฅ ํ†ต์‹  ๊ธฐ์ˆ ์ด๋‹ค. ๊ธฐ์กด HTTP API ์š”์ฒญ-์‘๋‹ต ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์—ฐ๊ฒฐ์ด ์œ ์ง€๋œ ์ƒํƒœ์—์„œ ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ฆ‰์‹œ Push๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๐Ÿงฑ GatewayWebSocket ์„œ๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” NestJS์˜ Controller ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค.NestJS๋Š” ์›น์†Œ์ผ“์„ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก Gateway๋ผ๋Š” ์ถ”์ƒํ™” ๋ ˆ์ด์–ด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. โœ… ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ/ํ•ด์ œ ๊ฐ์ง€โœ… ํด..
NestJS์—์„œ ๊ฐ„๋‹จํ•œ API๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.์ œ์ผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ToDo ๊ธฐ๋Šฅ์˜ API๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž. ๐Ÿ“ TODO๐Ÿ•น๏ธ*.controller.tsAPI์˜ ์ง„์ž…์ .์ฆ‰, ์š”์ฒญ์„ ๋ฐ›๋Š” ๊ณณ์„ ์ •์˜ํ•œ๋‹ค. โœ… URL ๋ผ์šฐํŒ… ์ •์˜ (@Get(), @Post ๋“ฑ)โœ… ์š”์ฒญ Parameter, Body ๋ฐ›๋Š”๋‹ค.โœ… ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์ž‘์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.โœ… ๋Œ€๋ถ€๋ถ„ service์— ์ผ์„ "์œ„์ž„" "/todos" ๊ฒฝ๋กœ๋กœ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ CRUD๋ฅผ ์ž‘์„ฑ.import { Controller, Get, Post, Body, Param, Patch, Delete } from '@nestjs/common';import { TodosService } from './todos.service';@Controller('todos')export cl..
ํšŒ์‚ฌ์—์„œ Undo, Redo๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•ด์„œ ์ž‘์„ฑํ•ด๋ณธ๋‹ค.๐Ÿซต๐Ÿป ์ปค๋งจ๋“œ ํŒจํ„ด์ด๋ž€?์ปค๋งจ๋“œ ํŒจํ„ด์€ ์š”์ฒญ(๋ช…๋ น)์„ ๊ฐ์ฒด๋กœ ์บก์Аํ™”ํ•˜์—ฌ, ์‹คํ•ผ์ž(Invoker)์™€ ์‹ค์ œ ์ˆ˜ํ–‰์ž(Receiver)๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ํŒจํ„ด์ด๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด, "ํ•˜๊ณ  ์‹ถ์€ ์ผ์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์„œ ํ•„์š”ํ•  ๋•Œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹"์ด๋‹ค. ์—ญํ• ์„ค๋ช…Command์‹คํ–‰ํ•  ๋™์ž‘์„ ๊ฐ€์ง„ ์ธํ„ฐํŽ˜์ด์Šค ํ˜น์€ ์ถ”์ƒ ํด๋ž˜์ŠคConcreteCommand์‹ค์ œ ์‹คํ–‰ ๋กœ์ง(Receiver๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž‘์—… ์ˆ˜ํ–‰)Receiver์‹ค์ œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒดInvoker๋ช…๋ น์„ ๋ณด๊ด€/์‹คํ–‰ํ•˜๋Š” ๊ฐ์ฒด (Button, Scheduelr ๋“ฑ) ๐Ÿค” ์™œ ํ•„์š”ํ•œ๋ฐ?๐ŸŽญ ์‹คํ–‰์ž์™€ ์ž‘์—… ๋‚ด์šฉ์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.๋ฒ„ํŠผ ํด๋ฆญ → ๊ตฌ์ฒด์ ์ธ ๋กœ์ง ์‹คํ–‰์ด๋ ‡๊ฒŒ ๋ฐ€์ฐฉ๋˜์–ด ์žˆ์œผ๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.์ปค๋งจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด..
๋‹ค์ค‘ ์ ‘์† ํŽธ์ง‘ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์†Œ์ผ“์„ ์‚ฌ์šฉํ•ด๋ณด๊ณ ์ž๊ฐ„๋‹จํ•œ ์ฑ„ํŒ…์„ ๋งŒ๋“ค์–ด๋ณด๋ ค๊ณ ํ•œ๋‹ค. ๋กœ๊ทธ์ธ ํ›„, ์‚ฌ์šฉ์ž๊ฐ€ ์ฑ„ํŒ…๋ฐฉ์„ ์ž…๋ ฅํ•˜๋ฉด ์ƒˆ๋กœ์šด ์œˆ๋„์šฐ์— ์ฑ„ํŒ…๋ฐฉ์„ ์—ด์–ด์ค€๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ฉ”์ธ ์œˆ๋„์šฐ๋ฅผ ๋‹ซ์œผ๋ฉด ๋ชจ๋“  ์œˆ๋„์šฐ๋ฅผ ๋‹ซ์•„๋ฒ„๋ฆด์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€.๋ ˆํผ๋Ÿฐ์Šค๋Š” ์นด์นด์˜คํ†ก์œผ๋กœ ์žก์•˜์œผ๋ฉฐ, ์ฑ„ํŒ…์ฐฝ์ด ์—ด๋ฆฐ ์ƒํƒœ์—์„œ ๋ฉ”์ธ ์œˆ๋„์šฐ(์ฑ„ํŒ…์ฐฝ ๊ด€๋ฆฌ ์œˆ๋„์šฐ)๊ฐ€ ๊บผ์ ธ๋„ ์ฑ„ํŒ…์ฐฝ์€ ์‚ด์•„์žˆ๋‹ค. ์œ„ ๋‚ด์šฉ์„ ๋ณด๋ฉดโ“์†Œ์ผ“๋งŒ ํ…Œ์ŠคํŠธํ•˜์ง€ ์™œ?์งˆ๋ฌธ์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‚˜๋Š” ๋ญ”๊ฐ€ ์™„๋ฒฝํ•จ(?)์„ ์ถ”๊ตฌํ•˜์—ฌ์„œ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค๋”๋ผ๋„ ์ œ๋Œ€๋กœ ๋งŒ์ ธ๋ณด๊ณ ์‹ถ๋‹ค. ๐Ÿ—๏ธ WindowManager์šฐ์„  ์œˆ๋„์šฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋งค๋‹ˆ์ €๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค. ๋‚ด๊ฐ€ ๋งŒ๋“  ๋งค๋‹ˆ์ €์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.๊ธ€์„ ์•ˆ ๋ณด๊ณ  ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณด๊ณ  ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด์•„๋„ ์ข‹๋‹ค.export ..
๐Ÿ—๏ธ QueryKey๋ž€?React Query์—์„œ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ ํ•œ ํ‚ค์ด๋‹ค.JavaScript ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ •์˜๋˜๋ฉฐ, ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.// ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ['todos']// ๊ตฌ์ฒด์ ์ธ ํ˜•ํƒœ['todos', 'list']['todos', 'detail', 1]['todos', 'list', {status: 'done', page: 1}] ๐Ÿ‘ท๐Ÿป QueryKey ์—ญํ• โœ… ์บ์‹œ ์‹๋ณ„์ž๊ฐ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ‚ค์ด๋‹ค.๋™์ผํ•œ QueryKey๋ฅผ ๊ฐ€์ง„ ์ฟผ๋ฆฌ๋Š” ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•œ๋‹ค. โœ… ์˜์กด์„ฑ ๊ด€๋ฆฌQueryKey๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ž๋™์œผ๋กœ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ fetch ํ•œ๋‹ค.ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํฌํ•จ๋œ QueryKey๋Š” ์˜์กด์„ฑ์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค.// userId๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ž๋™..
๐Ÿš @๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ž€?NestJS์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ํ”„๋กœํผํ‹ฐ, ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ถ”๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ถ€์—ฌํ•˜๊ฑฐ๋‚˜ ๋™์ž‘์„ ๋ฐ”๊พธ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.TypeScript์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ฌธ๋ฒ•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, NestJS์˜ ํ•ต์‹ฌ ์ฒ ํ•™์ธ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ + ์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ•ต์‹ฌ ์š”์†Œ์ด๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด,"Nest๊ฐ€ ์ด ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋„๋ก ์•Œ๋ ค์ฃผ๋Š” ํƒœ๊ทธ" ๐Ÿค” ์™œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ๋ฐ?NestJS๋Š” Angular ์˜ํ–ฅ์„ ํฌ๊ฒŒ ๋ฐ›์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.Nest๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค๋ฅผ ์Šค์บ”(scanning)ํ•˜๊ณ  ์—ญํ• ์„ ํŒŒ์•…ํ•ด ๋‚ธ๋ถ€ IoC/DI ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•œ๋‹ค. ์ฆ‰, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์žˆ์–ด์•ผ Nest๋Š” ๋‹ค์Œ ๋‚ด์šฉ๋“ค์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.โœ… ์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ์ปจํŠธ๋กค๋Ÿฌ์ธ์ง€โœ… ์–ด๋–ค ํด๋ž˜..
๋‚˜๋งŒ์˜ ๋ฐ์Šคํฌ ์•ฑ์„ ๋งŒ๋“œ๋ ค๋Š”๋ฐ ๊ณ ์ „์ ์ธ ์Šคํƒ€์ผ์˜ ์ƒ๋‹จ ํƒ€์ดํ‹€ ๋ฐ”๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๋Š”๋‹ค. Youtube Music์˜ ๋ฐ์Šคํฌํƒ‘ ์•ฑ๋งŒ ๋ณด๋”๋ผ๋„ ๋ญ”๊ฐ€ ๋‹ค์–‘ํ•˜๋‹ค. ( ์œ ํŠœ๋ธŒ ๋Œ€๊ธฐ์—… ์น˜๊ณ ๋Š” ๋ชป ์ƒ๊ธด ๊ฑฐ ๊ฐ™๋‹ค...) ์šฐ๋ฆฌ๋„ ์ปค์Šคํ…€ํ•ด๋ณด์ž. ๐Ÿ—‘๏ธ ํƒ€์ดํ‹€๋ฐ” ํ”„๋ ˆ์ž„ ์ œ๊ฑฐ ์šฐ์„  ๊ธฐ์กด TitleBar๋Š” ์‚ฌ๋ผ์ง€๋„๋ก ๐Ÿ“„electron/main.ts ์—์„œ ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํƒ€์ดํ‹€๋ฐ”์™€ ๋ฉ”๋‰ด๋ฐ”๊ฐ€ ์—†๋Š” ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.unction createWindow() { win = new BrowserWindow({ icon: path.join(process.env.VITE_PUBLIC, "electron-vite.svg"), webPreferences: { preload: path.join(__dirname, ..
ma.caron_g
๐Ÿงช ๋งˆ์นด๋กฑ ๊ฐœ๋ฐœ์‹ค