
๐ฅ Remix vs Next.js โ RemixJS๋ฅผ ์ ํํด์ผ ํ๋ ์ด์ ?
Remix์ Next.js๋ ๋ชจ๋ ์ต์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋๋ก ์ค๊ณ๋ ๊ฐ๋ ฅํ ํ ์คํ React ํ๋ ์์ํฌ์ ๋๋ค. Next.js๊ฐ Vercel์ ์ง์์ ๋ฐ๋ ์ค๋๋ ํ๋ ์ด์ด์ธ ๋ฐ๋ฉด, RemixJS๋ ์ฑ๋ฅ, ๋จ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ชจ๋ธ๋ก ๋น ๋ฅด๊ฒ ์ฃผ๋ชฉ๋ฐ๊ณ ์๋ ์๋ก์ด ์น ํ์ค ์ค์ฌ ํ๋ ์์ํฌ์ ๋๋ค.
์ด ๊ธฐ์ฌ์์๋ Remix๊ฐ Next.js์ ์ฐจ๋ณํ๋๋ ์ ๊ณผ Remix๊ฐ ์๋, ์ ์ง ๋ณด์์ฑ ๋ฐ ์น ๊ธฐ๋ฐ ์ ๋ ฌ์ ์ถ๊ตฌํ๋ค๋ฉด ๋ค์ ํ๋ก์ ํธ์ ๋ ์ ํฉํ ์ด์ ๋ฅผ ์ดํด๋ณผ ๊ฒ์ ๋๋ค.
๐ RemixJS ํ๋์ ๋ณด๊ธฐ
- ํ ์คํ React ํ๋ ์์ํฌ
- ์น ๊ธฐ๋ณธ (HTTP ์บ์ฑ, ๋ค์ดํฐ๋ธ ํผ ๋ฑ)์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋จ
- ์ ์ง์ ํฅ์์ ํฌ์ฉํจ
- ์ต์ํ์ JavaScript ์ข ์์ฑ์ ํตํด ๋น ๋ฅธ ์ฑ๋ฅ์ ์ค์
- ๋ชจ๋ ๋ฐฐํฌ ๋์ (Node, Cloudflare, Deno ๋ฑ)์์ ์๋
๐ Next.js์ ๋นํด Remix์ ์ฃผ์ ์ฅ์
์ค์ ๊ฐ๋ฐ์์ ๊ด์ฌ์ฌ์ ์ํคํ ์ฒ์ ์ฐจ์ด์ ์ ๊ธฐ๋ฐ์ผ๋ก ๋ ๊ฐ์ง๋ฅผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค.
1. ๐ง ๋ฐ์ดํฐ ๋ก๋ฉ ๋ชจ๋ธ
โ Remix: ์๋ฒ ์ฐ์ , ๊ณต๋ ๋ฐฐ์น ๋ก๋ Remix์ ๊ฐ ๋ผ์ฐํธ๋ ๋ ๋๋ง ์ ์ ์๋ฒ์์ ์คํ๋๋ `loader()` ํจ์๋ฅผ ์ ์ํฉ๋๋ค. ํ์ํ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณ๋ ฌ๋ก ๊ฐ์ ธ์ ์๋ต์ ์ผ๋ถ๋ก ๋ณด๋ ๋๋ค.
// app/routes/posts.tsx
export const loader = async () => {
const posts = await getPosts();
return json(posts);
};๐ซ Next.js: getServerSideProps ๋๋ getStaticProps Next.js๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ํน๋ณํ ํจ์๋ก ๋ถ๋ฆฌํ์ง๋ง, ํ์ด์ง ์์ค์์๋ง ๊ฐ๋ฅํ์ฌ ์ค์ฒฉ๋ ์ปดํฌ๋ํธ์ ์ฌ์ฌ์ฉ์ฑ ๋ฐ ๊ตฌ์ฑ ๊ฐ๋ฅ์ฑ์ ์ ํํฉ๋๋ค.
// pages/posts.js
export async function getServerSideProps() {
const posts = await getPosts();
return { props: { posts } };
}๐ ํ๊ฒฐ: Remix๋ ์ค์ฒฉ๋ ๋ผ์ฐํธ์๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ฐ๊ฒฐํ์ฌ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋จ์ํํฉ๋๋ค. ์ด๋ ๋ ๋์ ์ฑ๋ฅ๊ณผ ๊ตฌ์กฐ๋ก ์ด์ด์ง๋๋ค.
2. ๐งญ ์ค์ฒฉ ๋ผ์ฐํ ๋ฐ ๋ ์ด์์
โ Remix: ๋ค์ดํฐ๋ธ ์ค์ฒฉ ๋ผ์ฐํธ Remix ๋ผ์ฐํธ๋ ๊ณต๋ ๋ฐฐ์น๋๊ณ ๋ณธ์ง์ ์ผ๋ก ์ค์ฒฉ๋ฉ๋๋ค. ๋ ์ด์์๊ณผ ๋ผ์ฐํธ๋ ํด๋์ฒ๋ผ ๊ตฌ์กฐํ๋๋ฉฐ, ๋ ์ด์์ ์์ค ๋ก๋๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
routes/
โโโ dashboard.tsx --> /dashboard
โโโ dashboard/
โโโ settings.tsx --> /dashboard/settings๐ซ Next.js: ์ฑ ๋ผ์ฐํฐ ๋ฐ ํ์ผ ๊ท์น Next.js๋ ์ต๊ทผ ๋ ์ด์์์ ์ง์ํ๋ ์ฑ ๋๋ ํ ๋ฆฌ ๊ธฐ๋ฐ ๋ผ์ฐํ ์ ๋์ ํ์ง๋ง, ์ด๋ ๋ ์๋กญ๊ณ ๋ณต์กํ๋ฉฐ, ๋ ์ด์์์ ์๋ฒ ์ธก ๋ฐ์ดํฐ์ ๊น์ด ํตํฉ๋์ง ์์ต๋๋ค.
๐ ํ๊ฒฐ: Remix์ ์ค์ฒฉ ๋ผ์ฐํธ๋ ์ดํดํ๊ธฐ ์ฝ๊ณ , ๋ ์ ์ฐํ๋ฉฐ, ๋ณต์กํ UI ๊ณ์ธต ๊ตฌ์กฐ์์ ๋ ์ ํ์ฅ๋ฉ๋๋ค.
3. โก ์ฑ๋ฅ: ํด๋ผ์ด์ธํธ ์ธก JavaScript ๊ฐ์
โ Remix: ์ต์ JS ์ข ์์ฑ Remix๋ ํ์ํ ๋งํผ๋ง JS๋ฅผ ๋ก๋ํฉ๋๋ค. ํด๋ผ์ด์ธํธ ์ธก ๋ก์ง์ ์ค์ด๊ธฐ ์ํด ๋ค์ดํฐ๋ธ ํผ ์ ์ถ ๋ฐ ์บ์ฑ๊ณผ ๊ฐ์ ํ์ค ๋ธ๋ผ์ฐ์ ๋์์ ์์กดํฉ๋๋ค.
๐ซ Next.js: ํด๋ผ์ด์ธํธ ์ค์ฌ์ ์ํธ ์์ฉ์ฑ Next.js๋ Hydration ๋ฐ ํด๋ผ์ด์ธํธ ์ธก API์ ๋ ๋ง์ด ์์กดํ๋ฉฐ, ์ด๋ ์ข ์ข ๋ ๋ฌด๊ฑฐ์ด ๋ฒ๋ค๋ก ์ด์ด์ง๋๋ค.
๐ ํ๊ฒฐ: Remix ์ฑ์ ๋ธ๋ผ์ฐ์ ์ ์๋ฒ์ ๋ ๋ง์ ์์ ์ ์คํ๋ก๋ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋น ๋ฆ ๋๋ค.
4. ๐ค ํผ ๋ฐ ์ก์
โ Remix: ์ ์ง์ , ์๋ฒ ๊ธฐ๋ฐ ํผ Remix์ ํผ์ ๋ค์ดํฐ๋ธ `<form>` ํ๊ทธ๋ฅผ ์๋ฒ ์ธก `action()` ํจ์์ ํจ๊ป ์ฌ์ฉํ์ฌ ์ ์ถ์ ์ฒ๋ฆฌํฉ๋๋ค. JavaScript๊ฐ ํ์ํ์ง ์์ต๋๋ค.
export const action = async ({ request }) => {
const formData = await request.formData();
await savePost(formData);
return redirect("/success");
};๐ซ Next.js: JavaScript + API ๋ผ์ฐํธ ํ์ Next.js ํผ์ ์ผ๋ฐ์ ์ผ๋ก `fetch` ๋๋ ํด๋ผ์ด์ธํธ ์ธก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฒ๋ฆฌ๋ฉ๋๋ค. Remix์ ๊ฐ์ ๋ด์ฅ ํผ ์ฒ๋ฆฌ๋ ์์ต๋๋ค.
๐ ํ๊ฒฐ: Remix๋ ์ ํต์ ์ธ ์๋ฒ ๋ ๋๋ง ์ฑ์ ๋จ์์ฑ์ ๋์ด๋ ค ์ ์ ํด๋ผ์ด์ธํธ ์ฝ๋๋ก ๋น ๋ฅด๊ณ ์ ์ง์ ์ธ ํผ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
5. ๐ ์บ์ฑ ๋ฐ ์น ๊ธฐ๋ณธ
โ Remix: HTTP ์บ์ฑ ๊ธฐ๋ฐ ๋ก๋ ์์ค์์ ์บ์ฑ์ ์ ์ดํ ์ ์์ด ๋ธ๋ผ์ฐ์ ๋๋ CDN์ด ์ ์ฅํ๋ ๋ด์ฉ์ ์ง๋ฅ์ ์ผ๋ก ์ ์ดํ ์ ์์ต๋๋ค.
export const loader: LoaderFunction = async ({ request }) => {
return new Response(JSON.stringify(data), {
headers: { "Cache-Control": "max-age=3600" },
});
};๐ซ Next.js: ๋๋ถ๋ถ Vercel ํน์ ์ต์ ํ๋ก ์ฒ๋ฆฌ๋จ ํค๋๋ฅผ ์ ์ดํ ์ ์์ง๋ง, Vercel์์ ํธ์คํ ๋์ง ์๋ ๊ฒฝ์ฐ ๋ ์ถ์์ ์ด๊ณ ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋๋ค.
๐ ํ๊ฒฐ: Remix๋ HTTP ์๋ต ๋ฐ ์บ์์ ๋ํ ์ง์ ์ ์ธ ์ ์ด๋ฅผ ์ ๊ณตํ์ฌ ๋ค์ดํฐ๋ธ ์น ์์น์ ํฌ์ฉํฉ๋๋ค.
6. ๐ ๏ธ ๋ฐฐํฌ ์ ์ฐ์ฑ
- Remix๋ Node.js, Deno, Cloudflare Workers, Vercel, Netlify, Fly.io์์ ์คํ๋๋ฉฐ, ๋ ๋ฆฝํ Express ์ฑ์ผ๋ก๋ ์คํ๋ฉ๋๋ค.
- Next.js๋ Vercel(์คํฐ์)์์ ๊ฐ์ฅ ์ ์๋ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ๋ฐฐํฌ๋ ๊ฐ๋ฅํ์ง๋ง ๋ ์ํํฉ๋๋ค.
๐ ํ๊ฒฐ: ๊ณต๊ธ์ ์ฒด ์ข ์์ ํผํด์ผ ํ๋ค๋ฉด Remix๊ฐ ๋ ์ ์ฐํฉ๋๋ค.
7. ๐ง ๊ฐ๋ฐ์ ๊ฒฝํ
๋ค์์ Remix์ Next.js ๊ฐ์ ๋น ๋ฅธ ๊ธฐ๋ฅ ๋น๊ต์ ๋๋ค.
- ๋ผ์ฐํ โ Remix: ์ค์ฒฉ, ๋ ์ด์์ ์ฐ์ | Next.js: ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ฉด (ํ์ด์ง), ์ฑ ๋๋ ํ ๋ฆฌ๋ ์๋ก์ด ๊ธฐ๋ฅ
- ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ โ Remix: ๋ผ์ฐํธ ๊ธฐ๋ฐ ๋ก๋ | Next.js: getServerSideProps, API ๋ผ์ฐํธ
- ํผ โ Remix: ์ก์ ๊ณผ ํจ๊ป ๋ค์ดํฐ๋ธ | Next.js: ์ฌ์ฉ์ ์ง์ JS + API ์๋ํฌ์ธํธ
- ์บ์ฑ โ Remix: ์ ์ฒด HTTP ์ ์ด | Next.js: Vercel์์ ์ฒ๋ฆฌ ๋๋ ์ฌ์ฉ์ ์ง์
- ํด๋ผ์ด์ธํธ JS โ Remix: ๋ ์๊ณ ์ต์ | Next.js: ๋ ํฌ๊ณ Hydration ์ค์ฌ
- ๋ฐฐํฌ โ Remix: ๋ชจ๋ ๊ณณ (Cloudflare, Denoโฆ) | Next.js: Vercel์์ ๊ฐ์ฅ ์ข์
๐งฉ Next.js ๋์ Remix๋ฅผ ์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ?
- โ ์ ์ง์ ํฅ์ ๋ฐ ๋น ๋ฅธ ์ฑ๋ฅ์ ์ํ ๋
- โ ๋ผ์ฐํ ๋ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๋ํ ๊น์ ์ ์ด๋ฅผ ์ค์ํ๊ฒ ์๊ฐํ ๋
- โ ์ต์ํ์ JS ๋ฐ ๋ ๋์ SEO๋ฅผ ์ ํธํ ๋
- โ JS๊ฐ ๋นํ์ฑํ๋ ๊ฒฝ์ฐ์๋ ์๋ํ๋ ์ฑ์ ๊ตฌ์ถํ๊ณ ์ถ์ ๋
- โ Vercel ์ธ์ ์ ์ฐํ ๋ฐฐํฌ ์ต์ ์ด ํ์ํ ๋
๐ ๋ง์ง๋ง ์๊ฐ
Remix์ Next.js๋ ๋ชจ๋ ํ๋ฅญํ ๋๊ตฌ์ ๋๋ค. ๊ทธ๋ฌ๋ Remix๋ ๊ณ ์ ์ ์ธ ์๋ฒ ๋ ๋๋ง ์ฑ์ ๋จ์์ฑ๊ณผ ์ฑ๋ฅ์ ๋์ด๋ฆฌ๋ฉด์๋ ์ต์ React ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์ฌ์ฉ์ ์ ์ ์ถ์ํ๋ณด๋ค ์น ํ์ค์ ์ ํธํ์ฌ ์ฑ์ ๋น ๋ฅด๊ณ ํ๋ ฅ์ ์ด๋ฉฐ ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
Next.js์์ Remix๋ก ์ฑ์ ๋ง์ด๊ทธ๋ ์ด์ ํ๊ฑฐ๋ ์๋ก์ด Remix ์ฑ์ ์ฒ์๋ถํฐ ๊ตฌ์ถํ๋ ๋ฐ ๋์์ด ํ์ํ์ญ๋๊น? ์๋ ค์ฃผ์ธ์! ๐