์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธํ๋ผ ๊ตฌํ์ ์ํ ์ข ํฉ ๊ฐ์ด๋. ํ์ ๋๊ตฌ, ๋ชจ๋ฒ ์ฌ๋ก, ๊ธ๋ก๋ฒ ํ์ ์ํ ์ํฌํ๋ก์ฐ ์ต์ ํ๋ฅผ ๋ค๋ฃน๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธํ๋ผ: ์ต์ ํด์ฒด์ธ ๊ตฌํ
์ค๋๋ ๋น ๋ฅด๊ฒ ๋ณํํ๋ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์, ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ฐ๋ฉฐ ๊ณ ์ฑ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํด์๋ ๊ฒฌ๊ณ ํ๊ณ ์ ๊ตฌ์ฑ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธํ๋ผ๊ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ํด์ฒด์ธ์ ํ์ ๊ตฌ์ฑ ์์๋ฅผ ์ดํด๋ณด๊ณ , ๊ธ๋ก๋ฒ ํ์ ์ํด ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ค์ฉ์ ์ธ ์ง์นจ์ ์ ๊ณตํฉ๋๋ค.
์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ํด์ฒด์ธ ์ดํดํ๊ธฐ
์๋ฐ์คํฌ๋ฆฝํธ ํด์ฒด์ธ์ ์ด๊ธฐ ์ฝ๋ฉ๋ถํฐ ๋ฐฐํฌ ๋ฐ ์ ์ง๋ณด์์ ์ด๋ฅด๊ธฐ๊น์ง ์ํํธ์จ์ด ๊ฐ๋ฐ ๋ผ์ดํ์ฌ์ดํด ์ ๋ฐ์ ๊ฑธ์ณ ์ฌ์ฉ๋๋ ๋๊ตฌ์ ํ๋ก์ธ์ค์ ์งํฉ์ ์๋ฏธํฉ๋๋ค. ์ ์ค๊ณ๋ ํด์ฒด์ธ์ ๋ฐ๋ณต์ ์ธ ์์ ์ ์๋ํํ๊ณ , ์ฝ๋ฉ ํ์ค์ ๊ฐ์ ํ๋ฉฐ, ํ๋ก๋์ ์ฉ ์ฝ๋๋ฅผ ์ต์ ํํ์ฌ ๊ฐ๋ฐ์ ์์ฐ์ฑ์ ๋์ด๊ณ ์ ํ๋ฆฌ์ผ์ด์ ํ์ง์ ํฅ์์ํต๋๋ค.
์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ํด์ฒด์ธ์ ์ฃผ์ ๊ตฌ์ฑ ์์:
- ํจํค์ง ๋งค๋์ (npm, Yarn, pnpm): ํ๋ก์ ํธ ์์กด์ฑ(๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ํ๋ ์์ํฌ)์ ๊ด๋ฆฌํฉ๋๋ค.
- ํ์คํฌ ๋ฌ๋/๋ชจ๋ ๋ฒ๋ค๋ฌ (webpack, Parcel, Rollup): ๋ฐฐํฌ๋ฅผ ์ํด ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋๊ณผ ์์ฐ์ ๋ฒ๋ค๋งํฉ๋๋ค.
- ํธ๋์คํ์ผ๋ฌ (Babel): ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ(ES6+) ์ฝ๋๋ฅผ ๊ตฌํ ๋ธ๋ผ์ฐ์ ์ ํธํ๋๋ ๋ฒ์ ์ผ๋ก ๋ณํํฉ๋๋ค.
- ๋ฆฐํฐ (ESLint): ์ฝ๋ฉ ์คํ์ผ์ ๊ฐ์ ํ๊ณ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์๋ณํฉ๋๋ค.
- ํฌ๋งทํฐ (Prettier): ์ผ๊ด์ฑ์ ์ํด ์ฝ๋๋ฅผ ์๋์ผ๋ก ํฌ๋งทํ ํฉ๋๋ค.
- ํ ์คํ ํ๋ ์์ํฌ (Jest, Mocha, Jasmine): ์๋ํ๋ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ ์คํํฉ๋๋ค.
- ์ง์์ ํตํฉ/์ง์์ ๋ฐฐํฌ (CI/CD) (Jenkins, CircleCI, GitHub Actions): ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋น๋, ํ ์คํธ, ๋ฐฐํฌ๋ฅผ ์๋ํํฉ๋๋ค.
- ๋ฒ์ ๊ด๋ฆฌ (Git): ์ฝ๋๋ฒ ์ด์ค์ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๊ณ ํ์ ์ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ํ๊ฒฝ ์ค์ ํ๊ธฐ
ํด์ฒด์ธ์ ์ดํด๋ณด๊ธฐ ์ ์, ์ ๊ตฌ์ฑ๋ ๊ฐ๋ฐ ํ๊ฒฝ์ ๊ฐ์ถ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
1. Node.js ๋ฐ npm (๋๋ Yarn/pnpm) ์ค์น
Node.js๋ ์ฐ๋ฆฌ ํด์ฒด์ธ์ ๋ง์ ๋๊ตฌ๋ฅผ ๊ตฌ๋ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐํ์ ํ๊ฒฝ์ ๋๋ค. npm (Node Package Manager)์ ๊ธฐ๋ณธ ํจํค์ง ๋งค๋์ ์ด์ง๋ง, Yarn๊ณผ pnpm์ ์ฑ๋ฅ ๋ฐ ์์กด์ฑ ๊ด๋ฆฌ ๊ฐ์ ์ ์ ๊ณตํฉ๋๋ค.
์ค์น ์๋ด (์ผ๋ฐ):
- ๊ณต์ Node.js ์น์ฌ์ดํธ(nodejs.org)๋ฅผ ๋ฐฉ๋ฌธํ์ฌ ์ด์ ์ฒด์ (Windows, macOS, Linux)์ ๋ง๋ ์ค์น ํ๋ก๊ทธ๋จ์ ๋ค์ด๋ก๋ํฉ๋๋ค.
- ์ค์น ์ง์นจ์ ๋ฐ๋ฆ ๋๋ค. npm์ ์ผ๋ฐ์ ์ผ๋ก Node.js์ ํฌํจ๋์ด ์์ต๋๋ค.
- ๋๋, OS ์ ์ฉ ํจํค์ง ๋งค๋์ ๋ฅผ ์ฌ์ฉํฉ๋๋ค (์: macOS์์ `brew install node`).
Yarn ์ค์น:
npm install --global yarn
pnpm ์ค์น:
npm install --global pnpm
์ค์น ํ์ธ:
ํฐ๋ฏธ๋์ ์ด๊ณ ๋ค์์ ์คํํฉ๋๋ค:
node -v
npm -v
yarn -v (์ค์น๋ ๊ฒฝ์ฐ)
pnpm -v (์ค์น๋ ๊ฒฝ์ฐ)
์ด ๋ช ๋ น์ด๋ค์ ์ค์น๋ Node.js์ ์ ํํ ํจํค์ง ๋งค๋์ ์ ๋ฒ์ ์ ํ์ํด์ผ ํฉ๋๋ค.
2. ์ฝ๋ ์๋ํฐ/IDE
์ ํธ๋์ ๋ง๋ ์ฝ๋ ์๋ํฐ ๋๋ ํตํฉ ๊ฐ๋ฐ ํ๊ฒฝ(IDE)์ ์ ํํ์ธ์. ์ธ๊ธฐ ์๋ ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Visual Studio Code (VS Code): ๋ฐ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ง์์ ์ ๊ณตํ๋ ๋ฌด๋ฃ์ด๋ฉฐ ํ์ฅ์ฑ์ด ๋์ ์๋ํฐ์ ๋๋ค.
- WebStorm: ์น ๊ฐ๋ฐ์ ์ํด ํน๋ณํ ์ค๊ณ๋ ๊ฐ๋ ฅํ IDE์ ๋๋ค.
- Sublime Text: ๋ค์ํ ํ๋ฌ๊ทธ์ธ์ ๊ฐ์ถ ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅํ ํ ์คํธ ์๋ํฐ์ ๋๋ค.
- Atom: ํ๋ฐํ ์ปค๋ฎค๋ํฐ๋ฅผ ๊ฐ์ง ๋ ๋ค๋ฅธ ๋ฌด๋ฃ ์คํ์์ค ์๋ํฐ์ ๋๋ค.
์ ํํ ์๋ํฐ์ ๋ฆฐํฐ, ํฌ๋งทํฐ, ๋๋ฒ๊น ๋๊ตฌ์ ๊ฐ์ ๊ด๋ จ ํ์ฅ ํ๋ก๊ทธ๋จ์ ์ค์นํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์ ํฅ์์ํค์ธ์.
3. ๋ฒ์ ๊ด๋ฆฌ ์์คํ (Git)
Git์ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๊ณ ๋ค๋ฅธ ๊ฐ๋ฐ์์ ํ์ ํ๋ ๋ฐ ํ์์ ์ ๋๋ค. ์์คํ ์ Git์ ์ค์นํ๊ณ ๊ธฐ๋ณธ์ ์ธ Git ๋ช ๋ น์ด(clone, add, commit, push, pull, branch, merge)์ ์ต์ํด์ง์ธ์.
์ค์น ์๋ด (์ผ๋ฐ):
- ๊ณต์ Git ์น์ฌ์ดํธ(git-scm.com)๋ฅผ ๋ฐฉ๋ฌธํ์ฌ ์ด์ ์ฒด์ ์ ๋ง๋ ์ค์น ํ๋ก๊ทธ๋จ์ ๋ค์ด๋ก๋ํฉ๋๋ค.
- ์ค์น ์ง์นจ์ ๋ฐ๋ฆ ๋๋ค.
- ๋๋, OS ์ ์ฉ ํจํค์ง ๋งค๋์ ๋ฅผ ์ฌ์ฉํฉ๋๋ค (์: macOS์์ `brew install git`).
์ค์น ํ์ธ:
ํฐ๋ฏธ๋์ ์ด๊ณ ๋ค์์ ์คํํฉ๋๋ค:
git --version
ํด์ฒด์ธ ๊ตฌํํ๊ธฐ: ๋จ๊ณ๋ณ ์๋ด
1. ํ๋ก์ ํธ ์ค์ ๋ฐ ํจํค์ง ๊ด๋ฆฌ
์ ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ npm, Yarn, ๋๋ pnpm์ ์ฌ์ฉํ์ฌ package.json ํ์ผ์ ์ด๊ธฐํํฉ๋๋ค:
npm:
mkdir my-project
cd my-project
npm init -y
Yarn:
mkdir my-project
cd my-project
yarn init -y
pnpm:
mkdir my-project
cd my-project
pnpm init
`package.json` ํ์ผ์ ํ๋ก์ ํธ ๋ฉํ๋ฐ์ดํฐ, ์์กด์ฑ, ๊ทธ๋ฆฌ๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ฅํฉ๋๋ค.
2. webpack์ ์ด์ฉํ ๋ชจ๋ ๋ฒ๋ค๋ง
webpack์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋(๊ทธ๋ฆฌ๊ณ CSS ๋ฐ ์ด๋ฏธ์ง์ ๊ฐ์ ๋ค๋ฅธ ์์ฐ)์ ๊ฐ์ ธ์ ๋ฐฐํฌ์ฉ์ผ๋ก ์ต์ ํ๋ ํ์ผ๋ก ๋ฒ๋ค๋งํ๋ ๊ฐ๋ ฅํ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ ๋๋ค. ์ฒ์์๋ ๊ตฌ์ฑ์ด ๋ณต์กํ ์ ์์ง๋ง, ์๋นํ ์ฑ๋ฅ ๋ฐ ์ต์ ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค.
์ค์น:
npm install --save-dev webpack webpack-cli webpack-dev-server (๋๋ Yarn/pnpm ์ฌ์ฉ)
๊ตฌ์ฑ (webpack.config.js):
ํ๋ก์ ํธ ๋ฃจํธ์ `webpack.config.js` ํ์ผ์ ๋ง๋ค์ด webpack์ ๊ตฌ์ฑํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
},
mode: 'development', // ๋๋ 'production'
};
์ค๋ช :
- `entry`: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ์ (์ผ๋ฐ์ ์ผ๋ก `src/index.js`)์ ์ง์ ํฉ๋๋ค.
- `output`: ์ถ๋ ฅ ํ์ผ ์ด๋ฆ๊ณผ ๋๋ ํ ๋ฆฌ๋ฅผ ์ ์ํฉ๋๋ค.
- `devServer`: ํซ ๋ฆฌ๋ก๋ฉ์ ์ํ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- `mode`: ๋น๋ ๋ชจ๋๋ฅผ `development` ๋๋ `production`์ผ๋ก ์ค์ ํฉ๋๋ค. ํ๋ก๋์ ๋ชจ๋๋ ์ฝ๋ ์ถ์(minification)์ ๊ฐ์ ์ต์ ํ๋ฅผ ํ์ฑํํฉ๋๋ค.
`package.json`์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํ์ฌ webpack์ ์คํํฉ๋๋ค:
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development"
}
์ด์ `npm run build`๋ฅผ ์คํํ์ฌ ํ๋ก๋์ ๋ฒ๋ค์ ์์ฑํ๊ฑฐ๋ `npm run start`๋ฅผ ์คํํ์ฌ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์์ํ ์ ์์ต๋๋ค.
3. Babel์ ์ด์ฉํ ํธ๋์คํ์ผ๋ง
Babel์ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋(ES6+)๋ฅผ ๊ตฌํ ๋ธ๋ผ์ฐ์ ์์ ์คํํ ์ ์๋ ํ์ ํธํ ๋ฒ์ ์ผ๋ก ๋ณํํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค์ํ ๋ธ๋ผ์ฐ์ ์์ ์๋ํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
์ค์น:
npm install --save-dev @babel/core @babel/cli @babel/preset-env babel-loader (๋๋ Yarn/pnpm ์ฌ์ฉ)
๊ตฌ์ฑ (.babelrc ๋๋ babel.config.js):
ํ๋ก์ ํธ ๋ฃจํธ์ `.babelrc` ํ์ผ์ ๋ง๋ค๊ณ ๋ค์ ๊ตฌ์ฑ์ ์ถ๊ฐํฉ๋๋ค:
{
"presets": ["@babel/preset-env"]
}
์ด๋ Babel์ด `@babel/preset-env` ํ๋ฆฌ์ ์ ์ฌ์ฉํ๋๋ก ์ง์ํ๋ฉฐ, ์ด ํ๋ฆฌ์ ์ ๋์ ๋ธ๋ผ์ฐ์ ์ ๋ฐ๋ผ ํ์ํ ๋ณํ์ ์๋์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค.
webpack๊ณผ ํตํฉ:
`webpack.config.js`์ `module` ๊ท์น์ ์ถ๊ฐํ์ฌ `babel-loader`๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์ฒ๋ฆฌํ๋๋ก ํฉ๋๋ค:
module.exports = {
// ... ๋ค๋ฅธ ๊ตฌ์ฑ
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
],
},
};
4. ESLint๋ฅผ ์ด์ฉํ ๋ฆฐํ
ESLint๋ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์๋ณํ๊ณ ์์ ํ๋ฉฐ ์ฝ๋ฉ ์คํ์ผ ๊ฐ์ด๋๋ผ์ธ์ ๊ฐ์ ํ๋ ๋ฐ ๋์์ ์ค๋๋ค. ์ด๋ ์ฝ๋ ํ์ง๊ณผ ์ผ๊ด์ฑ์ ํฅ์์ํต๋๋ค.
์ค์น:
npm install --save-dev eslint (๋๋ Yarn/pnpm ์ฌ์ฉ)
๊ตฌ์ฑ (.eslintrc.js ๋๋ .eslintrc.json):
ํ๋ก์ ํธ ๋ฃจํธ์ `.eslintrc.js` ํ์ผ์ ๋ง๋ค๊ณ ์ ํธ๋์ ๋ฐ๋ผ ESLint๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'eslint:recommended',
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
rules: {
// ์ฌ๊ธฐ์ ์ฌ์ฉ์ ์ ์ ๊ท์น ์ถ๊ฐ
},
};
`eslint:recommended`์ ๊ฐ์ ๊ธฐ์กด ESLint ๊ตฌ์ฑ์ ํ์ฅํ๊ฑฐ๋ Airbnb๋ Google๊ณผ ๊ฐ์ ์ธ๊ธฐ ์๋ ์คํ์ผ ๊ฐ์ด๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
VS Code์ ํตํฉ:
VS Code์ฉ ESLint ํ์ฅ ํ๋ก๊ทธ๋จ์ ์ค์นํ์ฌ ์ค์๊ฐ ๋ฆฐํ ํผ๋๋ฐฑ์ ๋ฐ์ผ์ธ์.
`package.json`์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํ์ฌ ESLint๋ฅผ ์คํํฉ๋๋ค:
"scripts": {
"lint": "eslint ."
}
5. Prettier๋ฅผ ์ด์ฉํ ํฌ๋งทํ
Prettier๋ ํ๋ก์ ํธ ์ ๋ฐ์ ๊ฑธ์ณ ์ผ๊ด๋ ์คํ์ผ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ฝ๋๋ฅผ ์๋์ผ๋ก ํฌ๋งทํ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ฝ๋ ์คํ์ผ์ ๋ํ ๋ ผ์์ ์์ ๊ณ ์ฝ๋ ๊ฐ๋ ์ฑ์ ๋์ ๋๋ค.
์ค์น:
npm install --save-dev prettier (๋๋ Yarn/pnpm ์ฌ์ฉ)
๊ตฌ์ฑ (.prettierrc.js ๋๋ .prettierrc.json):
ํ๋ก์ ํธ ๋ฃจํธ์ `.prettierrc.js` ํ์ผ์ ๋ง๋ค๊ณ ์ ํธ๋์ ๋ฐ๋ผ Prettier๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
};
VS Code์ ํตํฉ:
VS Code์ฉ Prettier ํ์ฅ ํ๋ก๊ทธ๋จ์ ์ค์นํ์ฌ ์ ์ฅ ์ ์ฝ๋๋ฅผ ์๋์ผ๋ก ํฌ๋งทํ ํ์ธ์.
ESLint์ ํตํฉ:
ESLint์ Prettier ๊ฐ์ ์ถฉ๋์ ํผํ๊ธฐ ์ํด ๋ค์ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
๊ทธ๋ฐ ๋ค์, `.eslintrc.js` ํ์ผ์ ์ ๋ฐ์ดํธํ์ฌ `prettier`๋ฅผ ํ์ฅํ๊ณ `eslint-plugin-prettier` ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํฉ๋๋ค:
module.exports = {
// ... ๋ค๋ฅธ ๊ตฌ์ฑ
extends: [
'eslint:recommended',
'prettier',
],
plugins: [
'prettier',
],
rules: {
'prettier/prettier': 'error',
},
};
`package.json`์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํ์ฌ Prettier๋ฅผ ์คํํฉ๋๋ค:
"scripts": {
"format": "prettier --write ."
}
6. Jest๋ฅผ ์ด์ฉํ ํ ์คํ
Jest๋ ์ ๋ ํ ์คํธ, ํตํฉ ํ ์คํธ, ์๋ํฌ์๋ ํ ์คํธ๋ฅผ ์ฝ๊ฒ ์์ฑํ๊ณ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ ์ธ๊ธฐ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํ ํ๋ ์์ํฌ์ ๋๋ค. ํ ์คํ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ง๊ณผ ์ ๋ขฐ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ค์น:
npm install --save-dev jest (๋๋ Yarn/pnpm ์ฌ์ฉ)
๊ตฌ์ฑ (jest.config.js):
ํ๋ก์ ํธ ๋ฃจํธ์ `jest.config.js` ํ์ผ์ ๋ง๋ค์ด Jest๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
module.exports = {
testEnvironment: 'node',
};
ํ ์คํธ ์์ฑ:
`.test.js` ๋๋ `.spec.js` ํ์ฅ์๋ฅผ ๊ฐ์ง ํ ์คํธ ํ์ผ์ ๋ง๋ญ๋๋ค. ์๋ฅผ ๋ค์ด, `src/math.js`๋ผ๋ ํ์ผ์ด ์๋ค๋ฉด `src/math.test.js`๋ผ๋ ํ ์คํธ ํ์ผ์ ๋ง๋ค ์ ์์ต๋๋ค.
์์ ํ ์คํธ:
// src/math.test.js
const { add } = require('./math');
describe('math functions', () => {
it('should add two numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});
});
`package.json`์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํ์ฌ Jest๋ฅผ ์คํํฉ๋๋ค:
"scripts": {
"test": "jest"
}
7. ์ง์์ ํตํฉ/์ง์์ ๋ฐฐํฌ (CI/CD)
CI/CD๋ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋น๋, ํ ์คํธ, ๋ฐฐํฌํ๋ ํ๋ก์ธ์ค๋ฅผ ์๋ํํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ด ํญ์ ๋ฐฐํฌ ๊ฐ๋ฅํ ์ํ๋ฅผ ์ ์งํ๊ณ ์๋ก์ด ๊ธฐ๋ฅ๊ณผ ๋ฒ๊ทธ ์์ ์ด ๋น ๋ฅด๊ณ ์์ ์ ์ผ๋ก ๋ฆด๋ฆฌ์ค๋ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ธ๊ธฐ ์๋ CI/CD ํ๋ซํผ์ผ๋ก๋ Jenkins, CircleCI, Travis CI, GitHub Actions ๋ฑ์ด ์์ต๋๋ค.
์์: GitHub Actions
๋ฆฌํฌ์งํ ๋ฆฌ์ `.github/workflows` ๋๋ ํ ๋ฆฌ์ ์ํฌํ๋ก์ฐ ํ์ผ์ ๋ง๋ญ๋๋ค (์: `.github/workflows/ci.yml`).
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 16
uses: actions/setup-node@v2
with:
node-version: '16.x'
- name: Install dependencies
run: npm install
- name: Lint
run: npm run lint
- name: Test
run: npm run test
- name: Build
run: npm run build
์ด ์ํฌํ๋ก์ฐ๋ `main` ๋ธ๋์น๋ก์ ๋ชจ๋ ํธ์์ `main` ๋ธ๋์น๋ฅผ ๋์์ผ๋ก ํ๋ ๋ชจ๋ ํ ๋ฆฌํ์คํธ์์ ์๋์ผ๋ก ์คํ๋ฉ๋๋ค. ์์กด์ฑ์ ์ค์นํ๊ณ , ๋ฆฐํ ์ ์คํํ๊ณ , ํ ์คํธ๋ฅผ ์คํํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น๋ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ ์ต์ ํํ๊ธฐ
1. ์ฝ๋ ๋ฆฌ๋ทฐ
์ฝ๋ ํ์ง์ ๋ณด์ฅํ๊ณ ์ง์์ ๊ณต์ ํ๊ธฐ ์ํด ์ฝ๋ ๋ฆฌ๋ทฐ ํ๋ก์ธ์ค๋ฅผ ์๋ฆฝํ์ธ์. GitHub ํ ๋ฆฌํ์คํธ์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ฝ๊ฒ ๋ฆฌ๋ทฐํ๊ณ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
2. ์๋ํ
์์์ ์ ์ค์ด๊ณ ์ผ๊ด์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ๊ฐ๋ฅํ ํ ๋ง์ ์์ ์ ์๋ํํ์ธ์. npm ์คํฌ๋ฆฝํธ, Makefile ๋๋ ํ์คํฌ ๋ฌ๋์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ๋ณต์ ์ธ ์์ ์ ์๋ํํฉ๋๋ค.
3. ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
ํ๋ก๋์ ํ๊ฒฝ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ์ ๋ชจ๋ํฐ๋งํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ์์ ํ์ธ์. Google Analytics, New Relic ๋๋ Sentry์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ด์ง ๋ก๋ ์๊ฐ, ์ค๋ฅ์จ, ๋ฆฌ์์ค ์ฌ์ฉ๋๊ณผ ๊ฐ์ ์งํ๋ฅผ ์ถ์ ํฉ๋๋ค.
4. ๋ฌธ์ํ
๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ํ๋ก์ ํธ๋ฅผ ์ฝ๊ฒ ์ดํดํ๊ณ ๊ธฐ์ฌํ ์ ์๋๋ก ์ฝ๋์ ๊ฐ๋ฐ ํ๋ก์ธ์ค๋ฅผ ๋ฌธ์ํํ์ธ์. JSDoc ๋๋ Sphinx์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋์์ ๋ฌธ์๋ฅผ ์์ฑํฉ๋๋ค.
5. ์ง์์ ์ธ ํ์ต
์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ๋ ๋์์์ด ์งํํ๋ฏ๋ก ์ต์ ํธ๋ ๋์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ต์ ์ํ๋ก ์ ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ธ๋ก๊ทธ๋ฅผ ์ฝ๊ณ , ์ปจํผ๋ฐ์ค์ ์ฐธ์ํ๊ณ , ์๋ก์ด ๋๊ตฌ์ ๊ธฐ์ ์ ์คํํด ๋ณด์ธ์.
๊ธ๋ก๋ฒ ํ์ ์ํ ๊ณ ๋ ค์ฌํญ
๊ธ๋ก๋ฒ ํ๊ณผ ํจ๊ป ์ผํ ๋๋ ๋ช ๊ฐ์ง ์ถ๊ฐ์ ์ธ ๊ณ ๋ ค์ฌํญ์ ์ผ๋์ ๋์ด์ผ ํฉ๋๋ค:
- ์ปค๋ฎค๋์ผ์ด์ : ๋ช ํํ ์ปค๋ฎค๋์ผ์ด์ ์ฑ๋๊ณผ ๊ฐ์ด๋๋ผ์ธ์ ์๋ฆฝํ์ธ์. Slack, Microsoft Teams ๋๋ ์ด๋ฉ์ผ๊ณผ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ํจ๊ณผ์ ์ผ๋ก ์ํตํฉ๋๋ค. ์๊ฐ๋ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํ๊ณ ๊ทธ์ ๋ฐ๋ผ ํ์ ์ผ์ ์ ์ก์ผ์ธ์.
- ํ์ : Git, GitHub ๋๋ GitLab๊ณผ ๊ฐ์ ํ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๊ด๋ฆฌํ๊ณ ํ์ ์ ์ด์งํ์ธ์. ๋ชจ๋ ์ฌ๋์ด ํ์ํ ๋๊ตฌ์ ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ๋ฌธํ์ ์ฐจ์ด: ๋ฌธํ์ ์ฐจ์ด๋ฅผ ์ธ์ํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ปค๋ฎค๋์ผ์ด์ ์คํ์ผ์ ์กฐ์ ํ์ธ์. ๋ค๋ฅธ ๋ฌธํ์ ๋ํด ๊ฐ์ ํ๋ ๊ฒ์ ํผํฉ๋๋ค.
- ์ธ์ด ์ฅ๋ฒฝ: ํ์ํ ๊ฒฝ์ฐ ์ธ์ด ์ง์์ ์ ๊ณตํ์ธ์. ๋ฒ์ญ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ปค๋ฎค๋์ผ์ด์ ์ ์ฉ์ดํ๊ฒ ํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
- ์ ๊ทผ์ฑ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฅ์ ๋ฅผ ๊ฐ์ง ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ์ง ํ์ธํ์ธ์. WCAG์ ๊ฐ์ ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ฆ ๋๋ค.
๋ค์ํ ํ๋ก์ ํธ ์ ํ๋ณ ํด์ฒด์ธ ๊ตฌ์ฑ ์์
1. ๊ฐ๋จํ ์ ์ ์น์ฌ์ดํธ
- ํจํค์ง ๋งค๋์ : npm ๋๋ Yarn
- ๋ฒ๋ค๋ฌ: Parcel (๊ฐ๋จํ๊ณ ๊ตฌ์ฑ์ด ํ์ ์์)
- ๋ฆฐํฐ/ํฌ๋งทํฐ: ESLint ๋ฐ Prettier
2. React ์ ํ๋ฆฌ์ผ์ด์
- ํจํค์ง ๋งค๋์ : npm ๋๋ Yarn
- ๋ฒ๋ค๋ฌ: webpack ๋๋ Parcel
- ํธ๋์คํ์ผ๋ฌ: Babel (`@babel/preset-react` ์ฌ์ฉ)
- ๋ฆฐํฐ/ํฌ๋งทํฐ: ESLint ๋ฐ Prettier
- ํ ์คํ : Jest ๋๋ Mocha (Enzyme ์ฌ์ฉ)
3. Node.js ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์
- ํจํค์ง ๋งค๋์ : npm ๋๋ Yarn
- ๋ฒ๋ค๋ฌ: Rollup (๋ผ์ด๋ธ๋ฌ๋ฆฌ์ฉ) ๋๋ webpack (์ ํ๋ฆฌ์ผ์ด์ ์ฉ)
- ํธ๋์คํ์ผ๋ฌ: Babel
- ๋ฆฐํฐ/ํฌ๋งทํฐ: ESLint ๋ฐ Prettier
- ํ ์คํ : Jest ๋๋ Mocha (Supertest ์ฌ์ฉ)
๊ฒฐ๋ก
์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธํ๋ผ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋ณต์กํ์ง๋ง ๋ณด๋ ์๋ ๊ณผ์ ์ ๋๋ค. ์ฌ๋ฐ๋ฅธ ๋๊ตฌ๋ฅผ ์ ์คํ๊ฒ ์ ํํ๊ณ ํจ๊ณผ์ ์ผ๋ก ๊ตฌ์ฑํจ์ผ๋ก์จ ๊ฐ๋ฐ์ ์์ฐ์ฑ, ์ฝ๋ ํ์ง, ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ํ๋ก์ ํธ์ ํ์ ํน์ ์๊ตฌ์ ๋ง๊ฒ ํด์ฒด์ธ์ ์กฐ์ ํ๊ณ , ์ํฌํ๋ก์ฐ๋ฅผ ์ง์์ ์ผ๋ก ํ๊ฐํ๊ณ ๊ฐ์ ํ๋ ๊ฒ์ ์์ง ๋ง์ธ์.
์ด ๊ฐ์ด๋๋ ๊ฒฌ๊ณ ํ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ์ธํ๋ผ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ฒฌ๊ณ ํ ๊ธฐ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ค์ํ ๋๊ตฌ์ ๊ธฐ์ ์ ์คํํ์ฌ ์์ ๊ณผ ํ์ ๊ฐ์ฅ ์ ํฉํ ๊ฒ์ ์ฐพ์๋ณด์ธ์. ํ์ด์ ๋น๋๋ค!