๊ฒฌ๊ณ ํ๊ณ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ํจ์จ์ ์ธ JavaScript ๊ฐ๋ฐ ์ธํ๋ผ๋ฅผ ์ฒ์๋ถํฐ ๊ตฌ์ถํ์ธ์. ์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ ํด๋ง๋ถํฐ ๋ฐฐํฌ๊น์ง ๋ชจ๋ ๊ฒ์ ๋ค๋ฃน๋๋ค.
JavaScript ๊ฐ๋ฐ ์ธํ๋ผ: ํ๋ ํ์ ์ํ ์๋ฒฝํ ๊ตฌํ ๊ฐ์ด๋
์ญ๋์ ์ด๊ณ ๋์์์ด ์งํํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ ์ธ๊ณ์์ JavaScript๋ ์ํธ ์์ฉ์ ์ธ ํ๋ก ํธ ์๋ ๊ฒฝํ์์ ๊ฐ๋ ฅํ ๋ฐฑ์๋ ์๋น์ค์ ์ด๋ฅด๊ธฐ๊น์ง ๋ชจ๋ ๊ฒ์ ์ง์ํ๋ ๊ฑฐ๋ฌผ๋ก ์๋ฆฌ ์ก๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ค๋ฉด ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ์ด์์ด ํ์ํฉ๋๋ค. ๊ฒฌ๊ณ ํ ๊ธฐ๋ฐ, ์ฆ ์ ์ค๊ณ๋ ๊ฐ๋ฐ ์ธํ๋ผ๊ฐ ํ์ํฉ๋๋ค. ์ด ์ธํ๋ผ๋ ํ์ ์ง์ํ๊ณ ์ฝ๋ ํ์ง์ ๋ณด์ฅํ๋ฉฐ ๋ฐ๋ณต์ ์ธ ์์ ์ ์๋ํํ๊ณ ๊ถ๊ทน์ ์ผ๋ก ๊ณ ํ์ง ์ํํธ์จ์ด ์ ๊ณต์ ๊ฐ์ํํ๋ ๋ณด์ด์ง ์๋ ํ๋ ์์ํฌ์ ๋๋ค.
์๋ก ๋ค๋ฅธ ์๊ฐ๋์ ๋ฌธํ๊ถ์ ํฉ์ด์ ธ ์๋ ๊ธ๋ก๋ฒ ํ์ ๊ฒฝ์ฐ ํ์คํ๋ ์ธํ๋ผ๋ ์ฌ์น๊ฐ ์๋๋ผ ํ์ํ์ ๋๋ค. ๊ฐ๋ฐ์์ ์์น์ ๊ด๊ณ์์ด ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๊ณตํต ์ธ์ด์ ๊ท์น ์ธํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋๋ ๋ชจ๋ ๊ท๋ชจ์ ํ๋ก์ ํธ์ ์ ํฉํ ์๋ฒฝํ JavaScript ๊ฐ๋ฐ ์ธํ๋ผ๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ํฌ๊ด์ ์ธ ๋จ๊ณ๋ณ ์๋ด๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํ๋ JS ์ธํ๋ผ์ ํต์ฌ ์์
๊ฒฌ๊ณ ํ ์ธํ๋ผ๋ ๊ฐ๋ฐ ๋ผ์ดํ์ฌ์ดํด์ ํน์ ์ธก๋ฉด์ ๋ค๋ฃจ๋ ์ฌ๋ฌ ํต์ฌ ์์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ฉ๋๋ค. ์ด๋ฌํ ์์ ์ค ํ๋๋ผ๋ ์ํํ ํ๋ฉด ๊ธฐ์ ๋ถ์ฑ, ๋ถ์ผ์น ๋ฐ ์์ฐ์ฑ ์ ํ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ๊ฐ ์์๋ฅผ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. ํจํค์ง ๊ด๋ฆฌ: ํ๋ก์ ํธ์ ๊ธฐ๋ฐ
์ฌ์ํ์ง ์์ ๋ชจ๋ JavaScript ํ๋ก์ ํธ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ํจํค์ง์ ์์กดํฉ๋๋ค. ํจํค์ง ๊ด๋ฆฌ์๋ ์ด๋ฌํ ์ข ์์ฑ์ ์ค์น, ์ ๋ฐ์ดํธ, ๊ตฌ์ฑ ๋ฐ ์ ๊ฑฐํ๋ ํ๋ก์ธ์ค๋ฅผ ์๋ํํ๋ ๋๊ตฌ์ ๋๋ค. ํ์ ๋ชจ๋ ๊ฐ๋ฐ์์ ๋น๋ ์๋ฒ๊ฐ ๋ชจ๋ ํจํค์ง์ ์ ํํ ๋์ผํ ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํ์ฌ ์ ๋ช ๋์ "๋ด ์ปดํจํฐ์์๋ ์๋ํฉ๋๋ค" ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
- npm (Node Package Manager): Node.js์ ํจ๊ป ๋ฒ๋ค๋ก ์ ๊ณต๋๋ ๊ธฐ๋ณธ ํจํค์ง ๊ด๋ฆฌ์์ ๋๋ค. ์ธ๊ณ์์ ๊ฐ์ฅ ํฐ ์ํํธ์จ์ด ๋ ์ง์คํธ๋ฆฌ์ด๋ฉฐ ์ฌ์ค์์ ํ์ค์ ๋๋ค. `package.json` ํ์ผ์ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ ๋ฉํ๋ฐ์ดํฐ์ ์ข ์์ฑ์ ๊ด๋ฆฌํ๊ณ `package-lock.json` ํ์ผ์ ์ฌ์ฉํ์ฌ ์ฌํ ๊ฐ๋ฅํ ๋น๋๋ฅผ ์ํด ์ข ์์ฑ ๋ฒ์ ์ ์ ๊ธ๋๋ค.
- Yarn: npm์ ์ด๊ธฐ ์ฑ๋ฅ ๋ฐ ๋ณด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Facebook์์ ๊ฐ๋ฐํ์ต๋๋ค. Yarn์ ์คํ๋ผ์ธ ์บ์ฑ ๋ฐ `yarn.lock` ํ์ผ์ ์ฌ์ฉํ์ฌ ๋ณด๋ค ๊ฒฐ์ ์ ์ธ ์ค์น ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ๋์ ํ์ต๋๋ค. Yarn 2+ (Berry)์ ๊ฐ์ ์ต์ ๋ฒ์ ์ ๋ ๋น ๋ฅด๊ณ ์์ ์ ์ธ ์ข ์์ฑ ํด๊ฒฐ์ ์ํด Plug'n'Play (PnP)์ ๊ฐ์ ํ์ ์ ์ธ ๊ฐ๋ ์ ๋์ ํฉ๋๋ค.
- pnpm: "performant npm"์ ์ฝ์์ ๋๋ค. ์ฃผ์ ์ฐจ๋ณํ ์์๋ `node_modules` ๋๋ ํฐ๋ฆฌ ๊ด๋ฆฌ ๋ฐฉ์์ ๋๋ค. pnpm์ ํ๋ก์ ํธ ๊ฐ์ ํจํค์ง๋ฅผ ๋ณต์ ํ๋ ๋์ ์ฝํ ์ธ ์ฃผ์ ์ง์ ์ ์ฅ์์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ข ์์ฑ์ ๊ณต์ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ค์น ์๊ฐ์ด ํจ์ฌ ๋นจ๋ผ์ง๊ณ ๋์คํฌ ๊ณต๊ฐ ์ฌ์ฉ๋์ด ํฌ๊ฒ ์ค์ด๋ค์ด ๊ฐ๋ฐ์์ CI/CD ์์คํ ์ ํฐ ์ด์ ์ด ๋ฉ๋๋ค.
๊ถ์ฅ ์ฌํญ: ์ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ ํจ์จ์ฑ๊ณผ ์๋๋ก ์ธํด pnpm์ด ํ๋ฅญํ ์ ํ์ ๋๋ค. ๊ทธ๋ฌ๋ npm์ ์๋ฒฝํ๊ฒ ์คํ ๊ฐ๋ฅํ๊ณ ๋ณดํธ์ ์ผ๋ก ์ดํด๋๋ ์ต์ ์ผ๋ก ๋จ์ ์์ต๋๋ค. ํต์ฌ์ ํ๋๋ฅผ ์ ํํ๊ณ ํ ์ ์ฒด์์ ์ฌ์ฉ์ ๊ฐ์ ํ๋ ๊ฒ์ ๋๋ค.
์: npm์ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ ์ด๊ธฐํ
์์ํ๋ ค๋ฉด ํฐ๋ฏธ๋์์ ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋ํ์ฌ ๋ค์์ ์คํํฉ๋๋ค.
npm init -y
์ด๋ ๊ฒ ํ๋ฉด `package.json` ํ์ผ์ด ์์ฑ๋ฉ๋๋ค. Express์ ๊ฐ์ ์ข ์์ฑ์ ์ถ๊ฐํ๋ ค๋ฉด ๋ค์์ ์คํํฉ๋๋ค.
npm install express
์ด๋ ๊ฒ ํ๋ฉด `express`๊ฐ `package.json`์ `dependencies`์ ์ถ๊ฐ๋๊ณ `package-lock.json`์ด ์์ฑ/์ ๋ฐ์ดํธ๋ฉ๋๋ค.
2. ์ฝ๋ ํธ๋์คํ์ผ ๋ฐ ๋ฒ๋ค๋ง: ๊ฐ๋ฐ์์ ํ๋ก๋์ ๊น์ง
์ต์ JavaScript ๊ฐ๋ฐ์๋ ์ต์ ์ธ์ด ๊ธฐ๋ฅ(ESNext)์ ์ฌ์ฉํ์ฌ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋ชจ๋(ESM ๋๋ CommonJS)์ ํ์ฉํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ธ๋ผ์ฐ์ ์ ์ด์ Node.js ํ๊ฒฝ์์๋ ์ด๋ฌํ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ์ง ์์ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ ํธ๋์คํ์ผ๋ฌ์ ๋ฒ๋ค๋ฌ๊ฐ ๋ฑ์ฅํฉ๋๋ค.
ํธ๋์คํ์ผ๋ฌ: Babel
ํธ๋์คํ์ผ๋ฌ๋ ์์ค ๊ฐ ์ปดํ์ผ๋ฌ์ ๋๋ค. ์ต์ JavaScript ์ฝ๋๋ฅผ ๊ฐ์ ธ์์ ์ด์ ๋ฒ์ ์ ๋ ๋๋ฆฌ ํธํ๋๋ ๋ฒ์ (์: ES5)์ผ๋ก ๋ณํํฉ๋๋ค. Babel์ ์ด๋ฅผ ์ํ ์ ๊ณ ํ์ค์ ๋๋ค.
- ์ค๋๋ ์ต์ฒจ๋จ JavaScript ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ํ๋ฌ๊ทธ์ธ๊ณผ ์ฌ์ ์ค์ ์ ํตํด ๊ณ ๋๋ก ๊ตฌ์ฑ ๊ฐ๋ฅํ๋ฏ๋ก ํน์ ๋ธ๋ผ์ฐ์ ๋๋ ํ๊ฒฝ ๋ฒ์ ์ ๋์์ผ๋ก ์ง์ ํ ์ ์์ต๋๋ค.
- ์ผ๋ฐ์ ์ธ ์ฌ์ ์ค์ ์ `@babel/preset-env`์ด๋ฉฐ, ๋์ ํ๊ฒฝ์ ํ์ํ ๋ณํ๋ง ์ง๋ฅ์ ์ผ๋ก ํฌํจํฉ๋๋ค.
์์ `.babelrc` ๊ตฌ์ฑ:
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", ">> 0.5%", "not dead"]
}
}],
"@babel/preset-typescript", // If using TypeScript
"@babel/preset-react" // If using React
]
}
๋ชจ๋ ๋ฒ๋ค๋ฌ: Webpack vs. Vite
๋ชจ๋ ๋ฒ๋ค๋ฌ๋ JavaScript ํ์ผ๊ณผ ํด๋น ์ข ์์ฑ์ ๊ฐ์ ธ์ ๋ ์ ์ ์์ ์ต์ ํ๋ ํ์ผ(์ข ์ข "๋ฒ๋ค"์ด๋ผ๊ณ ํ๋ ๋จ์ผ ํ์ผ)๋ก ๋ณํฉํฉ๋๋ค. ์ด ํ๋ก์ธ์ค์๋ ์ถ์, ํธ๋ฆฌ ์ ฐ์ดํน(์ฌ์ฉํ์ง ์๋ ์ฝ๋ ์ ๊ฑฐ) ๋ฐ ์์ฐ ์ต์ ํ(์ด๋ฏธ์ง, CSS)๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค.
- Webpack: ์ค๋ ์ฑํผ์ธ์ ๋๋ค. ๋งค์ฐ ๊ฐ๋ ฅํ๋ฉฐ ๊ด๋ฒ์ํ ๋ก๋ ๋ฐ ํ๋ฌ๊ทธ์ธ ์์ฝ์์คํ ์ ๊ฐ์ถ๊ณ ์์ด ๊ฑฐ์ ๋ชจ๋ ์ฌ์ฉ ์ฌ๋ก์ ๋ง๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ตฌ์ฑ์ด ๋ณต์กํ ์ ์์ผ๋ฉฐ ๋ฒ๋ค๋ง ๊ธฐ๋ฐ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์ธํด ๋๊ท๋ชจ ํ๋ก์ ํธ์ ์ฑ๋ฅ์ด ๊ฐ๋ฐ ์ค์ ๋๋ ค์ง ์ ์์ต๋๋ค.
- Vite: ๊ฐ๋ฐ์ ๊ฒฝํ์ ์ค์ ์ ๋ ํ๋์ ์ธ ์๊ฒฌ์ด ์๋ ๋น๋ ๋๊ตฌ์ ๋๋ค. Vite๋ ๊ฐ๋ฐ ์ค์ ๋ธ๋ผ์ฐ์ ์์ ๊ธฐ๋ณธ ES ๋ชจ๋์ ํ์ฉํฉ๋๋ค. ์ฆ, ์ฝ๋๋ฅผ ์ ๊ณตํ๋ ๋ฐ ํ์ํ ๋ฒ๋ค๋ง ๋จ๊ณ๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์๋ฒ ์์ ์๊ฐ์ด ๋งค์ฐ ๋น ๋ฅด๊ณ HMR(Hot Module Replacement)์ด ๊ฐ๋ฅํฉ๋๋ค. ํ๋ก๋์ ์ ๊ฒฝ์ฐ Rollup์ ์ฌ์ฉํ์ฌ ๊ณ ๋๋ก ์ต์ ํ๋ ๋ฒ๋ค์ ๋ง๋ญ๋๋ค.
๊ถ์ฅ ์ฌํญ: ์๋ก์ด ํ๋ก ํธ ์๋ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ ๋ฐ์ด๋ ๊ฐ๋ฐ์ ๊ฒฝํ๊ณผ ์ฑ๋ฅ์ ์ํด Vite๊ฐ ํ์คํ ์น์์ ๋๋ค. ๋งค์ฐ ๊ตฌ์ฒด์ ์ธ ๋น๋ ์๊ตฌ ์ฌํญ์ด ์๋ ๋ณต์กํ ํ๋ก์ ํธ ๋๋ ๋ ๊ฑฐ์ ์์คํ ์ ์ ์ง ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ Webpack์ ์ฌ์ ํ ๊ฐ๋ ฅํ๊ณ ๊ด๋ จ์ฑ ์๋ ๋๊ตฌ์ ๋๋ค.
3. ์ฝ๋ ํ์ง ๋ฐ ํฌ๋งทํ : ์ผ๊ด์ฑ ์ ์ฉ
์ฌ๋ฌ ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฒ ์ด์ค์ ๊ธฐ์ฌํ๋ ๊ฒฝ์ฐ ์ผ๊ด๋ ์คํ์ผ์ ์ ์งํ๊ณ ์ผ๋ฐ์ ์ธ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ๋ฆฐํฐ์ ํฌ๋งทํฐ๋ ์ด ํ๋ก์ธ์ค๋ฅผ ์๋ํํ์ฌ ์คํ์ผ ๋ ผ์์ ์ ๊ฑฐํ๊ณ ์ฝ๋ ๊ฐ๋ ์ฑ์ ํฅ์์ํต๋๋ค.
๋ฆฐํฐ: ESLint
๋ฆฐํฐ๋ ์ฝ๋๋ฅผ ์ ์ ์ผ๋ก ๋ถ์ํ์ฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐ ์คํ์ผ ์ค๋ฅ๋ฅผ ์ฐพ์ต๋๋ค. ESLint๋ JavaScript ์์ฝ์์คํ ์ ์ํ ๋ฆฐํฐ์ ๋๋ค. ํ์ฅ์ฑ์ด ๋ฐ์ด๋๋ฉฐ ๋ค์ํ ๊ท์น์ ์ ์ฉํ๋๋ก ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
- ๋ณ์ ์ด๋ฆ์ ์คํ ๋๋ ์ฌ์ฉํ์ง ์๋ ๋ณ์์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค.
- ์ ์ญ ๋ณ์ ํผํ๊ธฐ์ ๊ฐ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ์ฉํฉ๋๋ค.
- Airbnb ๋๋ Standard์ ๊ฐ์ ์ธ๊ธฐ ์๋ ์คํ์ผ ๊ฐ์ด๋๋ก ๊ตฌ์ฑํ๊ฑฐ๋ ์ฌ์ฉ์ ์ง์ ๊ท์น ์ธํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์์ `.eslintrc.json` ๊ตฌ์ฑ:
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"rules": {
"no-console": "warn",
"semi": ["error", "always"]
}
}
ํฌ๋งทํฐ: Prettier
์ฝ๋ ํฌ๋งทํฐ๋ ๋ฏธ๋ฆฌ ์ ์๋ ์คํ์ผ์ ๋ง๊ฒ ์ฝ๋๋ฅผ ์๋์ผ๋ก ๋ค์ ํฌ๋งทํฉ๋๋ค. Prettier๋ ์๊ฒฌ์ด ์๋ ์ฝ๋ ํฌ๋งทํฐ๋ก ์ ๊ณ ํ์ค์ด ๋์์ต๋๋ค. ๋ชจ๋ ์๋ ์คํ์ผ์ ์ ๊ฑฐํ๊ณ ์ถ๋ ฅ๋ ๋ชจ๋ ์ฝ๋๊ฐ ์ผ๊ด๋ ์คํ์ผ์ ์ค์ํ๋์ง ํ์ธํฉ๋๋ค.
- ์ฝ๋ ์คํ์ผ(ํญ ๋ ๊ณต๋ฐฑ, ๋ฐ์ดํ ์คํ์ผ ๋ฑ)์ ๋ํ ๋ชจ๋ ๋ ผ์์ ๋๋ ๋๋ค.
- ๋๋ถ๋ถ์ ์ฝ๋ ํธ์ง๊ธฐ์ ์๋ฒฝํ๊ฒ ํตํฉ๋์ด ์ ์ฅ ์ ์ฝ๋๋ฅผ ํฌ๋งทํฉ๋๋ค.
- Prettier๋ฅผ ์ฌ์ฉํ์ฌ ํฌ๋งทํ ๊ท์น์ ์ฒ๋ฆฌํ๊ณ ESLint๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ ํ์ง ๊ท์น์ ์ฒ๋ฆฌํ๋๋ก ํ์ฌ ESLint์ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ํ๋ก ํ: ์ค์๊ฐ ํผ๋๋ฐฑ๊ณผ ์ ์ฅ ์ ํฌ๋งท ๊ธฐ๋ฅ์ ์ํด ESLint์ Prettier๋ฅผ ํธ์ง๊ธฐ(์: VS Code ํ์ฅ)์ ํตํฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ์ค ์ค์๊ฐ ์ฌ์์ง๋๋ค.
4. ๋ฒ์ ์ ์ด ์ ๋ต: ํ์ ๋ฐ ์์
๋ฒ์ ์ ์ด๋ ํ์ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ๊ธฐ๋ฐ์ ๋๋ค. ํ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๊ณ ์ด์ ์ํ๋ก ๋๋๋ฆฌ๊ณ ์๋ก ๋ค๋ฅธ ๊ธฐ๋ฅ์ ๋ํด ๋ณ๋ ฌ๋ก ์์ ํ ์ ์์ต๋๋ค.
- Git: ๋ฒ์ ์ ์ด๋ฅผ ์ํ ๋ ผ์์ ์ฌ์ง๊ฐ ์๋ ๊ธ๋ก๋ฒ ํ์ค์ ๋๋ค. ๋ชจ๋ ๊ฐ๋ฐ์๋ Git์ ๋ํ ๊ฐ๋ ฅํ ๋ช ๋ น์ ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค.
- ๋ถ๊ธฐ ์ ๋ต: ์ผ๊ด๋ ๋ถ๊ธฐ ์ ๋ต์ด ์ค์ํฉ๋๋ค. ์ธ๊ธฐ ์๋ ๋ชจ๋ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- GitFlow: ๊ธฐ๋ฅ, ๋ฆด๋ฆฌ์ค ๋ฐ ํซํฝ์ค์ ๋ํ ์ ์ฉ ๋ถ๊ธฐ๊ฐ ์๋ ๊ณ ๋๋ก ๊ตฌ์กฐํ๋ ๋ชจ๋ธ์ ๋๋ค. ๊ฐ๋ ฅํ์ง๋ง ์ง์์ ์ธ ๋ฐฐํฌ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ์๊ท๋ชจ ํ์ด๋ ํ๋ก์ ํธ์๋ ์ง๋์น๊ฒ ๋ณต์กํ ์ ์์ต๋๋ค.
- GitHub Flow / ํธ๋ ํฌ ๊ธฐ๋ฐ ๊ฐ๋ฐ: ๊ฐ๋ฐ์๊ฐ ๊ธฐ๋ณธ ๋ถ๊ธฐ(`main` ๋๋ `master`)์์ ๊ธฐ๋ฅ ๋ถ๊ธฐ๋ฅผ ๋ง๋ค๊ณ ๊ฒํ ํ ๋ค์ ๋ณํฉํ๋ ๋ ๊ฐ๋จํ ๋ชจ๋ธ์ ๋๋ค. ์ด๋ ์ง์์ ์ธ ํตํฉ ๋ฐ ๋ฐฐํฌ๋ฅผ ์ค์ฒํ๋ ํ์ ์ด์์ ์ ๋๋ค.
- ์ปค๋ฐ ๊ท์น: Conventional Commits์ ๊ฐ์ ์ปค๋ฐ ๋ฉ์์ง ์์ฑ์ ๋ํ ํ์ค์ ์ฑํํ๋ฉด Git ๊ธฐ๋ก์ ์ผ๊ด์ฑ์ด ์๊น๋๋ค. ๊ธฐ๋ก์ ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ค๊ณ ๋ณ๊ฒฝ ๋ก๊ทธ ์์ฑ ๋ฐ ์๋ฏธ๋ก ์ ๋ฒ์ ๋ฒํ ๊ฒฐ์ ๊ณผ ๊ฐ์ ์์ ์๋ํ๋ฅผ ํ์ฉํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์ปค๋ฐ ๋ฉ์์ง๋ `feat(auth): ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๊ธฐ๋ฅ ์ถ๊ฐ`์ ๊ฐ์ต๋๋ค.
5. ํ ์คํธ ํ๋ ์์ํฌ: ์์ ์ฑ ๋ณด์ฅ
์์ ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ค๋ฉด ํฌ๊ด์ ์ธ ํ ์คํธ ์ ๋ต์ด ํ์์ ์ ๋๋ค. ๊ฐ๋ฐ์๊ฐ ์์ ์๊ฒ ๋ฆฌํฉํฐ๋งํ๊ณ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ ์์ ๋ง์ ์ ๊ณตํฉ๋๋ค. ํ ์คํธ ํผ๋ผ๋ฏธ๋๋ ์ ์ฉํ ๋ชจ๋ธ์ ๋๋ค.
๋จ์ ๋ฐ ํตํฉ ํ ์คํธ: Jest
Jest๋ ๋จ์์ฑ์ ์ค์ ์ ๋ ์ ์พํ JavaScript ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค. ํ ์คํธ ์คํ๊ธฐ, ์ด์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ชจ์ ๊ธฐ๋ฅ์ ์ฆ์ ํฌํจํ๋ ์ฌ์ธ์ ์๋ฃจ์ ์ ๋๋ค.
- ๋จ์ ํ ์คํธ: ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ฅ ์์ ๊ฒฉ๋ฆฌ๋ ๋ถ๋ถ(์: ๋จ์ผ ํจ์)์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํฉ๋๋ค.
- ํตํฉ ํ ์คํธ: ์ฌ๋ฌ ๋จ์๊ฐ ์์๋๋ก ํจ๊ป ์๋ํ๋์ง ํ์ธํฉ๋๋ค.
Jest ํ ์คํธ ์์ :
// sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;
// sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
E2E(End-to-End) ํ ์คํธ: Cypress ๋๋ Playwright
E2E ํ ์คํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํตํ ์ค์ ์ฌ์ฉ์์ ์ฌ์ ์ ์๋ฎฌ๋ ์ด์ ํฉ๋๋ค. ์ค์ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋๋ฉฐ ์ค์ํ ์ฌ์ฉ์ ํ๋ฆ์ด ์ฒ์๋ถํฐ ๋๊น์ง ์๋ํ๋์ง ํ์ธํฉ๋๋ค.
- Cypress: ๋ฐ์ด๋ ๋๋ฒ๊น ๊ฒฝํ, ์๊ฐ ์ฌํ ๊ธฐ๋ฅ, ๋น ๋ฅด๊ณ ์์ ์ ์ธ ํ ์คํธ๋ก ์ ๋ช ํ ๊ฐ๋ฐ์ ์นํ์ ์ธ E2E ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค.
- Playwright: Microsoft์ ๊ฐ๋ ฅํ ํ๋ ์์ํฌ๋ก ๋ฐ์ด๋ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ์ง์(Chromium, Firefox, WebKit)๊ณผ ์๋ ๋๊ธฐ, ๋คํธ์ํฌ ๊ฐ๋ก์ฑ๊ธฐ ๋ฐ ๋ณ๋ ฌ ์คํ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
6. TypeScript๋ฅผ ์ฌ์ฉํ ์ ํ ์์
์๋ฐํ ๋งํ๋ฉด "์ธํ๋ผ"๋ ์๋์ง๋ง TypeScript๋ฅผ ์ฑํํ๋ ๊ฒ์ ํ๋ก์ ํธ์ ์ฅ๊ธฐ์ ์ธ ๊ฑด์ ์ฑ์ ํฐ ์ํฅ์ ๋ฏธ์น๋ ๊ทผ๋ณธ์ ์ธ ๊ฒฐ์ ์ ๋๋ค. TypeScript๋ ์ ์ ์ ํ์ ์ถ๊ฐํ๋ JavaScript์ ์์ ์งํฉ์ ๋๋ค.
- ์ค๋ฅ ๋ฐฉ์ง: ์ฝ๋๊ฐ ์คํ๋๊ธฐ ์ ์ ๊ฐ๋ฐ ์ค์ ๋ฐ์ํ๋ ๋ง์ ํด๋์ค์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค.
- ํฅ์๋ ๊ฐ๋ฐ์ ๊ฒฝํ: ์ง๋ฅํ ์๋ ์์ฑ, ๋ฆฌํฉํฐ๋ง ๋ฐ ์ ์๋ก ์ด๋๊ณผ ๊ฐ์ ๊ฐ๋ ฅํ ํธ์ง๊ธฐ ๊ธฐ๋ฅ์ ํ์ฑํํฉ๋๋ค.
- ์์ฒด ๋ฌธ์ํ ์ฝ๋: ์ ํ์ ์ฝ๋๋ฅผ ์ดํดํ๊ณ ์ถ๋ก ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด ๋๊ท๋ชจ ํ๊ณผ ์ค๋ ์ง์๋๋ ํ๋ก์ ํธ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
TypeScript๋ฅผ ํตํฉํ๋ ค๋ฉด ์ปดํ์ผ๋ฌ ์ต์ ์ ๊ตฌ์ฑํ๋ `tsconfig.json` ํ์ผ์ด ํ์ํฉ๋๋ค. ํนํ ์ค๊ฐ์์ ๋์ ๋ณต์ก์ฑ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ ์ด์ ์ ์ด๊ธฐ ํ์ต ๊ณก์ ๋ณด๋ค ๊ฑฐ์ ํญ์ ํฝ๋๋ค.
7. ์๋ํ ๋ฐ CI/CD: ์์ฐ์ฑ์ ์์ง
์๋ํ๋ ๋ค๋ฅธ ๋ชจ๋ ์์๋ฅผ ํจ๊ป ๋ฌถ๋ ๊ฒ์ ๋๋ค. ํ์ง ๊ฒ์ฌ ๋ฐ ๋ฐฐํฌ ํ๋ก์ธ์ค๊ฐ ์ผ๊ด๋๊ณ ์๋์ผ๋ก ์คํ๋๋๋ก ํฉ๋๋ค.
Git ํํฌ: Husky & lint-staged
Git ํํฌ๋ Git ๋ผ์ดํ์ฌ์ดํด์ ํน์ ์์ ์์ ์๋์ผ๋ก ์คํ๋๋ ์คํฌ๋ฆฝํธ์ ๋๋ค. Husky์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ํํฌ๋ฅผ ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ์ผ๋ฐ์ ์ธ ์ค์ ์ `pre-commit` ํํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ปค๋ฐํ๋ ค๋ ํ์ผ์์ ๋ฆฐํฐ, ํฌ๋งทํฐ ๋ฐ ๋จ์ ํ ์คํธ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค(lint-staged์ ๊ฐ์ ๋๊ตฌ ์ฌ์ฉ).
- ์ด๋ ๊ฒ ํ๋ฉด ์์๋๊ฑฐ๋ ์๋ชป ํฌ๋งท๋ ์ฝ๋๊ฐ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ค์ด๊ฐ๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ์์ค์์ ํ์ง์ ์ ์ฉํฉ๋๋ค.
CI/CD(์ง์์ ์ธ ํตํฉ ๋ฐ ์ง์์ ์ธ ๋ฐฐํฌ)
CI/CD๋ ์ ์ฝ๋๊ฐ ๋ฆฌํฌ์งํ ๋ฆฌ๋ก ํธ์๋ ๋๋ง๋ค ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋์ผ๋ก ๋น๋, ํ ์คํธ ๋ฐ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- CI(์ง์์ ์ธ ํตํฉ): CI ์๋ฒ(์: GitHub Actions, GitLab CI, CircleCI)๋ ๋ชจ๋ ํธ์ ๋๋ ํ ์์ฒญ์์ ์ ์ฒด ํ ์คํธ ์ค์ํธ(๋จ์, ํตํฉ ๋ฐ E2E)๋ฅผ ์๋์ผ๋ก ์คํํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์๋ก์ด ๋ณ๊ฒฝ ์ฌํญ์ด ๊ธฐ์กด ๊ธฐ๋ฅ์ ์์์ํค์ง ์์ต๋๋ค.
- CD(์ง์์ ์ธ ๋ฐฐํฌ): ๊ธฐ๋ณธ ๋ถ๊ธฐ์์ ๋ชจ๋ CI ๊ฒ์ฌ๋ฅผ ํต๊ณผํ๋ฉด CD ํ๋ก์ธ์ค๊ฐ ์๋์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํ ์ด์ง ๋๋ ํ๋ก๋์ ํ๊ฒฝ์ ๋ฐฐํฌํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์๋ก์ด ๊ธฐ๋ฅ์ ๋น ๋ฅด๊ณ ์์ ์ ์ผ๋ก ์ ๊ณตํ ์ ์์ต๋๋ค.
GitHub Actions์ ๋ํ ์์ `.github/workflows/ci.yml`:
name: Node.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
8. Docker๋ฅผ ์ฌ์ฉํ ์ปจํ ์ด๋ํ
Docker๋ ์์คํ ์์ค์์ "๋ด ์ปดํจํฐ์์๋ ์๋ํฉ๋๋ค" ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋ชจ๋ ์ข ์์ฑ(์ด์ ์ฒด์ ํฌํจ)์ ๊ฒฝ๋์ ์ด์ ๊ฐ๋ฅํ ์ปจํ ์ด๋๋ก ํจํค์งํ ์ ์์ต๋๋ค.
- ์ผ๊ด๋ ํ๊ฒฝ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ฐ๋ฐ, ํ ์คํธ ๋ฐ ํ๋ก๋์ ์์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์คํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ๊ฐ๋ฐ์๊ฐ ์๋ก ๋ค๋ฅธ ์ด์ ์ฒด์ ๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ธ๋ก๋ฒ ํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ๊ฐ์ํ๋ ์จ๋ณด๋ฉ: ์๋ก์ด ๊ฐ๋ฐ์๋ ์๋์ผ๋ก ์ปดํจํฐ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐ ๋ฉฐ์น ์ ์๋นํ๋ ๋์ ๋จ์ผ ๋ช ๋ น(`docker-compose up`)์ผ๋ก ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์คํ์ ์คํํ ์ ์์ต๋๋ค.
- ํ์ฅ์ฑ: ์ปจํ ์ด๋๋ Kubernetes์ ๊ฐ์ ์ต์ ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ ์ํคํ ์ฒ ๋ฐ ์ค์ผ์คํธ๋ ์ด์ ์์คํ ์ ํต์ฌ ๊ตฌ์ฑ ์์์ ๋๋ค.
Node.js ์ฑ์ ๋ํ ์์ `Dockerfile`:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD [ "node", "server.js" ]
๋ชจ๋ ํจ๊ป ๋ฃ๊ธฐ: ์ํ ํ๋ก์ ํธ ์ค์
์ด ์ธํ๋ผ๊ฐ ๊ตฌ์ถ๋ ์ ํ๋ก์ ํธ๋ฅผ ๋ง๋๋ ๋จ๊ณ๋ฅผ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
- ํ๋ก์ ํธ ์ด๊ธฐํ: `git init` ๋ฐ `npm init -y`.
- ์ข
์์ฑ ์ค์น:
- ์ ํ๋ฆฌ์ผ์ด์ ์ข ์์ฑ: `npm install express`
- ๊ฐ๋ฐ ์ข ์์ฑ: `npm install --save-dev typescript @types/node eslint prettier jest babel-jest ts-node husky lint-staged`
- ํด๋ง ๊ตฌ์ฑ:
- TypeScript ์ค์ ์ ์ํด `tsconfig.json`์ ๋ง๋ญ๋๋ค.
- ESLint ๊ท์น์ ๊ตฌ์ฑํ๊ธฐ ์ํด `.eslintrc.json`์ ๋ง๋ญ๋๋ค.
- ํฌ๋งทํ ์๊ฒฌ์ ์ ์ํ๊ธฐ ์ํด `.prettierrc`๋ฅผ ๋ง๋ญ๋๋ค.
- ํ ์คํธ ๊ตฌ์ฑ์ ์ํด `jest.config.js`๋ฅผ ๋ง๋ญ๋๋ค.
- ์๋ํ ์ค์ :
- Husky๋ฅผ ์ค์ ํ๋ ค๋ฉด `npx husky-init && npm install`์ ์คํํฉ๋๋ค.
- `npx lint-staged`๋ฅผ ์คํํ๋๋ก `.husky/pre-commit` ํ์ผ์ ์์ ํฉ๋๋ค.
- ์คํ ์ด์ง๋ ํ์ผ์์ ์คํํ ๋ช ๋ น(์: `eslint --fix` ๋ฐ `prettier --write`)์ ์ง์ ํ๋๋ก `package.json`์ `lint-staged` ํค๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- `npm` ์คํฌ๋ฆฝํธ ์ถ๊ฐ: `package.json`์์ ์ผ๋ฐ์ ์ธ ์์ ์ ๋ํ ์คํฌ๋ฆฝํธ(`"test": "jest"`, `"lint": "eslint ."`, `"build": "tsc"`)๋ฅผ ์ ์ํฉ๋๋ค.
- CI/CD ํ์ดํ๋ผ์ธ ๋ง๋ค๊ธฐ: ๋ชจ๋ ํ ์์ฒญ์์ ํ ์คํธ๋ฅผ ์๋ํํ๋ ค๋ฉด `.github/workflows/ci.yml` ํ์ผ(๋๋ ํด๋น ํ๋ซํผ์ ํด๋นํ๋ ํ์ผ)์ ์ถ๊ฐํฉ๋๋ค.
- ์ปจํ ์ด๋ํ: ์ ํ๋ฆฌ์ผ์ด์ ํ๊ฒฝ์ ์ ์ํ๋ ค๋ฉด `Dockerfile` ๋ฐ `docker-compose.yml`์ ์ถ๊ฐํฉ๋๋ค.
๊ฒฐ๋ก : ํ์ง๊ณผ ์๋์ ๋ํ ํฌ์
ํฌ๊ด์ ์ธ JavaScript ๊ฐ๋ฐ ์ธํ๋ผ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ์๋นํ ์ด๊ธฐ ํฌ์์ฒ๋ผ ๋ณด์ผ ์ ์์ง๋ง ์์ต์ ์์ฒญ๋ฉ๋๋ค. ์ผ๊ด๋ ํ๊ฒฝ์ ๋ ๋์ ์ฝ๋ ํ์ง๋ก ์ด์ด์ ธ ๋ฒ๊ทธ์ ๊ธฐ์ ๋ถ์ฑ๋ฅผ ์ค์ด๋ ์ ์ํ์ ๋ง๋ญ๋๋ค. ์๋ํ๋ ๊ฐ๋ฐ์๊ฐ ์๋์ ์ด๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฌ์ด ์์ ์์ ๋ฒ์ด๋ ๊ฐ์ฅ ์ํ๋ ์ผ, ์ฆ ๊ธฐ๋ฅ ๊ตฌ์ถ ๋ฐ ๊ฐ์น ์ ๊ณต์ ์ง์คํ ์ ์๋๋ก ํฉ๋๋ค.
๊ตญ์ ํ์ ๊ฒฝ์ฐ ์ด ๊ณต์ ๊ธฐ๋ฐ์ ํ๋ก์ ํธ๋ฅผ ํ๋๋ก ๋ฌถ๋ ์ ์ฐฉ์ ์ ๋๋ค. ์ง๋ฆฌ์ ๋ฐ ๋ฌธํ์ ๊ฒฝ๊ณ๋ฅผ ์ด์ํ์ฌ ์ ๊ณต๋๋ ๋ชจ๋ ์ฝ๋ ๋ผ์ธ์ด ๋์ผํ ๋์ ํ์ค์ ์ค์ํ๋์ง ํ์ธํฉ๋๋ค. ์ด๋ฌํ ๋๊ตฌ๋ฅผ ์ ์คํ๊ฒ ์ ํํ๊ณ ํตํฉํจ์ผ๋ก์จ ํ๋ก์ ํธ๋ฅผ ์ค์ ํ๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ํ์ฅ ๊ฐ๋ฅํ๊ณ ํ๋ ฅ์ ์ด๋ฉฐ ์์ฐ์ฑ์ด ๋์ ์์ง๋์ด๋ง ๋ฌธํ๋ฅผ ๊ตฌ์ถํ๊ณ ์์ต๋๋ค.