JavaScript ์ •์  ๋ถ„์„ ๋„๊ตฌ

2025๋…„์˜ JavaScript ์ •์  ๋ถ„์„ ๋„๊ตฌ SMART TS XL ESLint๋กœ

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

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

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

์ฐจ๋ก€

SMART TS XL: ํ‘œ๋ฉด์„ ๋„˜์–ด์„œ๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ํ†ต์ฐฐ๋ ฅ

์ „ํ†ต์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. COBOL ๋ฐ ๋ฉ”์ธํ”„๋ ˆ์ž„ ๋ถ„์„ ๊ธฐ๋Šฅ, SMART TS XL JavaScript๋ฅผ ํฌํ•จํ•œ ํ˜„๋Œ€์ ์ธ ๋‹ค๊ตญ์–ด ๊ธฐ์—… ํ™˜๊ฒฝ์˜ ์š”๊ตฌ๋ฅผ ์ถฉ์กฑํ•˜๋„๋ก ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์กฐ์ง์ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ ๋ฐ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์‹œ์Šคํ…œ์„ ๋„์ž…ํ•จ์— ๋”ฐ๋ผ, SMART TS XL ๋‹จ์ผ ํ†ตํ•ฉ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ •์  ์ฝ”๋“œ ๋ถ„์„์„ ์ œ๊ณตํ•˜์—ฌ ๊ฐ•๋ ฅํ•œ ์ด์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

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

์˜ ์žฅ์  SMART TS XL:

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

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

ESLint: ์—…๊ณ„ ํ‘œ์ค€

ESLint๋Š” ๊ฐœ์ธ ๊ฐœ๋ฐœ์ž์™€ ๋Œ€๊ทœ๋ชจ ์กฐ์ง ๋ชจ๋‘์—์„œ ์‚ฌ์šฉํ•˜๋Š” JavaScript ๋ฐ TypeScript์šฉ ์ •์  ๋ถ„์„ ๋„๊ตฌ ์ค‘ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋ฆฐํ„ฐ(linter) ์—ญํ• ์„ ํ•˜๋ฉฐ ์ฝ”๋“œ ํ’ˆ์งˆ ๊ทœ์น™๊ณผ ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ์„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค. ESLint๋Š” ๊ตฌ์„ฑ ๊ฐ€๋Šฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ , ๋‹ค์–‘ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ƒํƒœ๊ณ„๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ์ตœ์‹  IDE ๋ฐ CI/CD ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ์™„๋ฒฝํ•˜๊ฒŒ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค.

JavaScript์šฉ ESLint ์ •์  ๋ถ„์„ ๋„๊ตฌ

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ตฌ๋ฌธ ์˜ค๋ฅ˜, ์ฝ”๋“œ ๋ƒ„์ƒˆ ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€์— ๋Œ€ํ•œ ๊ทœ์น™ ๊ธฐ๋ฐ˜ ๋ฆฐํŒ…
  • ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•œ ํ™•์žฅ์„ฑ(์˜ˆ: React, Vue, TypeScript, Node)
  • ๋งŽ์€ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž๋™ ์ฝ”๋“œ ์ˆ˜์ •
  • Prettier์™€ ๊ฐ™์€ ํฌ๋งทํ„ฐ์™€์˜ ํ˜ธํ™˜์„ฑ
  • ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•œ IDE ํ†ตํ•ฉ
  • ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ€๋Šฅํ•œ ์ฝ”๋”ฉ ํ‘œ์ค€ ์‹œํ–‰ .eslintrc ํŒŒ์ผ
  • GitHub Actions, Jenkins, GitLab CI ๋ฐ ๊ธฐํƒ€ DevOps ๋„๊ตฌ์™€์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ

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

ESLint์˜ ๋‹จ์ :

  • ์•„ํ‚คํ…์ฒ˜๋‚˜ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ๋ถ„์„ ์—†์Œ
    ESLint๋Š” ํŒŒ์ผ๋ณ„ ๋˜๋Š” ํ•จ์ˆ˜๋ณ„๋กœ ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด ๋ฐ์ดํ„ฐ ํ๋ฆ„์€ ๋ชจ๋ธ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ฐ„ ๋ณ€์ˆ˜๋ฅผ ์ถ”์ ํ•˜๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์— ๊ฑธ์ณ ๋ฐœ์ƒํ•˜๋Š” ์ž ์žฌ์ ์ธ ๋Ÿฐํƒ€์ž„ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์ข…์†์„ฑ ๋ฐ ์˜ํ–ฅ์— ๋Œ€ํ•œ ๊ฐ€์‹œ์„ฑ์ด ์ œํ•œ๋จ
    ESLint๋Š” ์˜ํ–ฅ ๋ถ„์„, ์ข…์†์„ฑ ๋งต, ๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋‚˜ ํ•จ์ˆ˜์˜ ์ƒํ˜ธ ์ž‘์šฉ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์‹œ๊ฐํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์˜จ๋ณด๋”ฉ, ๊ฐ์‚ฌ ๋˜๋Š” ์‹œ์Šคํ…œ ์ „์ฒด ๋ณ€๊ฒฝ ๊ณ„ํš์— ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ ๊ฐ์‚ฌ์šฉ์œผ๋กœ ์ œ์ž‘๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
    ํ”Œ๋Ÿฌ๊ทธ์ธ(์˜ˆ: eslint-plugin-security)์ด ์กด์žฌํ•˜์ง€๋งŒ, ESLint๋Š” ๋ณด์•ˆ ์Šค์บ๋„ˆ๋กœ ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์—ญ์ง๋ ฌํ™”๋‚˜ ์ธ์ฆ ๊ฒฐํ•จ๊ณผ ๊ฐ™์€ ๋ณต์žกํ•œ ์ทจ์•ฝ์ ์„ ํƒ€์‚ฌ ๋„๊ตฌ ์—†์ด ํƒ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋ณต์žกํ•œ ๋ชจ๋…ธ๋ ˆํฌ์—์„œ๋Š” ํ™•์žฅํ•˜๊ธฐ ์–ด๋ ค์›€
    ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค, ํŠนํžˆ ๋ชจ๋…ธ๋ฆฌํฌ๋‚˜ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€์™€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ฑธ์ณ ESLint ๊ตฌ์„ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋‹ค๋ฃจ๊ธฐ ํž˜๋“ค๊ณ  ๊ตฌ์„ฑ์ด ์–ด๊ธ‹๋‚˜๋Š” ๊ฒฐ๊ณผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ํ˜„๋Œ€ํ™”์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    ESLint๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ชจ๋ธ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ถ”์ถœ ๋˜๋Š” ๋ณ€ํ™˜ ์ง€์นจ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ESLint๋Š” ๋ฆฐํŒ… ๋„๊ตฌ์ผ ๋ฟ, ํ˜„๋Œ€ํ™” ํ”Œ๋žซํผ์ด ์•„๋‹™๋‹ˆ๋‹ค.

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

TypeScript: ์ •์  ์•ˆ์ „์„ฑ์€ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

TSC ๋ฐ tsconfig ๊ธฐ๋ฐ˜ ๋ถ„์„์˜ ๋‹จ์ :

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

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

SonarQube(SonarJS ํฌํ•จ): ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฑฐ๋ฒ„๋„Œ์Šค

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript ๋ฐ TypeScript์˜ ๋ฒ„๊ทธ, ์ฝ”๋“œ ๋ƒ„์ƒˆ ๋ฐ ๋ณด์•ˆ ์ทจ์•ฝ์  ๊ฐ์ง€
  • ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ€๋Šฅํ•œ ํ’ˆ์งˆ ๊ฒŒ์ดํŠธ ๋ฐ ์ฝ”๋”ฉ ๊ทœ์น™ ์‹œํ–‰
  • ๊ณผ๊ฑฐ ์ง€ํ‘œ์™€ ์ถ”์„ธ ๊ทธ๋ž˜ํ”„๊ฐ€ ํฌํ•จ๋œ ํ’๋ถ€ํ•œ ๋Œ€์‹œ๋ณด๋“œ
  • Jenkins, GitHub Actions, GitLab, Azure DevOps ๋“ฑ๊ณผ์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ
  • ์ฝ”๋“œ ์ค‘๋ณต ๋ฐ ์ˆœํ™˜ ๋ณต์žก๋„ ๋ถ„์„์— ๋Œ€ํ•œ ์‹ฌ์ธต ์ง€์›
  • OWASP Top 10, CWE ๋ฐ SANS ์ง€์นจ์— ๋งž์ถฐ ๊ทœ์ • ์ค€์ˆ˜ ์ถ”์ 

SonarQube(SonarJS ํฌํ•จ)์˜ ๋‹จ์ :

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

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

JSHint: JS ๊ธฐ๋ณธ์„ ์œ„ํ•œ ๊ฐ€๋ฒผ์šด ๋ฆฐํŒ…

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜์ ์ธ ๊ตฌ๋ฌธ ์˜ค๋ฅ˜, ์„ ์–ธ๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜ ๋ฐ ์œ ํ˜• ๊ฐ•์ œ ๋ณ€ํ™˜ ํ•จ์ •์„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ตฌ์„ฑ์„ ํ†ตํ•ด ์ง€์› .jshintrc ๋˜๋Š” ์ธ๋ผ์ธ ๋Œ“๊ธ€
  • ์ตœ์†Œํ•œ์˜ ์ข…์†์„ฑ์œผ๋กœ ๋น ๋ฅธ ์‹คํ–‰
  • Grunt, Gulp, npm ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ์™€์˜ ๊ฐ„๋‹จํ•œ ํ†ตํ•ฉ
  • ์ด์ „ JavaScript ํ™˜๊ฒฝ(ES5 ๋ฐ ์ด์ „ ๋ฒ„์ „)์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €, ํ„ฐ๋ฏธ๋„ ๋˜๋Š” CI/CD ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ผ๋ถ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

JSHint์˜ ๋‹จ์ :

  • ์ตœ์‹  JavaScript(ES6+)์— ๋Œ€ํ•œ ์ง€์›์ด ์ œํ•œ๋จ
    JSHint๋Š” ์ตœ์‹  ๊ตฌ๋ฌธ์„ ์–ด๋А ์ •๋„ ์ง€์›ํ•˜์ง€๋งŒ, ๋ชจ๋“ˆ, ๊ตฌ์กฐ ๋ถ„ํ•ด, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, async/await, ์˜ต์…”๋„ ์ฒด์ด๋‹, TypeScript ๋“ฑ์˜ ๊ธฐ๋Šฅ ์ฒ˜๋ฆฌ์—๋Š” ๋’ค์ฒ˜์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ตœ์‹  JS ์ƒํƒœ๊ณ„๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ํ”Œ๋Ÿฌ๊ทธ์ธ ์•„ํ‚คํ…์ฒ˜ ์—†์Œ
    ESLint์™€ ๋‹ฌ๋ฆฌ JSHint๋Š” ํƒ€์‚ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ •์˜, ํ”„๋ ˆ์ž„์›Œํฌ๋ณ„ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(์˜ˆ: React, Vue) ๋˜๋Š” ๋™์  ๋ฆฐํŒ… ๊ทœ์น™์ด ํ•„์š”ํ•œ ํ”„๋กœ์ ํŠธ์—๋Š” ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ์ด๋‚˜ ์˜๋ฏธ ๋ถ„์„์ด ๋ถ€์กฑํ•จ
    JSHint๋Š” ์ทจ์•ฝ์ , ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํŒจํ„ด ๋˜๋Š” API ์˜ค์šฉ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ ๋ฐ ๊ธฐ๋ณธ ๋…ผ๋ฆฌ ๋ฌธ์ œ์—๋งŒ ์ง‘์ค‘ํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•ˆ์ „์„ฑ์ด๋‚˜ ์œ ์ง€ ๊ด€๋ฆฌ ์šฉ์ด์„ฑ์—๋Š” ์ค‘์ ์„ ๋‘์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์œ ํ˜• ์ธ์‹์ด๋‚˜ ํ๋ฆ„ ์ œ์–ด ๋ถ„์„์ด ์—†์Šต๋‹ˆ๋‹ค.
    JSHint๋Š” ํ”ผ์ƒ์ ์ธ ๊ตฌ๋ฌธ ์ˆ˜์ค€์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  JavaScript์—์„œ ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜ ์ˆ˜๋ช…, ํ•จ์ˆ˜ ๊ฐ„ ์ข…์†์„ฑ, ๋น„๋™๊ธฐ ๋…ผ๋ฆฌ ์ฒด์ธ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.
  • ์ œํ•œ๋œ ๊ตฌ์„ฑ ๊ฐ€๋Šฅ์„ฑ ๋ฐ IDE ํ†ตํ•ฉ ๋ถˆ๋Ÿ‰
    ๊ตฌ์„ฑ ์˜ต์…˜์€ ๊ธฐ๋ณธ์ ์ด๋ฉฐ, ์ตœ์‹  ํŽธ์ง‘๊ธฐ ์ง€์›์€ ํŽธ์ง‘๊ธฐ ๋‚ด ์ง„๋‹จ, ์ž๋™ ์™„์„ฑ ๋ฐ ๋ฆฌํŒฉํ† ๋ง ์ง€์›์„ ์ œ๊ณตํ•˜๋Š” ESLint ๋ฐ TypeScript ๋„๊ตฌ์— ํฌ๊ฒŒ ๊ฐ€๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ง€์—ญ ์‚ฌํšŒ ํ™œ๋™ ๊ฐ์†Œ
    ESLint๊ฐ€ ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด ๋˜๋ฉด์„œ JSHint์˜ ์—…๋ฐ์ดํŠธ์™€ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ์—ฌ๋Š” ๋‘”ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ง€์›์— ์ฐจ์งˆ์ด ์ƒ๊ธฐ๊ณ  ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๊ฐœ์„  ์‚ฌํ•ญ๋„ ์ค„์–ด๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

Prettier(ESLint ํ†ตํ•ฉ ํฌํ•จ): ๊ทœ๋ชจ์— ๋”ฐ๋ฅธ ์ผ๊ด€์„ฑ์„ ์œ„ํ•œ ์ž๋™ํ™”๋œ ์ฝ”๋“œ ํฌ๋งทํŒ…

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript, TypeScript, JSX, JSON, HTML, CSS ๋“ฑ์— ๋Œ€ํ•œ ์ž๋™ ์„œ์‹ ์ง€์ •
  • ์ผ๊ด€๋œ ๋“ค์—ฌ์“ฐ๊ธฐ, ๊ฐ„๊ฒฉ, ์ค„ ๋„ˆ๋น„ ๋ฐ ์ธ์šฉ ์Šคํƒ€์ผ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ผ๊ณผ ๊ธฐ์—ฌ์ž ๊ฐ„์˜ ์Šคํƒ€์ผ ๋ถˆ์ผ์น˜๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„์˜ ํŽธ์ง‘๊ธฐ(VSCode, WebStorm, Sublime ๋“ฑ)์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค.
  • CLI, ์‚ฌ์ „ ์ปค๋ฐ‹ ํ›„ํฌ(์˜ˆ: Husky ์‚ฌ์šฉ) ๋˜๋Š” CI ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ ์ ˆํ•˜๊ฒŒ ๊ตฌ์„ฑํ•˜๋ฉด ESLint์™€ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค.

Prettier์˜ ๋‹จ์ (ESLint ํ†ตํ•ฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„):

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

Prettier๋Š” JavaScript ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์—์„œ ์ผ๊ด€๋œ ์ฝ”๋“œ ํ˜•์‹์„ ์œ ์ง€ํ•˜๊ณ , ์Šคํƒ€์ผ ๋งˆ์ฐฐ์„ ์ค„์ด๋ฉฐ, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ •์  ์ฝ”๋“œ ๋ถ„์„์„ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ESLint์™€ ํ†ตํ•ฉํ•˜๋ฉด Prettier์˜ ์„ฑ๋Šฅ์ด ๊ทน๋Œ€ํ™”๋ฉ๋‹ˆ๋‹ค. Prettier๋Š” ์ฝ”๋“œ์˜ ์‹œ๊ฐ์  ์ธก๋ฉด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ˜๋ฉด, ESLint๋Š” ๊ตฌ์กฐ์  ๋ฐ ๋…ผ๋ฆฌ์  ๋ฌด๊ฒฐ์„ฑ์„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค.

Flow: ๋” ์•ˆ์ „ํ•œ JS๋ฅผ ์œ„ํ•œ ์ •์  ์œ ํ˜• ๊ฒ€์‚ฌ

Meta(Facebook)์—์„œ ๊ฐœ๋ฐœํ•œ Flow๋Š” JavaScript์šฉ ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ๊ธฐ๋กœ, ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ ๋„ ๋ถ„์„ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐœ๋ฐœ ์ฃผ๊ธฐ ์ดˆ๊ธฐ์— ํƒ€์ž… ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. TypeScript์™€ ์˜๋„๋Š” ์œ ์‚ฌํ•˜์ง€๋งŒ ์„ค๊ณ„ ๋ฐฉ์‹์ด ๋‹ค๋ฅธ Flow๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ JavaScript ํŒŒ์ผ์— ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์ง„์ ์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ vanilla JS์™€์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์กฐ๊ธฐ์— ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

Flow์˜ ๋‹จ์ :

  • ์œ ํ˜• ์•ˆ์ „์—๋งŒ ์ดˆ์ ์„ ๋งž์ถ”๋‹ค
    Flow๋Š” ์œ ํ˜• ์ •ํ™•์„ฑ๋งŒ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ๊ทœ์น™์„ ์ ์šฉํ•˜๊ฑฐ๋‚˜, ์ฝ”๋“œ ์•…์ทจ๋ฅผ ๊ฐ์ง€ํ•˜๊ฑฐ๋‚˜, ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ ๊ฒ€์ฆ, ๋ฆฐํŒ…, ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋‹ค๋ฅธ ๋„๊ตฌ๋“ค์ด ์—ฌ์ „ํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ง€์—ญ ์‚ฌํšŒ์™€ ์‚ฐ์—… ์ง€์› ์ถ•์†Œ
    ํ•œ๋•Œ TypeScript์— ๋Œ€ํ•œ ์ธ๊ธฐ ์žˆ๋Š” ๋Œ€์•ˆ์ด์—ˆ๋˜ Flow๋Š” ๊ฐ์†Œํ•˜๋Š” ์ฑ„ํƒMeta ์ž์ฒด ํ”„๋กœ์ ํŠธ๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๊ฐ€ TypeScript๋กœ ์ด์ „๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ƒํƒœ๊ณ„ ๊ฑด๊ฐ•, ํ”Œ๋Ÿฌ๊ทธ์ธ ์œ ์ง€ ๊ด€๋ฆฌ ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฆฌ์†Œ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
  • ์ตœ์‹  JS ํˆด๋ง๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋งˆ์ฐฐ
    Flow๋Š” Babel ์„ค์ •๊ณผ ์‚ฌ์šฉ์ž ์ง€์ • ํ”„๋ฆฌ์…‹์„ ํ†ตํ•ด ์œ ํ˜•์„ ์ œ๊ฑฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TypeScript์˜ ํ†ตํ•ฉ ์ปดํŒŒ์ผ๋Ÿฌ ๋ฐ ์ƒํƒœ๊ณ„์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ Flow๋Š” ๊ตฌ์„ฑ ๋ฐ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์–ด๋ ค์šด ๊ฒƒ์ฒ˜๋Ÿผ ๋А๊ปด์ง‘๋‹ˆ๋‹ค.
  • TypeScript์— ๋น„ํ•ด IDE ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ง€์›์ด ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.
    Flow๋Š” ํŽธ์ง‘๊ธฐ ํ†ตํ•ฉ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ TypeScript ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ณด๋‹ค ์™„์„ฑ๋„๊ฐ€ ๋‚ฎ๊ณ  ์ง€์› ๋ฒ”์œ„๋„ ๋„“์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ์ง„๋‹จ ์†๋„๊ฐ€ ๋А๋ฆฌ๊ฑฐ๋‚˜ ์ •ํ™•๋„๊ฐ€ ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.
  • ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ”„๋กœ์ ํŠธ์˜ ์œ ์—ฐ์„ฑ์ด ๋‚ฎ์Œ
    Flow์˜ ์ƒํƒœ๊ณ„๋Š” ์ฃผ๋กœ JavaScript์™€ React๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. TypeScript์˜ ๊ด‘๋ฒ”์œ„ํ•œ ํ”Œ๋žซํผ ์ง€์›(์˜ˆ: Node, Angular, ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค ๋“ฑ)์ด ๋ถ€์กฑํ•˜์—ฌ ํ’€์Šคํƒ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ํ‘œ์ค€ํ™”ํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ๊ฑฐ๋ฒ„๋„Œ์Šค ๊ธฐ๋Šฅ ์—†์Œ
    Flow๋Š” SonarQube๋‚˜ CodeQL๊ณผ ๊ฐ™์€ ๋„๊ตฌ์ฒ˜๋Ÿผ ๋Œ€์‹œ๋ณด๋“œ, ์ •์ฑ… ์ ์šฉ ๋˜๋Š” CI ์ค‘์‹ฌ ๋ถ„์„์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Flow๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐœ๋ฐœ ์‹œ์ ์— ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ์ด๋ฉฐ, ๊ฑฐ๋ฒ„๋„Œ์Šค ์†”๋ฃจ์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

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

Tern: ๊ฐ€๋ฒผ์šด JS ์ฝ”๋“œ ์ธํ…”๋ฆฌ์ „์Šค

Tern์€ ํŽธ์ง‘๊ธฐ ์ž๋™ ์™„์„ฑ ๋ฐ ํƒ์ƒ‰์„ ์œ„ํ•œ ์ง€๋Šฅํ˜• ์ฝ”๋“œ ๋ถ„์„์„ ์ œ๊ณตํ•˜๋Š” JavaScript ์ฝ”๋“œ ๋ถ„์„๊ธฐ ๋ฐ ์ถ”๋ก  ์—”์ง„์ž…๋‹ˆ๋‹ค. ์›๋ž˜๋Š” Vim, Emacs, Sublime Text ๋ฐ ์ดˆ๊ธฐ Visual Studio Code ์„ค์ •๊ณผ ๊ฐ™์€ ํŽธ์ง‘๊ธฐ์—์„œ ๋”์šฑ ์Šค๋งˆํŠธํ•œ ์ฝ”๋“œ ํžŒํŒ…, ํƒ€์ž… ์ถ”๋ก  ๋ฐ ๋ฌธ์„œ ์กฐํšŒ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

Tern์˜ ๋‹จ์ :

  • ์ „ํ†ต์ ์ธ ์˜๋ฏธ์˜ ์ •์  ๋ถ„์„๊ธฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค
    Tern์€ ๋ฒ„๊ทธ, ์ฝ”๋“œ ๋ƒ„์ƒˆ, ๋…ผ๋ฆฌ ์˜ค๋ฅ˜ ๋˜๋Š” ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ๊ฐ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ํƒ์ƒ‰ ๋ฐ ์ถ”๋ก ๋งŒ ๊ฐ€๋Šฅ์ฝ”๋“œ์˜ ์ •ํ™•์„ฑ์ด๋‚˜ ํ’ˆ์งˆ์„ ๊ฐ•์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ตœ์‹  JavaScript ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    Tern์€ ES5/ES6 ์ดˆ๊ธฐ ์‹œ๋Œ€์— ๊ฐœ๋ฐœ๋˜์—ˆ์œผ๋ฉฐ, async/await, ๊ตฌ์กฐ ๋ถ„ํ•ด, ์˜ต์…”๋„ ์ฒด์ด๋‹, ES ๋ชจ๋“ˆ, TypeScript์™€ ๊ฐ™์€ ์ตœ์‹  JavaScript ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ๊ฐ•๋ ฅํ•œ ์ง€์›์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ตœ์‹  ์ฝ”๋“œ์—์„œ๋Š” ํŒŒ์„œ๊ฐ€ ์ž์ฃผ ์ž‘๋™ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์ œํ•œ์ ์ด๊ณ  ์˜ค๋ž˜๋œ ์ƒํƒœ๊ณ„
    Tern ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ์ƒ๋‹นํžˆ ๋А๋ ค์กŒ๊ณ , ๋งŽ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋” ์ด์ƒ ์œ ์ง€ ๊ด€๋ฆฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. VSCode๋‚˜ WebStorm๊ณผ ๊ฐ™์€ IDE๊ฐ€ ๋ฐœ์ „ํ•จ์— ๋”ฐ๋ผ ๋Œ€๋ถ€๋ถ„์˜ ์›Œํฌํ”Œ๋กœ์—์„œ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์ด Tern์˜ ํ•„์š”์„ฑ์„ ๋Œ€์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค์—๋Š” ํ™•์žฅ ๋ถˆ๊ฐ€๋Šฅ
    Tern์€ ๋Œ€๊ทœ๋ชจ ๋ชจ๋…ธ๋ฆฌํฌ ๋˜๋Š” ๊ณ ๋„๋กœ ๋ชจ๋“ˆํ™”๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„ฑ๋Šฅ๊ณผ ์ •ํ™•๋„๊ฐ€ ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค. ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ์ธ๋ฑ์‹ฑ, ์บ์‹ฑ ๋ฐ ์•„ํ‚คํ…์ฒ˜ ๋ชจ๋ธ๋ง ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
  • CI/CD ๋˜๋Š” DevOps ์›Œํฌํ”Œ๋กœ์™€ ํ†ตํ•ฉ๋˜์ง€ ์•Š์Œ
    Tern์€ ์ง€์†์  ํ†ตํ•ฉ, ๋ณด๊ณ  ๋˜๋Š” ์ •์ฑ… ์ ์šฉ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋กœ์ปฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ ๊ธฐ๋ฐ˜ ํ’ˆ์งˆ ๊ฒŒ์ดํŠธ๋‚˜ ํŒ€ ์ „์ฒด ์ฝ”๋“œ ๊ฑฐ๋ฒ„๋„Œ์Šค์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • LSP(Language Server Protocol) ๊ธฐ๋ฐ˜ ๋„๊ตฌ๋กœ ๋Œ€์ฒด๋จ
    TypeScript์˜ ์–ธ์–ด ์„œ๋ฒ„, VSCode์— ๋‚ด์žฅ๋œ IntelliSense, LSP ๊ธฐ๋ฐ˜ ๋„๊ตฌ ๋“ฑ์˜ ๋„๊ตฌ๋กœ ์ธํ•ด Tern์€ ํ˜„๋Œ€ JavaScript ๊ฐœ๋ฐœ์— ์žˆ์–ด ๊ฑฐ์˜ ์“ธ๋ชจ์—†๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Tern์€ ๋‹น์‹œ๋กœ์„œ๋Š” ํ˜์‹ ์ ์ธ ๋„๊ตฌ์˜€์œผ๋ฉฐ, ์ดˆ๊ธฐ JavaScript ํŽธ์ง‘๊ธฐ์— ์ง€๋Šฅ์ ์ธ ์ฝ”๋“œ ์™„์„ฑ ๋ฐ ํƒ์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜ค๋ž˜๋œ ๊ตฌ๋ฌธ ์ง€์›, ์ œํ•œ๋œ ๊ธฐ๋Šฅ, ๊ทธ๋ฆฌ๊ณ  ์ตœ์‹  ํ†ตํ•ฉ ๊ธฐ๋Šฅ์˜ ๋ถ€์žฌ๋กœ ์ธํ•ด TypeScript, ESLint, ๊ทธ๋ฆฌ๊ณ  ํŽธ์ง‘๊ธฐ ๋„ค์ดํ‹ฐ๋ธŒ ์–ธ์–ด ์„œ๋ฒ„์™€ ๊ฐ™์€ ์ƒˆ๋กญ๊ณ  ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์— ๋ฐ€๋ ค๋‚ฌ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋‚  Tern์€ ํ˜„์žฌ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ์—์„œ ํ™œ์šฉ๋„๊ฐ€ ๋‚ฎ์€ ๋ ˆ๊ฑฐ์‹œ ๋„๊ตฌ๋กœ ๊ฐ„์ฃผํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

Snyk Code: ๋ณด์•ˆ์— ์ดˆ์ ์„ ๋งž์ถ˜ ๊ฐœ๋ฐœ์ž ์ค‘์‹ฌ ์ •์  ๋ถ„์„

Snyk Code๋Š” ์ •์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ(SAST), ์˜คํ”ˆ์†Œ์Šค ์ทจ์•ฝ์  ์Šค์บ๋‹, ์ปจํ…Œ์ด๋„ˆ ๋ณด์•ˆ ๋“ฑ ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ธ ๋ณด์•ˆ ์†”๋ฃจ์…˜์— ์ค‘์ ์„ ๋‘” Snyk ํ”Œ๋žซํผ์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. Snyk Code๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด JavaScript, TypeScript, Node.js ๋ฐ ๊ธฐํƒ€ ์ตœ์‹  ์–ธ์–ด์— ๋Œ€ํ•œ ์‹ค์‹œ๊ฐ„ ์ •์  ์ฝ”๋“œ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์—์„œ ์ง์ ‘ ์ทจ์•ฝ์ ๊ณผ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ฝ”๋”ฉ ํŒจํ„ด์„ ํƒ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Snyk Code๋Š” ์˜๋ฏธ๋ก ์  ๋ฐ ํŒจํ„ด ๊ธฐ๋ฐ˜ ๋ถ„์„์„ ํ†ตํ•ด ์šด์˜๋˜๋ฉฐ, ์„ ๋ณ„๋˜๊ณ  ํ™•์žฅ๋˜๋Š” ์ผ๋ จ์˜ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์ฃผ์ž… ์œ„ํ—˜, ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŒ…(XSS), ์†์ƒ๋œ ์ธ์ฆ ํ๋ฆ„ ๋“ฑ์˜ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋น ๋ฅธ IDE ๊ธฐ๋ฐ˜ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋™์‹œ์— CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉ๋˜์–ด ์ž๋™ํ™”๋œ ์ ์šฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ฝ”๋”ฉ ์ค‘ JavaScript ๋ฐ Node.js ์ทจ์•ฝ์  ์‹ค์‹œ๊ฐ„ ๊ฐ์ง€
  • ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ณด์•ˆ ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ํฌํ•จํ•œ ์˜๋ฏธ ์ฝ”๋“œ ๋ถ„์„
  • ํŽธ์ง‘๊ธฐ ๋‚ด ๋ฌธ์ œ ์ถ”์ ์„ ์œ„ํ•œ IDE ํ†ตํ•ฉ(VSCode, IntelliJ, WebStorm)
  • GitHub, GitLab, Bitbucket, Azure, Jenkins ๋“ฑ๊ณผ์˜ CI/CD ํ†ตํ•ฉ
  • ์•Œ๋ ค์ง„ ๋ณด์•ˆ ์œ„ํ—˜์— ๋Œ€ํ•ด ๋…์  ์ฝ”๋“œ์™€ ํƒ€์‚ฌ ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • OWASP Top 10 ๋ฐ ๊ณตํ†ต ๊ทœ์ • ์ค€์ˆ˜ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

Snyk ์ฝ”๋“œ์˜ ๋‹จ์ :

  • ๋ณด์•ˆ์—๋งŒ ์ง‘์ค‘
    Snyk Code๋Š” ๋ฒ”์šฉ ์ •์  ๋ถ„์„๊ธฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ฝ”๋“œ ์•…์ทจ, ์Šคํƒ€์ผ ์œ„๋ฐ˜, ์œ ์ง€ ๊ด€๋ฆฌ ๋ฌธ์ œ ๋˜๋Š” ์•„ํ‚คํ…์ฒ˜ ๋ฌธ์ œ๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ESLint๋‚˜ SonarQube์™€ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ๋ณด์™„ํ•˜์ง€๋งŒ ๋Œ€์ฒดํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ฐ ์ œ์–ด ํ๋ฆ„์— ๋Œ€ํ•œ ๊ฐ€์‹œ์„ฑ์ด ์ œํ•œ๋จ
    Snyk Code๋Š” ์˜๋ฏธ ์Šค์บ๋‹์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ, ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ๋…ผ๋ฆฌ, ๊นŠ์ด ์ค‘์ฒฉ๋œ ์ฝœ๋ฐฑ ๋˜๋Š” ๋Œ€๊ทœ๋ชจ JS ํ”„๋กœ์ ํŠธ์—์„œ์˜ ๋‹ค์ค‘ ํŒŒ์ผ ๋ฐ์ดํ„ฐ ์ „ํŒŒ๋ฅผ ์ถ”์ ํ•  ๋•Œ ๊นŠ์ด๊ฐ€ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ํฌ๋งทํŒ…์ด๋‚˜ ์ฝ”๋“œ ํ’ˆ์งˆ ๊ทœ์น™ ์ง€์› ์—†์Œ
    ESLint๋‚˜ Prettier์™€ ๋‹ฌ๋ฆฌ Snyk Code๋Š” ์Šคํƒ€์ผ ๊ทœ์น™์ด๋‚˜ ์„œ์‹ ๊ทœ์น™์„ ์ ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŒ€์€ ์ผ๊ด€๋œ ์ฝ”๋“œ ํ’ˆ์งˆ๊ณผ ์Šคํƒ€์ผ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ์ „ํžˆ ๋ณ„๋„์˜ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ํ์‡„ํ˜• ๊ทœ์น™ ์—”์ง„ ๋ฐ ์ œํ•œ๋œ ์‚ฌ์šฉ์ž ์ •์˜
    Semgrep์ด๋‚˜ CodeQL๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ Snyk Code๋Š” ํ˜„์žฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ง€์ • ๊ทœ์น™์ด๋‚˜ ๋…ผ๋ฆฌ ํŒจํ„ด์„ ์ •์˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Snyk์˜ ๊ธฐ๋ณธ ์ œ๊ณต ๊ทœ์น™ ์„ธํŠธ์™€ ์—…๋ฐ์ดํŠธ ์ฃผ๊ธฐ์— ๋”ฐ๋ผ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
  • ์ƒ์—… ๋ผ์ด์„ผ์Šค
    ๋ฌด๋ฃŒ ํ‹ฐ์–ด๊ฐ€ ์žˆ์ง€๋งŒ, ์ „์ฒด ํ”„๋กœ์ ํŠธ ์Šค์บ๋‹, ์ด๋ ฅ ๋ณด๊ณ , ์ •์ฑ… ์ ์šฉ๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์€ ์œ ๋ฃŒ ํ”Œ๋žœ์—์„œ๋งŒ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์†Œ๊ทœ๋ชจ ํŒ€์ด๋‚˜ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—๋Š” ์žฅ๋ฒฝ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ „์ฒด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ธํ„ฐ๋„ท ์ ‘์†์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    Snyk Code๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์—„๊ฒฉํ•œ ์—์–ด๊ฐญ ํ™˜๊ฒฝ์ด๋‚˜ ์˜จํ”„๋ ˆ๋ฏธ์Šค ๋ณด์•ˆ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์žˆ๋Š” ์กฐ์ง์˜ ๊ฒฝ์šฐ ํ†ตํ•ฉ์— ์–ด๋ ค์›€์„ ๊ฒช์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

Semgrep: ๊ฐ€๋ณ๊ณ  ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ธ ์ •์  ๋ถ„์„

Semgrep์€ ๊ธฐ์กด ๋ฆฐํ„ฐ์˜ ์†๋„์™€ ๊ฐ„ํŽธํ•จ์— ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ(AST) ๋ถ„์„์˜ ์˜๋ฏธ๋ก ์  ๊ฐ•๋ ฅํ•จ์„ ๊ฒฐํ•ฉํ•œ ์˜คํ”ˆ ์†Œ์Šค ํŒจํ„ด ๊ธฐ๋ฐ˜ ์ •์  ๋ถ„์„ ์—”์ง„์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ด๊ณ  ๋ณด์•ˆ์„ ๊ณ ๋ คํ•˜๋„๋ก ์„ค๊ณ„๋œ Semgrep์€ JavaScript, TypeScript, Node.js๋ฅผ ๋น„๋กฏํ•œ ์—ฌ๋Ÿฌ ์ตœ์‹  ์–ธ์–ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ฐ„๋‹จํ•œ YAML ๋˜๋Š” Semgrep์˜ ๋„๋ฉ”์ธ๋ณ„ ๊ตฌ๋ฌธ์œผ๋กœ ์ž‘์„ฑ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ํŒจํ„ด, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋…ผ๋ฆฌ, ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋น„๋ฐ€ ๋“ฑ์„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • JavaScript์— ๋Œ€ํ•œ ์‚ฌ์ „ ๊ตฌ์ถ•๋œ ๊ทœ์น™ ์„ธํŠธ ์ œ๊ณต(OWASP Top 10 ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€ ํฌํ•จ)
  • ๋กœ์ปฌ์—์„œ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋˜๋ฉฐ CI/CD ๋„๊ตฌ์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค.
  • ํŽธ์ง‘๊ธฐ ๋‚ด ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•œ IDE ํ†ตํ•ฉ(์˜ˆ: VSCode)
  • ์˜คํ”ˆ ์†Œ์Šค ๋ฐ ์ƒ์šฉ SaaS(๋Œ€์‹œ๋ณด๋“œ, ์ •์ฑ… ๋ฐ ํ†ต์ฐฐ๋ ฅ ํฌํ•จ)๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ๋ณด์•ˆ ๋ฐ ์ฝ”๋“œ ํ’ˆ์งˆ ์‚ฌ์šฉ ์‚ฌ๋ก€ ๋ชจ๋‘์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

Semgrep์˜ ๋‹จ์ :

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

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

CodeQL: ์ฟผ๋ฆฌ ๋กœ์ง์„ ํ™œ์šฉํ•œ ์˜๋ฏธ๋ก ์  ์ฝ”๋“œ ์Šค์บ๋‹

GitHub(ํ˜„์žฌ Microsoft์— ํŽธ์ž…๋จ)์—์„œ ๊ฐœ๋ฐœํ•œ CodeQL์€ ๊ฐœ๋ฐœ์ž์™€ ๋ณด์•ˆ ํŒ€์ด ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฌ์ธต์ ์ธ ์ •์  ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์˜๋ฏธ๋ก ์  ์ฝ”๋“œ ๋ถ„์„ ์—”์ง„์ž…๋‹ˆ๋‹ค. CodeQL์€ ๋‹จ์ˆœํ•œ ํŒจํ„ด ๋งค์นญ ๋Œ€์‹  ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ •๊ตํ•œ ์ทจ์•ฝ์ , ๋…ผ๋ฆฌ์  ๊ฒฐํ•จ, ์•ˆํ‹ฐํŒจํ„ด์„ ์ฐพ์•„๋‚ด๋Š” ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

JavaScript, TypeScript, Python, Java, C/C++, C#, Go ๋“ฑ ์—ฌ๋Ÿฌ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋ฉฐ, GitHub์˜ ์ฝ”๋“œ ์Šค์บ๋‹ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š” ํ•ต์‹ฌ ๋ถ„์„ ์—”์ง„์ž…๋‹ˆ๋‹ค. CodeQL์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ๊ฐ„ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ํƒ์ƒ‰ํ•˜๊ณ , ์˜ค์—ผ ์†Œ์Šค์—์„œ ์‹ฑํฌ๊นŒ์ง€ ์ถ”์ ํ•˜๊ณ , ์ทจ์•ฝํ•œ ์ฝ”๋”ฉ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • SQL๊ณผ ์œ ์‚ฌํ•œ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•œ ์˜๋ฏธ๋ก ์  ์ฟผ๋ฆฌ ๊ธฐ๋ฐ˜ ๋ถ„์„
  • ๋ฐ์ดํ„ฐ ํ๋ฆ„, ์ œ์–ด ํ๋ฆ„ ๋ฐ ๊ธฐ๋Šฅ ๋™์ž‘์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ํ†ต์ฐฐ๋ ฅ
  • OWASP Top 10, CWE ๋ฐ ์•Œ๋ ค์ง„ ๋ณด์•ˆ ์•ˆํ‹ฐํŒจํ„ด์— ๋Œ€ํ•œ ๋‚ด์žฅ ์ฟผ๋ฆฌ
  • GitHub Actions, GitHub Enterprise ๋ฐ CLI ์›Œํฌํ”Œ๋กœ์™€์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ
  • ์‚ฌ์šฉ์ž ์ •์˜ ์ฟผ๋ฆฌ ๋ฐ ์ฟผ๋ฆฌ ํŒฉ์„ ์ง€์›ํ•˜์—ฌ ๋†’์€ ์ˆ˜์ค€์˜ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณ ๊ธ‰ ๋ณด์•ˆ ์—ฐ๊ตฌ, ์ฝ”๋“œ ๊ฐ์‚ฌ ๋ฐ DevSecOps ํŒŒ์ดํ”„๋ผ์ธ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.

CodeQL์˜ ๋‹จ์ :

  • ๋†’์€ ํ•™์Šต ๊ณก์„ 
    CodeQL์˜ ์ฟผ๋ฆฌ ์–ธ์–ด๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ๋…ผ๋ฆฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ด๋ก , ๊ทธ๋ฆฌ๊ณ  CodeQL ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•œ ์ง€์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ CodeQL์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ๊ต์œก์ด๋‚˜ ๋ฌธ์„œ ๋ถ„์„ ์—†์ด๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ํ’ˆ์งˆ์ด๋‚˜ ์Šคํƒ€์ผ ๋ถ„์„์— ๋Œ€ํ•œ ์ œํ•œ๋œ ์œ ํ‹ธ๋ฆฌํ‹ฐ
    CodeQL์€ ๋‹ค์Œ์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ณด์•ˆ ๋ฐ ์ •ํ™•์„ฑ์„œ์‹, ๋ช…๋ช… ๊ทœ์น™ ๋˜๋Š” ์Šคํƒ€์ผ ๊ทœ์น™์„ ์ ์šฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋ƒ„์ƒˆ, ์ค‘๋ณต ๋˜๋Š” ์„œ์‹๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์—๋Š” ESLint๋‚˜ Prettier์™€ ๊ฐ™์€ ๋„๊ตฌ๊ฐ€ ์—ฌ์ „ํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ผ์ด๋ธŒ ๋˜๋Š” ํŽธ์ง‘๊ธฐ ๋‚ด ํ”ผ๋“œ๋ฐฑ ์—†์Œ
    CodeQL์€ ๊ฐœ๋ฐœ์ž ์ƒ์‚ฐ์„ฑ ๋„๊ตฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. IDE์—์„œ ์‹ค์‹œ๊ฐ„ ์ง„๋‹จ, ์ž๋™ ์™„์„ฑ ๋˜๋Š” ์ธ๋ผ์ธ ์ˆ˜์ • ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. GitHub Actions ๋˜๋Š” CLI๋ฅผ ํ†ตํ•œ ์‹คํ–‰ ๊ฒ€์‚ฌ์—๋Š” ํ”ผ๋“œ๋ฐฑ์ด ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋А๋ฆฐ ์Šค์บ” ์‹œ๊ฐ„
    CodeQL์€ ์‹ฌ์ธต์ ์ธ ์˜๋ฏธ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๊ณ„์‚ฐ์ ์œผ๋กœ ๋น„์‹ธ๋‹คํŠนํžˆ ๋ชจ๋…ธ๋ ˆํฌ์˜ ๊ฒฝ์šฐ ์ „์ฒด ํ”„๋กœ์ ํŠธ ์Šค์บ”์€ ๋ช‡ ๋ถ„ ์ด์ƒ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ˜„์žฅ์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜คํ”ˆ ์†Œ์Šค ๋ฒ„์ „์—๋Š” ์‹œ๊ฐํ™”๋‚˜ ๋Œ€์‹œ๋ณด๋“œ๊ฐ€ โ€‹โ€‹์—†์Šต๋‹ˆ๋‹ค.
    GitHub Advanced Security์—๋Š” ๋Œ€์‹œ๋ณด๋“œ ๋ฐ PR ์•Œ๋ฆผ๊ณผ ํ†ตํ•ฉ๋œ CodeQL์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€๋งŒ, ๋…๋ฆฝํ˜• ์˜คํ”ˆ์†Œ์Šค ๋„๊ตฌ๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ œํ’ˆ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ํฌ๊ด„์ ์ธ ์‹œ๊ฐํ™”, ๊ณผ๊ฑฐ ๊ธฐ๋ก ์ถ”์  ๋˜๋Š” ์ค‘์•™ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ ์ค‘์‹ฌ, ํ˜„๋Œ€ํ™” ์ค‘์‹ฌ ์•„๋‹˜
    CodeQL์€ ์ทจ์•ฝ์ , ์˜ค์—ผ ํ™•์‚ฐ, ๋ณต์žกํ•œ ์˜ค์šฉ ํŒจํ„ด์„ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ํƒ์›”ํ•˜์ง€๋งŒ ์•„ํ‚คํ…์ฒ˜ ๋ฆฌํŒฉํ† ๋ง, ๊ธฐ์ˆ  ๋ถ€์ฑ„ ํ‰๊ฐ€ ๋˜๋Š” ํ˜„๋Œ€ํ™” ๊ณ„ํš์—๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

PMD: ๋ ˆ๊ฑฐ์‹œ ์–ดํ•„์„ ํ™œ์šฉํ•œ ๊ทœ์น™ ๊ธฐ๋ฐ˜ ์ •์  ์ฝ”๋“œ ๋ถ„์„

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

PMD๋Š” Java ์ƒํƒœ๊ณ„์—์„œ ๊ฐ€์žฅ ์ž˜ ์•Œ๋ ค์ ธ ์žˆ์ง€๋งŒ, ์‚ฌ์ „ ์ •์˜๋œ ๋ช‡ ๊ฐ€์ง€ ๊ทœ์น™์„ ํ†ตํ•ด JavaScript๋„ ์ œํ•œ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. PMD๋Š” XML์„ ํ†ตํ•ด ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•˜๊ณ , ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ •์˜๋ฅผ ์ง€์›ํ•˜๋ฉฐ, Maven, Gradle, Ant์™€ ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ์™€ Jenkins ๋˜๋Š” GitHub Actions์™€ ๊ฐ™์€ CI ์„œ๋ฒ„์— ํ†ตํ•ฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

PMD์˜ ๋‹จ์ :

  • ์ œํ•œ๋œ JavaScript ์ง€์›
    PMD์˜ JavaScript ๊ทœ์น™์€ ์ œํ•œ์ ์ด๊ณ  ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  JavaScript ๊ตฌ๋ฌธ(์˜ˆ: ํด๋ž˜์Šค, async/await, ๋ชจ๋“ˆ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋“ฑ ES6+ ๊ธฐ๋Šฅ)์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ TypeScript๋„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜๋ฏธ ๋ถ„์„์ด๋‚˜ ์‹ฌ์ธต ํ๋ฆ„ ์ถ”์ ์ด ์—†์Šต๋‹ˆ๋‹ค.
    PMD๋Š” ๊ตฌ๋ฌธ ํŒจํ„ด์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๊ฐ„ ๋˜๋Š” ํŒŒ์ผ ๊ฐ„ ๋ฐ์ดํ„ฐ ํ๋ฆ„์— ๋Œ€ํ•œ ์˜๋ฏธ๋ก ์  ์ดํ•ด๋ฅผ ๊ตฌ์ถ•ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํ™ฉ์— ๋งž๋Š” ๋ฒ„๊ทธ๋‚˜ ์ทจ์•ฝ์ ์„ ๊ฐ์ง€ํ•˜๋Š” ๋Šฅ๋ ฅ์ด ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ ์ค‘์‹ฌ ๊ธฐ๋Šฅ ์—†์Œ
    PMD๋Š” ์ทจ์•ฝ์  ํƒ์ง€๋‚˜ ๊ทœ์ • ์ค€์ˆ˜ ์ ๊ฒ€(์˜ˆ: OWASP, CWE) ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฃผ์ž… ์ง€์ , ์•ˆ์ „ํ•˜์ง€ ์•Š์€ API ์‚ฌ์šฉ ๋˜๋Š” ๋ฐ์ดํ„ฐ ์œ ์ถœ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋ณด์•ˆ ๋ณด์ฆ์„ ์œ„ํ•œ SAST ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ตœ์‹  JavaScript ํˆด๋ง๊ณผ ํ†ตํ•ฉ๋˜์ง€ ์•Š์Œ
    PMD๋Š” ์ตœ์‹  JavaScript ์ƒํƒœ๊ณ„์™€์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ESLint, Prettier, Babel, Webpack๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋‚˜ React, Vue, Angular์™€ ๊ฐ™์€ ์ตœ์‹  ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ง€์›์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ์ˆ˜๋™ ๊ทœ์น™ ๊ด€๋ฆฌ ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    ๊ทœ์น™์€ ์ž์„ธํ•œ XML์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ž‘์„ฑ๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ์™€ XPath ๋˜๋Š” Java ๊ทœ์น™ ๊ฐœ๋ฐœ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • JavaScript์— ๋Œ€ํ•œ ์‹ค์‹œ๊ฐ„ IDE ํ”ผ๋“œ๋ฐฑ ์—†์Œ
    PMD๋Š” Java์šฉ IDE(์˜ˆ: Eclipse, IntelliJ)์— ํ†ตํ•ฉ๋˜์ง€๋งŒ, JavaScript ์ง€์›์—๋Š” ํ’๋ถ€ํ•œ ๋„๊ตฌ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. VSCode๋‚˜ WebStorm์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ PMD์˜ ๋„ค์ดํ‹ฐ๋ธŒ ํ”ผ๋“œ๋ฐฑ์„ ๊ฑฐ์˜ ๋ฐ›์ง€ ๋ชปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

PMD๋Š” Java ๋ฐ ๋ ˆ๊ฑฐ์‹œ JavaScript ํ”„๋กœ์ ํŠธ, ํŠนํžˆ ์ด๋ฏธ ๋‹ค๋ฅธ ์–ธ์–ด์— PMD๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์กฐ์ง์—์„œ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ •์  ๋ถ„์„ ๋„๊ตฌ๋กœ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ JavaScript ์ง€์›์€ ์ œํ•œ์ ์ด๊ณ  ์˜ค๋ž˜๋˜์—ˆ์œผ๋ฉฐ ์ตœ์‹  ๊ฐœ๋ฐœ ๋ฐฉ์‹์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์‹  JavaScript ๋ฐ TypeScript ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๊ฒฝ์šฐ, ESLint, Semgrep ๋˜๋Š” SonarQube๊ฐ€ ํ›จ์”ฌ ๋” ๊ด‘๋ฒ”์œ„ํ•œ ๊ธฐ๋Šฅ, ํ™œ๋ฐœํ•œ ์ƒํƒœ๊ณ„ ์ง€์›, ๊ทธ๋ฆฌ๊ณ  ์ตœ์‹  ํ”„๋ŸฐํŠธ์—”๋“œ ๋ฐ ํ’€์Šคํƒ ํˆด๋ง๊ณผ์˜ ํ–ฅ์ƒ๋œ ํ†ตํ•ฉ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

DeepScan: ๋Ÿฐํƒ€์ž„ ๋ฌธ์ œ์— ์ดˆ์ ์„ ๋งž์ถ˜ ์ •์  ๋ถ„์„

DeepScan์€ JavaScript ๋ฐ TypeScript์šฉ์œผ๋กœ ํŠน๋ณ„ํžˆ ์„ค๊ณ„๋œ ์ •์  ๋ถ„์„ ๋„๊ตฌ๋กœ, ESLint์™€ ๊ฐ™์€ ๊ธฐ์กด ๋ฆฐํ„ฐ๊ฐ€ ๊ฐ„๊ณผํ•˜๊ธฐ ์‰ฌ์šด ๋Ÿฐํƒ€์ž„ ๋ฌธ์ œ, ํ’ˆ์งˆ ๊ฒฐํ•จ, ๊ทธ๋ฆฌ๊ณ  ๋กœ์ง ๋ฒ„๊ทธ๋ฅผ ํƒ์ง€ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์Šคํƒ€์ผ ์ ์šฉ์„ ๋„˜์–ด ์‹ฌ์ธต์ ์ธ ์˜๋ฏธ์  ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์—ฌ React, Vue, Angular์™€ ๊ฐ™์€ ์ตœ์‹  ํ”„๋ŸฐํŠธ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript ๋ฐ TypeScript ์ฝ”๋“œ์˜ ์‹ฌ์ธต์  ์˜๋ฏธ ๋ถ„์„
  • null ์—ญ์ฐธ์กฐ, ์ž˜๋ชป๋œ ์กฐ๊ฑด, ์žŠ์–ด๋ฒ„๋ฆฐ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์€ ๋Ÿฐํƒ€์ž„ ๋ฌธ์ œ ๊ฐ์ง€
  • ์ธ๊ธฐ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ(React, Vue, Angular)์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ง€์›
  • ์ฝ”๋“œ ํ’ˆ์งˆ ์ถ”์  ๋ฐ ์ธก์ •์„ ์œ„ํ•œ ์›น ๊ธฐ๋ฐ˜ ๋Œ€์‹œ๋ณด๋“œ
  • ์ธ๋ผ์ธ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ ๋ถ„์„์„ ์œ„ํ•œ GitHub ํ†ตํ•ฉ
  • CLI ์ง€์› ๋ฐ VSCode ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐ–์ถ˜ ๊ฐ€๋ฒผ์šด ์„ค์ •

DeepScan์˜ ๋‹จ์ :

  • ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ง€์› ์—†์Œ
    ESLint๋‚˜ Semgrep๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ DeepScan์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ง€์ • ๊ทœ์น™์„ ์ •์˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ํ”„๋กœ์ ํŠธ๋ณ„ ์ฝ”๋”ฉ ์ง€์นจ์„ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ํŠน์ • ๋กœ์ง์„ ์ ์šฉํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ๊ธฐ์—… ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ํ™•์žฅ์„ฑ ์ œํ•œ
    DeepScan์˜ ๋Œ€์‹œ๋ณด๋“œ์™€ ์ •์ฑ… ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์€ ์†Œ๊ทœ๋ชจ ๋ฐ ์ค‘๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜์ง€๋งŒ, ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ๋ณด๊ณ , ๋‹ค์ค‘ ์ €์žฅ์†Œ ๊ฑฐ๋ฒ„๋„Œ์Šค ๋˜๋Š” ์กฐ์ง ๊ทœ์ • ์ค€์ˆ˜ ์ถ”์  ์ธก๋ฉด์—์„œ๋Š” SonarQube๋‚˜ CodeQL๊ณผ ๊ฐ™์€ ํ”Œ๋žซํผ๋งŒํผ ๊ฐ•๋ ฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ์ด ์•„๋‹Œ ๋Ÿฐํƒ€์ž„ ์ •ํ™•์„ฑ์— ์ง‘์ค‘ํ•˜์„ธ์š”
    DeepScan์€ ๋…ผ๋ฆฌ์  ๊ฒฐํ•จ์„ ํฌ์ฐฉํ•˜๋Š” ๋ฐ ๋งค์šฐ ๋›ฐ์–ด๋‚˜์ง€๋งŒ ๋ณด์•ˆ ๋ถ„์„์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹คXSS, SQL ์ฃผ์ž…, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ธ์ฆ ๋…ผ๋ฆฌ ๋˜๋Š” ์•Œ๋ ค์ง„ ์ทจ์•ฝ์  ํŒจํ„ด๊ณผ ๊ฐ™์€ ์ทจ์•ฝ์ ์€ ์ฝ”๋“œ ๋…ผ๋ฆฌ ๋ฌธ์ œ๋กœ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š” ํ•œ ๊ฐ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ฑด์ถ• ์‹œ๊ฐํ™”๋‚˜ ๊ธฐ์ˆ  ๋ถ€์ฑ„ ๋ชจ๋ธ๋ง์ด ์—†์Šต๋‹ˆ๋‹ค.
    DeepScan์€ ์ธก์ •ํ•ญ๋ชฉ๊ณผ ๋ฌธ์ œ ๋ถ„๋ฅ˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ์ข…์†์„ฑ ๊ทธ๋ž˜ํ”„, ์ค‘๋ณต ๊ฐ์ง€, ํ˜„๋Œ€ํ™” ์ค€๋น„์„ฑ ํ†ต์ฐฐ๋ ฅ๊ณผ ๊ฐ™์€ ๊ณ ์ˆ˜์ค€ ์‹œ๊ฐํ™” ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
  • ์›น ๊ธฐ๋ฐ˜์ด์ง€๋งŒ ์˜จํ”„๋ ˆ๋ฏธ์Šค ๋˜๋Š” ์—์–ด๊ฐญ ํ™˜๊ฒฝ์—์„œ๋Š” ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    DeepScan์˜ ๊ธฐ๋Šฅ ๋Œ€๋ถ€๋ถ„์€ ํด๋ผ์šฐ๋“œ ํ†ตํ•ฉ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. CLI๊ฐ€ ์กด์žฌํ•˜๋”๋ผ๋„, ์ œํ•œ์ ์ด๊ฑฐ๋‚˜ ์˜คํ”„๋ผ์ธ ํ™˜๊ฒฝ์—์„œ ์ž‘์—…ํ•˜๋Š” ์‚ฌ์šฉ์ž๋Š” ๋„์ž…์— ์–ด๋ ค์›€์„ ๊ฒช์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฆฐํ„ฐ๋‚˜ ํฌ๋งคํ„ฐ๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•˜์ง€ ์•Š์Œ
    DeepScan์€ ESLint๋‚˜ Prettier์™€ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ๋ณด์™„ํ•˜์ง€๋งŒ, ์ฝ”๋“œ ์Šคํƒ€์ผ์ด๋‚˜ ์„œ์‹์„ ๊ฐ•์ œํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํŒ€์€ ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๋ณ„๋„์˜ ๋„๊ตฌ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

Retire.js: ์ข…์†์„ฑ์— ๋Œ€ํ•œ ํƒ€๊ฒŸ ์ทจ์•ฝ์  ์Šค์บ๋‹

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์„ ์ฐพ๊ธฐ ์œ„ํ•ด JavaScript ์†Œ์Šค ํŒŒ์ผ๊ณผ Node.js ๋ชจ๋“ˆ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ฐœ ์ทจ์•ฝ์„ฑ ์ €์žฅ์†Œ(์ปค๋ฎค๋‹ˆํ‹ฐ ํ๋ ˆ์ด์…˜)๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋นŒ๋“œ ๋ฐ ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ CLI ๋„๊ตฌ
  • ํด๋ผ์ด์–ธํŠธ ์ธก ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ทจ์•ฝ์ ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐ์ง€ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ
  • ๋น ๋ฅธ ์‹คํ–‰ ๋ฐ ๊ฐ€๋ฒผ์šด ์„ค์ •
  • npm, Yarn ๋ฐ ๊ธฐํƒ€ Node.js ์ƒํƒœ๊ณ„์™€ ํ˜ธํ™˜ ๊ฐ€๋Šฅ

Retire.js์˜ ๋‹จ์ :

  • ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ๋งŒ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค
    Retire.js๊ฐ€ ๊ฐ์ง€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์•Œ ์ˆ˜์—†๋Š” or ์†Œ์„ค ์ทจ์•ฝ์ , ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ฝ”๋”ฉ ํŒจํ„ด ๋˜๋Š” ๋Ÿฐํƒ€์ž„ ๋กœ์ง ์˜ค๋ฅ˜๋ฅผ ํƒ์ง€ํ•ฉ๋‹ˆ๋‹ค. CVE ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ผ์น˜ํ•˜๋Š” ํŒจํ‚ค์ง€์™€ ์Šคํฌ๋ฆฝํŠธ๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ๋…ผ๋ฆฌ๋‚˜ ๋™์ž‘ ๋ถ„์„์ด ์—†์Šต๋‹ˆ๋‹ค.
    Retire.js๋Š” ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜์ง€ ์•Š๊ณ , ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ์ž์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ API ์‚ฌ์šฉ, ์˜ค์—ผ๋œ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ๋˜๋Š” ์ž˜๋ชป ๊ตฌ์„ฑ๋œ ๋ณด์•ˆ ์ œ์–ด๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ข…์†์„ฑ ํ•ด๊ฒฐ์€ ๊ธฐ๋ณธ์ž…๋‹ˆ๋‹ค
    Retire.js๋Š” ์™„์ „ํ•œ ์ข…์†์„ฑ ๊ทธ๋ž˜ํ”„, ์ „์ด์  ์ข…์†์„ฑ ํ•ด๊ฒฐ, ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๋ฐฉ์‹์— ๋Œ€ํ•œ ๋งฅ๋ฝ์  ํ†ต์ฐฐ๋ ฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ฐ€์–‘ ์„ฑ (๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์ง€๋งŒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ) ๋˜๋Š” ๊ฑฐ์ง“ ๋ถ€์ • (์ทจ์•ฝ์ ์ด ํŠธ๋ฆฌ์˜ ๋” ๊นŠ์€ ๊ณณ์— ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ).
  • ์ž์„ธํ•œ ๊ฐœ์„  ์ง€์นจ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
    Retire.js๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ทจ์•ฝํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๋ ค์ฃผ์ง€๋งŒ ํŠนํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ์ˆ˜์ • ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์กฐ์–ธ์€ ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. ์Šค ๋‹ˆํฌ or npm ๊ฐ์‚ฌ ํŠน์ • ์ˆ˜์ • ๋ฒ„์ „์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.
  • IDE ๋˜๋Š” ์ธ๋ผ์ธ ๊ฐœ๋ฐœ์ž ํ”ผ๋“œ๋ฐฑ๊ณผ์˜ ํ†ตํ•ฉ์ด ์—†์Šต๋‹ˆ๋‹ค.
    ESLint๋‚˜ Snyk Code์™€ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ Retire.js๋Š” ํŽธ์ง‘๊ธฐ ๋‚ด์—์„œ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ง์ ‘ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ๋นŒ๋“œ ํƒ€์ž„ ์ž๋™ํ™”์— ์˜์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์ฒด๋œ ๊ฐœ๋ฐœ๊ณผ ์ œํ•œ๋œ ์ƒํƒœ๊ณ„ ์ง€์›
    Retire.js๋Š” ์•„์ง ์ž‘๋™ํ•˜์ง€๋งŒ, ๋” ์ด์ƒ ํ™œ๋ฐœํ•˜๊ณ  ๋นˆ๋ฒˆํ•œ ๊ฐœ๋ฐœ์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ทœ๋ชจ๊ฐ€ ์ž‘๊ณ , ์ทจ์•ฝ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—…๋ฐ์ดํŠธ๊ฐ€ ์ตœ์‹  ๋„๊ตฌ๋ณด๋‹ค ๋А๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Retire.js๋Š” ํŠนํžˆ ํ”„๋ŸฐํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ์—์„œ ์˜ค๋ž˜๋˜์—ˆ๊ฑฐ๋‚˜ ์ทจ์•ฝํ•œ JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํƒ์ง€ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ์™„์ „ํ•œ ์ •์  ์ฝ”๋“œ ๋ถ„์„ ์†”๋ฃจ์…˜์ด ์•„๋‹Œ, ํŠน์ • ๋ชฉ์ ์— ๊ตญํ•œ๋œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ทจ์•ฝ์  ์Šค์บ๋‹, ์ฝ”๋“œ ๋กœ์ง ๋ถ„์„, ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ ๋“ฑ ๋” ๊ด‘๋ฒ”์œ„ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Retire.js๋ฅผ ์ตœ์‹  DevSecOps ์›Œํฌํ”Œ๋กœ์˜ ์ผ๋ถ€๋กœ Snyk, Semgrep, SonarQube์™€ ๊ฐ™์€ ๋„๊ตฌ๋กœ ๋ณด์™„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ: ์˜คํ”ˆ์†Œ์Šค ์ข…์†์„ฑ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ

OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ(ODASP Dependency-Check)๋Š” ์˜คํ”ˆ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ”„๋กœ์ ํŠธ(OWASP)์—์„œ ๊ฐœ๋ฐœ๋œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌ์„ฑ ๋ถ„์„(SCA) ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ์›จ์–ด ํŒจํ‚ค์ง€๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  ์ด๋ฅผ NVD(National Vulnerability Database)์™€ ๊ฐ™์€ ๊ณต๊ฐœ ์ทจ์•ฝ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋น„๊ตํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์ข…์†์„ฑ์—์„œ ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ (CVE)์„ ์‹๋ณ„ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Dependency-Check๋Š” ์ฒ˜์Œ์—๋Š” Java ์ƒํƒœ๊ณ„(Maven ๋ฐ Gradle์„ ํ†ตํ•ด)์— ๋งž์ถฐ์ ธ ์žˆ์—ˆ์ง€๋งŒ ๋ถ„์„์„ ํ†ตํ•ด JavaScript ๋ฐ Node.js ํ”„๋กœ์ ํŠธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. package.json package-lock.json ํŒŒ์ผ. ์ด ๋„๊ตฌ๋Š” CLI ์œ ํ‹ธ๋ฆฌํ‹ฐ, Maven ํ”Œ๋Ÿฌ๊ทธ์ธ, Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ, Ant ์ž‘์—… ๋ฐ Jenkins ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ œ๊ณต๋˜์–ด CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๋ฐ ๋นŒ๋“œ ์‹œ์Šคํ…œ์—์„œ ์ž๋™ํ™”๋ฅผ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์•Œ๋ ค์ง„ CVE์— ๋Œ€ํ•œ JavaScript(Node.js) ์ข…์†์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์‹ฑํ•˜๋‹ค package.json, npm-shrinkwrap.json๊ธ€๋ Œ๋ฐ์ผ package-lock.json ํŒŒ์ผ
  • CI/CD ๋„๊ตฌ์™€ ํ†ตํ•ฉํ•˜์—ฌ ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.
  • NVD, Retire.js DB, OSS Index ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ž์„ธํ•œ HTML, XML ๋ฐ JSON ๋ณด๊ณ ์„œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฑฐ์ง“ ์–‘์„ฑ์„ ๊ฑธ๋Ÿฌ๋‚ด๊ธฐ ์œ„ํ•œ ์–ต์ œ ํŒŒ์ผ ์ง€์›
  • OWASP ์žฌ๋‹จ์˜ ๋ฌด๋ฃŒ ์˜คํ”ˆ ์†Œ์Šค

์ข…์†์„ฑ ๊ฒ€์‚ฌ์˜ ๋‹จ์ :

  • ํƒ€์‚ฌ ์ข…์†์„ฑ์—๋งŒ ์ดˆ์ ์„ ๋งž์ถฅ๋‹ˆ๋‹ค.
    Dependency-Check๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์šฉ์ž ์ง€์ • JavaScript ๋˜๋Š” TypeScript ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ฝ”๋“œ๋ฒ ์ด์Šค ๋‚ด์˜ ๋…ผ๋ฆฌ์  ๊ฒฐํ•จ, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํŒจํ„ด ๋˜๋Š” ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์‚ฌ์šฉ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์˜๋ฏธ๋ก ์  ๋˜๋Š” ๋Ÿฐํƒ€์ž„ ๋ถ„์„ ์—†์Œ
    Semgrep ๋˜๋Š” CodeQL๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ Dependency-Check๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ •์  ์ฝ”๋“œ ๋ถ„์„ ์—†์Œ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์ถ”์ ํ•˜์ง€ ์•Š๊ณ , API ์˜ค์šฉ์„ ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ทจ์•ฝํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ๋ชจ๋ธ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • JavaScript ์ง€์›์ด ์ œํ•œ์ ์ด๊ณ  ๋œ ์„ฑ์ˆ™ํ•จ
    Java์— ๋น„ํ•ด Node.js ์ง€์›์€ ๋œ ๊ฒฌ๊ณ ํ•˜๋‹ค์ข…์†์„ฑ ํ•ด๊ฒฐ, ์ทจ์•ฝ์„ฑ ๋งคํ•‘ ๋ฐ ์ •ํ™•๋„๋Š” ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๋‹จ์ผ ๋ฆฌํฌ ๊ตฌ์กฐ์—์„œ ์ผ๊ด€๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠนํžˆ ๊นŠ์ด ์ค‘์ฒฉ๋˜๊ฑฐ๋‚˜ ์ „์ด์  ์ข…์†์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋А๋ฆฌ๊ณ  ๋ฌด๊ฑฐ์›€
    ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฌด๊ฑฐ์šด CVE ๋งคํ•‘์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ Dependency-Check๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๊ทœ๋ชจ JavaScript ๋˜๋Š” ๋‹ค๊ตญ์–ด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ๋Š” ๋А๋ฆผ.
  • ๊ฑฐ์ง“ ์–‘์„ฑ ๋ฐ ๊ฑฐ์ง“ ์Œ์„ฑ์€ ํ”ํ•ฉ๋‹ˆ๋‹ค.
    ํŠนํžˆ JavaScript์˜ ๊ฒฝ์šฐ CVE ๋งคํ•‘์€ ์ด๋ฆ„ ๋ฐ ๋ฒ„์ „ ํœด๋ฆฌ์Šคํ‹ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ ์ด๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์–‘ ์„ฑ (์˜ˆ: ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ง€์ •๋œ ์ทจ์•ฝ์ ) ๋˜๋Š” ๋†“์นœ ํƒ์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ๋ถˆ์™„์ „ํ•œ ๊ฒฝ์šฐ.
  • ์ˆ˜์ • ์ œ์•ˆ์ด๋‚˜ ์ˆ˜์ • ์ž๋™ํ™”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
    ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ ์Šค ๋‹ˆํฌ or npm ๊ฐ์‚ฌDependency-Check๋Š” ์ˆ˜์ • ๊ฐ€๋Šฅํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒฝ๋กœ, ํ˜ธํ™˜์„ฑ ๋ถ„์„ ๋˜๋Š” ์ž๋™ํ™”๋œ ์ˆ˜์ • ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • IDE ํ†ตํ•ฉ์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ๊ฐœ๋ฐœ์ž ํ”ผ๋“œ๋ฐฑ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
    ์ธ๋ผ์ธ ์ œ์•ˆ์ด๋‚˜ ๊ฐœ๋ฐœ์ž ์ค‘์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ถœ๋ ฅ์„ ํšจ๊ณผ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ, ๊ฐœ๋ฐœ์ž๋Š” ๋ณด๊ณ ์„œ๋ฅผ ์ง์ ‘ ๊ฒ€ํ† ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

OWASP Dependency-Check๋Š” ํŠนํžˆ ๊ทœ์ œ๋œ ํ™˜๊ฒฝ์—์„œ JavaScript ๋ฐ Node.js ์ข…์†์„ฑ์˜ ์ทจ์•ฝ์ ์„ ํŒŒ์•…ํ•˜๊ณ ์ž ํ•˜๋Š” ํŒ€์—๊ฒŒ ์œ ์šฉํ•œ ๋ฌด๋ฃŒ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋„๊ตฌ๋Š” ์ทจ์•ฝ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šค์บ๋„ˆ์ด๋ฉฐ, ์™„์ „ํ•œ ์ •์  ๋ถ„์„ ๋„๊ตฌ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ํšจ๊ณผ์ ์ธ JavaScript ๋ณด์•ˆ์„ ์œ„ํ•ด์„œ๋Š” Semgrep์ด๋‚˜ CodeQL๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ์ˆ˜์ค€ ๋ถ„์„๊ธฐ์™€ ESLint๋‚˜ Snyk Code์™€ ๊ฐ™์€ ์‹ค์‹œ๊ฐ„ ๋ฆฐํ„ฐ(linter)๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์†์„ฑ ์œ„ํ—˜๊ณผ ์ฝ”๋“œ ๋‚ด ์œ„ํ—˜์„ ๋ชจ๋‘ ํŒŒ์•…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

NodeJsScan: ์ •์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ

NodeJsScan์€ Node.js ๋ฐ JavaScript ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ํƒ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ๊ฐœ๋ฐœ๋œ ์˜คํ”ˆ์†Œ์Šค ์ •์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ(SAST) ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ธก JavaScript ์ฝ”๋“œ(Express ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํฌํ•จ)๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์ฃผ์ž… ๊ณต๊ฒฉ, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ฟ ํ‚ค ์ฒ˜๋ฆฌ, ๊ฒฝ๋กœ ์ˆœํšŒ, ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ ๋…ธ์ถœ๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

NodeJsScan์€ Node.js ์ƒํƒœ๊ณ„์— ๋งž์ถฐ ๋ฏธ๋ฆฌ ์ •์˜๋œ ๋ณด์•ˆ ๊ทœ์น™ ์ง‘ํ•ฉ์— ๋”ฐ๋ผ ์†Œ์Šค ํŒŒ์ผ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, CLI ๋„๊ตฌ, Docker ์ด๋ฏธ์ง€๋กœ ์ œ๊ณต๋˜์–ด ๋กœ์ปฌ ๊ฒ€์‚ฌ ๋˜๋Š” DevSecOps ํŒŒ์ดํ”„๋ผ์ธ ํ†ตํ•ฉ์— ์œ ์—ฐํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ํ†ตํ•œ ์ธ๋ผ์ธ ๋ณด์•ˆ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•ด GitHub ์—ฐ๋™์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์•Œ๋ ค์ง„ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์ฐพ๊ธฐ ์œ„ํ•ด JavaScript ๋ฐ Node.js ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • XSS, SQL/NoSQL ์ฃผ์ž…, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํ‰๊ฐ€ ๋ฐ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ข…์†์„ฑ๊ณผ ๊ฐ™์€ ์œ„ํ—˜์„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • CI/CD ์›Œํฌํ”Œ๋กœ์šฐ์— ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” CLI ๋ฐ Docker ์ง€์›
  • Express, HTTP ์ฒ˜๋ฆฌ, JWT ์‚ฌ์šฉ ๋ฐ ํŒŒ์ผ ์‹œ์Šคํ…œ API์— ๋Œ€ํ•œ ๋ฏธ๋ฆฌ ์ •์˜๋œ ๊ทœ์น™
  • ํ’€ ๋ฆฌํ€˜์ŠคํŠธ ์Šค์บ๋‹ ๋ฐ ์ธ๋ผ์ธ ์•Œ๋ฆผ์„ ์œ„ํ•œ GitHub ํ†ตํ•ฉ
  • ๋ฌด๊ฑฐ์šด SAST ๋„๊ตฌ์— ๋Œ€ํ•œ ๊ฐ€๋ณ๊ณ  ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ธ ๋Œ€์•ˆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

NodeJsScan์˜ ๋‹จ์ :

  • ๋ณด์•ˆ ์Šค์บ๋‹์—๋งŒ ๊ตญํ•œ๋จ
    NodeJsScan์€ ๋ณด์•ˆ ๋ฌธ์ œ์—๋งŒ ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ํ’ˆ์งˆ, ์œ ์ง€๋ณด์ˆ˜์„ฑ, ์•„ํ‚คํ…์ฒ˜ ๊ตฌ์กฐ ๋˜๋Š” ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ๋ถ„์„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ๋ฌธ์ œ, ๋กœ์ง ๋ฒ„๊ทธ, ๋ชจ๋ฒ” ์‚ฌ๋ก€ ์œ„๋ฐ˜์€ ๋ถ„์„ ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜๋ฏธ๋ก ์ ์ด๊ณ  ์‹ฌ์ธต์ ์ธ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ๋ถ„์„์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
    NodeJsScan์€ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํŒจํ„ด์„ ๊ฐ์ง€ํ•˜์ง€๋งŒ ํŒจํ„ด ๊ธฐ๋ฐ˜์˜๋ฏธ๋ก ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ์˜ค์—ผ ํ๋ฆ„, ๋น„๋™๊ธฐ ์ œ์–ด ๊ฒฝ๋กœ ๋˜๋Š” ๋‹ค์ธต ์ทจ์•ฝ์ ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋งŒํผ ๊นŠ์ด ์ถ”์ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. CodeQL or ์…ˆ๊ทธ๋ ™.
  • ์ž‘์€ ๊ทœ์น™ ์„ธํŠธ ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์Œ
    ์‚ฌ์ „ ์ •์˜๋œ ๊ทœ์น™ ์„ธํŠธ๋Š” ์ผ๋ฐ˜์ ์ธ ์ทจ์•ฝ์ ์— ๋„์›€์ด ๋˜์ง€๋งŒ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ƒ์„ฑ์ด ์ œํ•œ๋จ์œ ์—ฐํ•˜๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„ ๊ณ ์œ ํ•œ ํ”„๋กœ์ ํŠธ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋งž๊ฒŒ ์กฐ์ •ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ์ตœ์†Œํ•œ์˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ง€์›
    Express๋Š” ์ง€์›๋˜์ง€๋งŒ, Hapi, Koa, NestJS ๋“ฑ ๋‹ค๋ฅธ Node.js ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋”์šฑ ๋‹ค์–‘ํ•œ ๋ฐฑ์—”๋“œ ํ™˜๊ฒฝ์—์„œ ๋„๊ตฌ์˜ ํšจ์œจ์„ฑ์ด ์ œํ•œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • IDE ํ†ตํ•ฉ์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ๊ฐœ๋ฐœ์ž ํ”ผ๋“œ๋ฐฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
    NodeJsScan์€ ํŒŒ์ดํ”„๋ผ์ธ์ด๋‚˜ CLI๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ์ง์ ‘ ํ†ตํ•ฉ๋˜์ง€ ์•Š์Œ VSCode์ฒ˜๋Ÿผ์š”. ๊ฐœ๋ฐœ์ž๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์‹ฌ์ธต์ ์ธ ์ข…์†์„ฑ์ด๋‚˜ ํƒ€์‚ฌ ํŒจํ‚ค์ง€ ๋ถ„์„์ด ์—†์Šต๋‹ˆ๋‹ค.
    NodeJsScan์€ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํŒจํ„ด์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์Šค์บ”ํ•˜์ง€ ์•Š์Œ node_modules ๋˜๋Š” CVE ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ํŒจํ‚ค์ง€๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.. ๊ฐ™์€ ๋„๊ตฌ ์Šค ๋‹ˆํฌ or OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ ์ „์ฒด SCA(์†Œํ”„ํŠธ์›จ์–ด ๊ตฌ์„ฑ ๋ถ„์„)์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ ๋ณด๊ณ  ๋ฐ ๋Œ€์‹œ๋ณด๋“œ
    ์˜คํ”ˆ์†Œ์Šค ๋ฒ„์ „์€ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๋„๊ตฌ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ณ ๊ธ‰ ๋ณด๊ณ  ๊ธฐ๋Šฅ์ด๋‚˜ ๋Œ€์‹œ๋ณด๋“œ๊ฐ€ โ€‹โ€‹๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์ผ๋ฐ˜ ์ถœ๋ ฅ์ด๋‚˜ ๊ธฐ๋ณธ ์›น UI๋กœ ์ œ๊ณต๋˜๋ฉฐ, ์ •์ฑ… ์ ์šฉ ๊ธฐ๋Šฅ์€ ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.

NodeJsScan์€ Node.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ํƒ์ง€ํ•˜๋Š” ์‹ค์šฉ์ ์ด๊ณ  ์ง‘์ค‘์ ์ธ ์†”๋ฃจ์…˜์œผ๋กœ, ํŠนํžˆ ์ƒ์šฉ SAST ์ œํ’ˆ์— ๋Œ€ํ•œ ์˜คํ”ˆ์†Œ์Šค ๋Œ€์•ˆ์„ ์ฐพ๋Š” ํŒ€์—๊ฒŒ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์™„์ „ํ•œ ์ •์  ๋ถ„์„ ํ”Œ๋žซํผ์€ ์•„๋‹ˆ๋ฉฐ, ์ฝ”๋“œ ํ’ˆ์งˆ์„ ์œ„ํ•ด์„œ๋Š” ESLint, ์ข…์†์„ฑ ์Šค์บ๋‹์„ ์œ„ํ•ด์„œ๋Š” Snyk, ๊ทธ๋ฆฌ๊ณ  ๊ณ ๊ธ‰ ์˜๋ฏธ ๋ถ„์„ ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ์œ„ํ•ด์„œ๋Š” CodeQL์ด๋‚˜ Semgrep๊ณผ ๊ฐ™์€ ๋„๊ตฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

JSCS: ์ฝ”๋“œ ์Šคํƒ€์ผ ์‹œํ–‰์˜ ์‚ฌ๋ผ์ง„ ์„ ๊ตฌ์ž

JSCS(JavaScript Code Style์˜ ์•ฝ์ž)๋Š” ํ•œ๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ผ๊ด€๋œ ์ฝ”๋”ฉ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘” ์ธ๊ธฐ ์žˆ๋Š” ์ •์  ์ฝ”๋“œ ๋ถ„์„ ๋„๊ตฌ์˜€์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๋“ค์—ฌ์“ฐ๊ธฐ, ๊ณต๋ฐฑ, ์ค‘๊ด„ํ˜ธ ์Šคํƒ€์ผ, ๋”ฐ์˜ดํ‘œ ์‚ฌ์šฉ ๋“ฑ์˜ ์„œ์‹ ๋ถˆ์ผ์น˜๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์‚ฌ์ „ ์„ค์ •๋œ ๊ทœ์น™ ์„ธํŠธ(์˜ˆ: Google, Airbnb, jQuery)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํŒŒ์•…ํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. JSCS๋Š” ์ „์„ฑ๊ธฐ์—๋Š” ์„œ์‹๋ณด๋‹ค๋Š” ๋…ผ๋ฆฌ ๋ฐ ๊ตฌ๋ฌธ ์ •ํ™•์„ฑ์— ๋” ์ค‘์ ์„ ๋‘” JSHint ๋ฐ JSLint์™€ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ๋ณด์™„ํ•˜๋Š” ๋ฐ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ 2016๋…„์— JSCS๋Š” ๊ณต์‹์ ์œผ๋กœ ์ง€์› ์ค‘๋‹จ๋˜์–ด ESLint์— ํ†ตํ•ฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹œ ESLint๋Š” JavaScript์˜ ์ฃผ์š” ๋ฆฐํ„ฐ๋กœ ์ž๋ฆฌ ์žก์•˜์Šต๋‹ˆ๋‹ค. ESLint๋Š” JSCS์˜ ์Šคํƒ€์ผ ๊ฒ€์‚ฌ ๊ทœ์น™๊ณผ ์„œ์‹ ๊ธฐ๋Šฅ์„ ํ†ตํ•ฉํ•˜์—ฌ ๊ฒฐ๊ตญ JSCS๋ฅผ ์“ธ๋ชจ์—†๊ฒŒ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ JSCS๋Š” ๋” ์ด์ƒ ์œ ์ง€ ๊ด€๋ฆฌ๋˜์ง€ ์•Š์œผ๋ฉฐ, GitHub ์ €์žฅ์†Œ๋Š” ๋ณด๊ด€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

JSCS๊ฐ€ ์ œ๊ณตํ•œ ๊ฒƒ:

  • ๋“ค์—ฌ์“ฐ๊ธฐ, ์ค„ ๊ฐ„๊ฒฉ, ๋”ฐ์˜ดํ‘œ ์‚ฌ์šฉ, ์„ธ๋ฏธ์ฝœ๋ก ๊ณผ ๊ฐ™์€ ๊ฐ•์ œ ์ฝ”๋”ฉ ์Šคํƒ€์ผ ๊ทœ์น™
  • ์ง€์›๋˜๋Š” ์‚ฌ์ „ ์„ค์ • ๊ตฌ์„ฑ(Airbnb, Google ๋“ฑ) ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์ •์˜
  • ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ๊ณผ์˜ ํ†ตํ•ฉ ๋ฐ ๋ช…๋ น์ค„ ์‹คํ–‰์„ ์œ„ํ•œ CLI ๋„๊ตฌ
  • ๊ทœ์น™ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ JSON ๊ธฐ๋ฐ˜ ๊ตฌ์„ฑ
  • Sublime Text ๋ฐ Atom๊ณผ ๊ฐ™์€ ๋‹น์‹œ ์ธ๊ธฐ ์žˆ๋Š” ํŽธ์ง‘๊ธฐ์— ๋Œ€ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ง€์›

JSCS์˜ ๋‹จ์ (๋‹น์‹œ์™€ ํ˜„์žฌ):

  • ๋” ์ด์ƒ ์ง€์›๋˜์ง€ ์•Š์Œ
    JSCS๋Š” 2016๋…„ ์ดํ›„ ์œ ์ง€ ๊ด€๋ฆฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ, ๋ฒ„๊ทธ ์ˆ˜์ • ๋˜๋Š” ํ˜ธํ™˜์„ฑ ๊ฐœ์„ ์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. JSCS ์ƒํƒœ๊ณ„๋Š” ESLint์— ์™„์ „ํžˆ ํก์ˆ˜๋˜์—ˆ์œผ๋ฉฐ, ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋Š” JSCS๋ฅผ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ํ’ˆ์งˆ์ด๋‚˜ ๋ณด์•ˆ์ด ์•„๋‹Œ ์Šคํƒ€์ผ์—๋งŒ ์ง‘์ค‘
    JSCS๋Š” ์„œ์‹์„ ์ ์šฉํ–ˆ์ง€๋งŒ ๋ฒ„๊ทธ, ์ฝ”๋“œ ์Šค๋ฉœ, ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ํฌ์ฐฉํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ESLint๊ฐ€ ํ˜„์žฌ ํฌ๊ด„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜, ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ, ์œ„ํ—˜ํ•œ ํŒจํ„ด ํ•จ์ˆ˜ ๋“ฑ์„ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์œ ํ˜• ์ธ์‹์ด๋‚˜ ์˜๋ฏธ ๋ถ„์„์ด ์—†์Šต๋‹ˆ๋‹ค.
    JSCS๋Š” ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ด ํ”ผ์ƒ์ ์ธ ์„œ์‹ ๊ทœ์น™๋งŒ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜, ํƒ€์ž… ๊ด€๊ณ„ ๋˜๋Š” ์ œ์–ด ํ๋ฆ„ ๋…ผ๋ฆฌ๋ฅผ ๋ถ„์„ํ•˜๋Š” ๋Šฅ๋ ฅ์ด ๋ถ€์กฑํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ์ตœ์‹  ๊ตฌ๋ฌธ ์ง€์›์ด ์—†์Šต๋‹ˆ๋‹ค.
    JSCS๋Š” ์ „์„ฑ๊ธฐ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ƒˆ๋กญ๊ฒŒ ๋“ฑ์žฅํ•˜๋Š” JavaScript ๊ธฐ๋Šฅ(์˜ˆ: ES6+ ๊ตฌ๋ฌธ, JSX)์„ ์ง€์›ํ•˜๋Š” ๋ฐ ๋’ค์ฒ˜์กŒ์Šต๋‹ˆ๋‹ค. JavaScript๊ฐ€ ๋น ๋ฅด๊ฒŒ ๋ฐœ์ „ํ•จ์— ๋”ฐ๋ผ JSCS๋ฅผ ์ตœ์‹  ์›Œํฌํ”Œ๋กœ์— ๋งž๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋”์šฑ ์–ด๋ ค์›Œ์กŒ์Šต๋‹ˆ๋‹ค.
  • ํ˜„๋Œ€ ํ™˜๊ฒฝ์—์„œ๋Š” IDE ๊ธฐ๋ฐ˜ ํ”ผ๋“œ๋ฐฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
    ์˜ค๋Š˜๋‚ ์˜ ํŽธ์ง‘๊ธฐ(์˜ˆ: VSCode, WebStorm)๋Š” ESLint ํ†ตํ•ฉ์— ํฌ๊ฒŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค. JSCS๋Š” ์ตœ์‹  ํ”Œ๋Ÿฌ๊ทธ์ธ ์‹œ์Šคํ…œ์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์‹ค์‹œ๊ฐ„ ๋ฆฐํŒ…์ด๋‚˜ ์ž๋™ ์ˆ˜์ • ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋‹จํŽธํ™”๋œ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜
    ESLint์— ๋ณ‘ํ•ฉ๋˜๊ธฐ ์ „์—๋Š” ๋งŽ์€ ํ”„๋กœ์ ํŠธ์—์„œ JSCS(์Šคํƒ€์ผ์šฉ)์™€ JSHint ๋˜๋Š” JSLint(๋…ผ๋ฆฌ์šฉ)๋ฅผ ๋ชจ๋‘ ์‹คํ–‰ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์„ฑ์ด ์ค‘๋ณต๋˜๊ณ  ๊ทœ์น™์ด ์ผ๊ด€๋˜์ง€ ์•Š์œผ๋ฉฐ ๋„๊ตฌ ํ”ผ๋กœ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

JSCS๋Š” JavaScript ์ƒํƒœ๊ณ„์—์„œ ์ฝ”๋“œ ์Šคํƒ€์ผ ์ ์šฉ์„ ๋Œ€์ค‘ํ™”ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญ์‚ฌ์  ์—ญํ• ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ, ๋ชจ๋“  ์ฃผ์š” ๊ธฐ๋Šฅ๊ณผ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์—…๊ณ„ ํ‘œ์ค€์œผ๋กœ ๋‚จ์•„ ์žˆ๋Š” ESLint์— ์™„์ „ํžˆ ํก์ˆ˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์™€ ํŒ€์€ ESLint(Prettier ๋˜๋Š” eslint-plugin-prettier์™€ ํ•จ๊ป˜)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ๊ตฌ์„ฑ์œผ๋กœ ์Šคํƒ€์ผ๊ณผ ํ’ˆ์งˆ์„ ๋ชจ๋‘ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

StandardJS: Zero-Config JS ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ ๋ฐ Linter

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

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

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ตฌ์„ฑ์ด ํ•„์š” ์—†๋Š” ์‚ฌ์ „ ์ •์˜๋œ ์—„๊ฒฉํ•œ ๋ฆฐํŒ… ๋ฐ ์„œ์‹ ๊ทœ์น™
  • ESLint + ํ‘œ์ค€ ๊ทœ์น™์„ ์‚ฌ์šฉํ•œ ๋‚ด์žฅ ํฌ๋งทํŒ…
  • ํ•œ ๋‹จ๊ณ„๋กœ ํฌ๋งทํŒ… ๋ฐ ๋ฆฐํŒ…์„ ์œ„ํ•œ ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค
  • VSCode, Atom, Sublime Text, WebStorm๊ณผ ๊ฐ™์€ ํŽธ์ง‘๊ธฐ์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ
  • Prettier์™€ ์œ ์‚ฌํ•œ ์„œ์‹ ์›Œํฌํ”Œ๋กœ์™€ ํ˜ธํ™˜๋˜์ง€๋งŒ ์ถ”๊ฐ€ ํ’ˆ์งˆ ๊ทœ์น™์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • Optional standard --fix ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜์ •ํ•˜๋Š” ๋ช…๋ น

StandardJS์˜ ๋‹จ์ :

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

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

CodeClimate: ์ •์  ๋ถ„์„ ๋ฐ ํ’ˆ์งˆ ์ธก์ •์„ ํ†ตํ•œ ์—”์ง€๋‹ˆ์–ด๋ง ํ†ต์ฐฐ๋ ฅ

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

์ด ํ”Œ๋žซํผ์€ ์ •์  ๋ถ„์„๊ณผ ํŒ€ ์„ฑ๊ณผ ์ง€ํ‘œ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ํ’ˆ์งˆ ๊ธฐ์ค€, ์ฝ”๋“œ ๊ฒ€ํ†  ์‹œํ–‰, ๊ทธ๋ฆฌ๊ณ  ์†๋„, ์ฒ˜๋ฆฌ๋Ÿ‰, ์ดํƒˆ๋ฅ ์— ๋Œ€ํ•œ ๊ฐ€์‹œ์„ฑ์„ ํ†ตํ•ฉํ•˜๊ณ ์ž ํ•˜๋Š” ๊ธฐ์—…์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. GitHub, GitLab, Bitbucket๊ณผ ํ†ตํ•ฉ๋˜์–ด ์ธ๋ผ์ธ ์ฝ”๋“œ ๊ฒ€ํ†  ํ”ผ๋“œ๋ฐฑ, ์œ ์ง€๋ณด์ˆ˜์„ฑ ์ ์ˆ˜, ๊ทธ๋ฆฌ๊ณ  ๊ณผ๊ฑฐ ์ถ”์„ธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript, TypeScript ๋ฐ ๊ธฐํƒ€ ์–ธ์–ด์— ๋Œ€ํ•œ ์ •์  ์ฝ”๋“œ ๋ถ„์„
  • ๋ณต์žก์„ฑ, ์ค‘๋ณต ๋ฐ ๋ฆฐํŒ… ๊ทœ์น™์— ๋”ฐ๋ฅธ ์œ ์ง€ ๊ด€๋ฆฌ์„ฑ ์ ์ˆ˜
  • ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์— ๋Œ€ํ•œ ํ’ˆ์งˆ ๊ฒŒ์ดํŠธ ๋ฐ ์ธ๋ผ์ธ ํ”ผ๋“œ๋ฐฑ
  • ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ€๋Šฅํ•œ ์—”์ง„ ๋ฐ ๊ทœ์น™ ๊ตฌ์„ฑ(ESLint, PMD ๋“ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•จ)
  • GitHub Actions, Travis CI ๋ฐ ๊ธฐํƒ€ CI/CD ํŒŒ์ดํ”„๋ผ์ธ๊ณผ์˜ ํ†ตํ•ฉ
  • ํŒ€ ์ƒ์‚ฐ์„ฑ ๋ฐ ์ฝ”๋“œ ์ƒํƒœ ์ถ”์„ธ์— ๋Œ€ํ•œ ์—”์ง€๋‹ˆ์–ด๋ง ๋ถ„์„
  • ๊ธฐ์—…์„ ์œ„ํ•œ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ ๋ฐ ์ž์ฒด ํ˜ธ์ŠคํŒ… ์˜ต์…˜

CodeClimate์˜ ๋‹จ์ :

  • JavaScript์— ํŠนํ™”๋˜์ง€ ์•Š์Œ
    CodeClimate๋Š” JavaScript์™€ TypeScript๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ ๋ฒ”์šฉ ํ”Œ๋žซํผESLint, Semgrep, SonarQube์™€ ๊ฐ™์€ ๋„๊ตฌ์—์„œ ์ œ๊ณตํ•˜๋Š” JavaScript์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ํ”„๋ ˆ์ž„์›Œํฌ๋ณ„ ๋ฌธ์ œ(์˜ˆ: React, Vue, Node.js API)์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์  ๋ถ„์„ ์—”์ง„ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ์ œํ•œ์ ์ด๊ฑฐ๋‚˜ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.
    YAML ๋ฐ ์˜คํ”ˆ ์†Œ์Šค ์—”์ง„์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์—”์ง„ ๊ด€๋ฆฌ ๋ฐ ํŠœ๋‹(์˜ˆ: eslint, ์ค‘๋ณต, ๋ณต์žก์„ฑ) ํ•ด๋‹น ์•„ํ‚คํ…์ฒ˜์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋ณต์žกํ•˜๊ณ  ์ง๊ด€์ ์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜๋ฏธ ๋ถ„์„์ด๋‚˜ ์˜ค์—ผ ๋ถ„์„์ด ์—†์Šต๋‹ˆ๋‹ค.
    CodeClimate๋Š” ๋ฐ์ดํ„ฐ ํ๋ฆ„, ์˜ค์—ผ๋œ ์ž…๋ ฅ ๋˜๋Š” ๋น„๋™๊ธฐ ๋กœ์ง์„ โ€‹โ€‹์‹ฌ์ธต์ ์œผ๋กœ ์ถ”์ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณด์•ˆ ๋„๊ตฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค ํƒ€์‚ฌ ํ†ตํ•ฉ ์—†์ด๋Š” ์ฃผ์ž… ์œ„ํ—˜, ์ธ์ฆ ์˜ค๋ฅ˜ ๋˜๋Š” ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์—ญ์ง๋ ฌํ™”๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • TypeScript ๊ด€๋ จ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ง€์›์ด ์ œํ•œ๋จ
    CodeClimate์˜ TypeScript ์ฒ˜๋ฆฌ๋Š” TSC๋‚˜ TypeScript ์ง€์› ESLint ์„ค์ •๊ณผ ๊ฐ™์€ ๋„๊ตฌ์— ๋น„ํ•ด ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. ์œ ํ˜•, ์ธํ„ฐํŽ˜์ด์Šค ๋˜๋Š” ์—„๊ฒฉ ๋ชจ๋“œ ๊ตฌ์„ฑ์˜ ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ํ•ด์„ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ๊ตฌ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    "ํ”Œ๋Ÿฌ๊ทธ ์•ค ํ”Œ๋ ˆ์ด"๋กœ ํŒ๋งค๋˜์ง€๋งŒ ๋งŽ์€ ํ”„๋กœ์ ํŠธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ด‘๋ฒ”์œ„ํ•œ ํŠœ๋‹ ๋…ธ์ด์ฆˆ์™€ ์˜คํƒ์ง€๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๋ชจ๋…ธ๋ฆฌํฌ๋‚˜ ๋น„ํ‘œ์ค€ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ์—์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.
  • ๋ฌด๋ฃŒ ์‚ฌ์šฉ์ด ์ œํ•œ๋œ ์ƒ์—…์  ์ดˆ์ 
    CodeClimate๋Š” ๋ฌด๋ฃŒ ํ”Œ๋žœ์—์„œ๋Š” ์ œํ•œ๋œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ(๋Œ€์‹œ๋ณด๋“œ, ์ง€ํ‘œ, ๊ณผ๊ฑฐ ๋ถ„์„, ํŒ€ ๋น„๊ต)์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์œ ๋ฃŒ ํ”Œ๋žœ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์‹ค์‹œ๊ฐ„ IDE ํ”ผ๋“œ๋ฐฑ ์—†์Œ
    ๊ฐœ๋ฐœ์ž๋Š” ํŽธ์ง‘๊ธฐ์—์„œ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. CodeClimate๋Š” ํ’€ ๋ฆฌํ€˜์ŠคํŠธ ๋ฐ CI ๋‹จ๊ณ„์—์„œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜ ๋ฐœ๊ฒฌ์ด ์ง€์—ฐ๋˜๊ณ  ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๊ฐ€ ์ง€์—ฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CodeClimate๋Š” ์ •์  ๋ถ„์„์„ ์ฝ”๋“œ ํ’ˆ์งˆ ์ง€ํ‘œ, ํŒ€ ์„ฑ๊ณผ ๋ฐ ์—”์ง€๋‹ˆ์–ด๋ง ๋ชฉํ‘œ์— ์—ฐ๊ฒฐํ•˜๋ ค๋Š” ์กฐ์ง์— ํšจ๊ณผ์ ์ธ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. ํƒ„ํƒ„ํ•œ ๊ณ ์ˆ˜์ค€ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ณ  PR ์›Œํฌํ”Œ๋กœ์— ์›ํ™œํ•˜๊ฒŒ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ JavaScript ๊ด€๋ จ ๋ณด์•ˆ, ์˜๋ฏธ๋ก ์  ๋ถ„์„ ๋˜๋Š” ์•„ํ‚คํ…์ฒ˜ ๋ถ„์„์ด ๋”์šฑ ์‹ฌ๋„ ์žˆ๊ฒŒ ํ•„์š”ํ•œ ํŒ€์˜ ๊ฒฝ์šฐ, CodeClimate๋Š” ESLint, Semgrep, Snyk Code์™€ ๊ฐ™์€ ๋„๊ตฌ์™€ ํ•จ๊ป˜ ๊ด‘๋ฒ”์œ„ํ•œ ํˆด์ฒด์ธ์˜ ์ผ๋ถ€๋กœ ์‚ฌ์šฉ๋˜์–ด ํฌ๊ด„์ ์ธ ๋ถ„์„์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

Coverity(Synopsys): ๋ณด์•ˆ์— ์ดˆ์ ์„ ๋งž์ถ˜ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ์ •์  ๋ถ„์„

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

Coverity๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ์˜๋ฏธ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜์—ฌ null ์—ญ์ฐธ์กฐ, ๋ฆฌ์†Œ์Šค ๋ˆ„์ˆ˜, ๊ฒ€์ฆ๋˜์ง€ ์•Š์€ ์ž…๋ ฅ, ์•ˆ์ „ํ•˜์ง€ ์•Š์€ API ์‚ฌ์šฉ ๋“ฑ์˜ ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค. JavaScript์˜ ๊ฒฝ์šฐ, ์„œ๋ฒ„ ์ธก(Node.js) ๋ฐ ํ”„๋ŸฐํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Coverity๋Š” CI/CD ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ํ†ตํ•ฉ๋˜์–ด ๋Œ€๊ทœ๋ชจ ํŒ€์„ ์œ„ํ•œ ์ƒ์„ธ ๋Œ€์‹œ๋ณด๋“œ, ๊ทœ์ • ์ค€์ˆ˜ ์ถ”์  ๋ฐ ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript, TypeScript ๋ฐ ๊ธฐํƒ€ ์ฃผ์š” ์–ธ์–ด์— ๋Œ€ํ•œ ์‹ฌ์ธต์  ์ •์  ๋ถ„์„
  • ๋ณด์•ˆ ์ทจ์•ฝ์ , ๋…ผ๋ฆฌ ๋ฒ„๊ทธ ๋ฐ ์ฝ”๋”ฉ ์•ˆํ‹ฐ ํŒจํ„ด ๊ฐ์ง€
  • OWASP, CWE ๋ฐ CERT ๊ทœ์ • ์ค€์ˆ˜ ๋ณด๊ณ 
  • GitHub, GitLab, Azure DevOps, Jenkins ๋“ฑ๊ณผ์˜ ํ†ตํ•ฉ
  • ํ’€ ๋ฆฌํ€˜์ŠคํŠธ ๋ฐ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ์˜ ์ •์ฑ… ์‹œํ–‰ ๋ฐ ๋ฌธ์ œ ์ถ”์ 
  • ์œ„ํ—˜ ์ ์ˆ˜, ์ˆ˜์ • ์ง€์นจ ๋ฐ ๊ฐ์‚ฌ ์ถ”์  ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๋Œ€์‹œ๋ณด๋“œ
  • ๋ชจ๋…ธ๋ ˆํฌ ๋ฐ ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

Coverity์˜ ๋‹จ์ :

  • ์ฃผ๋กœ ๊ธฐ์—…์šฉ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค
    Coverity๋Š” ๋Œ€๊ทœ๋ชจ์˜ ๊ทœ์ œ ๋Œ€์ƒ ์กฐ์ง์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ฒผ์šด ๋ฆฐํŒ…์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ์„ ์›ํ•˜๋Š” ์†Œ๊ทœ๋ชจ ํŒ€์ด๋‚˜ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—๋Š” ๊ณผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ณ  ๋ผ์ด์„ผ์‹ฑ์ด ๋ณต์žกํ•จ
    Coverity์˜ ์ƒ์—… ๋ชจ๋ธ์€ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ณ  ๊ธฐ์—… ๊ตฌ๋งค์ž์—๊ฒŒ ๋งž์ถฐ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๊ฒฉ ์ฑ…์ •์ด ํˆฌ๋ช…ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๊ตฌ์ถ•ํ•˜๋ ค๋ฉด ์ „์šฉ ์˜ˆ์‚ฐ๊ณผ ๋ฒ•์  ์Šน์ธ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ€ํŒŒ๋ฅธ ํ•™์Šต ๊ณก์„ ๊ณผ ์„ค์ • ๋ณต์žก์„ฑ
    ๊ตฌ์„ฑ, ํ™˜๊ฒฝ ์„ค์ • ๋ฐ ํ†ตํ•ฉ์—๋Š” ์ƒ๋‹นํ•œ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•˜๋ฉฐ, ํŠนํžˆ Java ๋˜๋Š” C/C++๊ฐ€ ์•„๋‹Œ ์ƒํƒœ๊ณ„์˜ ๊ฒฝ์šฐ ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. JavaScript ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ ์ตœ์ ์˜ ๊ฒฐ๊ณผ๋ฅผ ์œ„ํ•ด ๋งž์ถค ์กฐ์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ์˜ ๋А๋ฆฐ ์Šค์บ” ์‹œ๊ฐ„
    Coverity๋Š” ๋ถ„์„์˜ ์‹ฌ๋„ ๋•Œ๋ฌธ์— ๊ณ„์‚ฐ๋Ÿ‰์ด ๋งŽ์•„ ๋Œ€๊ทœ๋ชจ JavaScript/TypeScript ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ ๊ฒ€์‚ฌ ์†๋„๊ฐ€ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠนํžˆ React๋‚˜ Next.js์™€ ๊ฐ™์€ ์ตœ์‹  ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.
  • ์ œํ•œ๋œ ์ตœ์‹  JavaScript ์ƒํƒœ๊ณ„ ์ธ์‹
    Coverity๋Š” JavaScript๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, ์„ ํƒ์  ์ฒด์ด๋‹, ๋™์  ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ๊ฐ™์€ ์ตœ์‹  ES ๊ธฐ๋Šฅ์ด๋‚˜ Vue, Svelte, Angular์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์„ฌ์„ธํ•œ ํŒจํ„ด์„ ์ดํ•ดํ•˜๋Š” ๋ฐ๋Š” ๋А๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„œ์‹, ์Šคํƒ€์ผ ๋˜๋Š” ๋ชจ๋ฒ” ์‚ฌ๋ก€ ๋ฆฐํŒ… ์—†์Œ
    ESLint๋‚˜ Prettier์™€ ๊ฐ™์€ ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ Coverity๋Š” ๋ฌธ์ฒด ๊ทœ์น™์„ ์‹œํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฝ”๋“œ ์ผ๊ด€์„ฑ์ด๋‚˜ ๊ฐ€๋…์„ฑ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•œ ์ผ์ƒ์ ์ธ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.
  • IDE ๊ธฐ๋ฐ˜ ํ”ผ๋“œ๋ฐฑ ์—†์Œ
    ๊ฐœ๋ฐœ์ž๋Š” VSCode๋‚˜ WebStorm๊ณผ ๊ฐ™์€ ํŽธ์ง‘๊ธฐ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ์ง์ ‘ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ ๋ฐœ๊ฒฌ์€ ์Šค์บ” ์‹คํ–‰์ด ์ง€์—ฐ๋จ๋‹ค๋ฅธ ๋„๊ตฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋น ๋ฅธ ๋ฐ˜๋ณต ์ž‘์—…๊ณผ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

Coverity๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ JavaScript ๋ณด์•ˆ ๋ฐ ๊ฒฐํ•จ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ์ •์  ๋ถ„์„ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ํŠนํžˆ ๊ทœ์ • ์ค€์ˆ˜ ๋ฐ ์œ„ํ—˜ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•œ ํ™˜๊ฒฝ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ESLint, Semgrep, Snyk Code์™€ ๊ฐ™์€ ๊ฐœ๋ฐœ์ž ์ค‘์‹ฌ ๋„๊ตฌ๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์œผ๋ฉฐ, ๋ฆฌ์†Œ์Šค, ๊ต์œก ๋ฐ ์ธํ”„๋ผ ์ธก๋ฉด์—์„œ ์ƒ๋‹นํ•œ ํˆฌ์ž๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Coverity๋Š” ๊ณ„์ธตํ™”๋œ AppSec ์ „๋žต์˜ ๋ฐฑ์Šคํ†ฑ์œผ๋กœ ๊ฐ€์žฅ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉ๋˜๋ฉฐ, ์ตœ์‹  JavaScript ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ๋ฏผ์ฒฉํ•œ ๋„๊ตฌ๋ฅผ ๋ณด์™„ํ•ฉ๋‹ˆ๋‹ค.

Veracode ์ •์  ๋ถ„์„: ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ์„ ์œ„ํ•œ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ SAST

Veracode Static Analysis๋Š” ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ์ •์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํ…Œ์ŠคํŠธ(SAST) ์†”๋ฃจ์…˜์œผ๋กœ, ์กฐ์ง์ด ์ „์ฒด ๋นŒ๋“œ ํ™˜๊ฒฝ์— ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ ๋„ ์†Œ์Šค ์ฝ”๋“œ, ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ ๋ฐ”์ดํŠธ์ฝ”๋“œ์˜ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. JavaScript ๋ฐ TypeScript๋ฅผ ํฌํ•จํ•œ ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์•ˆ์ „ํ•œ SDLC ํ†ตํ•ฉ, ๊ฑฐ๋ฒ„๋„Œ์Šค ๋ฐ ๊ทœ์ • ์ค€์ˆ˜๋ฅผ ์œ„ํ•ด ๋Œ€๊ธฐ์—…์—์„œ ๋„๋ฆฌ ์ฑ„ํƒ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Veracode๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์ž๋™ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ฃผ์ž… ์ทจ์•ฝ์ , ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์ž˜๋ชป๋œ ์ธ์ฆ ๋ฐ ๊ธฐํƒ€ ๊ณ ์œ„ํ—˜ ๋ณด์•ˆ ๋ฌธ์ œ์™€ ๊ฐ™์€ ์ทจ์•ฝ์ ์„ ํƒ์ง€ํ•ฉ๋‹ˆ๋‹ค. CI/CD ํŒŒ์ดํ”„๋ผ์ธ, ๋ฒ„์ „ ์ œ์–ด ์‹œ์Šคํ…œ ๋ฐ DevOps ๋„๊ตฌ์™€ ํ†ตํ•ฉ๋˜๋ฉฐ, ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๊ฐ ์ทจ์•ฝ์ ๊ณผ ์ง์ ‘ ์—ฐ๊ฒฐ๋œ ์ˆ˜์ • ์ง€์นจ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. JavaScript ์ง€์›์€ ํ”„๋ŸฐํŠธ์—”๋“œ ๋ฐ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ(์˜ˆ: Node.js) ๋ชจ๋‘์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • JavaScript, TypeScript ๋ฐ ๊ธฐํƒ€ 20๊ฐœ ์ด์ƒ์˜ ์–ธ์–ด์— ๋Œ€ํ•œ ์ •์  ๋ถ„์„
  • ์ฝ”๋“œ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ OWASP Top 10 ๋ฐ CWE ์ทจ์•ฝ์  ๊ฐ์ง€
  • ์‹ ์†ํ•œ ์˜จ๋ณด๋”ฉ ๋ฐ ์ค‘์•™ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ ์Šค์บ๋‹
  • ์ •์ฑ… ์‹œํ–‰ ๋Œ€์‹œ๋ณด๋“œ ๋ฐ ๊ทœ์ • ์ค€์ˆ˜ ์ถ”์ (์˜ˆ: PCI-DSS, HIPAA, ISO)
  • ์ž์„ธํ•œ ์ˆ˜์ • ์ง€์นจ, ์œ„ํ—˜ ๋“ฑ๊ธ‰ ๋ฐ ๋ฌธ์ œ ๋ถ„๋ฅ˜
  • GitHub, Azure DevOps, Jenkins, GitLab, Bitbucket ๋ฐ Jira์™€์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ
  • ์ž„์› ๋ฐ ๊ฐ์‚ฌ ์ดํ•ด ๊ด€๊ณ„์ž๋ฅผ ์œ„ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ํƒœ์„ธ ๋ณด๊ณ 

Veracode ์ •์  ๋ถ„์„์˜ ๋‹จ์ :

  • ์ฃผ๋กœ ์ฝ”๋“œ ํ’ˆ์งˆ์ด ์•„๋‹Œ ๋ณด์•ˆ์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.
    Veracode๋Š” ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ, ๋ชจ๋ฒ” ์‚ฌ๋ก€ ๋˜๋Š” ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์„ ๊ฐ•์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋ƒ„์ƒˆ, ์„œ์‹ ๋ฌธ์ œ ๋˜๋Š” ๋ณด์•ˆ๊ณผ ๊ด€๋ จ ์—†๋Š” ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ํฌ์ฐฉํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.
  • IDE ๊ธฐ๋ฐ˜ ์Šค์บ๋‹ ๊ฒฝํ—˜ ์—†์Œ
    Veracode Static Analysis๋Š” ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜์ด๋ฉฐ ์‹ค์‹œ๊ฐ„ ํŽธ์ง‘์ž ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (์˜ˆ: VSCode ๋˜๋Š” WebStorm์—์„œ). ๊ฐœ๋ฐœ์ž๋Š” CI ๋˜๋Š” ์ˆ˜๋™ ์—…๋กœ๋“œ๋ฅผ ํ†ตํ•ด ์Šค์บ” ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ œํ•œ๋œ JavaScript ๊ด€๋ จ ์‚ฌ์šฉ์ž ์ •์˜
    Veracode๋Š” JavaScript๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ, JavaScript ํŠน์ • ํ”„๋ ˆ์ž„์›Œํฌ(์˜ˆ: React, Vue, Svelte)์— ๋Œ€ํ•œ ์‹ฌ์ธต์ ์ธ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™ ์กฐ์ •์€ Semgrep์ด๋‚˜ CodeQL๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋ณด๋‹ค ์„ธ๋ถ€์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์Šค์บ”์„ ์œ„ํ•ด์„œ๋Š” ์ „์ฒด ๋นŒ๋“œ ๋˜๋Š” ํŒจํ‚ค์ง€ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    ํšจ๊ณผ์ ์ธ ์Šค์บ”์„ ์œ„ํ•ด Veracode๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฒˆ๋“ค, ๋นŒ๋“œ ๋˜๋Š” ์••์ถ•๋œ ์ฝ”๋“œ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ์ฆ๋ถ„์  ๋ณ€๊ฒฝ์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ํ”„๋ŸฐํŠธ์—”๋“œ ์ค‘์‹ฌ ์›Œํฌํ”Œ๋กœ์—์„œ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋ฅผ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ตœ์‹  JavaScript ๊ฐœ๋ฐœ์ž ์›Œํฌํ”Œ๋กœ์— ๋งž๊ฒŒ ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
    Veracode๋Š” ๋ฆฐํŒ…, ์„œ์‹ ์ง€์ • ๋˜๋Š” ํ…Œ์ŠคํŠธ ๊ธฐ๋ฐ˜ ๊ทœ์น™์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ESLint๋‚˜ Prettier๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰๋˜๋Š” ํ”ผ๋“œ๋ฐฑ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ ๋ฐฉ์‹์— ์‰ฝ๊ฒŒ ํ†ตํ•ฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ฑฐ์ง“ ์–‘์„ฑ ๋ฐ ์ œํ•œ๋œ ํˆฌ๋ช…์„ฑ
    Veracode๋Š” ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ด์ง€๋งŒ ๊ฐ€์–‘ ์„ฑํŠนํžˆ ๋А์Šจํ•˜๊ฒŒ ์ž…๋ ฅ๋œ ์ฝ”๋“œ๋‚˜ ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ๋ฌธ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ฐ์ง€๋˜๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์›Œ ๋ถ„๋ฅ˜๊ฐ€ ๋”์šฑ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.
  • ์ƒ์—…์  ๋ผ์ด์„ ์Šค์™€ ๊ณต๊ธ‰์—…์ฒด ์ž ๊ธˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    ๋ฒ ๋ผ์ฝ”๋“œ๋Š” ํ”„๋ฆฌ๋ฏธ์—„, ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ œํ’ˆ๋น„์šฉ, ๋ผ์ด์„ ์Šค ๊ตฌ์กฐ, ์ž์ฒด ํ˜ธ์ŠคํŒ… ์˜คํ”ˆ์†Œ์Šค ๋Œ€์‘ ์†”๋ฃจ์…˜์˜ ๋ถ€์กฑ ๋“ฑ์œผ๋กœ ์ธํ•ด ์†Œ๊ทœ๋ชจ ํŒ€์ด๋‚˜ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

JS ์ •์  ๋ถ„์„ ๋„๊ตฌ ํ™˜๊ฒฝ ํƒ์ƒ‰

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

ESLint, Prettier, TypeScript์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ๋„๊ตฌ๋Š” ๊ฐœ๋ฐœ์ž ์ˆ˜์ค€์—์„œ ์ •ํ™•์„ฑ, ์ผ๊ด€์„ฑ, ๋ช…ํ™•์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋ณด์•ˆ์„ ์œ„ํ•ด Semgrep, Snyk Code, CodeQL์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ๊ณผ ์‹ฌ์ธต์ ์ธ ์ทจ์•ฝ์  ํƒ์ง€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ€์ผ๊ณผ ๋‹จ์ˆœ์„ฑ์„ ์œ„ํ•ด StandardJS์™€ ๊ฐ™์€ ์˜ต์…˜์€ ๋น ๋ฅด๊ณ  ๊ฐ„๊ฒฐํ•œ ํ”„๋กœ์ ํŠธ์—์„œ ์—ฌ์ „ํžˆ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

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

SMART TS XL ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ JS ํ™˜๊ฒฝ์—์„œ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ์‚ฌํ•ญ

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

๊ธฐ์—… ํŒ€์ด ์ฑ„ํƒํ•˜๋Š” ์ฃผ์š” ์ด์œ  SMART TS XL:

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

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

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