今天給大家帶來的主題是全??蚣?Remix,同時介紹了Remix v1.16的諸多新特性,話不多說,直接進入正題。
前言
如今,當想要基于 React 創建一個新的 Web 項目時,有許多不同的框架可以選擇。 作為一名前端開發人員,您會發現自己很難知道應該選擇哪一個框架,或者哪一個框架最適合你的開發需求。
最常用的框架之一是 Next.js?.NETflix、Twitch 或 Uber 等公司都已經在生產項目中使用它, Next.js 被認為是增長最快的 React 框架之一。其他框架很難與 Next.js 媲美,因為它涵蓋了三種不同的頁面渲染策略,但自 2021 年 11 月以來,前端又多了一個全新的、強大的備選框架,稱為 Remix。
隨著 Remix v1.16 版本的發布,Remix 也成為越來越多 React 開發者的不二選擇。
為何需要 Remix 而不是純 React
React 可以制作單頁應用程序 (SPA),其僅使用一個 html 文件來渲染所有網頁,路由由客戶端控制。
當客戶端發出初始請求時,瀏覽器會立即收到一個包含所有應用程序的 HTML 頁面,沒有預渲染內容。當用戶在應用導航時,JAVAScript 僅替換那些與請求路由相關的組件和內容,但 HTML 文件內容保持不變。 簡而言之,瀏覽器負責管理應加載哪個 JavaScript 文件以渲染當前頁面,這就是客戶端渲染 ,即 CSR。
客戶端渲染,圖片來自https://www.heavy.ai/
但是,CSR 也存在諸多限制:
- Slow Initial Render:當用戶第一次訪問頁面時,需要很長時間才能加載完成。 這意味著較長的空白頁面,直到 JavaScript 加載并渲染所有內容。
- seo:因為初始時只有一個 HTML 頁面,所以很難讓搜索引擎對內容進行索引。
- 緩存問題:HTML 結構無法緩存,因為它在第一次渲染時不可用。
由于 CSR 的三大核心問題,Next.js 和 Remix 出現了, Remix 可以在發送客戶端請求之前在服務器端渲染內容,從而最大限度的縮短頁面白屏時間。
什么是 Remix
Remix 是一個完整的堆棧 Web 框架,讓開發者專注于用戶界面并通過 Web 基礎知識進行工作,以提供快速、流暢和有彈性的用戶體驗,該體驗可以部署到任何 Node.js 服務器甚至非 Node.js 環境,比如: Cloudflare Workers 的邊緣平臺。
目前 Remix 在 Github 上有超過 23.4k 的 star、1.9k 的 fork、26.9k 的項目依賴量,代碼貢獻者 550+,是一個妥妥的前端開源明星項目。
Remix v1.16.0 新特性
Remix 團隊目前正在全力為即將發布的 v2 版本做準備,而 Remix v1.16.0 穩定了一些 css 功能,對新 Remix 開發服務器的內部結構進行了重大變更,并修復了一堆錯誤。
CSS Modules/Vanilla Extract/CSS Side-Effect Imports
Remix 版本 v1.16.0 穩定了對 CSS module、Vanilla Extract 和 CSS 副作用導入的內置支持,以前只能通過未來標志(
future.unstable_cssModules、future.unstable_vanillaExtract、future.unstable_cssSideEffectImports)獲得這些特性。
PostCSS 支持
Remix v1.16.0 版通過 remix.config.js 中的新 postcss 選項穩定了內置的 PostCSS 支持。 因此,future.unstable_postcss 選項在該版本中也已被棄用。 postcss 選項默認為 false,但是當設置為 true 時,如果存在 postcss.config.js,將啟用使用 PostCSS 處理所有 CSS 文件。
如果遵循 Remix 的原始 PostCSS 設置指南,開發者可能會有一個如下所示的文件夾結構,將源文件與其處理后的輸出分開:
.
├── App
│ └── styles (processed files)
│ ├── app.css
│ └── routes
│ └── index.css
└── styles (source files)
├── app.css
└── routes
└── index.css
啟用新的 postcss 選項后,開發者可以從 app/styles 文件夾中刪除已處理的文件,并將源文件從 styles 移動到 app/styles:
.
├── app
│ └── styles (source files)
│ ├── app.css
│ └── routes
│ └── index.css
然后開發者應該從 .gitignore 文件中刪除 app/styles, 因為它現在包含源文件而不是處理過的輸出。
然后開發者可以更新 package.json 腳本以刪除任何對 postcss 的使用,因為 Remix 會自動處理它。 例如,如果遵循了原始設置指南:
{
"scripts": {
- "dev:css": "postcss styles --base styles --dir app/styles -w",
- "build:css": "postcss styles --base styles --dir app/styles --env production",
- "dev": "concurrently "npm run dev:css" "remix dev""
+ "dev": "remix dev"
}
}
Tailwind
Remix v1.16 版通過 remix.config.js 中的新 tailwind 選項穩定了內置的 Tailwind 支持。 因此,future.unstable_tailwind 選項在該版本中也已被棄用。
默認情況下,tailwind 選項為 false,但設置為 true 時,如果安裝了 tailwindcss,將在 CSS 文件中啟用對 Tailwind 函數和指令的內置支持。
如果開發者遵循 Remix 的原始 Tailwind 設置指南并想要使用此功能,應該首先刪除生成的 app/tailwind.css。然后,如果有 styles/tailwind.css 文件,則應將其移至 app/tailwind.css。
rm app/tailwind.css
mv styles/tailwind.css app/tailwind.css
否則,如果還沒有 app/tailwind.css 文件,應該創建一個包含以下內容的文件:
@tailwind base;
@tailwind components;
@tailwind utilities;
然后,應該從 .gitignore 文件中刪除 /app/tailwind.css,因為它現在包含源代碼而不是處理后的輸出。接著需要更新 package.json 腳本以刪除任何對 tailwindcss 的使用,因為 Remix 會自動處理它。 例如,如果遵循了原始設置指南:
{
"scripts": {
- "build": "run-s "build:*"",
+ "build": "remix build",
- "build:css": "npm run generate:css -- --minify",
- "build:remix": "remix build",
- "dev": "run-p "dev:*"",
+ "dev": "remix dev",
- "dev:css": "npm run generate:css -- --watch",
- "dev:remix": "remix dev",
- "generate:css": "npx tailwindcss -o ./app/tailwind.css"
}
}
開發服務器變更
Remix v1.16.0 版包含對新開發服務器的重大改進,可以通過 remix.config.js 中的 future.unstable_dev 標志啟用。 Remix 開發服務器現在將應用程序服務器作為托管子進程啟動。 這使開發環境盡可能接近生產環境,也意味著 Remix 開發服務器與任何應用程序服務器兼容。
默認情況下,開發服務器將使用 Remix App Server,但開發者可以通過 -c/--command 標志指定運行它的命令來選擇使用自己的應用服務器:
remix dev
// uses `remix-serve <serve build path>` as the app server
remix dev -c "node ./server.js"
// uses your custom app server at `./server.js`
開發服務器將做以下幾個事情:
- 強制 NODE_ENV=development ,如果之前被設置為其他內容則拋出警告
- 每當 Remix 應用程序代碼更改時重新打包的應用程序
- 每當重新打包成功時重新啟動應用程序服務器
- 處理實時重新加載和 HMR + 熱數據重新驗證
應用服務器協調
為了管理應用服務器,開發服務器需要被告知應用服務器當前正在使用什么服務器版本。 這是通過讓應用服務器發送“I'm ready!”來實現的,以 Remix 服務器構建哈希作為有效負載的消息。
這是在 Remix App Server 中自動處理的,并通過調用官方 Remix 模板中的 broadcastDevReady 或 logDevReady 自動設置。如果沒有使用 Remix App Server,并且服務器沒有調用 broadcastDevReady,需要在應用服務器啟動并運行后調用它。
例如,在 Express 服務器中:
// server.js
// <other imports>
import { broadcastDevReady } from '@remix-run/node';
// Remix 服務器構建目錄的路徑(默認為“build/”)
const BUILD_DIR = path.join(process.cwd(), 'build');
// <設置快速服務器的代碼>
app.listen(3000, () => {
const build = require(BUILD_DIR);
console.log('Ready: http://localhost:' + port);
// 在開發中,在服務器啟動并運行后調用`broadcastDevReady`
if (process.env.NODE_ENV === 'development') {
broadcastDevReady(build);
}
});
Cloudflare
對于 CF 工作程序和頁面,需要使用 logDevReady 而不是 broadcastDevReady,因為實驗性 CF 運行時不能很好地與 fetch 配合使用,而 fetch 是 broadcastDevReady 的實現方式。
選項優先級順序為:1. flags,2. config,3. defaults。
--http-* 標志僅用于內部開發服務器與應用服務器雙向通信,應用程序將在應用程序服務器的正常 URL 上運行。
要設置 unstable_dev 配置,請將 unstable_dev: true 替換為 unstable_dev: { }。 例如,要靜態設置 HTTP(S) 端口:
// remix.config.js
module.exports = {
future: {
unstable_dev: {
httpPort: 8001,
},
},
};
如果開發者需要對開發服務器的 scheme、主機、端口進行細粒度控制,則只需要使用 --http-* 標志和 --websocket-port 標志。Remix 不會為開發者設置 SSL 和自定義主機。
--http-scheme 和 --http-host 標志用于告訴 Remix 開發者是如何設置的。 如果需要這些功能,則需要自行設置 SSL 證書和主機文件。
如果開發者想自己管理服務器更改,可以使用 --no-restart 標志告訴開發服務器在構建成功時不要重啟應用程序服務器:
remix dev -c "node ./server.js" --no-restart
開發者還可以清除應用服務器的 require 緩存以使其在獲取服務器更改時保持運行。 如果需要類似功能,則應該觀察服務器構建路徑(默認情況下為 build/)的更改,并且僅在檢測到更改時清除 require 緩存。
如果使用 --no-restart,開發者需要自行處理在應用服務器接收到服務器更改時調用 broadcastDevReady。比如下面的示例利用 chokidar 實現了這個功能:
// server.dev.js
const BUILD_PATH = path.resolve(__dirname, 'build');
const watcher = chokidar.watch(BUILD_PATH);
watcher.on('all', () => {
// 1. 清除require緩存
purgeRequireCache();
// 2. 加載更新的服務器構建
const build = require(BUILD_PATH);
// 3. 告訴開發服務器這個應用服務器現在準備好了
broadcastDevReady(build);
});
其他變更
- feat:在所有適配器中支持異步 getLoadContext (#6170)
- 在使用 CSS 模塊、 Vanilla Extract 和 CSS 副作用導入時修復 CSS url() 規則中的絕對路徑 (#5788)
- 展開加載器返回類型時更好的類型區分(#5516)
- 將 AppLoadContext 傳遞給 handleRequest (#5836)
- 添加 @remix-run/node/install 副作用以允許 node --require @remix-run/node/install (#6132)
- 由于錯誤而未渲染的路由短路鏈接和元數據 (#6107)
- React Router 的更新 Remix 不再依賴于 useSyncExternalStore (#6121)
- 如果路由僅導出邊界,則修復誤報資源路由標識 (#6125)
- 將 React Router 依賴項更新為最新版本:react-router-dom@6.11.0,@remix-run/router@1.6.0
參考資料
https://github.com/remix-run/remix/releases/tag/remix%401.16.0
https://www.oschina.net/news/241208/remix-1-16-released
https://github.com/remix-run/remix
https://dev.to/joshhortt/the-future-of-web-development-is-the-remix-framework-leading-the-way-4fpa
封面圖版權:Jose Horta Calvario的 《The Future of Web Development: Is the Remix Framework Leading the Way?》