๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“‚ Project/์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค

[์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค] ์šฐํ…Œ์ฝ” ํ”„๋ฆฌ์ฝ”์Šค 6๊ธฐ 1์ฃผ์ฐจ ์ˆซ์ž ์•ผ๊ตฌ ๋ฏธ์…˜ ํšŒ๊ณ 

by Dev. Ella 2023. 10. 25.
๊ฐœ์ธ์ ์œผ๋กœ๋Š” ๋ฏธ์…˜ ์ˆ˜ํ–‰์„ ํ†ตํ•ด ์„ฑ์žฅํ•œ ๊ณผ์ •์„ ๊ธฐ๋กํ•˜๊ณ ,
๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ๋Š” ์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋งˆ์Œ์ž…๋‹ˆ๋‹ค :)

 

๐Ÿ› ๏ธ 1์ฃผ ์ฐจ ๊ฒฐ๊ณผ๋ฌผ

1์ฃผ ์ฐจ ๋ฏธ์…˜: ์ˆซ์ž ๊ฒŒ์ž„ ์•ผ๊ตฌ PR

๊ฒŒ์ž„ ์‹คํ–‰ ํ™”๋ฉด๊ณผ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™”๋ฉด

 

 

๐Ÿ“ฎ 1์ฃผ ์ฐจ ๋ฏธ์…˜ ๋ฉ”์ผ ๋‚ด์šฉ

1๏ธโƒฃ ๊ฐ€๋ฒผ์šด ๋ฏธ์…˜..?

1์ฃผ ์ฐจ ๋ฏธ์…˜์ธ '์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„'์„ ๋ณด๊ณ  ๋ฐ˜๊ฐ€์› ๋‹ค. ์ง€๋‚œ ๊ธฐ์ˆ˜๋“ค์—์„œ ์ž์ฃผ ๋‚˜์™”๋˜ ๋ฏธ์…˜์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (ํ•„์ž๋Š” 6๊ธฐ์— ์ง€์›ํ–ˆ๊ณ ) ์ง€๋‚œ 5๊ธฐ์—์„œ๋Š” 2์ฃผ ์ฐจ ๋ฏธ์…˜์ด์—ˆ๋Š”๋ฐ ์ด๋ฒˆ์—” 1์ฃผ ์ฐจ์— ๋ฐฐ์ •๋ผ์„œ ์˜ค์ž‰? ํ–ˆ๋‹ค. ์•„๋งˆ ์ง€๋‚œ ๊ธฐ์ˆ˜ 1์ฃผ ์ฐจ '์˜จ๋ณด๋”ฉ' ๋ฏธ์…˜์ด ๊ธฐ๋Šฅ ๊ตฌํ˜„๋ณด๋‹ค๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ ํ’€์ด์— ๊ฐ€๊นŒ์›Œ์„œ ๊ทธ๋Ÿฐ ๊ฒŒ ์•„๋‹๊นŒ? ํ•˜๋Š” ์ถ”์ธก์„ ํ•ด๋ณด์•˜๋‹ค.

 

์ฒซ ๋ฉ”์ผ ๋‚ด์šฉ์— ์˜ํ•˜๋ฉด, ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ธํŒ…๊ณผ Git ๋“ฑ ๋ฏธ์…˜ ์™ธ์—๋„ ์ถ”๊ฐ€๋กœ ์ตํ˜€์•ผ ํ•˜๋Š” ๋ถ€๋ถ„๋“ค์ด ์žˆ์–ด '๊ฐ€๋ฒผ์šด ๋ฏธ์…˜'์œผ๋กœ ์ค€๋น„ํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ •๋ง ๊ฐ€๋ฒผ์šธ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ์•ฝ ์ผ์ฃผ์ผ์ด๋ผ๋Š” ์‹œ๊ฐ„์ด ์ฃผ์–ด์ง„ ๋งŒํผ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ผผ๊ผผํ•˜๊ฒŒ ํ•ด ๋ณด์ž!

 

2๏ธโƒฃ ์‹ ๊ฒฝ ์จ์•ผ ํ•˜๋Š” ๊ฒƒ๋“ค

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

 

 

โœˆ๏ธ ํ”„๋ฆฌ์ฝ”์Šค ์ง„ํ–‰ ๋ฐฉ์‹

1๏ธโƒฃ ๋ฏธ์…˜ ์ง„ํ–‰

ํ”„๋ฆฌ์ฝ”์Šค 1์ฃผ ์ฐจ ๋ฏธ์…˜์˜ ์ €์žฅ์†Œ์—์„œ ์ž์‹ ์˜ ๊นƒํ—™์— fork ํ›„ clone ํ•˜์—ฌ ์ง„ํ–‰ํ•œ๋‹ค. ์‹œ์ž‘๋ถ€ํ„ฐ git์— ๋Œ€ํ•œ ๊ธฐ์ดˆ์ ์ธ ์ดํ•ด๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ git ์ •๋„๋Š” ์ž์œ ์ž์žฌ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋ฏธ๋ฆฌ ์ต์ˆ™ํ•ด์ง„๋‹ค๋ฉด ๋ฏธ์…˜ ์ง„ํ–‰ ๋™์•ˆ ์–ด์ด์—†๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค. (๋ฌผ๋ก  ์šฐํ…Œ์ฝ” ์ธก์—์„œ ์ œ๊ณตํ•œ ์ด ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค.) ๋‚˜๋Š” ์–ด๋Š ์ •๋„ git์— ๋Œ€ํ•ด์„œ๋Š” ์ต์ˆ™ํ•ด์ง„ ํ„ฐ๋ผ, ์ตœ๋Œ€ํ•œ ๊น”๋”ํ•˜๊ณ  ์ง๊ด€์ ์œผ๋กœ ์ปค๋ฐ‹ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ–ˆ๋‹ค.

 

2๏ธโƒฃ ๋ฏธ์…˜ ๊ตฌ์„ฑ

๋งค์ฃผ ๋ฏธ์…˜์€ (1) ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ, (2) ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ, (3) ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ ์„ธ ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹จ์ˆœํžˆ ๊ธฐ๋Šฅ ๊ตฌํ˜„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „ํ›„๋กœ ์š”๊ตฌํ•˜๋Š” ์‚ฌํ•ญ๋“ค์„ ๊ผผ๊ผผํžˆ ํ™•์ธํ•˜์—ฌ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ฒ ๋‹ค. ์‹ค์ œ๋กœ ํ”„๋ฆฌ์ฝ”์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด๋Ÿฌํ•œ ์š”๊ตฌ์‚ฌํ•ญ๋“ค์„ ๊ผผ๊ผผํ•˜๊ฒŒ ํ™•์ธํ•˜์ง€ ์•Š๊ณ  ์งˆ๋ฌธ์„ ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋งŽ์•„์„œ ๋†€๋ž๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ง€ํ‚ค์ง€ ์•Š์•„์„œ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋Š” ๋ฌผ๋ก  ์ œ์ถœ ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ๋˜ ์‚ฌ๋žŒ๋“ค๋„ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ด๋Ÿฐ ๊ฒƒ๋“ค์€ ๊ฐ์ž๊ฐ€ ์•Œ์•„์„œ ๊ผผ๊ผผํ•˜๊ฒŒ ์ฑ™๊ธฐ์‹œ๊ธธ!

 

3๏ธโƒฃ ๋ฏธ์…˜ ๋งˆ๊ฐ ๋ฐ ๊ธฐ์ค€

๋ฏธ์…˜ ์ง„ํ–‰ ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„์€ ์•ฝ ์ผ์ฃผ์ผ, ๊ทธ๋ฆฌ๊ณ  ๋ฏธ์…˜ ์ œ์ถœ ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„์€ ๋ฐ˜๋‚˜์ ˆ ์ •๋„์˜ ์‹œ๊ฐ„์ด ์ฃผ์–ด์ง„๋‹ค. ์ผ๋‹จ ๋ณธ์ธ Github์— commit์„ ํ•ด๋‘๊ณ , ๋ฏธ์…˜ ์ œ์ถœ ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„ ๋™์•ˆ push & PR์„ ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค. (๋ฌผ๋ก  ๋ฏธ์…˜ ์ œ์ถœ ๊ธฐ๊ฐ„์ด ์•„๋‹ˆ๋”๋ผ๋„ push๋Š” ํ•ด๋„ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค.) ๋ฌผ๋ก , ๋งˆ๊ฐ์ผ ์ดํ›„ ์ถ”๊ฐ€ push๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฌผ๋ก  ๋ฆฌํŒฉํ† ๋ง์€ ์ž์œ ์ž์žฌ๊ฒ ์ง€๋งŒ, ๊ทธ๋ณด๋‹ค 1์ฃผ ์ฐจ ๋ฏธ์…˜์„ ๋ณต์Šตํ•˜๊ณ  ๋‹ค์Œ ๋ฏธ์…˜์„ ํ•˜๋Š๋ผ ์ •์‹ ์ด ์—†์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

 

๐Ÿคผ‍โ™‚๏ธ ํ”„๋ฆฌ์ฝ”์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ

1๏ธโƒฃ ํ”„๋ฆฌ์ฝ”์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ๋ž€?

ํ”„๋ฆฌ์ฝ”์Šค์—์„œ๋Š” 4์ฒœ ์—ฌ ๋ช…์— ๋‹ฌํ•˜๋Š” ์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค ์ง€์›์ž๋“ค์ด ํ•จ๊ป˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋‚ด์—์„œ ํ•™์Šตํ•˜๊ณ  ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ๋””์Šค์ฝ”๋“œ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๊ถŒ์žฅํ•˜๋Š” ํ™œ๋™์€ ์„œ๋กœ ๋ฆฌ๋ทฐํ•˜๊ธฐ(์ฝ”๋“œ ๋ฆฌ๋ทฐ), ํ† ๋ก ํ•˜๊ธฐ, ํ•จ๊ป˜ ๋‚˜๋ˆ„๊ธฐ(์ •๋ณด ๊ณต์œ ), ๋‹ค์‹œ ๋Œ์•„๋ณด๊ธฐ(ํšŒ๊ณ )์ด๋ฉฐ ์ด ํ™œ๋™์ด ์•„๋‹ˆ๋”๋ผ๋„ ํ•จ๊ป˜ ํ•™์Šตํ•˜๊ณ  ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํ„ฐ๋”” ๊ฐœ์„ค ๋“ฑ ๋ฌด์—‡์ด๋“  ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

 

2๏ธโƒฃ ์ฐธ๊ณ ํ•  ์‚ฌํ•ญ

๋‹จ, ๊ฐ์ž ์Šค์Šค๋กœ ํ•™์Šตํ•  ๊ธฐํšŒ๋ฅผ ์œ„ํ•ด ์•„์ง ๋งˆ๊ฐ๋˜์ง€ ์•Š์€ ๋ฏธ์…˜์— ๊ด€๋ จ๋œ ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์€ ๋งˆ๊ฐ์ผ ์ดํ›„๋กœ ๊ณต์œ ํ•˜๋Š” ๊ฒŒ ์•”๋ฌต์  ์›์น™์ด๋‹ค. ๋ฌผ๋ก  ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™ ๊ธฐ๋ก์€ ์ตœ์ข… ํ•ฉ๊ฒฉ์— ์ „ํ˜€ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์šฐํ…Œ์ฝ” ์ธก์—์„œ ์ž…ํ•™์„ค๋ช…ํšŒ ๋“ฑ์„ ํ†ตํ•ด ๊ณต์‹์ ์œผ๋กœ ์ด์•ผ๊ธฐํ–ˆ๋‹ค. ์‹ฌ์ง€์–ด ๋””์Šค์ฝ”๋“œ ์ฑ„๋„์— ๋“ค์–ด์˜ค์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

3๏ธโƒฃ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ฒซ์ธ์ƒ

๋””์Šค์ฝ”๋“œ์— ์ ‘์†ํ–ˆ๋Š”๋ฐ ํ”„๋ฆฌ์ฝ”์Šค ์‹œ์ž‘ ์ „๋ถ€ํ„ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™์ด ์—„์ฒญ ํ™œ๋ฐœํ•ด์„œ ๋†€๋ž๋‹ค. ๋‹ค๋“ค ์—ด์ •์ด ๋Œ€๋‹จํ•˜๋‹ค๊ณ  ๋Š๊ผˆ์ง€๋งŒ, ๋ฏธ์…˜์„ ์Šค์Šค๋กœ ํ•˜๋Š”๋ฐ์— ์‚ด์ง ๋…ธ์ด์ฆˆ๊ฐ€ ๋˜๋Š” ๋ฉด๋„ ์—†์ง€ ์•Š์•„ ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค. ํ•จ๊ป˜ ๋ฆฌ๋ทฐํ•˜๊ณ  ํ† ๋ก ํ•˜๋Š” ๊ฒƒ๋„ ํ”„๋ฆฌ์ฝ”์Šค์—์„œ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋Š” ํ˜œํƒ์ด๊ธฐ ๋•Œ๋ฌธ.

 

 

๐Ÿคš ๋ฏธ์…˜์— ์•ž์„œ,

1๏ธโƒฃ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋งŒ๋“ค๊ธฐ

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

 

2๏ธโƒฃ ์ œ์ถœ ์ „ ํ…Œ์ŠคํŠธ ํ•„์ˆ˜

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

 

3๏ธโƒฃ Node ๋ฒ„์ „ ํ™•์ธ ํ•„์ˆ˜

ํ…Œ์ŠคํŠธ ํŒจํ‚ค์ง€ ์„ค์น˜๋ฅผ ์œ„ํ•ด Node.js ๋ฒ„์ „ 18.17.1 ์ด์ƒ์ด ํ•„์š”ํ•˜๋‹ค. ๋ณธ์ธ ๋กœ์ปฌ์˜ Node ๋ฒ„์ „์ด ๋ช‡์ธ์ง€ ๊ผญ ํ™•์ธ ํ›„ ๋ฏธ์…˜์„ ์ง„ํ–‰ํ•˜์ž. ์ฐธ๊ณ ๋กœ Node ๋ฒ„์ „ ํ™•์ธ์€ 'node --version'์œผ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์—…๋ฐ์ดํŠธ๋Š” Node.js ๊ณต์‹ ์‚ฌ์ดํŠธ๋ฅผ ์ฐธ๊ณ ํ•˜๊ฑฐ๋‚˜, ์•„๋ž˜์™€ ๊ฐ™์ด 'nvm install'๋กœ ํŠน์ • Node ๋ฒ„์ „์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Node ๋ฒ„์ „ ์„ค์ • ํ™”๋ฉด

 

โšพ๏ธ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ

1๏ธโƒฃ ์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„ ์„ค๋ช…

๋ฏธ์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์šฐํ…Œ์ฝ” ํ”„๋ฆฌ์ฝ”์Šค ๋ ˆํฌ์— ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜๊ธธ ๋ฐ”๋ผ๋ฉฐ, ๊ฐ„๋‹จํžˆ ๊ฒŒ์ž„ ์„ค๋ช…์„ ํ•˜์ž๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ 1๋ถ€ํ„ฐ 9๊นŒ์ง€ ์„œ๋กœ ๋‹ค๋ฅธ ์ˆ˜๋กœ ์ด๋ฃจ์–ด์ง„ 3์ž๋ฆฌ์˜ ์ˆ˜๋ฅผ ๋งžํžˆ๋Š” ๊ฒŒ์ž„์ด๋‹ค.

 

๊ฐ™์€ ์ˆ˜๊ฐ€ ๊ฐ™์€ ์ž๋ฆฌ์— ์žˆ์œผ๋ฉด ์ŠคํŠธ๋ผ์ดํฌ, ๋‹ค๋ฅธ ์ž๋ฆฌ์— ์žˆ์œผ๋ฉด ๋ณผ, ๊ฐ™์€ ์ˆ˜๊ฐ€ ์ „ํ˜€ ์—†์œผ๋ฉด ๋‚ซ์‹ฑ์ด๋ž€ ํžŒํŠธ๋ฅผ ์–ป๊ณ , ๊ทธ ํžŒํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๋จผ์ € ์ƒ๋Œ€๋ฐฉ(์ปดํ“จํ„ฐ)์˜ ์ˆ˜๋ฅผ ๋งž์ถ”๋ฉด ์Šน๋ฆฌํ•œ๋‹ค. ์ฆ‰, ์ œ์‹œํ•œ ์ˆซ์ž์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ ๊ณจ์ž์ธ ๋“ฏํ•˜๋‹ค.

 

2๏ธโƒฃ ์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„ ์˜ˆ์‹œ

์˜ˆ) ์ƒ๋Œ€๋ฐฉ(์ปดํ“จํ„ฐ)์˜ ์ˆ˜๊ฐ€ 425์ผ ๋•Œ
123์„ ์ œ์‹œํ•œ ๊ฒฝ์šฐ → 1 ์ŠคํŠธ๋ผ์ดํฌ
456์„ ์ œ์‹œํ•œ ๊ฒฝ์šฐ → 1 ๋ณผ 1 ์ŠคํŠธ๋ผ์ดํฌ
789๋ฅผ ์ œ์‹œํ•œ ๊ฒฝ์šฐ → ๋‚ซ์‹ฑ

 

์œ„ ์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„์—์„œ ์ƒ๋Œ€๋ฐฉ์˜ ์—ญํ• ์„ ์ปดํ“จํ„ฐ๊ฐ€ ํ•œ๋‹ค. ์ปดํ“จํ„ฐ๋Š” 1์—์„œ 9๊นŒ์ง€ ์„œ๋กœ ๋‹ค๋ฅธ ์ž„์˜์˜ ์ˆ˜ 3๊ฐœ๋ฅผ ์„ ํƒํ•œ๋‹ค. ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด์–ด๋Š” ์ปดํ“จํ„ฐ๊ฐ€ ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ 3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ์ปดํ“จํ„ฐ๋Š” ์ž…๋ ฅํ•œ ์ˆซ์ž์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

 

์ด ๊ฐ™์€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด ์ปดํ“จํ„ฐ๊ฐ€ ์„ ํƒํ•œ 3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋งžํžˆ๋ฉด ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ → ์ปดํ“จํ„ฐ๊ฐ€ ์ƒ์„ฑํ–ˆ๋˜ 3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋งžํžˆ๊ฑฐ๋‚˜ / ๋งžํžˆ์ง€ ์•Š์•˜์„ ๋•Œ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ๊ฒฐ๊ณผ๊ฐ€ ํ•‘ํํ•‘ํ ์ž˜ ๋‚˜์˜ค๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

 

๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ ํ›„ ๊ฒŒ์ž„์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ์™„์ „ํžˆ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ throw๋ฌธ์„ ์‚ฌ์šฉํ•ด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ ํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ˆ์ƒ๋˜๋Š” ๊ฐ’ ์™ธ์˜ ๊ฐ’์„ ์ž…๋ ฅํ–ˆ์„ ๊ฒฝ์šฐ ๊ผผ๊ผผํ•˜๊ฒŒ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๊นŒ์ง€ ๊ผญ ํ•ด์ฃผ์–ด์•ผ๊ฒ ๋‹ค.

 

 

๐Ÿšจ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - ์‹คํ–‰ ํ™˜๊ฒฝ

โœ… Node.js 18.17.1 ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰ Node ๋ฒ„์ „ ์ฒดํฌ ํ•„์ˆ˜

 

โœ… ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์‹œ์ž‘์ ์€ App.js์˜ play ๋ฉ”์„œ๋“œ๋‹ค.

๐Ÿ‘‰ play()๋กœ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ˆ ์ด๋ฅผ ์ถ”๊ฐ€ํ•˜์ž.

 

โœ… package.json์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ  ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(jQuery, Lodash ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ˆœ์ˆ˜ Vanilla JS๋กœ๋งŒ ๊ตฌํ˜„ํ•œ๋‹ค.

๐Ÿ‘‰ ํ•˜์ง€๋งŒ ํ•„์ž๋Š” ESLint์™€ Prettier๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋ณ€๊ฒฝ๋œ package.json ๋‚ด์—ญ์€ ๊ตณ์ด push ํ•˜์ง€ ์•Š์•˜๋‹ค.

 

โœ… JavaScript ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค.

๐Ÿ‘‰ ์•„๋ž˜์—์„œ ์ž์„ธํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ•˜๊ฒ ์ง€๋งŒ, Airbnb ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ณด๊ณ  ๋”ฐ๋ฅด๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋ฒˆ๊ฑฐ๋กœ์› ๊ธฐ์— ESLint์™€ Prettier๋ฅผ ์„ค์ •ํ•ด์„œ ์ปจ๋ฒค์…˜์„ ๋งž์ถ”์—ˆ๋‹ค.

 

โœ… ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ process.exit()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘‰ ๋ณดํ†ต ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•  ๋•Œ Console.Close()๋‚˜ process.exit()๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ๋Š” ํ–ˆ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ•„์ž๋Š” ๊ทธ๋ƒฅ '๊ฒŒ์ž„ ์ข…๋ฃŒ' ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ–ˆ๋‹ค. (์ฐธ๊ณ : Node.js์—์„œ ์ข…๋ฃŒํ•˜๋Š” ๋ฐฉ๋ฒ•)

 

โœ… ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜๋ฉด ApplicationTest์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.

๐Ÿ‘‰ ์œ„์—์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‘ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ํ†ต๊ณผํ•ด์•ผ ํ•œ๋‹ค.

 

โœ… ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘‰ ๋””ํดํŠธ๋กœ ์žˆ๋˜ ํŒŒ์ผ, ์ฝ”๋“œ, ํด๋”๋Š” ๊ตณ์ด ๊ฑด๋“ค์ง€ ์•Š์•˜๋‹ค.

 

 

๐Ÿšจ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

โœ… @woowacourse/mission-utils์˜ Random ๋ฐ Console API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

โœ… Random ๊ฐ’ ์ถ”์ถœ์€ Random.pickNumberInRange()๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

โœ… ์‚ฌ์šฉ์ž์˜ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›๊ณ  ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Console.readLineAsync, Console.print๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

๐Ÿ‘‰ ๊ตณ์ด ๋”ฐ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์šฐํ…Œ์ฝ”์—์„œ ์ œ๊ณตํ•˜๋Š” utils๋“ค์„ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ์„ ํ•˜๋ฉด ๋œ๋‹ค.

 

 

๐Ÿ“š ๋ฏธ์…˜์„ ํ†ตํ•ด ๋ฐฐ์šด ์ 

1๏ธโƒฃ ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ

์ „์ฒด์ ์ธ ํ”Œ๋กœ์šฐ๋ฅผ ํ…์ŠคํŠธ์™€ ํ”Œ๋กœ์šฐ ์ฐจํŠธ๋กœ ์ •๋ฆฌ

 

์‹œ๊ฐ„์ด ์กฐ๊ธˆ ๊ฑธ๋ฆฌ๋”๋ผ๋„ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ํ”Œ๋กœ์šฐ๋ฅผ ํ…์ŠคํŠธ์™€ ํ”Œ๋กœ์šฐ ์ฐจํŠธ๋ฅผ ํ†ตํ•ด ์ •๋ฆฌํ•˜๋‹ˆ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋“ค์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์˜€๋‹ค. ํŠนํžˆ ์ฒซ ๋ฒˆ์งธ ๋ฏธ์…˜์ธ ๋งŒํผ ์ต์ˆ™ํ•˜์ง€ ์•Š์„ ํ„ฐ๋ผ ์ดˆ๋ฐ˜์— ๋” ๋งŽ์ด ๊ณ ๋ฏผํ•ด ๋ณด์•„์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

 

๋˜ํ•œ, ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ๋Š” ๊ผผ๊ผผํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ํ• ์ˆ˜๋ก (๋‚˜์—๊ฒŒ) ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ํ•จ์ˆ˜๋ช…, ๋ณ€์ˆ˜๋ช…๊นŒ์ง€ ๋ชจ๋‘ ์ •ํ•ด๋‘๋ฉด ํ›จ์”ฌ ๋น ๋ฅธ ์ฝ”๋”ฉ์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค. (๋ฌผ๋ก  ์ด๊ฒƒ๋„ ์ ์ฐจ ์ต์ˆ™ํ•ด์ง€๋ฉด ์ด๋ ‡๊ฒŒ๊นŒ์ง€ ํด๋ž˜์Šค๋ช…, ๋ฉ”์„œ๋“œ๋ช…๊นŒ์ง€ ์ •์˜ํ•˜๋ฉฐ ์ž์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์ง„ ์•Š์•„๋„ ๋œ๋‹ค.) ๋ช…์„ธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ ์ „์ฒด์ ์ธ ๋กœ์ง ๊ตฌ์ƒ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฝ”๋“œ๋ฅผ ๋‹ค ์จ๋‘๊ณ  ๋กœ์ง์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํ—ท๊ฐˆ๋ฆฌ๋Š” ์ผ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

๊ธฐ๋Šฅ ๋ช…์„ธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋‹ค ๋ณด๋‹ˆ ํ”Œ๋กœ์šฐ๊ฐ€ ์ฑ…์˜ ๋ชฉ์ฐจ์ฒ˜๋Ÿผ ์ „์ฒด์ ์ธ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง€๋„๋ก ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๋ฌผ๋ก  ์ฝ”๋“œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€. ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๊ทธ๋ ค์ง€๋„๋ก ์ž‘์„ฑํ•ด์•ผ๊ฒ ๋‹ค๊ณ ๋„ ์ƒ๊ฐํ–ˆ๋‹ค.


๋ฌผ๋ก  ์ค‘๊ฐ„์— ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…์„ ํ•˜๊ฑฐ๋‚˜ ๋ฆฌํŒฉํ† ๋ง์„ ํ•˜๋ฉด์„œ ๋กœ์ง์„ ๋ณ€๊ฒฝํ•˜๋Š๋ผ, ์ผ๋‹จ ์ฝ”๋“œ ์ˆ˜์ • → ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ ์ˆ˜์ •์œผ๋กœ ๊ฑฐ๊พธ๋กœ ํ•˜๊ธฐ๋„ ํ–ˆ์ง€๋งŒ, ์–ด์จŒ๋“  ๊ธฐ๋Šฅ ๋ช…์„ธ ์ž‘์„ฑ์€ ๋ฏธ์…˜์„ ๋งˆ์ฃผํ•˜๋Š” ๋ง‰๋ง‰ํ•จ์„ ๋œ์–ด์ค„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค.

 

2๏ธโƒฃ ํ•จ์ˆ˜ ์ด๋ฆ„ ์ง“๊ธฐ

ํ•จ์ˆ˜ ํ•˜๋‚˜๋Š” ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•ด์•ผ ํ•˜๋‹ˆ ํ•จ์ˆ˜ ๋ช…์€ ๋ˆ„๊ฐ€ ๋ด๋„ ์ง๊ด€์ ์œผ๋กœ ์ง“๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, checkPermission()๋Š” ์Šน์ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋™์ž‘๋งŒ ํ•ด์•ผ ํ•œ๋‹ค. ์Šน์ธ์—ฌ๋ถ€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋„์šฐ๋Š” ๋™์ž‘์€ ์ด ํ•จ์ˆ˜์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” ๊ฒŒ ์ข‹๋‹ค. (์ฐธ๊ณ : function ํ•จ์ˆ˜์ด๋ฆ„ ์ง“๊ธฐ (2) - javascript 0604)

 

ํ•จ์ˆ˜ ์ด๋ฆ„ ์˜๋ฏธ ์˜ˆ์‹œ
show... ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํ•จ์ˆ˜ showMessage()
get... ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ getAge()
calc... ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ calcSum()
create... ๋ฌด์–ธ๊ฐ€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜ createForm()
check... ๋ฌด์–ธ๊ฐ€๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ถˆ๋ฆฐ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ checkPermission()

 

3๏ธโƒฃ Eslint์™€ Prettier ์„ค์ •

Airbnb ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ๋ฅผ ๋ณด๋ฉด์„œ ์ฝ”๋”ฉํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ์ปจ๋ฒค์…˜ ํ•˜๋‚˜ํ•˜๋‚˜ ์–ด๋–ป๊ฒŒ ๋‹ค ์‹ ๊ฒฝ ์จ์„œ ํ•˜๋‚˜ ์‹ถ์–ด ESLint์™€ Prettier๋ฅผ ์ง์ ‘ ์„ค์ •ํ•ด ๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. ํ˜‘์—… ํ”„๋กœ์ ํŠธ ํ•  ๋•Œ๋Š” ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ•ด์คฌ๋Š”๋ฐ, ์ด๋ฒˆ์— ์ฒ˜์Œ์œผ๋กœ ํ•ด๋ดค๊ณ  ๋„์›€์ด ๋งŽ์ด ๋˜์—ˆ๋‹ค. ์„ค์ •์— ๋งค์šฐ ๋„์›€์ด ๋œ ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ฒจ๋ถ€ํ•œ๋‹ค.

 

ESLint์™€ Prettier ์„ค์ •์œผ๋กœ ๋ณ€๊ฒฝ๋œ package.json

 

ํŒจํ‚ค์ง€ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์ง€ ๋ง๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์—ˆ์ง€๋งŒ, ๊ฑฑ์ •๋œ๋‹ค๋ฉด ์šฐ์„  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š” ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ๋งŒ ESLint์™€ Prettier๋ฅผ ์„ค์น˜ ๋ฐ ์„ค์ •ํ•ด ๋‘๊ณ , ์ปค๋ฐ‹๊ณผ ํ‘ธ์‹œ๋ฅผ ํ•˜์ง€ ์•Š์œผ๋ฉด ๋œ๋‹ค. (ํ•˜์ง€๋งŒ ํ”„๋ฆฌ์ฝ”์Šค 1์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์—์„œ ๊ฐ€๋Šฅํ•˜๋ฉด ESlint์™€ Prettier๋ฅผ ์ด์šฉํ•ด ๋”์šฑ ์ƒ์‚ฐ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ž๋ผ๊ณ  ๊ธฐ์žฌ๋œ ๊ฒƒ์„ ๋ณด๋‹ˆ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•ด๋„ ์ข‹๊ฒ ๋‹ค.)

 

4๏ธโƒฃ ํ•จ์ˆ˜ vs. ํด๋ž˜์Šค

ํ•จ์ˆ˜๋งŒ ์ž‘์„ฑํ•˜๊ธฐ๋ณด๋‹ค ์•„๋ž˜์™€ ๊ฐ™์ด ํด๋ž˜์Šค์˜ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด ์ƒํƒœ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ํด๋ž˜์Šค ๋‚ด์— ์บก์Šํ™”ํ•˜๊ณ ์ž ํ–ˆ๋‹ค. ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•ด๋„ ๋˜์ง€๋งŒ ์ด๊น€์— ํด๋ž˜์Šค ๊ฐœ๋…์— ๋” ์ต์ˆ™ํ•ด์ง€๊ณ  ์‹ถ๊ธฐ๋„ ํ–ˆ๊ณ , ์ถ”ํ›„ ํ•จ์ˆ˜ ๋‚ด์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ์— ํ•„์š”ํ•œ ์ƒํƒœ๋‚˜ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค.

 

// Generator.js

class Generator {
  constructor() {
    this.computerNumber = this.generateRandomNumber();
  }

  generateNewCorrectNumber() {
    this.computerNumber = this.generateRandomNumber();
  }

  generateRandomNumber() {
  // ... ์ƒ๋žต
}

export default Generator;

 

ํด๋ž˜์Šค๋กœ ๋‚˜ํƒ€๋ƒˆ์„ ๋•Œ ๋” ๋งŽ์€ ์ฝ”๋“œ์™€ ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์–ด ์ฒ˜์Œ์—๋Š” ์กฐ๊ธˆ ๋ณต์žกํ•˜๊ฒŒ ๋Š๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ์–ด์จŒ๋“  ๊ฐ’์˜ ์ƒํƒœ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ํด๋ž˜์Šค ๋‚ด์— ์บก์Šํ™”ํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ธ์Šคํ„ด์Šค๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์ƒ์„ฑํ•ด์„œ ์ถ”ํ›„ ์ถ”์ ์— ์œ ์šฉํ•˜๊ธฐ๋„ ํ•˜๋‹ค.

 

5๏ธโƒฃ ๋น„๋™๊ธฐ๋กœ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ ์ฒ˜๋ฆฌ

async & await๋กœ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›์€ ์ด์œ ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์„ ์™„๋ฃŒํ•  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

  // BaseballGame.js
  
  async startGame() {
    await this.getUserInput();
  }

  async getUserInput() {
    const input = await Console.readLineAsync(LOG_MESSAGE.INPUT_NUMBER);
    this.handleUserInputDuringGame(input);
  }
  
  // ... ์ƒ๋žต
  
  handleUserInputDuringGame(input) {
    if (!isValidGameInputDuringGame(input)) {
      throwError(ERROR_MESSAGE.INCORRECT_VALUE);
    }


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

 

์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ์ž์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์€ ์‹œ๊ฐ„์ด ๋ถˆ๊ทœ์น™ํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๊ธฐ์—, ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ํ”„๋กœ๊ทธ๋žจ์ด ๋ธ”๋กœํ‚น๋˜๋ฉด ์‚ฌ์šฉ์„ฑ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ, ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.

 

6๏ธโƒฃ throw Error๋ฌธ๊ณผ throw new Error๋ฌธ์˜ ์ฐจ์ด

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜์ž๋ฉด, ๋‘ ๊ฐœ๊ฐ€ ํฐ ์ฐจ์ด๋Š” ์—†์œผ๋‚˜, new Error๋ฌธ์ด ๊ธฐ์ˆ ์ ์œผ๋กœ ๋” ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค. throw Error๋ฌธ์€ JavaScript์—์„œ ๊ตฌ์‹์ธ ๋ฐฉ์‹์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋ฉฐ, Error ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‚ด์žฅ๋œ Error ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. (์ฐธ๊ณ : JavaScript ‘throw new Error’ vs ‘throw Error’ vs ‘throw something’)

 

๋ฐ˜๋ฉด, throw new Error ๋ฌธ์€ ๋” ํ˜„๋Œ€์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด ๋ฐฉ์‹์€ ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ์˜ˆ์™ธ ๊ฐ์ฒด์— ๋” ๋งŽ์€ ์ •๋ณด๋‚˜ ์ปค์Šคํ…€ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํ˜•ํƒœ์˜ ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. (์ฐธ๊ณ : Differences Between “throw” and “throw new Error” in Javascript / NodeJS)

 

7๏ธโƒฃ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ๋ช…๊ณผ ํด๋”๋ช… ์ปจ๋ฒค์…˜

์ปจ๋ฒค์…˜์€ ์Šต๊ด€์ ์œผ๋กœ ์•Œ๋ คํ•˜์ง€ ์•Š์œผ๋ฉด ๋‚˜์ค‘์— ์ ์šฉํ•˜๋ ค ํ•  ๋•Œ ํ—ท๊ฐˆ๋ฆฐ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ด๋ฒˆ ๊ธฐํšŒ์— ํ™•์‹คํ•˜๊ฒŒ ์งš๊ณ  ๋„˜์–ด ๊ฐ€์ž. (์ฐธ๊ณ : google.github.io, 30secondsofcode.org)

 

ํŒŒ์ผ๋ช…์€ camelCase๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. (e.g. myJavaScriptFile.js) ๋‹ค๋งŒ, ํด๋ž˜์Šค ์ด๋ฆ„์˜ ๊ฒฝ์šฐ PascalCase๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ํด๋ž˜์Šค ์ •์˜๊ฐ€ ํฌํ•จ๋œ ํŒŒ์ผ๋ช… ์—ญ์‹œ PascalCase๋กœ ์ž‘์„ฑํ•œ๋‹ค. (e.g. Generator.js) ๊ทธ๋ฆฌ๊ณ  ํด๋”๋ช…์€ kebab-case๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. (e.g. my-javascript-folder) ๋‹ค๋งŒ, ์–ด๋–ค ํŒŒ์ผ ์‹œ์Šคํ…œ(์˜ˆ: NTFS, git, macOS์˜ ๊ธฐ๋ณธ ์„ค์ •)์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๋ฌด์‹œํ•˜๋ฏ€๋กœ, ํŒŒ์ผ ๋ฐ ํด๋”๋ช…์ด ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” kebab-case๋‚˜ snake_case ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.

 

8๏ธโƒฃ require? import?

์ด๋ฒˆ ๋ฏธ์…˜์„ ํ•˜๋ฉด์„œ ์™ธ๋ถ€ ๋ชจ๋“ˆ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ require๊ณผ import ๋‘˜ ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์จ์•ผ ํ•˜๋Š”์ง€ ๊ณ ๋ฏผํ–ˆ๋‹ค. ๋‘˜ ๋‹ค ๋น„์Šทํ•œ ๊ฑฐ ์•„๋‹Œ๊ฐ€? ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ.

 

์•Œ๊ณ  ๋ณด๋‹ˆ (์ฐธ๊ณ : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ CommonJS ๋ชจ๋“ˆ ๋‚ด๋ณด๋‚ด๊ธฐ/๋ถˆ๋Ÿฌ์˜ค๊ธฐ) require๋Š” Node.js์—์„œ ์˜ˆ์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” CommonJS์˜ ํ‚ค์›Œ๋“œ์ด๊ณ , import๋Š” ES6(ES2015)์—์„œ ์ƒˆ๋กญ๊ฒŒ ๋„์ž…๋˜์–ด ํ˜„์žฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ƒํƒœ๊ณ„์—์„œ ํ‘œ์ค€์ด ๋˜์–ด๊ฐ€๊ณ  ์žˆ๋Š” ํ‚ค์›Œ๋“œ๋ผ๊ณ  ํ•œ๋‹ค. ๋‘ ๊ฐœ์˜ ํ‚ค์›Œ๋“œ ๋ชจ๋‘ ํ•˜๋‚˜์˜ ํŒŒ์ผ์—์„œ ๋‹ค๋ฅธ ํŒŒ์ผ์˜ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค๋Š” ๋™์ผํ•œ ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋น„์Šทํ•œ ๋“ฏ ์•ฝ๊ฐ„์”ฉ ๋‹ค๋ฅธ ๋ฌธ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ•„์ž๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํ‘œ์ค€์ด ๋˜์–ด๊ฐ€๊ณ  ์žˆ๋‹ค๋Š” import๋ฌธ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

// Node.js์—์„œ ์˜ˆ์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” CommonJS์˜ ํ‚ค์›Œ๋“œ

const express = require("express");
const app = express();


// ES6(ES2015)์—์„œ ์ƒˆ๋กญ๊ฒŒ ๋„์ž…๋˜์–ด ํ˜„์žฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ƒํƒœ๊ณ„์—์„œ ํ‘œ์ค€์ด ๋˜์–ด๊ฐ€๊ณ  ์žˆ๋Š” ํ‚ค์›Œ๋“œ

import express from "express";
const app = express();

 

 

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ”ง ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

์ผ๋ฐ˜์ ์ธ ์—๋Ÿฌ๋Š” ๋”ฐ๋กœ ๋‹ค๋ฅธ ๊ธ€๋กœ ๋ฐœํ–‰ํ•˜๊ณ ,
๋ณธ ๋ฏธ์…˜์—์„œ ๋งˆ์ฃผํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐœ๋งŒ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค.

 

1๏ธโƒฃ App.js ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋‹ˆ

์—๋Ÿฌ ํ™”๋ฉด

 

์œ„์˜ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ž˜ ์ฝ์–ด๋ณด๋ฉด 'App.js ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค'๋Š” ๋‚ด์šฉ์ด๊ธฐ์—, ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐ์„ ์‹œ๋„ํ–ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” Node ํ™˜๊ฒฝ์—์„œ ๊ฒŒ์ž„ ์‹คํ–‰ ์‹œ 'node App.js' ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ์œ„์น˜๊ฐ€ ๋ฃจํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ '/src'์—์„œ ํ•ด๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

 

App.js๋ฅผ src์—์„œ ์‹คํ–‰

 

๋˜ํ•œ, ์œ„์—์„œ ๊ธฐ์ˆ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ const & require๋ฌธ์„ ๋ชจ๋‘ import & export ๋ฌธ์œผ๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค. (๋ฌผ๋ก  ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”) ์‚ฌ์‹ค ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ์›์ธ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๊ฒ ์ง€๋งŒ ์šฐ์„  ์œ„์™€ ๊ฐ™์ด ํ•ด๊ฒฐ์„ ํ–ˆ๋‹ค.

 

2๏ธโƒฃ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๊ฐ€ ์•ˆ๋œ๋‹ค๋‹ˆ

ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ํ™”๋ฉด

 

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

 

์ด๊ฒŒ ์›ฌ๊ฑธ! ๋น„๋™๊ธฐ๊ฐ€ ๋ฌธ์ œ์˜€๋‹ค. async๋ฅผ ๋ถ™์ธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , await๋ฅผ ๋ถ™์ด์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. await๋ฅผ ๋ถ™์ด์ง€ ์•Š์œผ๋ฉด play ํ•จ์ˆ˜๋Š” ์—๋Ÿฌ๋ฅผ ๋ฑ‰๋Š” ํ•จ์ˆ˜๋งŒ ์‹คํ–‰์‹œ์ผœ ๋†“๊ณ  ๋๋‚˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. async & await๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ฒŒ์ž„ ์‹คํ–‰์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ await ๊ฐ€๋Šฅํ•œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฒŒ์ž„ ์‹คํ–‰ ๋ฉ”์„œ๋“œ ๋‹จ๊ณ„(์‚ฌ์šฉ์ž๊ฐ€ ์ˆซ์ž๋ฅผ ์ž…๋ ฅ์„ ์™„๋ฃŒํ•˜๋Š” ๋“ฑ)๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ App ํด๋ž˜์Šค์˜ play ๋ฉ”์„œ๋“œ๊ฐ€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ๋‹ค.

 

์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ชจ๋“  ๊ณณ์— async & await๋ฅผ ๋ถ™์—ฌ ์ฃผ์—ˆ๋‹ค.

 

// App.js

import BaseballGame from './BaseballGame.js';
import { Console } from '@woowacourse/mission-utils';
import { LOG_MESSAGE } from './constants.js';
import { printMessage } from './utils.js'

class App {
  constructor() {
    this.game = new BaseballGame();
  }

  async play() {
    printMessage(LOG_MESSAGE.START_GAME);
    await this.game.startGame(); // ์ˆ˜์ •๋œ ๊ฒŒ์ž„ ์‹œ์ž‘ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  }
}

const app = new App();
app.play();

export default App;

 

App.js ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์•„๋ž˜ BaseballGame.js์—์„œ๋„ ๊ฒŒ์ž„ ์‹คํ–‰ ๋ฉ”์„œ๋“œ startGame์„ ๋น„๋™๊ธฐ ๋ฒ„์ „์œผ๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Console.readLine๋ฅผ Promise๋กœ ๋ž˜ํ•‘ ํ•˜๊ฑฐ๋‚˜ ์ ์ ˆํ•œ ๋ฐฉ์‹์œผ๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์ด๋Š” await์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ. ๊ทธ๋Ÿฌ๋‹ˆ ๊ฒŒ์ž„ ์‹คํ–‰ ์‹œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋‹ค๋ฃจ๋Š” ๋ชจ๋“  ๊ณณ์„ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ๋‹ค.

 

// BaseballGame.js

// ... ์ƒ๋žต

class BaseballGame {
  constructor() {
    this.computer = new Generator();
  }

  async startGame() {
    await this.getUserInput();
  }  // ์ˆ˜์ •๋œ ๊ฒŒ์ž„ ์‹œ์ž‘ ๋ฉ”์„œ๋“œ

  async getUserInput() {
    const input = await Console.readLineAsync(LOG_MESSAGE.INPUT_NUMBER);
    this.handleUserInputDuringGame(input);
  }  // ์ˆ˜์ •๋œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฉ”์„œ๋“œ

  async recommendRestart() {
    await printMessage(LOG_MESSAGE.CORRECT_END);

    const input = await Console.readLineAsync(`${LOG_MESSAGE.RESTART_INPUT}\n`);
    this.handleUserInputEndGame(input);
  }  // ์ˆ˜์ •๋œ ๊ฒŒ์ž„ ์žฌ์‹œ์ž‘ ์ž…๋ ฅ ๋ฉ”์„œ๋“œ

  handleUserInputDuringGame(input) {
	// ... ์ƒ๋žต
  }

  async handleUserInputEndGame(input) {
    const isValidGameInputEndGame = [GAME_SELECT.RESTART, GAME_SELECT.END];

    // ... ์ƒ๋žต
  }

  restartGame() {
    this.computer.generateNewCorrectNumber();
    this.startGame();
  }
}

export default BaseballGame;

 

์œ„ ์ฝ”๋“œ ํ•˜๋‹จ์˜ ๊ฒŒ์ž„ ์ข…๋ฃŒ ์ž…๋ ฅ์„ ๋‹ด๋‹นํ•˜๋Š” handleUserInputEndGame ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ await๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋™๊ธฐ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ์—, ์ž…๋ ฅ๊ฐ’์„ ๊ฒ€์‚ฌํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์ถ”๊ฐ€์ ์ธ ๋น„๋™๊ธฐ ์ž‘์—…์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

3๏ธโƒฃ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋ฅผ ์œ„ํ•ด์„  ๊ณต๋ฐฑ ํ•˜๋‚˜๋„ ์ค‘์š”

'n๋ณผ n์ŠคํŠธ๋ผ์ดํฌ' ๋ฌธ์ž์—ด์ด ๋‚˜์˜ค์ง€ ์•Š๋Š” ์—๋Ÿฌ

 

์–ผ์ถ” ๊ธฐ๋Šฅ ๊ตฌํ˜„์€ ๋‹ค ๋๋‚œ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ ค ๋ณด์•˜๋Š”๋ฐ, ์œ„์™€ ๊ฐ™์ด ์ถœ๋ ฅ ๊ฐ’์ด ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜จ๋‹ค๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์•˜๋‹ค. ๋ฉ”์‹œ์ง€๋ฅผ ์ž์„ธํžˆ ๋ณด๋‹ˆ '1 ๋ณผ 1 ์ŠคํŠธ๋ผ์ดํฌ'๊ฐ€ ๋‚˜์™€์•ผ ํ•˜๋Š”๋ฐ ๊ทธ๋ ‡์ง€ ์•Š์•„์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๊ฒƒ ๊ฐ™์•˜๋‹ค. 

 

์–ด์ด์—†๊ฒŒ๋„ n๋ณผ n์ŠคํŠธ๋ผ์ดํฌ๋ผ๋Š” ํžŒํŠธ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ ๋ณผ๊ณผ ์ŠคํŠธ๋ผ์ดํฌ ์‚ฌ์ด์˜ ๊ณต๋ฐฑ์ด ์—†์–ด์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ์˜€๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณผ ๊ฐœ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด ๋ฐ”๋กœ ๋’ค์— ๊ณต๋ฐฑ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ๋‹ค.

 

const convertNumberToString = (strikeNumber, ballNumber) => {
  let hintMessage = '';

  if (ballNumber > 0) {
    hintMessage += `${ballNumber}${HINT_MESSAGE.BALL} `; // ๊ณต๋ฐฑ ์ถ”๊ฐ€
  }

  if (strikeNumber > 0) {
    hintMessage += `${strikeNumber}${HINT_MESSAGE.STRIKE}`;
  }

  if (hintMessage.length === 0) {
    hintMessage += HINT_MESSAGE.NOTING;
  }

  return hintMessage;
};

 

4๏ธโƒฃ ํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผ๋˜๋Š”๋ฐ..

Jest์˜ ๋…ธ๋ž€์ƒ‰ ๋ฉ”์‹œ์ง€

 

์œ„์™€ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋„ ๋˜์—ˆ๊ณ , Node ํ™˜๊ฒฝ์—์„œ ์ž˜ ์ž‘๋™๋˜๋Š” ๊ฒƒ๋„ ํ™•์ธํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ•˜๋‹จ์— ๋…ธ๋ž€์ƒ‰ ๊ธ€์ž๋กœ "Jest did not exit one second after the test run has completed."๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋–ด๋‹ค. ๋ฌด์Šจ ์˜๋ฏธ์ธ๊ฐ€ ์ฐพ์•„๋ณด๋‹ˆ ์•„๋ž˜์™€ ๊ฐ™๋‹ค๊ณ  ํ•œ๋‹ค.

 

Jest์˜ ์ด๋Ÿฌํ•œ ์—๋Ÿฌ๋Š” ์ฃผ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•„ ํ…Œ์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์•Œ๋ ค์ฃผ๋“ฏ, ์ œ์•ˆํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ธ '--detectOpenHandles' ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ํ•ธ๋“ค(Handles)์„ ์‹๋ณ„ํ•˜๊ณ  ํ•ด๊ฒฐํ•ด๋„ ๋œ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด package.json์— ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋” ์ด์ƒ ๋…ธ๋ž€์ƒ‰ ๋ฉ”์‹œ์ง€๊ฐ€ ๋œจ์ง€ ์•Š๋Š”๋‹ค. (ํ•˜์ง€๋งŒ ์ด ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๊ฑด ์•„๋‹ˆ๋‹ˆ ๊ฑฑ์ •๋ง์ž.)

 

"scripts": {
  "test": "jest --detectOpenHandles"
}

 

 

๐Ÿงน ๋ฆฌํŒฉํ† ๋ง

1๏ธโƒฃ ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€๋“ค์€ constants๋กœ ๋™๊ฒฐ

์ถœ๋ ฅ ๋ฉ”์‹œ์ง€๋“ค์€ ์˜คํƒˆ์ž๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ณ , (ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋ฅผ ์œ„ํ•ด์„œ๋ผ๋ฉด ๋”๋”์šฑ) ์ดํ›„ ๋ณ€๊ฒฝ๋˜์–ด์„œ๋„ ์•ˆ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋ช… '๋™๊ฒฐ' ์‹œ์ผœ๋†“์•„์•ผ ํ•œ๋‹ค. Object.freeze()๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์žฅ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ ์ค‘ ํ•˜๋‚˜๋กœ, ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋ณ€๊ฒฝ ๋˜๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋„๋ก ๋งŒ๋“œ๋Š” ๋ถˆ๋ณ€์„ฑ์„ ๋ถ€์—ฌํ•œ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋™๊ฒฐํ•˜๊ณ , ๋‚˜์ค‘์— ์ด ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋Š” ์‹œ๋„๊ฐ€ ์‹คํŒจํ•˜๋„๋ก ํ•˜๊ธฐ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ ์šฉํ–ˆ๋‹ค.

 

const LOG_MESSAGE = Object.freeze({
  START_GAME: '์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.',
  INPUT_NUMBER: '์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š” : ',
  CORRECT_END: '3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋งžํžˆ์…จ์Šต๋‹ˆ๋‹ค! ๊ฒŒ์ž„ ์ข…๋ฃŒ',
  END_GAME: '๊ฒŒ์ž„ ์ข…๋ฃŒ',
  RESTART_INPUT: '๊ฒŒ์ž„์„ ์ƒˆ๋กœ ์‹œ์ž‘ํ•˜๋ ค๋ฉด 1, ์ข…๋ฃŒํ•˜๋ ค๋ฉด 2๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.',
});

// ... ์ดํ•˜๋Š” ์ƒ๋žต

 

2๏ธโƒฃ ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•

๊ฒŒ์ž„ ํ๋ฆ„ ์ƒ, ์ปดํ“จํ„ฐ๊ฐ€ ๋žœ๋ค ํ•œ 3์ž๋ฆฌ ์ˆซ์ž๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋•Œ ์ค‘์š”ํ•œ ์กฐ๊ฑด์ด '์ค‘๋ณต์ด ์—†์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ'์ด์—ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ์—๋Š” ๋ฐฐ์—ด์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด, includes()๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ ์ˆซ์ž๊ฐ€ ๋ฐฐ์—ด์— ๋“ค์–ด์žˆ๋Š”์ง€ (์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ๋Š”์ง€) ํ™•์ธํ•˜๊ณ , ์—†๋‹ค๋ฉด ํ•ด๋‹น ์ˆซ์ž๋ฅผ push()๋กœ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‹ค ๋‚ด์žฅ ํ•จ์ˆ˜ ์ค‘, set()์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ๋ฆฌํŒฉํ† ๋ง ํ–ˆ๋‹ค. Set์˜ ๊ฐ€์žฅ ํฐ ํŠน์ง•์€ '์ค‘๋ณต๋œ ์š”์†Œ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ'์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋˜์—ˆ๋‹ค. array์˜ ์š”์†Œ๋ฅผ push()ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, set()์€ add()๋ฅผ ํ™œ์šฉํ•ด ๊ฐ’์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ณ  ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  array์˜ ์š”์†Œ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” includes()์ฒ˜๋Ÿผ, set()์€ has()๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด set & add๋ฅผ ์‚ฌ์šฉํ•ด ์ˆ˜์ •ํ•˜๋‹ˆ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•ด์กŒ๋‹ค.

 

// ์ˆ˜์ • ์ „ : includes & push ์‚ฌ์šฉ

generateRandomNumber() {
  const computerArray = [];
  while (computerArray.length < 3) {
    const newComputerNumber = Random.pickNumberInRange(1, 9);
    if (!computerArray.includes(newComputerNumber)) {
      computerArray.push(newComputerNumber);
    }
  }
  return computerArray.join('');
}


// ์ˆ˜์ • ํ›„ : set & add ์‚ฌ์šฉ

generateRandomNumber() {
    const generatedNumber = new Set();

    while (generatedNumber.size < 3) {
      const newComputerNumber = generateNumberInRange(1, 9);
      generatedNumber.add(newComputerNumber);
    }

    return Array.from(generatedNumber).join('');
  }
}

 

3๏ธโƒฃ ์ด๋ฆ„์€ ์ง๊ด€์ ์œผ๋กœ

๋ฉ”์„œ๋“œ๋ช…, ํŒŒ์ผ๋ช…, ํด๋ž˜์Šค๋ช…์„ ์ „์ฒด์ ์œผ๋กœ ์‚ดํŽด๋ณด๋ฉฐ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ˆ„๊ตฌ๋‚˜ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ์ˆ˜์ •ํ–ˆ๋‹ค. ๋ฌผ๋ก  ์ฃผ์„์„ ์‚ฌ์šฉํ•ด ๊ฐ ๋ฉ”์„œ๋“œ์™€ ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์จ๋„ ๋‚˜์˜์ง€ ์•Š์ง€๋งŒ, ์‚ฌ์‹ค ๊ฐ€์žฅ ์ข‹์€ ๊ฑด ์ด๋ฆ„ ์ž์ฒด์—์„œ ๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

// 1. ๊ฒŒ์ž„ ์ง„ํ–‰์ค‘ ์ž…๋ ฅ ๊ฐ’์ด ์œ ํšจํ•œ์ง€ ํŒ๋‹จํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์ˆ˜์ •
// ๋ณดํ†ต boolean์„ returnํ•˜๋Š” ํ•จ์ˆ˜๋Š” is ~ ์ด๋Ÿฐ ์‹์œผ๋กœ ์“ฐ๊ธฐ ๋•Œ๋ฌธ
checkValidNumberDuringGame → isValidGameInput

// 2. ์ž…๋ ฅ ๊ฐ’์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ํŒŒ์ผ ์ด๋ฆ„ ์ˆ˜์ •
// ๋™์‚ฌ๋„ ์ข‹์ง€๋งŒ '์—ญํ• '์„ ๋ถ„๋ช…ํžˆ ๋“œ๋Ÿฌ๋‚ด๋ฉด ๋” ์ข‹๋‹ค.
checkValid.js → validator.js

// 3. ์ปดํ“จํ„ฐ๊ฐ€ ๋žœ๋คํ•œ ์ˆซ์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค ์ด๋ฆ„ ์ˆ˜์ •
// ์ปดํ“จํ„ฐ ๋ผ๊ณ  ์ด๋ฆ„๋งŒ ์จ๋†“๋Š” ๊ฒƒ๋ณด๋‹ค ์ปดํ“จํ„ฐ๊ฐ€ ํ•˜๋Š” '์—ญํ• '์„ ๋ถ„๋ช…ํžˆ ๋“œ๋Ÿฌ๋‚ด๋ฉด ๋” ์ข‹๋‹ค.
Computer.js → Generator.js

 

๊ทธ๋ฆฌ๊ณ  ์ฑ… <ThoughtWorks Anthology>์— ๋‚˜์˜ค๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์ƒํ™œ ์ฒด์กฐ ์›์น™์—์„œ๋Š” ์ด๋ฆ„์„ ๋ฌด์ž‘์ • ์ค„์ด๊ธฐ๋ณด๋‹ค ๊ฐ„๋žตํ•˜๊ณ ๋„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๋ผ๊ณ  ๋งํ•œ๋‹ค. "๋ˆ„๊ตฌ๋‚˜ ์‹ค์€ ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ๋˜๋Š” ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ์ค„์ด๋ ค๋Š” ์œ ํ˜น์— ๊ณง์ž˜ ๋น ์ง€๊ณค ํ•œ๋‹ค. ๊ทธ๋Ÿฐ ์œ ํ˜น์„ ๋ฟŒ๋ฆฌ์ณ๋ผ. ์ถ•์•ฝ์€ ํ˜ผ๋ž€์„ ์•ผ๊ธฐํ•˜๋ฉฐ, ๋” ํฐ ๋ฌธ์ œ๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค. ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ํ•œ ๋‘ ๋‹จ์–ด๋กœ ์œ ์ง€ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ๋ฌธ๋งฅ์„ ์ค‘๋ณตํ•˜๋Š” ์ด๋ฆ„์„ ์ž์ œํ•˜์ž." 

 

4๏ธโƒฃ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์•„๋‹Œ ํ•จ์ˆ˜๋“ค์„ utils.js์— ๋ถ„๋ฆฌ

ํ”ํžˆ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋ฉด์„œ '๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง', '๋„๋ฉ”์ธ ๋กœ์ง'์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•œ๋‹ค. ๋“ค์–ด๋Š” ๋ดค์ง€๋งŒ ํ•ด๋‹น ๊ฐœ๋…์— ์ž˜ ๋ชฐ๋ผ์„œ ๊ณต๋ถ€ํ•ด ๋ณด๊ณ  (์ฐธ๊ณ : ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง, ๋„๋ฉ”์ธ ๋กœ์ง์ด ๋„๋Œ€์ฒด ๋ญ์ง€?) ์ด๋ฒˆ ๋ฏธ์…˜ ์ฝ”๋“œ์—๋„ ์ ์šฉํ–ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด utils.js๋ผ๋Š” ํŒŒ์ผ์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด export ํ•˜๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๊ณณ์— import ํ–ˆ๋‹ค.

 

// utils.js

// ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜
const printMessage = (message) => Console.print(message);

// ์ปดํ“จํ„ฐ๊ฐ€ ๋žœ๋คํ•œ ์ˆซ์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
const generateNumberInRange = (min, max) => Random.pickNumberInRange(min, max);

// ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜
const throwError = (message, condition = true) => {
  if (condition) throw new Error(message);
};

// ... ์ƒ๋žต

export { printMessage, generateNumberInRange, throwError };

 

์ฐธ๊ณ ํ•œ ๊ธ€์— ๋”ฐ๋ฅด๋ฉด, ๋„๋ฉ”์ธ ๋กœ์ง์€ ํ˜„์‹ค ๋ฌธ์ œ์— ๋Œ€ํ•œ ์˜์‚ฌ๊ฒฐ์ •์„ ํ•˜๋Š” ์ฝ”๋“œ์ด๋ฉฐ, ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋Š” ๊ทธ ๊ฒฐ์ •์„ ์œ„ํ•œ ์ž…๋ ฅ๊ฐ’์„ ๋งŒ๋“ค์–ด์ฃผ๊ฑฐ๋‚˜, ๊ทธ ๊ฒฐ์ •์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ํ•ด์„ํ•˜๊ณ  ๋ณด์—ฌ์ฃผ๊ณ  ์ „ํŒŒํ•˜๋Š” ์ฝ”๋“œ๋ผ๊ณ  ํ•œ๋‹ค. ์ด๋Ÿฐ ๊ธฐ์ค€์„ ์„ธ์›Œ์„œ ์šฐ๋ฆฌ๊ฐ€ ๋„๋ฉ”์ธ ๋กœ์ง๊ณผ ์•„๋‹Œ ๊ฒƒ์„ ๋‚˜๋ˆ„๋Š” ์ด์œ ๋Š” ๋ช…ํ™•ํ•œ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ๋‹ค.

 

๋„๋ฉ”์ธ ๋กœ์ง๊ณผ ์•„๋‹Œ ๊ฒƒ์„ ์ž˜ ๋‚˜๋ˆ„๊ณ  ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋ฉด, ๊ฐœ๋ฐœ์ž๊ฐ€ ๋กœ์ง์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜์—์„œ๋Š” ๋‹ค๋ฅธ ๊ณ„์ธต๋“ค์€ ๋„๋ฉ”์ธ ๋กœ์ง์—๊ฒŒ ์ž…๋ ฅ์„ ์ „๋‹ฌํ•˜๊ณ , ๋ณ€ํ™”๋ฅผ ์™ธ๋ถ€๋กœ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋„๋ก ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ์•ž์œผ๋กœ์˜ ๋ฏธ์…˜์—์„œ๋„ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ์— ๋” ์‹ ๊ฒฝ ์“ฐ๋ฉด์„œ ์ฝ”๋”ฉํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

 

5๏ธโƒฃ else๋ณด๋‹ค early return

์šฐํ…Œ์ฝ” ํด๋ฆฐ์ฝ”๋“œ ์ฒดํฌ๋ฆฌ์ŠคํŠธ์— ๋”ฐ๋ฅด๋ฉด, else ์˜ˆ์•ฝ์–ด ์‚ฌ์šฉ์„ ์ง€์–‘ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋ฌผ๋ก  ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ์ด ์›์น™์„ ์ค€์ˆ˜ํ•˜๋ผ๊ณ  ๋”ฐ๋กœ ๋ง์€ ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ํด๋ฆฐ์ฝ”๋“œ๋ฅผ ์—ผ๋‘ํ•˜๋ฉฐ ์ฝ”๋“œ๋ฅผ ์งœ๋ ค๊ณ  ํ–ˆ๋‹ค. ์„œ์นญํ•ด ๋ณด๋‹ˆ ์ง€๋‚œ ๊ธฐ์ˆ˜์—์„œ๋Š” else๋ฅผ ํฌํ•จํ•œ else if, switch๋ฌธ๋„ ์ง€์–‘ํ•˜๋ฉด ์ข‹๋‹ค๋Š” ๋ง์ด ์žˆ์–ด์„œ ๋˜๋„๋ก์ด๋ฉด early return์„ ํ•˜๊ณ ์ž ํ–ˆ๋‹ค. (๋ฌผ๋ก  ์ด ๋ถ€๋ถ„์€ ์‚ฌ๋žŒ๋งˆ๋‹ค ๊ฐ‘๋ก ์„๋ฐ•์ด ์žˆ์„ ์ˆ˜ ์žˆ๊ณ , ํŒ€๋งˆ๋‹ค ํšŒ์‚ฌ๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ๋งŒ ํ•˜์ž.)

 

// ์ˆ˜์ • ์ „

async handleUserInputEndGame(input) {
    const isValidGameInputEndGame = [GAME_SELECT.RESTART, GAME_SELECT.END];

    if (!isValidGameInputEndGame.includes(input)) {
      throwError(ERROR_MESSAGE.INCORRECT_VALUE);
    }
    switch (input) { // switch๋ฌธ ์‚ฌ์šฉ
      case GAME_SELECT.RESTART:
        this.restartGame();
        break;
      case GAME_SELECT.END:
        printMessage(LOG_MESSAGE.END_GAME);
        break;
    }
  }
  
 // ์ˆ˜์ • ํ›„
 async handleUserInputEndGame(input) {
    const isValidGameInputEndGame = [GAME_SELECT.RESTART, GAME_SELECT.END];

    if (!isValidGameInputEndGame.includes(input)) {
      throwError(ERROR_MESSAGE.INCORRECT_VALUE);
      return; // early return
    }
    if (input === GAME_SELECT.RESTART) {
      this.restartGame();
      return; // early return
    }
    if (input === GAME_SELECT.END) {
      printMessage(LOG_MESSAGE.END_GAME);
    }
  }

 

 

โ˜•๏ธ 1์ฃผ ์ฐจ ์†Œ๊ฐ

1๏ธโƒฃ ๋ง์„ค์ž„ ์—†์ด ๊ฐ€์ž

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

 

2๏ธโƒฃ ๋ฌ˜๋ฏธ๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ

๊ฐœ๋ฐœ์ž๋Š” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ๋งŒ๋‚ ์ˆ˜๋ก ์„ฑ์žฅํ•œ๋‹ค๊ณ  ๋ฏฟ๋Š”๋‹ค. ํ•˜์ง€๋งŒ ๋ฏฟ๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์‹ค์ฒœํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ณ , ์ฆ๊ฒ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ๋”๋”์šฑ ์–ด๋ ค์šด ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋ฒˆ ๋ฏธ์…˜ ์ˆ˜ํ–‰์„ ํ•˜๋ฉด์„œ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ์—๋Ÿฌ๋“ค์„ ๋งˆ์ฃผํ•˜๋ฉฐ ๋„ˆ๋ฌด๋‚˜ ๊ณ ๋˜์—ˆ์ง€๋งŒ, ํ•ด๊ฒฐํ•œ ๋’ค ์„ฑ์ทจ๊ฐ์€ ์ด๋ฃจ ๋งํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. ์—ญ์‹œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๋ฌ˜๋ฏธ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ๋ง์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์‹ค๊ฐํ–ˆ๋‹ค. ์•ž์œผ๋กœ๋Š” ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚˜๋ฉด ์˜คํžˆ๋ ค ์„ฑ์žฅ์˜ ๊ธฐํšŒ๋ผ ์ƒ๊ฐํ•˜๊ณ  ์‹ ๋‚˜๊ฒŒ ๋ฐ˜๊ฒจ์ฃผ์–ด์•ผ๊ฒ ๋‹ค.

 

3๏ธโƒฃ ‘๊ทธ๋ ‡๊ตฌ๋‚˜’๋Š” ํ™”์‚ด

๊ทธ๋™์•ˆ ๊ฐœ๋ฐœ์„ ๊ฐ•์˜๋‚˜ ์ฑ…์œผ๋กœ ํ•™์Šตํ•  ๋•Œ๋Š” ‘๊ทธ๋ ‡๊ตฌ๋‚˜’ ํ•˜๊ณ  ๋„˜๊ฒผ๋˜ ๊ฒƒ๋“ค์ด ๋น„๋กœ์†Œ ํ™”์‚ด(?)์ด ๋˜์–ด ๋Œ์•„์™”๋‹ค. ์ด๋ฒˆ ๋ฏธ์…˜์„ ํ•˜๋ฉด์„œ ์‚ฌ์†Œํ•œ ์‹ค์ˆ˜๊ฐ€ ์—๋Ÿฌ์˜ ์›์ธ์ด ๋˜๊ฑฐ๋‚˜, ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์„ ํ™•์‹คํ•˜๊ฒŒ ์•Œ์ง€ ๋ชปํ•ด ์Šค์Šค๋กœ ๋†€๋ž๋˜ ์ ์ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฅผ ์„ฑ์žฅ์˜ ๊ณ„๊ธฐ๋กœ ์‚ผ์•„ ๋‹ค์‹œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋ถ€์กฑํ•œ ๊ฒƒ์„ ์ฑ„์šธ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์•ž์œผ๋กœ๋Š” ์‚ฌ์†Œํ•œ ๊ฐœ๋…์ด๋ผ๋„ ํ™”์‚ด์ด ๋˜์ง€ ์•Š๋„๋ก ๋ฐ˜๋“œ์‹œ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์จ๋ณด๊ฑฐ๋‚˜ ์ž‘๊ฒŒ๋ผ๋„ ๋งŒ๋“œ๋Š” ์—ฐ์Šต์„ ํ•˜๋ฉฐ, ํ™•์‹คํžˆ ๋‚ด ๊ฒƒ์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ๊ฒ ๋‹ค.

 

 

 

๋Œ“๊ธ€