Remix 시작기 (NextJS와 비교하며)

Jiwoo JEONG·2023년 2월 19일
1

Remix+supabase

목록 보기
1/2
post-thumbnail

들어가며

  • Remix에 대한 소개글은 너무 많기에, 실제 사용하면서 느낀 점을 작성하였습니다.
  • 기존에 사용하던 NextJS와 비교가 다수 있습니다.
  • Remix 공식 홈페이지

왜 Remix인가?

개발을 혼자서 할 사이드 프로젝트를 진행함에 있어서 두 가지 선택지가 있었다.

  1. 기존에 사용하던 NextJS를 사용할까?
  2. 새로운 React 프레임워크인 Remix를 사용할까?

Remix를 선택하였다.

  1. Remix는 DB에 직접 접근하여 Server side에서 데이터를 가져올 수 있다.
  2. 기존에는 NextJS를 사용하였으나 SSR을 제대로 활용하지 못하는 것 같다는 고민이 있었다.
  3. 하던 것만 하기 보다는 새로운 것을 사용하여 개발하고 싶었다.

시작

눈에 띈 것

디렉터리 구조

  • 프로젝트를 init한 Remix 프로젝트는 디렉터리 구조가 다음과 같았다.
Remix

app
 ⌙root.tsx
 ⌙entry.client.tsx
 ⌙entry.server.tsx
 ⌙routes
     ⌙index.tsx 
     
NextJS
src
 ⌙pages
    ⌙index.tsx
    ⌙_app.tsx
    ⌙_document.tsx
  • 개인적으로 느낀 점은 NextJS의 _app.tsx + _document.tsx와 Remix의 root.tsx와 비슷하다는 것이다. 이유는 root.tsx에서 <meta/>, <link/>, <script /> 관련 코드를 입력하기 때문이다. 또한, 아래와 같이 root.tsx에 작성하면 Remix에서 제공하는 <Meta />, <Links />, <Scripts>를 통해 html에 입력된다.
export const links: LinksFunction = () => {
  return [{ rel: "stylesheet", href: globalStylesheetUrl }];
};

export const meta: MetaFunction = () => ({
  charset: "utf-8",
  title: "My Amazing App",
  viewport: "width=device-width,initial-scale=1",
});
  • entry.client.tsx는 브라우저의 엔트리포인트를 제공하고 여기서 ReactDOM.hydrate()를 통해 이미 render 되어 있는 html에 대해 이벤트 리스너를 추가하여 서버사이드에서 받은 값만 넣어준다. (참고: ReactDOM.hydrate())
  • entry.server.tsx는 서버 사이드에서 렌더링할 때 HTTP의 응답을 생성할 때 사용한다.

[위 두 가지에 대한 이해는 부족합니다..]

  • routes 디렉터리는 NextJS의 pages와 같다고 느꼈고 동적 라우팅 역시 지원한다. 아래처럼 디렉터리 구조가 되어 있다면 생성된 route(page)는 다음과 같다.(도메인 네임은 임시로 temp.com)
app
 ⌙routes
     ⌙index.tsx 
     ⌙my-page
     	⌙index.tsx
        ⌙edit
        	⌙name.tsx
            ⌙nickname.tsx
  1. temp.com
  2. temp.com/my-page
  3. temp.com/my-page/edit/name
  4. temp.com/my-page/edit/nickname

.env를 통해 환경변수를 사용할 때, NODE_ENV의 위치

  • NextJS를 사용할 때, .env 파일을 통해 설정한 NODE 환경 변수를 next.config.js를 통해 클라이언트 사이드(브라우저)에서도 사용할 수 있었다. 하지만 아직 remix.config.js에서는 그런 configuration을 지원하지 않는 듯하다..(혹시라도 아신다면 알려주세요 !)
  • 브라우저에서 사용해야할 외부 패키지를 init하기 위해서는 환경변수에서 API_KEY를 가져와야했다. Remix 공식 홈페이지에서는 다음과 같이 소개한다. (Remix#browser-environment-variables)

파파고로 번역한 것을 조금 수정하였습니다.

브라우저 환경 변수

몇몇 사람들은 Remix가 환경 변수를 클라이언트 사이드(브라우저 번들)에 넣을 수 있는지 묻습니다. 이것은 빌드가 무거운 프레임워크에서 일반적인 전략입니다. 그러나 이 접근법은 몇 가지 이유로 문제가 될 수 있습니다:

  1. 이것은 실제 환경 변수가 아닙니다. 빌드하는 시점에 어떠한 서버에 배포하는지 당신은 알아야만 합니다.
  2. 다시 빌드하고 다시 배포하지 않으면 환경변수의 값을 변경할 수 없습니다.
  3. 공개적으로 접근 가능한 파일에 실수로 중요한 정보(암호)를 노출하기 쉽습니다.

대신, 모든 환경 변수(모든 서버 암호와 브라우저의 JavaScript에 필요한 정보)를 서버에 보관하고, window.ENV를 통해서만 브라우저 코드에 노출하는 것이 좋습니다. 항상 서버가 있고 브라우저 번들에 이 모든 정보가 필요하지 않으므로, 서버가 Remix가 제공하는 loader에서 클라이언트 사이드로 환경 변수를 제공할 수 있습니다.

export async function loader() {
  return json({
    ENV: {
      STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
    },
  });
}

export function Root() {
  const data = useLoaderData<typeof loader>();
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <script
          dangerouslySetInnerHTML={{
            __html: `window.ENV = ${JSON.stringify(
              data.ENV
            )}`,
          }}
        />
        <Scripts />
      </body>
    </html>
  );
}

개발 진행 중 ..

확실히 개발 진행 중에 느낀 점은 NextJS에 비해 서버 사이드와 클라이언트 사이드가 분리되어 있다는 것입니다. NextJS를 통해 서버 사이드와 클라이언트 사이드에 대해 조금 이해하셨다면 Remix도 충분히 재밌게 개발해 볼 수 있지 않을까라는 개인적인 의견입니다.

사이드프로젝트는 계속 될 것이라 앞으로도 느리지만 꾸준히 업로드하겠습니다 ! 🥰

profile
FE Developer as Efficiency Maker

0개의 댓글