簡介
在 2017 年 9 月,Cloudflare 推出 Cloudflare Workers,讓使用者能夠在其 Edge 網路 上運行 JavaScript。這表示您的程式碼將在大約 30 秒內部署到遍布全球一百多個地點的整個 Edge 網路。這項技術讓您可以專注於編寫靠近使用者的應用程式,無論他們身在世界何處(~50 毫秒延遲)。
Worker 的運行環境與 Node.js 或瀏覽器不同,它使用 Google Chrome 開發的 JavaScript 引擎 V8 執行程式碼。到目前為止,您可以在其平台上運行的程式碼是在擊中您的伺服器之前在 Edge 上運行的小腳本,以提高效能或根據請求標頭新增一些邏輯,例如。
在 2020 年 11 月,在開發 Nuxt 3 時,我們決定嘗試在 Edge 運行環境 / V8 隔離區中正式運行 Nuxt。
這解鎖了從世界各地約 50 毫秒內伺服器端渲染頁面的能力,當使用像 Cloudflare Workers 這樣的平台時,無需處理伺服器、負載平衡器和快取,費用約為 每百萬次請求 0.3 美元。截至今日,新的平台紛紛出現,讓應用程式可以在 V8 隔離區上運行,例如 Deno Deploy。
挑戰
為了讓 Nuxt 能夠在 workers 中運行,我們必須重寫 Nuxt 的某些部分,使其環境不可知(在 Node.js、瀏覽器或 V8 中運行)。
我們從伺服器開始,並創建了 unjs/h3:一個為高效能和可移植性而建構的最小 http 框架。它取代了我們在 Nuxt 2 中使用的 Connect,但與其相容,因此您可以繼續使用 Connect/Express 中介軟體。在 workers 中,對於每個傳入的請求,它都會在生產環境中啟動 Nuxt,將請求發送給它,然後發送回響應。
在 Nuxt 2 中,在記憶體中啟動正式環境伺服器的時間(也稱為冷啟動)約為 300 毫秒,因為我們必須載入伺服器和應用程式的所有依賴項才能處理請求。
透過開發 h3,我們決定程式碼分割附加到伺服器的每個處理程序,並僅在請求時才延遲載入它們。當您啟動 Nuxt 3 時,我們只在記憶體中載入 h3 和相應的處理程序。當請求進入時,我們載入對應於路由的處理程序並執行它。
透過採用這種方法,我們將冷啟動時間從 ~300 毫秒縮短到 ~2 毫秒。
為了在 Edge 上運行 Nuxt,我們還有另一個挑戰:正式環境套件大小。這包括伺服器、Vue 應用程式和 Node.js 依賴項的組合。Cloudflare workers 目前對 worker 大小有限制,免費方案為 1MB,付費方案(每月 5 美元)為 5MB。
為了實現這一點,我們創建了 unjs/nitro,我們的伺服器引擎,當運行 nuxt build
命令時,它會將您的整個專案捆綁在一起,並將所有依賴項包含到最終輸出中。它使用 Rollup 和 vercel/nft 來追蹤 node_modules
使用的程式碼,以移除不必要的程式碼。基本 Nuxt 3 應用程式產生的總輸出大小約為 700kB gzip。
最後,為了在開發 (Node.js) 和 Cloudflare (Edge 運行環境) 的正式環境之間提供相同的開發者體驗,我們創建了 unjs/unenv:一個透過模擬或新增已知依賴項的 Polyfill,將 JavaScript 程式碼轉換為可在任何地方(平台不可知)運行的函式庫。
在 Nuxt,我們相信您應該有自由選擇最適合您的託管服務供應商。
這就是為什麼您可以在以下平台上部署具有 Edge 伺服器端渲染的 Nuxt 應用程式
- NuxtHub
- Cloudflare Page
- Deno Deploy
- Vercel Edge Functions(底層使用 Cloudflare Workers)
- Netlify Edge Functions(底層使用 Deno)
我們也支援許多其他部署服務供應商,包括 靜態託管 或 傳統 Node.js 無伺服器和伺服器主機。
推進全端功能
現在 Nuxt 可以在 Edge 運行環境上運行,我們可以做的不僅僅是渲染 Vue 應用程式。感謝 server 目錄,建立 API 路由只需一個 TypeScript 檔案。
要新增 `/api/hello` 路由,請建立 `server/api/hello.ts` 檔案
export default defineEventHandler((event) => {
return {
hello: 'world'
}
})
您現在可以在頁面和元件中通用地呼叫此 API
<script setup>
const { data } = await useFetch('/api/hello')
</script>
<template>
<pre>{{ data }}</pre>
</template>
當我們建立 useFetch 和 $fetch 時,需要注意的重要一點是,在伺服器端渲染期間,如果您呼叫 API 路由,它將模擬請求並直接呼叫函式程式碼:避免 HTTP 請求並減少頁面渲染時間。
就開發者體驗而言,您會注意到在建立伺服器檔案時,Nuxt 伺服器會持續運行,而無需重建 Vue 應用程式。這是因為 Nuxt 3 在建立 API 和伺服器路由時支援熱模組替換 (HMR)。
此外,透過利用物件關係對應 (ORM)(如 drizzle-orm),開發人員可以連接 Edge 和無伺服器資料庫,例如 D1、Turso、Neon、Planetscale 等。
我創建了 Atidone,一個開源演示,展示了一個在 Edge 上運行的具有身份驗證和資料庫的全端應用程式。原始碼可在 GitHub 上以 MIT 許可證在 atinux/atidone 取得。
結論
我們對 Edge 伺服器端渲染及其解鎖的功能感到興奮。Nuxt 團隊迫不及待想看看您將在此基礎上建構什麼!
歡迎加入我們的 Discord 伺服器 或在 Twitter 上提及 @nuxt_js 來分享您的作品。