๐Ÿต ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์„ ๋†’์—ฌ์ฃผ๋Š” MSW!

Lee Jooamยท2022๋…„ 4์›” 21์ผ
1

์‚ฌ์ง„ ์ถœ์ฒ˜: https://selftaughtcoders.com/from-idea-to-launch/lesson-9/how-objects-flow-through-web-applications/

node.js ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ฆฌ์•กํŠธ๋ฅผ ์ด์šฉํ•ด ์ž‘์€ ํ’€์Šคํƒ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋ณธ ์ ์ด ์žˆ๋‹ค.

๋‹น์‹œ์—๋Š” API ์„œ๋ฒ„๋ฅผ ๋ชจ๋‘ ๋งˆ๋ จํ•ด๋†“๊ณ  ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ–ˆ๊ณ , ๋˜ ๋‚˜ ํ˜ผ์ž ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์˜ ์ „์ฒด์ ์ธ ๊ณผ์ •์—์„œ ๋ง‰ํž˜์€ ์ „ํ˜€ ์—†์—ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ํ”„๋กœ์ ํŠธ ๋˜ํ•œ ๊ทธ๋ ‡๊ฒŒ ์ง„ํ–‰๋  ์ง€๋Š” ๋ฏธ์ง€์ˆ˜๋‹ค.

MSW(Mock Service Worker)๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ์— ์•ž์„œ Service Worker์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Service Worker๋Š” Web Worker์˜ ํ•œ ์ข…๋ฅ˜์ด๊ธฐ ๋•Œ๋ฌธ์— Web Worker ๋˜ํ•œ ๊ฐ„๋‹จํ•œ๊ฒŒ ๋งํ•ด๋ณด๊ฒ ๋‹ค.

Web Worker

์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋Œ€๋ถ€๋ถ„์˜ ์Šคํฌ๋ฆฝํŠธ ์—ฐ์‚ฐ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์›น ์›Œ์ปค๋Š” ๊ทธ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฒ—์–ด๋‚˜ ๋ฐฑ ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์Šคํฌ๋ฆฝํŠธ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์—ฐ์‚ฐํ•˜๋Š” ๋งŒํผ ๋‹น์—ฐํžˆ ์ œ์•ฝ์ด ์กด์žฌํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ DOM ์กฐ์ž‘ ๋ถˆ๊ฐ€, ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€ postMessage ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ†ต์‹  ๋ฐฉ์‹์ด ์žˆ๋‹ค.

์›น ์›Œ์ปค๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฌด๊ฑฐ์šด ์—ฐ์‚ฐ์„ ๋ฐฑ ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ๋ถ€ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

์ž์„ธํ•œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ Web Worker mdn ๋ฌธ์„œ์— ๋‚˜์™€์žˆ๋‹ค.

Service Worker??

์„œ๋น„์Šค ์›Œ์ปค๋Š” ์›น ์›Œ์ปค์˜ ํ•œ ์ข…๋ฅ˜๋‹ค. ์„œ๋น„์Šค ์›Œ์ปค๋Š” ์›น ํŽ˜์ด์ง€์™€ ๋ณ„๊ฐœ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋Œ€๋žต์ ์ธ ์ž‘๋™์€ install - activate - idle ์ˆœ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋ฉฐ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„ ์บ์‹ฑํ•˜๊ฑฐ๋‚˜, ๋ฐฑ ๊ทธ๋ผ์šด๋“œ ๋™๊ธฐํ™”, ํ‘ธ์‹œ ์•Œ๋ฆผ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋‹ค๋ฃจ๋Š” ๋งŒํผ ์ œ์•ฝ์ด ์กด์žฌํ•˜๋ฉฐ, localhost๊ฐ€ ์•„๋‹Œ ๋ฐฐํฌ๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค ์›Œ์ปค๋ฅผ ์ œ๊ณตํ•  ๊ฒฝ์šฐ HTTPS ์„ค์ •์„ ํ•ด์•ผํ•œ๋‹ค.

๐Ÿ‘“ MSW ์™œ ์ผ์–ด์š”?

๋ฐฑ์—”๋“œ์—์„œ ๋ชจ๋“  API์™€ ๋กœ์ง๋“ค์„ ๋งˆ๋ จํ•˜๊ณ  ๋””์ž์ธ ๋˜ํ•œ ํ™•์ •๋œ ์ƒํ™ฉ์—์„œ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒŒ ํ™•์‹คํžˆ ์ด์ƒ์ ์ด๋‹ค.

๋ณ€๋™์„ฑ์ด ์ ์€ ์ƒํ™ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜ํ•˜๋‚˜ ๊ธฐ๋Šฅ์ด ํ™•์ •๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•˜์ง€๋งŒ ํ˜„์‹ค์€ ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ๋‹ค. ์‹œ๊ฐ„์€ ์ œํ•œ์ ์ด๊ณ  ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์€ ๋งŽ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐฑ์—”๋“œ API์˜ ๊ตฌํ˜„์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์† ๋†“๊ณ  ๊ธฐ๋‹ค๋ฆด ์ˆ˜๋งŒ์€ ์—†๋‹ค.

ํ”„๋ก ํŠธ์—”๋“œ์˜ ๊ธฐ๋Šฅ ์ค‘ API์— ๋Œ€ํ•œ ์˜์กด๋„๊ฐ€ ๋†’์„ ๋•Œ, ๊ทธ๋ฆฌ๊ณ  ๊ทธ API์— ๋Œ€ํ•œ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์„ ๋•Œ MSW๋Š” ๊ทธ ํž˜์„ ๋ฐœํœ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

MSW๋Š” ๋ณ‘๋ ฌ์ ์ธ ๊ฐœ๋ฐœ์„ ํšจ์œจ์ ์œผ๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ์œ ์šฉํ•œ ๋„๊ตฌ๋‹ค.

์œ„์—์„œ ์„œ๋น„์Šค ์›Œ์ปค์— ๋Œ€ํ•ด ๊ธฐ์ˆ ํ–ˆ๋“ฏ์ด MSW๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์„ค์ •ํ•œ ์ž„์˜์˜ ์‘๋‹ต ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

1. install

yarn add msw --dev

์ž์‹ ์˜ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์— ๋งž๊ฒŒ msw ํŒจํ‚ค์ง€๋ฅผ ์ธ์Šคํ†จํ•œ๋‹ค. --dev ์˜ต์…˜์€ package.json์˜ devDependencies์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์˜ต์…˜์œผ๋กœ ๊ฐœ๋ฐœ์—๋Š” ํ•„์š”ํ•˜์ง€๋งŒ ์‹ค์งˆ์ ์ธ ์ž‘๋™์—” ํ•„์š”ํ•˜์ง€ ์•Š์€ ํŒจํ‚ค์ง€๋“ค์„ ๋„ฃ๋Š”๋‹ค.

2. ์š”์ฒญ, ์‘๋‹ต handler ์„ค์ •

import { rest } from "msw";

export const handler = [
  rest.get("/contents", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(mockPosts));
  }),
  rest.post("/login", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(req.body));
  }),
  rest.post("/register", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(req.body));
  }),
];

3. Service Worker ๋“ฑ๋ก

MSW ๋˜ํ•œ ์„œ๋น„์Šค ์›Œ์ปค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋“ฑ๋ก ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผํ•œ๋‹ค.

npx msw init <PUBLIC_DIR> --save

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ CLI ๋ช…๋ น์„ ์ œ๊ณตํ•˜๋ฉฐ CRA๋กœ ์ƒ์„ฑํ•œ ํ”„๋กœ์ ํŠธ์ผ ๊ฒฝ์šฐ <PUBLIC_DIR>์— /public์„ ๋„ฃ๋Š”๋‹ค.

4. Setup, Start

// browser.js
import { setupWorker } from "msw";
import { handler } from "./handler";

export const worker = setupWorker(...handler);
// index.js
import { worker } from "./mocks/browser";

worker.start();

๋…ธ๋“œ์™€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ worker๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์กฐ๊ธˆ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. MSW DOCS์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •๋˜์ง€ ์•Š์€ ์š”์ฒญ์ด ์žˆ๋‹ค๋ฉด ๊ฒฝ๊ณ ๋ฅผ ๋‚ ๋ฆฌ๊ณ  ์„ฑ๊ณตํ•œ ์š”์ฒญ์ด ์žˆ๋‹ค๋ฉด ๊ทธ์— ๊ด€ํ•œ ๋‚ด์—ญ์„ ๋ณด์—ฌ์ค€๋‹ค.

ํ›„๊ธฐ

์›น ์›Œ์ปค๋‚˜ ์„œ๋น„์Šค ์›Œ์ปค์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ์ฒ˜์Œ ์•Œ์•˜๋‹ค. MSW๋„ ๊ฐ„๋‹จํ•œ ๋™์ž‘ ๋ฐ–์— ์ฒดํ—˜ํ•ด๋ณด์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •ํ™•ํ•œ ์ž‘๋™ ์›๋ฆฌ๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค.

๊ทธ๋ž˜๋„ ์œ ์šฉํ•œ ๋„๊ตฌ์ธ MSW์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋์œผ๋‹ˆ ์ถ”ํ›„ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋‚˜ ์‹คํ—˜์— ์จ๋ณด๋ฉฐ ์ˆ™๋ จ๋„๋ฅผ ๋†’์—ฌ์•ผ๊ฒ ๋‹ค.

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ๊ฑธ์–ด๊ฐ€๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€