ํ๋ ์ ํ ์ด์ ํธ์ง๊ธฐ์ ๋ณต์กํ UI ์ํ(์ฌ๋ผ์ด๋ ๋ชฉ๋ก, ์คํฌ๋ฆฝํธ ํธ์ง, ๋๊ธ, ๋ฆฌ์ก์ ๋ฑ)๋ฅผ ์ปดํฌ๋ํธ ๋จ์๋ก ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๊ธฐ์ ์ ํฉํฉ๋๋ค. React 19์ ๊ฐ์ ๋ ๋ ๋๋ง ์ฑ๋ฅ๊ณผ ํ๋ถํ ์ํ๊ณ(React Router, TanStack Query, Zustand ๋ฑ)๋ฅผ ํ์ฉํด ๋น ๋ฅธ ๊ฐ๋ฐ ์๋๋ฅผ ํ๋ณดํ์ต๋๋ค. Vue๋ Svelte ๋๋น ์ปค๋ฎค๋ํฐ ๊ท๋ชจ์ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํธํ์ฑ์ด ์๋์ ์ด์ด์, ์์ ํผ๋๋ฐฑยท์ฐจํธยท๊ณต์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ๋ฐํด๋ฅผ ์ฌ๋ฐ๋ช ํ ํ์๊ฐ ์์ต๋๋ค.
ํ๋ก์ ํธ ์ ์ฒด์ strict ๋ชจ๋๋ฅผ ์ ์ฉํ์ฌ ๋ฐํ์ ์๋ฌ๋ฅผ ์ปดํ์ผ ํ์์ ์ฐจ๋จํฉ๋๋ค. ์ฌ๋ผ์ด๋ยท๋๊ธยท๋ฆฌ์ก์ ๋ฑ ๋๋ฉ์ธ ํ์ ์ด ๋ณต์กํ๊ฒ ์ฝํ ์๋ ๊ตฌ์กฐ์์, ํ์ ์์คํ ์ด API ์๋ต๋ถํฐ ์ปดํฌ๋ํธ props๊น์ง ๋ฐ์ดํฐ ํ๋ฆ์ ์ ํฉ์ฑ์ ๋ณด์ฅํฉ๋๋ค. JavaScript ๋๋น ๋ฆฌํฉํ ๋ง ์์ ์ฑ์ด ๋์ ํ ํ์ ์ ์ค์๋ฅผ ์ค์ฌ์ค๋๋ค.
๊ธฐ์กด Webpack/CRA ๋๋น ESM ๊ธฐ๋ฐ ์ฆ์ ์๋ฒ ์์๊ณผ HMR(Hot Module Replacement) ์๋๊ฐ ์๋ฑํ ๋น ๋ฆ
๋๋ค. ์ฌ๋ผ์ด๋ ํธ์ง์ฒ๋ผ ์ฝ๋ ์์ โ ํ๋ฉด ํ์ธ ์ฌ์ดํด์ด ์ฆ์ ๊ฐ๋ฐ ํ๊ฒฝ์์ ์์ฐ์ฑ์ ํฌ๊ฒ ๋์ฌ์ค๋๋ค. SWC ํ๋ฌ๊ทธ์ธ(@vitejs/plugin-react-swc)์ ํจ๊ป ์ฌ์ฉํ์ฌ Babel ๋๋น ๋น๋ ์๋๋ฅผ ์ถ๊ฐ๋ก ๋จ์ถํ์ต๋๋ค.
์ ํธ๋ฆฌํฐ ํผ์คํธ ๋ฐฉ์์ผ๋ก ๋ณ๋ CSS ํ์ผ ์์ด ์ปดํฌ๋ํธ ๋ด์์ ์คํ์ผ์ ์ง์ ์ ์ธํฉ๋๋ค. ๋์์ธ ํ ํฐ(--color-main, --color-gray-*)๊ณผ ๊ฒฐํฉํด ๋คํฌ ๋ชจ๋ยทํ
๋ง ์ ํ์ CSS ๋ณ์ ๊ต์ฒด๋ง์ผ๋ก ๊ตฌํํ ์ ์์์ต๋๋ค. v4์ Rust ๊ธฐ๋ฐ ์์ง์ผ๋ก ๋น๋ ์ CSS ์์ฑ ์๋๊ฐ ๋ํญ ๊ฐ์ ๋์๊ณ , Vite ํ๋ฌ๊ทธ์ธ(@tailwindcss/vite)์ผ๋ก ์ค์ ๋ ๊ฐ์ํ๋ฉ๋๋ค.
Redux ๋๋น ๋ณด์ผ๋ฌํ๋ ์ดํธ๊ฐ ๊ทน๋๋ก ์ ์ผ๋ฉด์๋ DevTools, persist, immer ๋ฑ ๋ฏธ๋ค์จ์ด๋ฅผ ์ง์ํฉ๋๋ค. ํ๋ก์ ํธ์ 6๊ฐ ๋๋ฉ์ธ ์คํ ์ด(authStore, slideStore, themeStore ๋ฑ)๋ฅผ ๊ฐ๊ฐ ๋
๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ๋ฉด์๋, ์
๋ ํฐ ํ
ํจํด(useSlideTitle(), useSlideScript())์ผ๋ก ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ต์ํํฉ๋๋ค. getState()/setState()๋ก React ์ธ๋ถ์์๋ ์ ๊ทผ ๊ฐ๋ฅํ์ฌ Axios ์ธํฐ์
ํฐ ๋ด ์ธ์ฆ ํ ํฐ ์ฃผ์
๊ฐ์ ํจํด์ ์์ฐ์ค๋ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
์๋ฒ ์ํ์ ํด๋ผ์ด์ธํธ ์ํ๋ฅผ ๋ช
ํํ ๋ถ๋ฆฌํฉ๋๋ค. TanStack Query๊ฐ ์บ์ฑยท๋ฆฌํ์นญยท๋๊ด์ ์
๋ฐ์ดํธยท์๋ฌ ์ฌ์๋๋ฅผ ์ ์ธ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , Axios๋ ์ธํฐ์
ํฐ ๊ธฐ๋ฐ ํ ํฐ ์๋ ์ฃผ์
๊ณผ ์ค์ํ๋ ์๋ฌ ํธ๋ค๋ง์ ๋ด๋นํฉ๋๋ค. ๊ณ์ธต์ ์ฟผ๋ฆฌ ํค ํฉํ ๋ฆฌ(queryKeys.slides.list(projectId))๋ก ์ธ๋ฐํ ์บ์ ๋ฌดํจํ๊ฐ ๊ฐ๋ฅํด, ์ฌ๋ผ์ด๋ ์์ ์ ๊ด๋ จ ๋ชฉ๋ก๋ง ์ ํํ ๊ฐฑ์ ํฉ๋๋ค. fetch API ๋๋น ์์ฒญ ์ทจ์, ์งํ๋ฅ ์ถ์ , ์ธํฐ์
ํฐ ๋ฑ์ ๊ธฐ๋ฅ์ ๋ณ๋ ๊ตฌํ ์์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ์ผ ๊ธฐ๋ฐ์ด ์๋ ์ค์ ๊ธฐ๋ฐ ๋ผ์ฐํ
์ผ๋ก ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์ ์ฐํ๊ฒ ๊ฐ์ ธ๊ฐ๋๋ค. ์ค์ฒฉ ๋ผ์ฐํธ์ useParams()๋ฅผ ํ์ฉํด /:projectId/slide/:slideId ๊ฐ์ ๊ณ์ธต์ URL ๊ตฌ์กฐ๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ๋งคํํ๊ณ , ๋ผ์ฐํธ๋ณ ํ
๋ง ์ค๋ฒ๋ผ์ด๋(ํผ๋๋ฐฑ ํ์ด์ง ๋คํฌ ๋ชจ๋)๋ props ์ ๋ฌ๋ง์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
Vite์ ์ค์ ์ ๊ณต์ ํ์ฌ ๋ณ๋์ ํ
์คํธ ๋น๋ ํ์ดํ๋ผ์ธ ์์ด ๋์ผํ ๊ฒฝ๋ก ๋ณ์นญ(@/*)๊ณผ ํ๊ฒฝ์ ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค. Jest ํธํ API๋ก ํ์ต ๋น์ฉ์ด ๋ฎ์ผ๋ฉด์๋ ESM ๋ค์ดํฐ๋ธ ์ง์๊ณผ ๋ณ๋ ฌ ์คํ์ผ๋ก ํ
์คํธ ์๋๊ฐ ๋น ๋ฆ
๋๋ค. React Testing Library๋ ๊ตฌํ ์ธ๋ถ์ฌํญ์ด ์๋ ์ฌ์ฉ์ ๊ด์ ์ ํ๋ ๊ธฐ๋ฐ ํ
์คํธ๋ฅผ ๊ฐ์ ํ์ฌ, ๋ฆฌํฉํ ๋ง์๋ ๊นจ์ง์ง ์๋ ์์ ์ ์ธ ํ
์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. happy-dom์ ํ๊ฒฝ์ผ๋ก ์ ํํ์ฌ jsdom ๋๋น ์คํ ์๋๋ฅผ ์ถ๊ฐ๋ก ๊ฐ์ ํ์ต๋๋ค.
Service Worker๋ฅผ ํ์ฉํด ๋คํธ์ํฌ ๋ ๋ฒจ์์ API๋ฅผ ๊ฐ๋ก์ฑ๊ธฐ ๋๋ฌธ์, ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ๋ชฉ ๋ฐ์ดํฐ๋ก ๊ฐ๋ฐํ ์ ์์ต๋๋ค. ๋ฐฑ์๋ API๊ฐ ์ค๋น๋์ง ์์ ์ํ์์๋ npm run dev:local๋ก ์ ์ฒด ๊ธฐ๋ฅ์ ๊ฐ๋ฐยทํ
์คํธํ ์ ์์ด ํ๋ก ํธ์๋์ ๋ฐฑ์๋์ ๊ฐ๋ฐ ์ผ์ ์ ๋ถ๋ฆฌํฉ๋๋ค. ๋ชฉ ํธ๋ค๋ฌ๋ฅผ ๊ทธ๋๋ก ํ
์คํธ์์ ์ฌ์ฌ์ฉํ ์ ์์ด ์ผ๊ด์ฑ๋ ์ ์ง๋ฉ๋๋ค.
ESLint๊ฐ ์ฝ๋ ํ์ง(๋ฏธ์ฌ์ฉ ๋ณ์, ํ
๊ท์น ์๋ฐ ๋ฑ)์, Prettier๊ฐ ์ฝ๋ ํฌ๋งท(๋ค์ฌ์ฐ๊ธฐ, ๋ฐ์ดํ ๋ฑ)์ ๊ฐ๊ฐ ๋ด๋นํ์ฌ ์ญํ ์ด ๊ฒน์น์ง ์์ต๋๋ค. eslint-plugin-check-file๋ก ํ์ผยทํด๋ ๋ค์ด๋ฐ ์ปจ๋ฒค์
(kebab-case ํด๋, PascalCase ์ปดํฌ๋ํธ)์ ์๋ ๊ฐ์ ํ๊ณ , Husky + lint-staged๋ก ์ปค๋ฐ ์์ ์ ์๋ ๊ฒ์ฌํ์ฌ ์ปจ๋ฒค์
์ ์๋ฐํ๋ ์ฝ๋๊ฐ ์ ์ฅ์์ ์ ์
๋๋ ๊ฒ์ ์์ฒ ์ฐจ๋จํฉ๋๋ค.