๊ฐœ๋ฐœ/FRONTEND

Next, MSW ๊ทธ๋ฆฌ๊ณ  ESlint

caffhheine 2024. 8. 6. 14:33

 

๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ์—์„œ ์„ธํŒ…๋œ ESLint ์˜ค๋ฅ˜๊ฐ€ ํ™”๋ฉด์— ๋ณด์ด์ง€ ์•Š๋Š” ๋ฌธ์ œ


ํ˜„์žฌ ์ง„ํ–‰์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ•˜์—ฌ ๊ฐœ๋ฐœ์„ ์ด์–ด๋‚˜๊ฐ€๊ณ  ์žˆ๋Š”๋ฐ, ์ด์ƒํ•˜๊ฒŒ ESlint ์˜ค๋ฅ˜๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ ๋˜ ๋‹ค ์•ˆ๋ณด์ด๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ , ๋ช‡๊ฐœ๋Š” ๋ณด์ด๊ณ  ๋ช‡๊ฐœ๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ–ˆ๊ตฌ์š”.

๋˜ ํ™”๋ฉด์—๋Š” ๋‹ค ์•ˆ์žกํžˆ์ง€๋งŒ eslint ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ™•์ธํ•˜๋ฉด ๋ณด์ด์ง€ ์•Š๋˜ ์˜ค๋ฅ˜๊ฐ€ ๋‹ค ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ถ€๋ถ„์—์„œ ์ €๋Š” eslint ๊ธฐ๋Šฅ์˜ ๋ฌธ์ œ๋ผ๊ธฐ๋ณด๋‹จ IDE๋ฅผ ์˜์‹ฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ ๋ณดํ†ต IDE๋ฅผ ์˜์‹ฌํ•˜๊ฒŒ๋˜๋ฉด '๋‚ด IDE ์„ค์ •์˜ ์ž˜๋ชป'์œผ๋กœ ์ดํ•ดํ•˜์ง€, ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊นŒ์ง€ ๊ทธ๋Ÿด๊ฑฐ๋ผ๊ณ ๋Š” ์ƒ๊ฐํ•˜์ง€ ์•Š์ž–์•„์š”.

์ €๋ฅผ ๋” ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ๋งŒ๋“ค์—ˆ๋˜ ๊ฑด, ๋‹ค๋ฅธ ํŒ€์›๋“ค๋„ ESlint ์˜ค๋ฅ˜๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๊ฐ™์€ ์ฆ์ƒ์ด์—ˆ๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

๊ทธ๋ƒฅ ๋ฌด์‹œํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ณ  ์‹ถ์—ˆ์œผ๋‚˜ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€์ ์œผ๋กœ ์ ์šฉ๋˜์–ด์žˆ๋˜ husky์—์„œ lint-staged ์—์„œ ๊ณ„์† ์žก์œผ๋‹ˆ ์ปค๋ฐ‹ ์ž์ฒด๊ฐ€ ๋˜์ง€ ์•Š์•„ ํ•ด๊ฒฐํ•˜์ง€ ์•Š๊ณ ์„œ๋Š” ๋„˜์–ด๊ฐˆ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‹ค ๋ฐœ๊ฒฌํ•œ ๊ธ€์ด ํ•˜๋‚˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ์—์„œ VSCODE์˜ eslint extension์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ์˜€์Šต๋‹ˆ๋‹ค.

์ž‘์„ฑ์ž๋ถ„๊ฒŒ์„œ๋Š” turborepo๋ฅผ ์‚ฌ์šฉ์ค‘์— ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์…จ์ง€๋งŒ ๋น„๋‹จ turborepo์˜ ๋ฌธ์ œ๋งŒ์€ ์•„๋‹ˆ๊ณ  ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒช์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ผ ๊ฑฐ๋ผ๊ณ  ํ•˜์…จ๋Š”๋ฐ ๋งž์•˜์Šต๋‹ˆ๋‹ค.

์ €๋Š” pnpm์„ ํ†ตํ•ด ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ์—ˆ๊ฑฐ๋“ ์š”.

์ € ๊ธ€์ด ๊ธฐ๋‹ˆ ์š”์•ฝ์„ ํ•ด๋ณด์ž๋ฉด,

  • ๋ชจ๋…ธ๋ ˆํฌ ํ™˜๊ฒฝ์—์„œ ํŠน์ • eslint์˜ config๋ฅผ extension์— ๋„ฃ๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ @typescript-eslint/parser๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, parserOptions.project๋ฅผ ์„ค์ •ํ•ด์ค˜์•ผ ํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” VSCODE์ƒ์˜ eslint ์˜ต์…˜์—์„œ workingDirectories์˜ ๊ฐ’์„ auto๋กœ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธ€์„ ๋ณด๋ฉด์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์‚ฌ์‹ค์€, ์ด๋ถ„๊ณผ ๋‚ด๊ฐ€ ๋ชจ๋‘ airbnb ๋ฆฐํŠธ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

๋˜, airbnb ๋ฆฐํŠธ ์„ค์ •์„ ํ•˜๊ธฐ ์ „์—๋Š” eslint ์—๋Ÿฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ‘œ์‹œ๋˜์—ˆ๋‹ค๋Š” ์  (์ด๋ถ„๋„ turborepo ๊ธฐ๋ณธ๊ฐ’์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ–ˆ๋‹ค๊ณ  ํ•ด์š”)

์œ„์˜ ์ด์œ ๋ฅผ ๋ฏธ๋ฃจ์–ด๋ณด์•„ airbnb lint ์„ค์ • ๋‚ด์ง€ plugin๊ฐ„์˜ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์‹œ๊ฐ„์ด ๋˜๋ฉด ์ด๋ฅผ ๋ถ„์„ํ•ด์„œ ๊ธฐ์—ฌ๋ฅผ ์ข€ ํ•ด๋ณด๊ณ ์‹ถ์€๋ฐ.. ์ผ๋‹จ ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ์„ ๋๋‚ด๊ณ  ์ƒ๊ฐํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

MSW - Next๊ฐ„์˜ ์ถฉ๋Œ ๋ฌธ์ œ


API ๋ชจํ‚น์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์ „์— next ํ”„๋กœ์ ํŠธ์—์„œ msw ์„ธํŒ…์„ ํ•ด์ฃผ์—ˆ๋Š”๋ฐ, ์ œ ํ™˜๊ฒฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

โจฏ SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON    at JSON.parse (<anonymous>)    at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
โจฏ TypeError: Cannot read properties of null (reading 'useContext')    at t.useContext (/Users/swarvy/Repository/attraction_fe/node_modules

 

์ผ๋‹จ ์œ„์˜ ๋‚ด์šฉ๋ถ€ํ„ฐ ์„ค๋ช…์„ ๋“œ๋ฆฌ๋ฉด, ์ €ํฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” msw ์„ธํŒ…์„ server๋งŒ ์„ธํŒ…ํ•˜๊ณ  browser ์„ธํŒ…์„ ํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋Œ€์ฑ…์œผ๋กœ Next์˜ reWrite ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์ผ์ข…์˜ ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์ธ๋ฐ, ์ œ๊ฐ€ ์ƒ๊ฐํ–ˆ์„ ๋•Œ msw๋Š” ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์š”์ฒญ์„ ์ธํ„ฐ์…‰ํŠธํ•˜์—ฌ ์‘๋‹ต์„ ์ฃผ๋Š” ๊ฒƒ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ํ”„๋ก์‹œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜, ์ œ ํ™˜๊ฒฝ์—์„œ MSW๋กœ ํ–ฅํ•˜๋Š” api ์š”์ฒญ์— ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๋ฒˆ์”ฉ ๋“ค์–ด๊ฐ€๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด reWrite ๊ธฐ๋Šฅ์„ ์ง€์šฐ๊ณ  ์‹คํ–‰์„ ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

reWrite๋ฅผ ํ†ตํ•ด ์‹คํ–‰์‹œ์ผฐ์„ ๋•Œ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๊ฐ€ ์‹ถ์—ˆ๋”๋‹ˆ ์œ„์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ๊ฐ„ํ—์ ์œผ๋กœ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง์ด ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์Šˆ๋ฅผ ํ™•์ธํ•ด ๋ณธ ๊ฒฐ๊ณผ MSW์—์„œ Next app router๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜๊ณ ์žˆ์ง€ ์•Š์œผ๋ฉฐ + ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” browser worker์™€ server๋ฅผ ๋ชจ๋‘ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์•„์‰ฝ๊ฒŒ๋„ ์ €ํฌ ํ”„๋กœ์ ํŠธ๋Š” ํ•ด๋‹น ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋” ํŒŒ๋ณด๊ณ ์‹ถ์—ˆ์ง€๋งŒ ์• ์ดˆ์— MSW์—์„œ ์•„์ง App router๋ฅผ ์ •์‹์ง€์›ํ•˜์ง€ ์•Š๊ณ  ์žˆ์œผ๋ฉฐ, ์œ„์˜ ๋‘˜ ์—๋Ÿฌ๋Š” Next ์ž์ฒด์˜ ์—๋Ÿฌ์— ๊ฐ€๊นŒ์› ๊ธฐ๋•Œ๋ฌธ์— ์ €ํฌ ์ˆ˜์ค€์—์„œ๋Š” ํ•ด๊ฒฐ์ด ํž˜๋“ค๋‹ค๊ณ  ๋ณด์•˜๊ณ ,

๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์ง„ ์•Š์ง€๋งŒ, ํ”„๋กœ์ ํŠธ ์ง„ํ–‰์ค‘์ด๊ธฐ๋•Œ๋ฌธ์— msw์— ์ด ์ด์ƒ ์‹œ๊ฐ„์ด ๋“ค์–ด๊ฐ„๋‹ค๋ฉด ์•ˆ๋  ๊ฒƒ ๊ฐ™์•„ ์ผ๋‹จ ํ•ด๋‹น ๋ฌธ์ œ๋Š” ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค์Œ์— ์ฐพ์•„๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์•„๋ž˜ ์ด์Šˆ๋ฅผ ํ•™์Šตํ•œ ๋’ค ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ๋•Œ ์ ์šฉํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

next lint๋Š” ๋ชจ๋‘๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์•„


์œ„์˜ lint ๋ฌธ์ œ์™€ ์—ฐ๊ณ„๋˜๋Š” ์‚ฌํ•ญ์ด์—ˆ๋Š”๋ฐ, next lint๋ฅผ ์ฐ์—ˆ๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๊ฑธ ํ™•์ธํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  eslint ์ปค๋งจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฆฐํŠธ ์—๋Ÿฌ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๋” ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ…

next lint์˜ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ pages/, app/, components/, lib/, src/ ๋งŒ์„ ๊ฒ€์‚ฌํ•œ๋‹ค๋Š” ๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋‚ด์šฉ์„ ํ™•์ธํ•˜๊ณ  ์ปค๋งจ๋“œ๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋”๋‹ˆ ์ •์ƒ์ ์œผ๋กœ eslint๋ฅผ ํ†ตํ•ด ๋กœ์ง์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ์—์„œ ์„ธํŒ…๋œ ESLint ์˜ค๋ฅ˜๊ฐ€ ํ™”๋ฉด์— ๋ณด์ด์ง€ ์•Š๋Š” ๋ฌธ์ œ


ํ˜„์žฌ ์ง„ํ–‰์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ•˜์—ฌ ๊ฐœ๋ฐœ์„ ์ด์–ด๋‚˜๊ฐ€๊ณ  ์žˆ๋Š”๋ฐ, ์ด์ƒํ•˜๊ฒŒ ESlint ์˜ค๋ฅ˜๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ ๋˜ ๋‹ค ์•ˆ๋ณด์ด๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ , ๋ช‡๊ฐœ๋Š” ๋ณด์ด๊ณ  ๋ช‡๊ฐœ๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ–ˆ๊ตฌ์š”.

๋˜ ํ™”๋ฉด์—๋Š” ๋‹ค ์•ˆ์žกํžˆ์ง€๋งŒ eslint ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ™•์ธํ•˜๋ฉด ๋ณด์ด์ง€ ์•Š๋˜ ์˜ค๋ฅ˜๊ฐ€ ๋‹ค ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ถ€๋ถ„์—์„œ ์ €๋Š” eslint ๊ธฐ๋Šฅ์˜ ๋ฌธ์ œ๋ผ๊ธฐ๋ณด๋‹จ IDE๋ฅผ ์˜์‹ฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ ๋ณดํ†ต IDE๋ฅผ ์˜์‹ฌํ•˜๊ฒŒ๋˜๋ฉด '๋‚ด IDE ์„ค์ •์˜ ์ž˜๋ชป'์œผ๋กœ ์ดํ•ดํ•˜์ง€, ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊นŒ์ง€ ๊ทธ๋Ÿด๊ฑฐ๋ผ๊ณ ๋Š” ์ƒ๊ฐํ•˜์ง€ ์•Š์ž–์•„์š”.

์ €๋ฅผ ๋” ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ๋งŒ๋“ค์—ˆ๋˜ ๊ฑด, ๋‹ค๋ฅธ ํŒ€์›๋“ค๋„ ESlint ์˜ค๋ฅ˜๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๊ฐ™์€ ์ฆ์ƒ์ด์—ˆ๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

๊ทธ๋ƒฅ ๋ฌด์‹œํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ณ  ์‹ถ์—ˆ์œผ๋‚˜ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€์ ์œผ๋กœ ์ ์šฉ๋˜์–ด์žˆ๋˜ husky์—์„œ lint-staged ์—์„œ ๊ณ„์† ์žก์œผ๋‹ˆ ์ปค๋ฐ‹ ์ž์ฒด๊ฐ€ ๋˜์ง€ ์•Š์•„ ํ•ด๊ฒฐํ•˜์ง€ ์•Š๊ณ ์„œ๋Š” ๋„˜์–ด๊ฐˆ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‹ค ๋ฐœ๊ฒฌํ•œ ๊ธ€์ด ํ•˜๋‚˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ์—์„œ VSCODE์˜ eslint extension์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ์˜€์Šต๋‹ˆ๋‹ค.

์ž‘์„ฑ์ž๋ถ„๊ฒŒ์„œ๋Š” turborepo๋ฅผ ์‚ฌ์šฉ์ค‘์— ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์…จ์ง€๋งŒ ๋น„๋‹จ turborepo์˜ ๋ฌธ์ œ๋งŒ์€ ์•„๋‹ˆ๊ณ  ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒช์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ผ ๊ฑฐ๋ผ๊ณ  ํ•˜์…จ๋Š”๋ฐ ๋งž์•˜์Šต๋‹ˆ๋‹ค.

์ €๋Š” pnpm์„ ํ†ตํ•ด ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ์—ˆ๊ฑฐ๋“ ์š”.

์ € ๊ธ€์ด ๊ธฐ๋‹ˆ ์š”์•ฝ์„ ํ•ด๋ณด์ž๋ฉด,

  • ๋ชจ๋…ธ๋ ˆํฌ ํ™˜๊ฒฝ์—์„œ ํŠน์ • eslint์˜ config๋ฅผ extension์— ๋„ฃ๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ @typescript-eslint/parser๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, parserOptions.project๋ฅผ ์„ค์ •ํ•ด์ค˜์•ผ ํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” VSCODE์ƒ์˜ eslint ์˜ต์…˜์—์„œ workingDirectories์˜ ๊ฐ’์„ auto๋กœ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธ€์„ ๋ณด๋ฉด์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์‚ฌ์‹ค์€, ์ด๋ถ„๊ณผ ๋‚ด๊ฐ€ ๋ชจ๋‘ airbnb ๋ฆฐํŠธ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

๋˜, airbnb ๋ฆฐํŠธ ์„ค์ •์„ ํ•˜๊ธฐ ์ „์—๋Š” eslint ์—๋Ÿฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ‘œ์‹œ๋˜์—ˆ๋‹ค๋Š” ์  (์ด๋ถ„๋„ turborepo ๊ธฐ๋ณธ๊ฐ’์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ–ˆ๋‹ค๊ณ  ํ•ด์š”)

์œ„์˜ ์ด์œ ๋ฅผ ๋ฏธ๋ฃจ์–ด๋ณด์•„ airbnb lint ์„ค์ • ๋‚ด์ง€ plugin๊ฐ„์˜ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์‹œ๊ฐ„์ด ๋˜๋ฉด ์ด๋ฅผ ๋ถ„์„ํ•ด์„œ ๊ธฐ์—ฌ๋ฅผ ์ข€ ํ•ด๋ณด๊ณ ์‹ถ์€๋ฐ.. ์ผ๋‹จ ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ์„ ๋๋‚ด๊ณ  ์ƒ๊ฐํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

MSW - Next๊ฐ„์˜ ์ถฉ๋Œ ๋ฌธ์ œ


API ๋ชจํ‚น์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์ „์— next ํ”„๋กœ์ ํŠธ์—์„œ msw ์„ธํŒ…์„ ํ•ด์ฃผ์—ˆ๋Š”๋ฐ, ์ œ ํ™˜๊ฒฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

โจฏ SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON    at JSON.parse (<anonymous>)    at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
โจฏ TypeError: Cannot read properties of null (reading 'useContext')    at t.useContext (/Users/swarvy/Repository/attraction_fe/node_modules

 

์ผ๋‹จ ์œ„์˜ ๋‚ด์šฉ๋ถ€ํ„ฐ ์„ค๋ช…์„ ๋“œ๋ฆฌ๋ฉด, ์ €ํฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” msw ์„ธํŒ…์„ server๋งŒ ์„ธํŒ…ํ•˜๊ณ  browser ์„ธํŒ…์„ ํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋Œ€์ฑ…์œผ๋กœ Next์˜ reWrite ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์ผ์ข…์˜ ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์ธ๋ฐ, ์ œ๊ฐ€ ์ƒ๊ฐํ–ˆ์„ ๋•Œ msw๋Š” ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์š”์ฒญ์„ ์ธํ„ฐ์…‰ํŠธํ•˜์—ฌ ์‘๋‹ต์„ ์ฃผ๋Š” ๊ฒƒ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ํ”„๋ก์‹œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜, ์ œ ํ™˜๊ฒฝ์—์„œ MSW๋กœ ํ–ฅํ•˜๋Š” api ์š”์ฒญ์— ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๋ฒˆ์”ฉ ๋“ค์–ด๊ฐ€๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด reWrite ๊ธฐ๋Šฅ์„ ์ง€์šฐ๊ณ  ์‹คํ–‰์„ ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

reWrite๋ฅผ ํ†ตํ•ด ์‹คํ–‰์‹œ์ผฐ์„ ๋•Œ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๊ฐ€ ์‹ถ์—ˆ๋”๋‹ˆ ์œ„์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ๊ฐ„ํ—์ ์œผ๋กœ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง์ด ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์Šˆ๋ฅผ ํ™•์ธํ•ด ๋ณธ ๊ฒฐ๊ณผ MSW์—์„œ Next app router๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜๊ณ ์žˆ์ง€ ์•Š์œผ๋ฉฐ + ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” browser worker์™€ server๋ฅผ ๋ชจ๋‘ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์•„์‰ฝ๊ฒŒ๋„ ์ €ํฌ ํ”„๋กœ์ ํŠธ๋Š” ํ•ด๋‹น ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋” ํŒŒ๋ณด๊ณ ์‹ถ์—ˆ์ง€๋งŒ ์• ์ดˆ์— MSW์—์„œ ์•„์ง App router๋ฅผ ์ •์‹์ง€์›ํ•˜์ง€ ์•Š๊ณ  ์žˆ์œผ๋ฉฐ, ์œ„์˜ ๋‘˜ ์—๋Ÿฌ๋Š” Next ์ž์ฒด์˜ ์—๋Ÿฌ์— ๊ฐ€๊นŒ์› ๊ธฐ๋•Œ๋ฌธ์— ์ €ํฌ ์ˆ˜์ค€์—์„œ๋Š” ํ•ด๊ฒฐ์ด ํž˜๋“ค๋‹ค๊ณ  ๋ณด์•˜๊ณ ,

๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์ง„ ์•Š์ง€๋งŒ, ํ”„๋กœ์ ํŠธ ์ง„ํ–‰์ค‘์ด๊ธฐ๋•Œ๋ฌธ์— msw์— ์ด ์ด์ƒ ์‹œ๊ฐ„์ด ๋“ค์–ด๊ฐ„๋‹ค๋ฉด ์•ˆ๋  ๊ฒƒ ๊ฐ™์•„ ์ผ๋‹จ ํ•ด๋‹น ๋ฌธ์ œ๋Š” ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค์Œ์— ์ฐพ์•„๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์•„๋ž˜ ์ด์Šˆ๋ฅผ ํ•™์Šตํ•œ ๋’ค ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ๋•Œ ์ ์šฉํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

next lint๋Š” ๋ชจ๋‘๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์•„


 

์œ„์˜ lint ๋ฌธ์ œ์™€ ์—ฐ๊ณ„๋˜๋Š” ์‚ฌํ•ญ์ด์—ˆ๋Š”๋ฐ, next lint๋ฅผ ์ฐ์—ˆ๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๊ฑธ ํ™•์ธํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  eslint ์ปค๋งจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฆฐํŠธ ์—๋Ÿฌ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๋” ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ…

next lint์˜ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ pages/, app/, components/, lib/, src/ ๋งŒ์„ ๊ฒ€์‚ฌํ•œ๋‹ค๋Š” ๊ฒƒ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋‚ด์šฉ์„ ํ™•์ธํ•˜๊ณ  ์ปค๋งจ๋“œ๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋”๋‹ˆ ์ •์ƒ์ ์œผ๋กœ eslint๋ฅผ ํ†ตํ•ด ๋กœ์ง์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.