2023年如何搭建新的 React 項目?
最近 React 發布了全新的文檔,文檔中已經不再將 create-react-app (CRA) 作為搭建 React 應用的推薦方式,而是推薦了很多其他方式,包括 Vite、Next.js、Remix、Gatsby 等,下面就分別看看這些方式都有哪些優缺點,2023年該如何做出選擇!
Vite
Vite 很顯然是 create-react-app (CRA) 的繼任者,因為它與 CRA 沒有太大的區別。與 create-react-app(使用 Webpack)相比,它要快得多,因為它在底層使用了esbuild。
和 create-react-app (CRA) 一樣,Vite 也更傾向于使用客戶端路由和渲染來創建單頁面應用(SPA)。然而,由于服務端渲染(SSR)越來越受到重視,因此在 Vite 中它作為一個可選功能提供。
如果已經在使用 create-react-app(CRA),那么遷移到 Vite 是非常簡單的。Vite 的 vite.config.js 文件以及特定功能的文件(例如 tsconfig)只需進行少量配置,就可以使用 TypeScript、ESLint 和 SSR 等可選功能了。
在 Vite 中允許開發者在沒有框架的情況下使用 React。開發者可以自由選擇用于路由、數據獲取、狀態管理和測試的 React 庫。與所有 React 框架相比,它不會強制要求在項目級別上使用任何特定的 React 功能、庫或配置。
Vite 鼓勵初學者在沒有框架的干擾下學習 React 及其基礎知識。當使用 Vite 時,一個初學者可以專注于學習 React 和它的核心特性,而不需要受到框架的限制。相比之下,在使用框架的環境中學習 React 時,React 幾乎處于被動狀態,必須要遵循框架的意圖來進行學習。
React + Vite 的優勢:
- 幾乎可以替代 create-react-app(CRA)
- 仍然支持 SPA/CSR,但 SSR 是可選的
- 沒有框架/公司的束縛
- 輕量級
- 不會對 React 的功能進行干擾。因此,可以將重心放在 React 本身,而不是框架上
- 對于了解 React 基本原理的開發者來說,學習曲線比較平緩
React + Vite 的缺點:
- Vite 更注重單頁應用(SPA)/客戶端渲染(CSR)的支持。
- 沒有框架的支持
- 無法使用 React 為集成框架提供的體系結構特性,例如 React 服務器組件(RSC)。
為什么 Vite 可能不會成為 React 文檔中的默認工具:
- 它使用 SPA/CSR 而不是 SSR。
- 技術鎖定使開發人員無法使用所有可用的 React 功能,比如 React 服務器組件(RSC)。
- 它不能貢獻于以下愿景:構建一個 React 框架、實現多樣化渲染技術、以及實現所有可用的 React 特性,例如 React 服務器組件(RSC)。
- 它不關注任何特定的框架(包括 React)。
- 對于 Vite 的創建者尤雨溪來說,React 并不是 Vite 的優先考慮。
Next.js
Next.js 作為框架是最成熟的,因此當 React 開發人員想要在框架環境中使用 React 時,這可能是最好的選擇。它包含許多內置的功能(例如基于文件的路由)。如果 Next.js不適合你,可以看看去年開源的 Remix 框架;它與 Next.js 的不同之處在于它專注于 Web 標準。
Next.js 更注重服務端渲染(SSR)作為渲染技術。然而,它也可以與靜態網站生成(SSG)和客戶端渲染(CSR)一起使用。此外還有一些更先進的渲染技術可用,如增量靜態再生(ISR)和 React 服務器組件(RSC)。另外,可以在 Next.js 應用中混合使用這些渲染技術。例如,一個營銷頁面可以使用 SSG,而注冊/登錄功能使用 SSR。
然而,使用這么多強大的功能需要付出代價:不同的渲染技術會增加工程開銷,框架不斷地開發新的渲染技術,因此最終會改變其優先順序,而且并不是所有開發者都能跟得上這個速度。盡管 Next.js 在過去沒有引入破壞性變化,做得非常好,但在推動 JavaScript/React 渲染到后端的前沿工作中,總會有新的標準/配置。
總之,雖然 React 本身(例如使用Vite)相對穩定,但在 Next.js 生態系統中肯定會看到變化,因為它是將 React 引入服務端領域的開路先鋒。
Next.js 的優點:
- 帶有內置庫的的框架
- SSR和許多其他渲染技術
- 提高性能
- 與CSR相比,具有改進的SEO
- Vercel 作為擁有大量資金的重要參與者
- 與 React 核心團隊密切合作
- 雇用了許多 React 核心團隊成員
- 在前沿領域工作
Next.js 的缺點:
- 與只使用 React + Vite 相比,會增加開銷/穩定性/可維護性
- 相對于React + Vite,學習曲線更陡峭
- 更多關注框架特定內容,而非 React 本身
- 框架綁定
為什么 Next.js 可能是 React 文檔中的默認選擇:
- 它是最成熟的框架,符合 React 的框架的目標
- SSR 是一等公民,符合 React 的 SSR 目標
- 使用了React的所有基本原語,例如React Server Components (RSC)
- 不優先考慮“老式”SPA/CSR
- 與 React 及其核心團隊密切關系,與React核心團隊合作實現Next中的新功能,并最終由Meta/Facebook 使用
Astro
Astro 允許開發人員創建以內容為中心的網站。由于其 island 架構和選擇性水合作用,它默認為每個網站提供了快速性能。因此 SEO 相關的網站可以從使用 Astro 中受益。
從實現的角度來看,Astro更傾向于多頁面應用(MPA)的概念,而不是單頁面應用(SPA)。Astro 是一個與框架(此處為 React)無關的解決方案。因此,可以使用 Astro 的內置組件語法或選擇的框架(例如 React)。該框架僅用于服務端渲染,不會暴露給客戶端。只有當決定為客戶端添加一個交互式 island 時,它才會將所有必需的 JavaScript 代碼發送到瀏覽器。
在以內容為中心的網站方面,Astro 被視為 Gatsby 的競爭對手。在過去的幾年里,Gatsby 在與 Next 的競爭中失敗了。在這場競爭中,可能過于關注與 Next 的功能平衡(例如 SSR),因此較少關注真正重要的開發者體驗和以內容為中心的網站的性能方面。這給了Astro一個機會成為可行的替代選擇。
總之,即使是 Next(具有SSR / SSG / ISR)或 Gatsby 也適用于面向內容的網站,Astro 作為競爭對手雖然相對較新,但似乎更適合具有面向內容的網站的更具體要求(性能,注重內容生產(例如MDX))。
相比之下,支持使用 Next 的唯一事實是:它混合了渲染技術,因此可以在同一個應用中實現性能優化的營銷頁面和隱藏在登錄后面的實際應用。但根據 Astro 的基準測試結果,它的性能仍然較低(不考慮 RSC,因為還不穩定),因此可以在現代 Monorepo 設置中混合使用 Next 和 Astro,以便同時擁有 Web 應用和網站。
React + Astro 的優點:
- 面向內容的網站
- 性能
- SEO
React + Astro 的缺點:
- 不適用于動態Web應用
為什么它可能不是 React 文檔中的默認設置:
- 不與框架綁定
- React不是Astro的重點
- 不與React的新功能對齊,例如 React Server Components
- 每次鏈接點擊都會重新加載整個頁面,因此,對于導航而言不是最佳的 UX。
其他
除了上述方式之外,還有一些其他創建 React 應用的方式:
- 使用 Parcel[1] 而不是 Vite
- 使用 Monorepo(例如Turborepo),可選擇使用Vite、Next和/或Astro
- 使用 create-t3-app[2] 來進行 tRPC 開發
- 使用 React Native[3]/Expo[4] 開發移動應用
- 使用 Tauri[5] / Electron[6] 開發桌面應用
使用 React 之外的其他庫來啟動 SSR 項目:
- SvelteKit
- SolidStart
- QwikCity
總結
- 從 React 初學者的角度,可以選擇使用 Vite + React,因為它盡可能地接近 React 的基本原理。如果只需要一個輕量級的單頁應用/客戶端渲染解決方案,也可以選擇 Vite + React。
- 如果正在尋找在 React 之上的框架,其包含了幾種渲染技術(和基礎設施),推薦使用 Next + React 作為最成熟的解決方案。
- 如果 Next.js 不符合需求,但仍在尋找一個內置了所有功能的服務端渲染的框架,可以看看 Remix + React。
- 如果想做一個面向內容的網站,請查看 Astro + React。
參考:https://www.robinwieruch.de/react-starter/。
相關鏈接
[1]Parcel: https://parceljs.org/?。
[2]create-t3-app: https://create.t3.gg/?。
[3]React Native: https://reactnative.dev/?。
[4]Expo: https://expo.dev/?。
[5]Tauri: https://tauri.app/?。
[6]Electron: https://www.electronjs.org/?。