繁體中文(香港)
  • nextjs
  • sdk
  • edge

我們在 Next.js SDK 中加入 Edge Runtime 的經驗

Logto 的 Next.js SDK 現在支援 Edge Runtime。本文章將分享我們的冒險旅程,看看我們面對的障礙、如何克服它們,以及在這過程中學到的酷炫知識。

Sijie
Sijie
Developer

介紹

Edge Runtime 已經成為技術界的一個熱門詞,驅動著如 AWS Lambda@EdgeCloudflare WorkersVercel Edge 等平台中的動態和低延遲功能。強調其重要性,Vercel 最近將 "experimental-edge" 改為 "edge",這表示對其受歡迎的 Next.js 框架提供了正式支援。

隨著我們的 Next.js SDK 獲得很大迴響,我們在 Logto 想:"為何不加入 Edge Runtime 支援?" 所以,我們捲起袖子,立刻開始行動。在這篇文章中,我們將分享我們的冒險旅程,看看我們面對的障礙、如何克服它們,以及在這過程中學到的酷炫知識。

過渡模組和依賴以支援 Edge Runtime

處理 Edge Runtime 帶來了一些獨特的挑戰,主要是因為它不支援 Node.js 常用的所有模組和依賴項。我們遇到了 crypto、lodash 和 iron-session 模組的問題,這需要一些創新的解決方案。

Crypto

在 Node.js 環境中,crypto 模組 作為 OpenSSL 加密功能的封裝。不幸的是,Edge Runtime 不支援它。但別擔心,大多數 Edge Runtimes 提供了對 Web Crypto API 的支援。儘管有些小差異,但它是 crypto 模組的堅實替代品。例如,要生成隨機字節數:

和雜湊:

Lodash

Lodash 是很多開發者喜愛的工具,但 Edge Runtime 不支持。我們的解決方案?用原生 JavaScript 方法替換掉 Lodash 函數,保持程式碼高效和可讀。

雖然 替換大多數 Lodash 函數 並不困難,但需要一些技巧。讓我們來看看我們如何以自己的方式重建了 "once" 的實用性:

Iron Session

最新版本的 iron-session 模組是 Edge Runtime 友好的,所以我們所做的就是更新版本。就這麼簡單!

遊走於 Edge Runtime 的 "Response" 細節

另一個挑戰是我們在為 Edge Runtime 調整 SDK 時需要處理 "Response" 物件的分別。以下是我們如何克服這些分別:

手動創建回應

與 Node.js 不同,在 Edge Runtime 中一個請求並沒有附帶回應。我們必須透過調用 new Response() 來創建它,以下是一個返回數據的例子:

放棄 "withIronSessionApiRoute"

在 Edge Runtime 中,Response.body 是只讀的。這意味着我們無法在數據準備之前初始化響應。因此,我們的可靠工具 "withIronSessionApiRoute"(以及其他中介軟件)不得不被擱置。

要理解我們更換了什麼,首先讓我們解開 withIronSessionApiRoute 的實際作用:

  1. 它查看 cookie,構建出一個會話物件,再將其與 res 綁定。
  2. 如果會話有變化,它會自動將 "set-cookie" 標頭附加到 res

那麼,我們如何在新的 Edge Runtime 環境中模擬這一功能?

  1. 讀取:我們利用現有的 getIronSession 功能。通過給它一個空的和假的 response,按需要檢索會話。這替換了 req.session 中的 "get" 方法。
  2. 寫入:我們事先準備了一個包含數據的 response,然後在此 response 實例上使用 getIronSession 來獲取會話物件。一旦掌握了這個物件,我們便可以按需修改會話。

重定向

在 Edge Runtime 中進行重定向時,我們需要手動將 Location 標頭添加到回應中。

一個包,兩個運行時

在我們的旅程中,我們決定使用一個包來支持 Edge 和 Node.js 運行時。

原因如下

我們曾考慮為 Edge 創建一個單獨的包,但很快意識到這是不必要的。我們的大部分代碼在兩個運行時之間是共享的,只有少數代碼需要調整。此外,SDK 在兩個運行時中的使用大致相同,因此維持一個統一的包最為合理。

我們的做法

我們沒有重複工作的過程,而是決定擴展現有的包。我們在包的根目錄內加入了一個 "edge" 文件夾,使其緊挨著舊的 "src" 文件夾。然後,我們更新了 package.json 文件,加入了一個新路徑到 "exports" 中。這樣,Edge 和 Node.js 運行時就可以和諧地生活在同一個包中,幾乎不必費心。

結論

你可以在這裡查看我們 Next.js SDK edge 部分的完整源代碼。

通過分享我們擁抱 Edge Runtime 的旅程,我們希望能啟發和指導其他人探索類似的道路。敬請期待我們的 Next.js SDK 的更多更新。