React.Js 框架比較:NextJs vs Remix

前言

NextJs 已經是 React.Js 生態裡相當知名的框架,提到 SSR 幾乎都會直接想到他
Remix名氣就沒這麼大了,為何突然在2022年逐漸進入大家的眼裡呢?

因為他開源了!
而 Remix 主打盡可能的使用 Browser API 以達到高效、輕量的框架
以下簡單做個對比,對於新專案框架選型時,可以有個簡單的快速參考

主要差異

Remix比較大的特點是

  1. 盡可能的使用原生 API,不允許 JavaScript 時,網站仍可運作。允許執行 JavaScript 時,則會有更佳的使用體驗
  2. 提交表單時,若有JavaScript,則會使用 XHR;若無,則使用原生的方式 submit(即發出 HTTP POST 請求)
  3. Remix 目前沒有提供靜態頁面產生(SSG, Static Site Generator)

ROUTE

兩個都是file-base routing system,也就是只要將js或ts檔放在指定目錄下,就會自動產出對應路由
主要在動態路由的檔案命名不同

Next.Js

pages/index.js ==> /  <-- 主頁面
pages/users/index.js ==> /users <-- USER頁面  
pages/users/[userid].js ==> /users/:userid <-- 動態路由,由網址取得參數
pages/

Remix

routes/index.js ==> /  <-- 主頁面
routes/users/index.js ==> /users <-- USER頁面  
routes/users/$userid.js ==> /users/:userid <-- 動態路由,由網址取得參數

比較特別的是,在深層路由時,Remix可以在檔名使用.來分離
而nextjs則是透過深層目錄來產生相應路由

routes/blog.news.js ==> /blog/news

SSR資料載入

Next.Js

你可以自行控制資料載入的時機點,如下

  • 執行期(runtime) Server-side + Client-side: getInitialProps (deprecated,會使next優化效果不彰)
  • 編譯期(build time)且僅Server-side: getStaticProps
  • 執行期(runtime)且僅Server-side: getServerSidePropsReact Server Components
  • 僅Client-side

範例

import fs from 'fs';
import path from 'path'

export async function getServerSideProps(context) {
    // 此處的程式碼僅會在Server side執行,故可以使用Node.Js原生語法如fs
    // 而next打包時會自動判斷不將其打包至前端
    const DUMMY =await fs.readFile(path.join(process.cwd(), 'TEST_DATA', 'DUMMY_DATA.json'))
  return {
    props: { data: DUMMY }, // 回傳時一律為內含props的object,此參數會被傳入React.Js裡
  }
}

export default function Home(props) {  
    const { data } = props;
    return (  
        <div>{data}</div>  
    );  
}

Remix

Remix僅提供以下2種

  • 執行期(runtime) Server-side
  • 執行期(runtime) client-side
    import { useLoaderData } from 'remix';
      
    export let loader = async ({ params, request }) => {  
        // 由網址取得id,
        const id = params.id;
        // 由網址的 query string取得資料
        const url = new URL(request.url);
        const name = url.searchParams.get('name');  
        return { id, name };
    };  
      
    export default function Home() {  
        const { id, name } = useLoaderData();  
        return (  
            <div>  
                <h1>網址參數: {id}</h1>  
                <h1>query string欄位: {name}</h1>  
            </div>  
        );  
    }

Sessions和cookies

Next.Js

框架本身沒提供相關函式,但可以使用套件,如NextAuth.js來輔助

Remix

框架本身即提供相關函式可以使用

import { createCookie } from 'remix';

const cookie = createCookie('cookie-name', {
  expires: new Date(Date.now() + 60),
  httpOnly: true,
  maxAge: 60,
  path: '/',
  secrets: ['mysecret'],
  secure: true
});

後記

想追求效能極緻,可以試試新開源的Remix,畢竟是2021年尾才開源
目前 production 應用的網站算少
使用上遇到問題時可能會查不太到解法或著須至官方提 issue 詢問

不想要太過冒險,則推薦繼續使用已經成熟穩健的的 Next.Js
可以產生靜態頁面真的是最大優勢!

對於個人 Side Project,靜態頁面可以佈署在 netlify 或 GitHub page
上線後的營運成本絕對是最低的0元!

但仍可以關注 Remix 資訊,也許未來提供了靜態頁面產生
想必對於 Next.Js 目前已穩固的地位來說,將是一大挑戰!

參考資料

Next.js vs. Remix: Analyzing Key Aspects and Differences
Remix vs. Next.js: A Detailed Comparison