๐Ÿ› ๏ธ Yup ์™„์ „ ์ •๋ณตํ•˜๊ธฐ โ€” (Zod์™€์˜ ๋น„๊ต๊นŒ์ง€!)

์†ก์—ฐ์ง€ยท2025๋…„ 4์›” 29์ผ
1

๐Ÿ‘‹ ์‹œ์ž‘ํ•˜๋ฉฐ

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ํ”„๋กœํ•„ ์ˆ˜์ • ๊ฐ™์€ ํ™”๋ฉด์„ ์ •๋ง ๋งŽ์ด ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋งค๋ฒˆ ๋ฐ˜๋ณตํ•ด์„œ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์ฃ .

โ“ "์ด ์ž…๋ ฅ๊ฐ’์€ ํ•„์ˆ˜์ธ๊ฐ€์š”?"

โ“ "๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 8์ž ์ด์ƒ์ด์–ด์•ผ ํ•˜๋‚˜์š”?"

โ“ "์ด๋ฉ”์ผ ํ˜•์‹์ด ๋งž๋Š”์ง€ ์–ด๋–ป๊ฒŒ ํ™•์ธํ•˜์ฃ ?"

์ด๋Ÿฐ ๊ณ ๋ฏผ์„ ๋œ์–ด์ฃผ๊ณ , ๊ฐœ๋ฐœ์„ ํ›จ์”ฌ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ”๋กœ Yup ์ž…๋‹ˆ๋‹ค!

(๋ฌผ๋ก  ์š”์ฆ˜์€ Zod ๊ฐ™์€ ๋‹ค๋ฅธ ๋Œ€์•ˆ๋„ ์žˆ์–ด์„œ, ์˜ค๋Š˜์€ ๋น„๊ต๋„ ํ•จ๊ป˜ ํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.)


โœจ Yup์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Yup์€ ์Šคํ‚ค๋งˆ(Schema)๋ฅผ ์ •์˜ํ•ด์„œ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

  • ์Šคํ‚ค๋งˆ = "์ด ๋ฐ์ดํ„ฐ๋Š” ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์–ด์•ผ ํ•œ๋‹ค"๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค.
  • Yup์€ ์ด ๊ทœ์น™์— ๋งž๋Š”์ง€ ํ™•์ธํ•ด์ฃผ๊ณ , ํ‹€๋ฆฌ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠนํžˆ Form(์ž…๋ ฅ ํผ)๊ณผ ํ•จ๊ป˜ ์“ฐ๋ฉด ์ •๋ง ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ๋Ÿฐํƒ€์ž„ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.


๐Ÿ“š Yup ๊ธฐ๋ณธ ์‚ฌ์šฉ ์˜ˆ์‹œ


import * as yup from 'yup';

const loginSchema = yup.object({
  loginId: yup
    .string()
    .required('์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.')
    .matches(/^[a-zA-Z0-9]{5,20}$/, '5~20์ž์˜ ์˜๋ฌธ ๋˜๋Š” ์ˆซ์ž ์กฐํ•ฉ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.'),
  userPw: yup
    .string()
    .required('๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.')
    .matches(
      /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()\-_=+{};:,<.>]).{8,}$/,
      '์˜๋ฌธ ๋Œ€์†Œ๋ฌธ์ž, ์ˆซ์ž, ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ํฌํ•จํ•ด 8์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'
    ),
});
  • object()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์Šคํ‚ค๋งˆ๋ฅผ ๋งŒ๋“ค๊ณ ,
  • ๊ฐ ํ•„๋“œ์— ๋Œ€ํ•ด .string(), .required(), .matches() ๋“ฑ ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ๊ฒ€์ฆ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํผ์„ ์ž‘์„ฑํ•  ๋•Œ Yup๊ณผ ํ•จ๊ป˜ ํ•˜๋ฉด, ๊ฒ€์ฆ์ด ์ •๋ง ๊น”๋”ํ•˜๊ฒŒ ๋๋‚ฉ๋‹ˆ๋‹ค.


๐ŸŽฏ Yup์˜ ์žฅ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

์žฅ์ ์„ค๋ช…
๋ฐฐ์šฐ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค๋‹จ์ˆœํ•œ ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฌธ๋ฒ•์ด ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.
Form ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ฐฐ๋–ก์ž…๋‹ˆ๋‹คReact Hook Form, Formik ๋“ฑ๊ณผ ์‰ฝ๊ฒŒ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์‰ฝ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค์œ ์ €์—๊ฒŒ ์นœ์ ˆํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์–‘ํ•œ ํƒ€์ž… ์ง€์›๋ฌธ์ž์—ด, ์ˆซ์ž, ๋‚ ์งœ, ๋ฐฐ์—ด, ๊ฐ์ฒด ๋“ฑ ๊ฑฐ์˜ ๋ชจ๋“  ํƒ€์ž…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
๋น„๋™๊ธฐ ๊ฒ€์ฆ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ๊ฒ€์ฆ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ๊ทธ๋ ‡๋‹ค๋ฉด Zod๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

Zod๋Š” ์ตœ๊ทผ ์ฃผ๋ชฉ๋ฐ›๊ณ  ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

Zod๋Š” ํŠนํžˆ TypeScript์™€์˜ ๊ถํ•ฉ์ด ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค.

Zod ํŠน์ง•์„ ๊ฐ„๋‹จํžˆ ์š”์•ฝํ•˜๋ฉด:

  • ์Šคํ‚ค๋งˆ๋กœ ํƒ€์ž…์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (z.infer<typeof schema>)
  • ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ + ํƒ€์ž… ๋ณด์žฅ๊นŒ์ง€ ๋™์‹œ์— ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Yup๋ณด๋‹ค ์‚ด์ง ๋” ์ตœ์‹ ์Šค๋Ÿฝ๊ณ  ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ†š Yup vs Zod ๋น„๊ต ์ •๋ฆฌ

ํ•ญ๋ชฉYupZod
๋Ÿฐ์นญ ์‹œ๊ธฐ2017๋…„ (์˜ค๋ž˜๋จ)2020๋…„ (์‹ ์„ธ๋Œ€)
์ฃผ์š” ํŠน์ง•๊ฒ€์ฆ ์ค‘์‹ฌํƒ€์ž…๊ณผ ๊ฒ€์ฆ ๋™์‹œ ์ง€์›
TypeScript ์ง€์›์•ฝ๊ฐ„ ์•„์‰ฌ์›€ (ํƒ€์ž… ์ถ”๋ก  ๋ถˆํŽธ)์•„์ฃผ ๊ฐ•๋ ฅํ•จ (ํƒ€์ž… ์ถ”๋ก  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ)
Form ์—ฐ๋™์•„์ฃผ ์‰ฌ์›€ (Formik, React Hook Form ๋“ฑ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ)์ตœ๊ทผ ์—ฐ๋™ ์ง€์› ๊ฐ•ํ™”
์—๋Ÿฌ ๋ฉ”์‹œ์ง€์ปค์Šคํ„ฐ๋งˆ์ด์ง• ์ž์œ ๋กœ์›€๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฝ”๋“œ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์Œ
ํ•™์Šต ๋‚œ์ด๋„๋” ์‰ฌ์›€์•ฝ๊ฐ„ ์ง„์ž…์žฅ๋ฒฝ ์žˆ์Œ
์•ˆ์ •์„ฑ๋งค์šฐ ๊ฒ€์ฆ๋จ (์ˆ˜๋…„๊ฐ„ ์‚ฌ์šฉ)๊ธ‰์„ฑ์žฅ ์ค‘์ด์ง€๋งŒ ์•ฝ๊ฐ„์˜ ๋ณ€ํ™” ์žˆ์Œ

์ •๋ฆฌ

  • ๋งŒ์•ฝ Form๊ณผ ํ•จ๊ป˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋งŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Yup์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ ํƒ€์ž…๊นŒ์ง€ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด์žฅ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด Zod๋„ ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์™œ Yup์„ ์ผ์„๊นŒ์š”?

์ œ๊ฐ€ Yup์„ ์„ ํƒํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๋น ๋ฅธ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค

    ํผ ๊ฒ€์ฆ์— ํ•„์š”ํ•œ ๊ทœ์น™๋“ค์„ ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋„ ๋”ฐ๋กœ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

  2. Form ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€์˜ ์—ฐ๋™์ด ์‰ฌ์› ์Šต๋‹ˆ๋‹ค

    ํŠนํžˆ React Hook Form๊ณผ ์‚ฌ์šฉํ•  ๋•Œ resolver ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋์ด์—ˆ์Šต๋‹ˆ๋‹ค.

  3. ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ์‰ฌ์› ์Šต๋‹ˆ๋‹ค

    ํ•œ๊ธ€ ๋ฉ”์‹œ์ง€ ์„ค์ •, ๋™์  ๊ฒ€์ฆ ์กฐ๊ฑด ์ถ”๊ฐ€ ๋“ฑ ๋ชจ๋“  ๋ถ€๋ถ„์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


๐Ÿ“ฆ ๊ฒฐ๋ก 

  • โœ… ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฅธ ํผ ๊ฒ€์ฆ โ†’ Yup ์ถ”์ฒœ
  • โœ… ๋Ÿฐํƒ€์ž„ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ + ํƒ€์ž… ๋ณด์žฅ โ†’ Zod ๊ณ ๋ ค
  • โœ… Form ์ค‘์‹ฌ ํ”„๋กœ์ ํŠธ โ†’ Yup ์‚ฌ์šฉํ•ด๋„ ์ถฉ๋ถ„ํžˆ ์ข‹์Šต๋‹ˆ๋‹ค.

ํผ ๊ฒ€์ฆ์ด ๋ฒˆ๊ฑฐ๋กœ์šฐ์…จ๋˜ ๋ถ„๋“ค์ด๋ผ๋ฉด, ํ•œ ๋ฒˆ Yup์„ ์จ๋ณด์‹œ๊ธธ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

string(), number(), required() ๋งŒ ์•Œ์•„๋„ 80%๋Š” ๋๋‚ผ ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ์š”.


๐Ÿ™Œ ๋งˆ์น˜๋ฉฐ

"๊ฒ€์ฆ์€ ๊ท€์ฐฎ์ง€๋งŒ, ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."

Yup์€ ์ด ๊ท€์ฐฎ์Œ์„ ์ฆ๊ฑฐ์šด ๊ฐœ๋ฐœ๋กœ ๋ฐ”๊ฟ”์ค„ ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์Ÿˆ!!

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