作者 | Philippe Serhal & Elad Rosenheim
譯者 | 張衛(wèi)濱
策劃 | Tina
Netlify 部署了數(shù)十萬(wàn)個(gè) Next.js 網(wǎng)站,真正的挑戰(zhàn)也隨之而來(lái)。本文最初發(fā)表于 Netlify 的博客網(wǎng)站,由 InfoQ 中文站翻譯分享。
關(guān)于此刻的說(shuō)明
實(shí)際上,我們?cè)谶@篇文章上花費(fèi)了很多的時(shí)間,思考如何以最好的方式呈現(xiàn)下面的事實(shí)和建議,同時(shí)又能避免讓它顯得是一篇攻擊性文章。畢竟,我們與 Vercel 在平臺(tái)領(lǐng)域存在競(jìng)爭(zhēng)關(guān)系。
最近,圍繞 Next.js 中間件發(fā)生了一起安全事件,在社交網(wǎng)絡(luò)上引發(fā)了一場(chǎng)小型的風(fēng)波,并招致了對(duì)意外事件處理方式的批評(píng)。
這篇文章并不是關(guān)于這一安全事件的。相反,本文關(guān)注的是當(dāng)前更大的背景,也就是確保 Next.js 按預(yù)期方式為客戶(hù)運(yùn)行所面臨挑戰(zhàn)。其中許多挑戰(zhàn)(也可以說(shuō)是意外事件響應(yīng))都與 Next.js 維護(hù)方式的封閉性有關(guān)。但現(xiàn)在每個(gè)人都在真誠(chéng)努力地解決這個(gè)問(wèn)題。
在此,我們的目的是更好地了解所面臨的挑戰(zhàn),并為今后的協(xié)作規(guī)劃出一條道路。
重新介紹 Next.js
Next.js 是一個(gè)開(kāi)源的 Web 開(kāi)發(fā)框架,由提供 Next.js 托管服務(wù)的云提供商 Vercel 創(chuàng)建和管理。
該框架在 React 的基礎(chǔ)上進(jìn)行了創(chuàng)新,使其成為許多開(kāi)發(fā)人員的首選工具,開(kāi)發(fā)人員這樣做是有充分理由的,Next.js 引入了對(duì) SSR、SSG、ISR 和 API 路由等概念的內(nèi)置支持。
在 Netlify,我們很自豪能提供全面的 Next.js 支持,確保開(kāi)發(fā)人員在不犧牲功能的情況下選擇部署方案。然而,保持對(duì) Next.js 這種級(jí)別的支持是有代價(jià)的,并且會(huì)帶來(lái)獨(dú)特的工程挑戰(zhàn)。這些挑戰(zhàn)不僅局限于 Netlify,還包括 Cloudflare、AWS Amplify Hosting、SST、Google Firebase App Hosting 和 Microsoft Azure Static Web Apps 等同行。
現(xiàn)在,我們來(lái)看看 Netlify 的工程師為保持與 Vercel 平臺(tái)特性對(duì)等所做的幕后工作,以及我們?yōu)楦?Next.js 不斷變化的節(jié)奏所做的工作。
挑戰(zhàn) 1:沒(méi)有適配器支持
開(kāi)源軟件的一大優(yōu)勢(shì)在于其可移植性,開(kāi)發(fā)人員和組織應(yīng)該可以在不同的提供商之間自由轉(zhuǎn)移,而不必?fù)?dān)心被某個(gè)特定的供應(yīng)商鎖定。例如,npm CLI 既集成了 npm 公司的注冊(cè)表,也集成了所有第三方的注冊(cè)表,Docker 也集成了 DockerHub,這樣的例子不勝枚舉。
為了實(shí)現(xiàn)這一目標(biāo),大多數(shù)現(xiàn)代 web 開(kāi)發(fā)框架都使用了適配器、插件或預(yù)設(shè)(preset)的概念,以便根據(jù)特定的部署目標(biāo)調(diào)整框架的輸出。提供商需要采用這種方式來(lái)提供和配置基礎(chǔ)設(shè)施,以便于為應(yīng)用程序提供動(dòng)力。例如,Remix、Astro、SvelteKit、Gatsby 和 Qwik。
為可替換的構(gòu)建適配器提供一流支持的框架(Astro),每個(gè)適配器都面向特定的部署環(huán)境或提供商
有些框架甚至更進(jìn)一步,Nuxt、Analog、SolidStart 和 TanStack Start 都使用相同的底層機(jī)制(Nitro),因此可以共享部署目標(biāo)預(yù)設(shè)。這種通用基礎(chǔ)的預(yù)期工具和范圍是一個(gè)快速發(fā)展的話(huà)題,不同的意見(jiàn)在公開(kāi)場(chǎng)合爭(zhēng)論不休,這也是很正常的事情。
基于 Nitro 的框架對(duì)可交換的構(gòu)建適配器具有一流的支持,但更進(jìn)一步的是共享它們的適配器
這些模式允許前端開(kāi)發(fā)人員保持代碼核心不變,如果決定部署到另一個(gè)提供商,只需替換適配器即可。
這些適配器可以由框架作者、托管服務(wù)提供商、社區(qū)或上述各方共同維護(hù)。框架通常具有良好的結(jié)構(gòu),這樣任何人都能構(gòu)建自己的適配器,以防他們所選擇的提供商沒(méi)有對(duì)應(yīng)的適配器。之所以能做到這一點(diǎn),是因?yàn)樗鼈冇泄_(kāi)的適配器規(guī)范文檔。這也意味著意外情況會(huì)更少,因?yàn)檫m配器接口的更改會(huì)遵循語(yǔ)義化版本的約定。
在平臺(tái)供應(yīng)商方面,他們通常有自己的 API 文檔,說(shuō)明框架應(yīng)如何與平臺(tái)交互,任何框架都可以使用這些 API。在我們的場(chǎng)景中,這就是 Netlify Framework API。
以 Netlify 如何使用帶有 Netlify 構(gòu)建適配器的框架 (Astro) 來(lái)構(gòu)建站點(diǎn)為例
Next.js 所面臨的獨(dú)特挑戰(zhàn)在于,盡管 Vercel(平臺(tái))早在 2022 年就為框架提供了構(gòu)建輸出 API(Build Output API),但 Next.js 本身并不遵循該 API,也沒(méi)有適配器機(jī)制,任何其他角色都無(wú)法通過(guò)該機(jī)制支持其他平臺(tái)。相反,Next.js 構(gòu)建使用的是一種私有的、基本沒(méi)有文檔記錄的格式,這種格式可能會(huì)發(fā)生變化。
相反,Netlify、Cloudflare、AWS Amplify Hosting、SST、Google Firebase App Hosting 和 Microsoft Azure Static Web Apps 等提供商必須從磁盤(pán)讀取 Vercel 定制的、部分未文檔化的構(gòu)建輸出,將其轉(zhuǎn)換為自己的格式,然后再寫(xiě)回磁盤(pán)上 。
Next.js 構(gòu)建僅與 Vercel 兼容,因此其他平臺(tái)(如 Netlify)必須在事后將其轉(zhuǎn)換為自己的格式。
在 Netlify,我們會(huì)在 Next.js 構(gòu)建后自動(dòng)運(yùn)行一個(gè)構(gòu)建插件(OpenNext Netlify 適配器)。再加上全面的自動(dòng)化測(cè)試(包括框架自身的測(cè)試和我們自己的測(cè)試套件),最終在 Netlify 實(shí)現(xiàn)了強(qiáng)大的 Next.js 體驗(yàn)。對(duì)于絕大多數(shù)站點(diǎn)來(lái)說(shuō),都可以做到開(kāi)箱即用,無(wú)需任何配置。但是,如果 Next.js 能夠遵循既定的適配器模式,實(shí)現(xiàn)起來(lái)會(huì)更簡(jiǎn)單、更易于維護(hù),也更便于社區(qū)為其做出貢獻(xiàn)。這個(gè)問(wèn)題已經(jīng)斷斷續(xù)續(xù)討論了一段時(shí)間,但自從 OpenNext 小組的范圍擴(kuò)大,明確表達(dá)了多方的需求后,這個(gè)問(wèn)題才真正得到解決。現(xiàn)在,它 終于啟動(dòng)了!
挑戰(zhàn) 2:沒(méi)有針對(duì)無(wú)服務(wù)器部署的生產(chǎn)級(jí)文檔
Next.js 部署文檔列出了這些部署選項(xiàng):
你可以使用 Vercel 部署托管的 Next.js,也可以在 Node.js 服務(wù)器、Docker 鏡像甚至靜態(tài) HTML 文件上自行托管。
這里的“Node.js 服務(wù)器”指的就是一個(gè)簡(jiǎn)單的 Node.js 服務(wù)器。對(duì)于正式的項(xiàng)目來(lái)說(shuō),Node.js 服務(wù)器的單個(gè)唯一實(shí)例(無(wú)論是否使用 Docker)不具備橫向擴(kuò)展的能力和零停機(jī)部署的能力,這并不是一種可行的部署策略,而且完全靜態(tài)的網(wǎng)站目前只能覆蓋有限的 Next.js 使用場(chǎng)景。在默認(rèn)的情況下,這并不能支撐 Next.js 的大部分功能,比如,邊緣中間件、全局持久化頁(yè)面、獲取緩存以實(shí)現(xiàn)增量式靜態(tài)再生(Incremental Static Regeneration)和按需重新驗(yàn)證等,正是這些特性使得 Next.js 在大規(guī)模環(huán)境中變得非常強(qiáng)大。
自托管文檔 簡(jiǎn)要介紹了一些復(fù)雜問(wèn)題:
緩存和重新驗(yàn)證頁(yè)面(使用增量靜態(tài)再生(ISR)或 App Router 中較新的功能)使用相同的共享緩存。
[...]
默認(rèn)情況下,生成的緩存資產(chǎn)將存儲(chǔ)在內(nèi)存(默認(rèn)為 50MB)和磁盤(pán)中。如果使用 Kubernetes 等容器編排平臺(tái)托管 Next.js,每個(gè) pod 都將擁有一份緩存。由于默認(rèn)情況下 pod 之間不共享緩存,為防止顯示陳舊的數(shù)據(jù),可以配置 Next.js 緩存以提供緩存處理器并禁用內(nèi)存緩存。
陳舊數(shù)據(jù)的問(wèn)題比想象中更棘手。例如,由于每個(gè)節(jié)點(diǎn)都有自己的緩存,如果在服務(wù)器操作或路由處理器代碼中使用 revalidatePath,該代碼將僅在處理該操作 / 路由的某個(gè)節(jié)點(diǎn)上運(yùn)行,并且僅清除該節(jié)點(diǎn)的緩存。
文檔提供了如何通過(guò)自定義 CacheHandler 來(lái)實(shí)現(xiàn)這一功能的概述。自定義緩存處理器必須要關(guān)注多種類(lèi)型的緩存條目(比如,頁(yè)面、路由、抓取、圖像、重定向),并為每種緩存條目制定單獨(dú)的邏輯,將緩存鍵與后備存儲(chǔ)進(jìn)行規(guī)范化,處理按需觸發(fā)的重新驗(yàn)證,處理緩存標(biāo)簽,解析和處理各種未文檔化的構(gòu)建清單文件,處理大量極端情況等等。
由于 Next.js 是一個(gè)被廣泛采用的重要框架,我們致力于為其提供全面的支持,這意味著專(zhuān)門(mén)負(fù)責(zé)平臺(tái)框架支持的工程團(tuán)隊(duì)已經(jīng)積累了必要的知識(shí),并實(shí)現(xiàn)了自己的緩存處理器和相關(guān)的測(cè)試。如果即將推出的金絲雀版本有什么變化,我們會(huì)及時(shí)發(fā)現(xiàn)。
上述挑戰(zhàn)意味著,團(tuán)隊(duì)很容易就會(huì)把過(guò)多的時(shí)間花在 Next.js 上。幸運(yùn)的是,我們盡可能使用自己的 平臺(tái)原語(yǔ)(platform primitive),并在強(qiáng)大功能的基礎(chǔ)上進(jìn)行構(gòu)建(在必要時(shí)進(jìn)行迭代),而不是為每一個(gè)需求均量身定制特定框架的解決方案。
你應(yīng)該也能做到這一點(diǎn)
即便盡可能使用我們自己的現(xiàn)有功能,但 Netlify 的緩存處理器也需要約 500 行代碼和約 500 行測(cè)試,這并不是一件容易完成的任務(wù)。對(duì)于大多數(shù)考慮自托管的開(kāi)發(fā)人員來(lái)說(shuō),這種類(lèi)型的投資就超出他們的能力范圍了。
由于 Next.js 對(duì)這些運(yùn)行時(shí)細(xì)節(jié)進(jìn)行了抽象,因此急需擴(kuò)展適配器的概念,使其不僅能夠支持構(gòu)建時(shí)的問(wèn)題。例如,也許應(yīng)該重新設(shè)計(jì)平臺(tái)的 CacheHandler 接口,以便在平臺(tái)側(cè)要求最少的框架邏輯(隨時(shí)可能發(fā)生變化)。
目前,這些內(nèi)容超出了 OpenNext 小組和 Vercel 討論的構(gòu)建時(shí)適配器的范圍,但我們樂(lè)觀(guān)地認(rèn)為,在共享論壇上加強(qiáng)合作將為 Next.js 開(kāi)發(fā)人員帶來(lái)更好、更輕松、更簡(jiǎn)單、更加文檔化的部署方案。
挑戰(zhàn) 3:未文檔化的行為
Next.js 框架包含 大量未文檔化的選項(xiàng)、功能和行為。為使平臺(tái)與 Vercel 實(shí)現(xiàn)功能對(duì)等,平臺(tái)供應(yīng)商目前需要了解這些情況并將其考慮在內(nèi)。
例如,部署到 Vercel 的 Next.js 站點(diǎn)會(huì)使用自己獨(dú)特的 Next.js 代碼路徑,并通過(guò)未文檔化的 minimalMode 進(jìn)行選擇。這樣就禁用了該框架的許多核心功能,而這些功能可能會(huì)在 Vercel 平臺(tái)(自然是閉源的)中重新實(shí)現(xiàn)。雖然 Netlify 沒(méi)有這樣做,但一些供應(yīng)商甚至選擇利用這種未文檔化的模式,并在自己的平臺(tái)中反向?qū)崿F(xiàn)了同等的功能。
我們的方法:主動(dòng)的自動(dòng)化測(cè)試
我們的 Next.js 適配器包含數(shù)百個(gè)測(cè)試,這些測(cè)試能夠在 Linux、macOS 和 Windows 上針對(duì) Next.js 13、14、15 和最新的金絲雀版本運(yùn)行。其中大部分是集成測(cè)試,用于構(gòu)建和運(yùn)行 Next.js 站點(diǎn),還有很多是端到端測(cè)試,用于將測(cè)試站點(diǎn)部署到 Netlify。
當(dāng)然,這些只是入門(mén)級(jí)的測(cè)試。此外,對(duì)于所測(cè)試的每個(gè) Next.js 版本,我們還克隆了源 Next.js Git 倉(cāng)庫(kù),并運(yùn)行其 1700 多個(gè)端到端的集成測(cè)試,調(diào)整后部署到 Netlify。這些測(cè)試設(shè)計(jì)的范圍非常廣泛,而且通過(guò)在瀏覽器中像用戶(hù)一樣運(yùn)行 Playwright 測(cè)試,能夠?qū)φ麄€(gè)真實(shí)體驗(yàn)進(jìn)行測(cè)試,這讓我們對(duì)發(fā)布變更非常有信心。
我們每天都在運(yùn)行這套測(cè)試,并生成一份報(bào)告(可公開(kāi)獲取),其中自動(dòng)包含我們?cè)?GitHub 上跟蹤的已知問(wèn)題的評(píng)注,并主動(dòng)通知我們的框架團(tuán)隊(duì)新的未知問(wèn)題。
這一點(diǎn)尤為重要,因?yàn)樗粌H針對(duì)穩(wěn)定的 Next.js 版本進(jìn)行測(cè)試,還針對(duì)“金絲雀”預(yù)發(fā)布版本進(jìn)行測(cè)試。通過(guò)匹配最新的“金絲雀”版本的測(cè)試,我們就能確保在新功能發(fā)布和普遍可用之前,逐步增加對(duì)新功能的支持,并處理即將到來(lái)的破壞性更改(對(duì)文檔化和未文檔化接口的更改)。由于缺乏路線(xiàn)圖的透明度和發(fā)布的可預(yù)測(cè)性(見(jiàn)下文第 5 和第 6 項(xiàng)挑戰(zhàn)),我們確實(shí)有必要這樣做。
挑戰(zhàn) 4:不是建立在開(kāi)放 Web 標(biāo)準(zhǔn)之上
在撰寫(xiě)本文時(shí),Remix 框架的網(wǎng)站 上明確寫(xiě)著“專(zhuān)注于網(wǎng)絡(luò)標(biāo)準(zhǔn)”,Astro 的網(wǎng)站 的宣傳語(yǔ)是“零鎖定”,SvelteKit 網(wǎng)站則要求你“學(xué)習(xí)跨環(huán)境工作的網(wǎng)絡(luò)標(biāo)準(zhǔn)”。
使用增量靜態(tài)再生(ISR)時(shí),Next.js 會(huì)帶有一個(gè) Cache-Control 響應(yīng)頭,其中包含不合法的 Stale-While-Revalidate (SWR) 指令,如:
Cache-Control: s-maxage=600, stale-while-revalidate
而 RFC 5861 要求使用 Time-To-Live 值,例如:Cache-Control: s-maxage=600, stale-while-revalidate=60
這看起來(lái)可能只是一個(gè)煩人的小問(wèn)題,也許根本不值得在此提及。但這一細(xì)節(jié)的影響在于,許多 CDN 會(huì)默默地忽略不合法的指令。供應(yīng)商必須首先發(fā)現(xiàn)問(wèn)題的存在,然后要么為了 Next.js 而選擇支持不合法的頭信息,要么在其 Next.js 膠水代碼中加入轉(zhuǎn)換頭信息的代碼。雖然現(xiàn)在可以選擇默認(rèn)使用合法的頭信息(參見(jiàn) GitHub #52251、#61330、#65867 和 #65887),但這個(gè)問(wèn)題最終還是以默認(rèn)返回非標(biāo)準(zhǔn)的頭信息而 告終。這只是眾多問(wèn)題中的一個(gè)樣例而已。
此外,Next.js 的某些功能(如 ISR)是通過(guò)與 Vercel 平臺(tái)功能深度集成的特殊解決方案來(lái)實(shí)現(xiàn)的。在許多情況下,這些功能也可以建立在開(kāi)放 Web 標(biāo)準(zhǔn)(如標(biāo)準(zhǔn) Web API)之上,以實(shí)現(xiàn)更大的可移植性。Kent C. Dodds 就是出于這種考慮,撰寫(xiě)了“為什么我不會(huì)使用 Next.js”這篇文章。
倡導(dǎo)開(kāi)放的 Web
Netlify 的使命是共同構(gòu)建一個(gè)更好的 Web。
我們通過(guò)參與 WinterCG(現(xiàn)為 WinterTC)等工作組和 OpenNext 等計(jì)劃、為框架和整個(gè)社區(qū)起草 RFC、為合作伙伴提供穩(wěn)定的文檔化平臺(tái)、隨著 Web 的不斷發(fā)展為新的平臺(tái)標(biāo)準(zhǔn)和 API 提供支持,以及抓住一切機(jī)會(huì)倡導(dǎo)開(kāi)放 web,努力將這一理念付諸實(shí)踐。
但是,為了解決我們對(duì) Next.js 的直接、具體需求,我們需要更多的東西:
原語(yǔ)而非框架
Kent Beck 說(shuō):“首先讓改變變得簡(jiǎn)單(這可能很難),然后再進(jìn)行簡(jiǎn)單的改變”。在某種程度上,這就是我們 去年的策略。我們的目標(biāo)不是針對(duì)性地解決 Next.js 的每個(gè)新功能,而是先確定底層平臺(tái)原語(yǔ),使該功能易于采用,它不僅局限在 Next.js 中,而是在任何框架中,甚至在沒(méi)有框架的情況下。
例如,我們沒(méi)有在平臺(tái)深處實(shí)現(xiàn) Next.js 的增量靜態(tài)再生(ISR),而是 完全通過(guò)簡(jiǎn)單的 HTTP 響應(yīng)頭實(shí)現(xiàn)了對(duì)標(biāo)準(zhǔn) Stale-While-Revalidate 指令和其他高級(jí)緩存原語(yǔ)的支持。因此,在我們的 Next.js 適配器中,只需幾行簡(jiǎn)單的代碼就能實(shí)現(xiàn) Next.js ISR,而且由于所有其他 SSR 框架都允許用戶(hù)設(shè)置頭信息,因此這些框架也能自動(dòng)使用這一功能,甚至 無(wú)需任何框架。
挑戰(zhàn) 5:缺乏路線(xiàn)圖的可見(jiàn)性
大多數(shù)框架都會(huì)發(fā)布公開(kāi)的路線(xiàn)圖,讓開(kāi)發(fā)人員、提供商和集成開(kāi)發(fā)人員及時(shí)了解即將推出的新功能、棄用的功能、破壞性變更等。例如,Astro、Remix、Qwik、Nuxt、Angular,以及 Vite 和 Svelte 的最小化路線(xiàn)圖
Next.js 沒(méi)有公開(kāi)的路線(xiàn)圖,也沒(méi)有同樣的透明度。
雖然開(kāi)發(fā)人員可以自由選擇何時(shí)升級(jí)自己的網(wǎng)站,但托管服務(wù)提供商和集成開(kāi)發(fā)人員必須滿(mǎn)足社區(qū)的期望,盡快為新版本提供支持。
此外,大多數(shù)框架的路線(xiàn)圖都是與社區(qū)合作制定的。
Next.js 的治理模式規(guī)定,“大型架構(gòu)決策和功能以征求意見(jiàn)(Request for Comments,RFC) 的形式啟動(dòng)”。然而,在撰寫(xiě)本文時(shí),八年來(lái)只有四個(gè)社區(qū) RFC 被采納,其中只有一個(gè)非谷歌貢獻(xiàn)者。構(gòu)思、決策和路線(xiàn)圖都是閉門(mén)造車(chē),每年在發(fā)布新版本的同時(shí),都會(huì)在 Vercel Conf 和 Next.js Conf 上與公眾分享兩次。
通過(guò)與社區(qū)(OpenNext 成員和其他成員)的合作,我們將致力于為 Next.js RFC 提出建議并做出貢獻(xiàn),以應(yīng)對(duì)這些的挑戰(zhàn),例如上述的構(gòu)建輸出適配器。讓我們攜手共建!
挑戰(zhàn) 6:缺乏發(fā)布的可預(yù)測(cè)性
大多數(shù)框架要么定期更新其公開(kāi)路線(xiàn)圖(見(jiàn)上文第 5 條),要么在取得進(jìn)展時(shí)公開(kāi)宣布即將發(fā)生的變更(如 Nuxt),要么遵守固定的發(fā)布時(shí)間表(如 Angular)。但是 Next.js 的情況并非如此。開(kāi)發(fā)人員、托管提供商、集成開(kāi)發(fā)人員和整個(gè)社區(qū)只能靠猜測(cè)以及字里行間的解讀。
例如,Next.js 15 發(fā)布候選版于去年 5 月份發(fā)布,但從它發(fā)布后到 5 個(gè)月之后的下一個(gè)發(fā)布候選版(幾天后就發(fā)布了 Next.js 15 穩(wěn)定版)之間沒(méi)有共享任何更新,只能通過(guò)查看 canary 分支的 2254 次提交來(lái)了解其更新情況。
我們是如何跟蹤 Next.js 發(fā)行版和預(yù)發(fā)布版的
我們像鷹一樣關(guān)注著 Next.js 的 PR 和發(fā)布。事實(shí)上,我們花了太多時(shí)間來(lái)做這件事,以至于我們構(gòu)建了一個(gè)小型的服務(wù)來(lái)自動(dòng)完成這項(xiàng)繁重的工作。
請(qǐng)放心,Cloudflare、AWS Amplify Hosting、SST、Google Firebase App Hosting、Microsoft Azure Static Web Apps 等公司的團(tuán)隊(duì)也在做同樣的事情。
幸運(yùn)的是,在 Vercel 的努力下,我們與 Next.js 團(tuán)隊(duì)建立了溝通渠道。有了這些,我們希望能更好地了解框架即將發(fā)生的變化。
展望未來(lái)
現(xiàn)在,總結(jié)一下我們的現(xiàn)狀和采取的具體步驟:
首先,我們致力于與其他提供商、社區(qū)和 Next.js 團(tuán)隊(duì)合作。我們有一個(gè)共同的目標(biāo),那就是為 Next.js 開(kāi)發(fā)人員及其站點(diǎn)訪(fǎng)問(wèn)者提供良好的體驗(yàn)。這也是我們與 SST 和 Cloudflare 團(tuán)隊(duì)一起 加入 OpenNext 計(jì)劃 的原因。
其次,在 Vercel 工程師的努力下,我們已經(jīng)與 Next.js 核心團(tuán)隊(duì)建立了直接的溝通渠道。我們樂(lè)觀(guān)地認(rèn)為,這將有助于我們從源頭上應(yīng)對(duì)挑戰(zhàn)。
第三,行勝于言,根據(jù)明確定義的 Next.js 治理模式,我們將開(kāi)始與其他提供商合作起草 RFC,以應(yīng)對(duì)其中的一些挑戰(zhàn),目前這項(xiàng)工作已經(jīng)開(kāi)始。
我們期待著共同建設(shè)一個(gè)更美好的 Web。
聲明:本文由 InfoQ 翻譯,未經(jīng)許可禁止轉(zhuǎn)載。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶(hù)上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.