๋ฆฌ์กํธ๋ก ํ๋ก ํธ์๋ ๊ฐ๋ฐ ์ ์ ์ฉํ ์ปดํฌ๋ํธ ๊ด๋ฆฌ ๋๊ตฌ, ์คํ ๋ฆฌ๋ถ์ ๋์ ํด๋ณด๊ธฐ
(CRA + ESLint + TypeScript + Storybook + chromatic)
์์ ํ๋ก์ ํธ์์ ๋์์ธ์ด ์์๋ก ๋ณ๊ฒฝ๋์๋๋ฐ, ๋์์ธ ๋ฒ์ ๊ด๋ฆฌ ์ฒด๊ณ๋ ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์์์ ์ด๋ ๊ฒ์ด ์ต์ ๋ฒ์ ์ธ์ง, ์ ํจํ ๋์์ธ์ธ์ง ํ์ธํ๊ธฐ ์ด๋ ค์ ๋ค. Theme์ด ์ธ ๊ฐ์ง๋ ๋ค๋ฅธ ๋์์ธ์ ๋ํด ๊ฐ๊ฐ ์ปดํฌ๋ํธ์ ํ์ด์ง๋ฅผ ๋ค๋ฃจ๊ธฐ๊ฐ ๋๋ฌด ๋๊ฐํ๋ค. ์์ฑํ๊ณ ์๋ ์ปดํฌ๋ํธ๋ ์ฌ์ฌ์ฉ์ ์ํ๋ค๊ณ ๊ฐ๋ฉด, ๋๋ฌด ๋ง์ prop์ด ๊ฑธ๋ ค์ ๋ฒ๋ฒํ ํ ์คํธ ์ฝ๋๋ ์๋ ์์ค์ ๋๋ฒ๊น ํ๊ธฐ๊ฐ ํ๋ค์๋ค.
๊ทธ๋์ ์ด๋ฒ ํ๋ก์ ํธ์์๋ ๋์์ด๋์ ํ์ ํจ์จ๋ ๋์ด๊ณ , ์๊ฐ์ ์ผ๋ก ์ปดํฌ๋ํธ๋ค์ ๋ฐ๋ก ๋ณผ ์ ์์ผ๋ฉฐ, ๊ฐ๋ณ์ ์ผ๋ก ๊ฐ๋ฐํด์ bottom-up ๋ฐฉ์์ผ๋ก ์ฝ๋์ ์์ ์ฑ์ ์ฃผ๊ณ ์ถ์๋ค. ๋ง์นจ, ๋ค๋ฅธ ๊ฐ๋ฐ์๋ CI ๋ฅผ ์ํ ๊ฐ์ด๋๋ผ์ธ์ ์์ฑ ์ค์ด๊ณ , ๋๋ ๊ทธ๋์ ์น ํ๋ก์ ํธ๋ฅผ ์ํ ํ๋ก ํธ์๋ ๊ธฐ๋ณธ ํ๋ก์ ํธ ์ค์ ์ ํ ํ๋ฆฟํํด์ ์ฌ์ฉํ ์ ์์ผ๋ฉด ์ด๋จ๊น ํ๊ณ ์ด๋ฐ ์ ๋ฐ ํ ์คํธ๋ฅผ ์๋ํ๋ค. Storybook์ ์์์ ์ธ๊ธํ ๋ฌธ์ ์ ๋ค์ ์ด๋ ์ ๋๋ ๋ณด์ถฉํด์ค ์ ์์ ๊ฒ ๊ฐ์๋ค. ์ด๋ฒ template ํ๋ก์ ํธ์์๋ CRA๋ฅผ ํตํด ๊ธฐ๋ณธ ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์ฌ๋ ๊ฒ๋ถํฐ ์์ํด์, ๋ค๋ฅธ ํ๋ก๊ทธ๋๋จธ์ ํ์ ์์ ๊ฐ์ ์ฝ๋ ํฌ๋งท์ ์ ์งํ ์ ์๊ฒ ๋์์ฃผ๋ ESLint/Prettier ์ค์ ์ ํ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ํ๋ก์ ํธ์ ์ค์ ์ TypeScript๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ๋ค.
์ฌ๊ธฐ๊น์ง ํ์ ์ ์ํ ์ค๋น๊ฐ ๋๋ค๋ฉด, Storybook ํ๊ฒฝ์ ์์ํ ๊ฒ์ธ๋ฐ, ๋จ๊ณ๊ฐ ์กฐ๊ธ ๋ง์ผ๋ ์๋ฆฌ์ฆ๋ก ์์ฑํ ์์ ์ด๋ค. ๋์ค์๋ chromatic์ผ๋ก ์ ์ ์คํ ๋ฆฌ๋ถ์ ๋ฐฐํฌํ๋ ๊ฒ๊น์ง ํด๋ณด๋ ค๊ณ ํ๋ค.
Create React App
Creact React App์ ํตํด bare project๋ฅผ ๋ง๋ค์ด์ค ๊ฒ์ธ๋ฐ, ์ฌ๊ธฐ์ typescript ํ๋๊ทธ๋ฅผ ๋ฃ์ด์ ์ธ์คํจํ๋ค.
์ฐ์ ๋ ํ์งํ ๋ฆฌ๋ฅผ ํ๋ ์์ฑํ๋ค.
๊ทธ๋ฆฌ๊ณ ํฐ๋ฏธ๋์ ๊ฐ์, ์์ฑํ๊ณ ์ ํ๋ ํ๋ก์ ํธ์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์ค ๋ค์, ์๋ ๋ช ๋ น์ด๋ฅผ ์คํํ๋ค.
# ์) npx create-react-app react-typescript-storybook-template --template=typescript
npx create-react-app <ํ๋ก์ ํธ์ด๋ฆ> --template=typescript
ํ์ํ ๋ํ๋์๋ค์ ๋ค ๋ฐ๊ณ ๋๋ฉด, ์๋์ฒ๋ผ ํฐ๋ฏธ๋ ํ๋ฉด์ด ๋ฐ๋๋ค.
ํด๋น ํ๋ก์ ํธ๋ก ์ง์ ํ๊ณ , ์ฝ๋ ์๋ํฐ๋ฅผ ์ด์ด์ค๋ค.
์ฌ์ค ์๋๋ ํ์ ์คํฌ๋ฆฝํธ ํ๋๊ทธ๋ฅผ ๋ฃ์ง ์๊ณ ์ธ์คํจํ์ ๋์ ํด๋ ๊ตฌ์กฐ์ด๋ค.
๐ฆsrc
โฃ ๐App.css
โฃ ๐App.js
โฃ ๐App.test.js
โฃ ๐index.css
โฃ ๐index.js
โฃ ๐logo.svg
โฃ ๐reportWebVitals.js
โ ๐setupTests.js
์ ํด๋ ํธ๋ฆฌ ๊ตฌ์กฐ์์ ์๋๋ง ๋จ๊ธฐ๊ณ , ์๋ ์ฝ๋์ฒ๋ผ js->ts๋ก ๋ฐ๊ฟ์ฃผ๊ณ JSX ๋ฌธ๋ฒ์ด ์๋ ํ์ผ์ ๊ฒฝ์ฐ tsx๋ก ํ์ฅ์ ๋ช ์ ๋ณ๊ฒฝํด์ค๋ค. ํ์ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ์ผ๋ก ํ ๊ฒฝ์ฐ ์๋ตํด๋ ๋๋ ๊ณผ์ ์ด๋ค.
๐ฆsrc
โฃ ๐App.test.js
โฃ ๐App.tsx
โฃ ๐index.tsx
โฃ ๐reportWebVitals.ts
โ ๐setupTests.ts
๊ทธ๋ฆฌ๊ณ ํ์ํ ๋ํ๋์๋ฅผ ์๋์ ๊ฐ์ด ๋ฐ์์ค๋ค.
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
# or
yarn add typescript @types/node @types/react @types/react-dom @types/jest
์์ธํ ๋ด์ฉ์ ์ด๊ณณ์์ ๋ ํ์ธํ ์ ์๋ค. ๊ธฐ์กด CRA ํ๋ก์ ํธ์ ํ์ ์คํฌ๋ฆฝํธ ์ถ๊ฐํ๊ธฐ
Git initialization
๋ค์ ๊นํ์ผ๋ก ๋์๊ฐ์, ์ด์ ์๊ฒฉ ์ ์ฅ์๋ฅผ ์ฐ๊ฒฐํด์ค๋ค.
echo "# react-typescript-storybook-template" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin [https://github.com/hannah26hannah/react-typescript-storybook-template.git](https://github.com/hannah26hannah/react-typescript-storybook-template.git)
git push -u origin main
TypeScript configuration
๊ทธ๋๋ก ๋ณต์ฌํด์ ์คํํด์ฃผ๊ณ , ๋๋จธ์ง ๋ณ๊ฒฝ๋ ์์ค ์ฝ๋๋ค๋ ์ถ๊ฐํด์ ์ปค๋ฐํด์ค๋ค.
tsconfig.json
ํ์ผ์ด ์์ผ๋ ํ๋ก์ ํธ ๋ฃจํธ์ echo "" > tsconfig.json
์ผ๋ก ํ์ผ์ ์์ฑํด์ค ๋ค์ ์๋ ์ฝ๋๋ฅผ ๋ณต์ฌํด ๋ถ์ฌ๋ฃ๋๋ค.
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"noImplicitAny": true, // added
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"outDir": "./dist", // added
"typeRoots": ["./node_modules/@types", "types"] // added
},
"include": ["src"]
}
Next : ์ด์ ์ฝ๋ ํฌ๋งทํ ์ ์ํด์ ESLint์ Prettier๋ฅผ ์ธ์คํจํ ๊ฒ์ด๋ค. Git์ ํตํด ์์ค๋ฅผ ์ฌ๋ฆด ๋ ์๋์ผ๋ก ESLint์ Prettier๋ฅผ ์คํํ๊ฒ ๋์์ฃผ๋ husky์ lint-staged๋ ๊ฐ์ด ์ธ์คํจํ๊ณ ์ค์ ํด๋ณด๋ ค๊ณ ํ๋ค.
์ฌ๊ธฐ๊น์ง ์ ์ฒด ์์ค ์ฝ๋๊ฐ ๊ถ๊ธํ๋ค๋ฉด, ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.