2022 年 6 月 28 日 星期二
Next.js 12.2
作者:我們正在為 Next.js 的未來奠定基礎,推出 12.2 版本
- 中介層 (穩定版): 應用程式整體的動態路由。
- 隨需應變 ISR (穩定版): 無需重新部署即可更新內容。
- 邊緣 API 路由 (實驗性): 高效能 API 端點。
- 邊緣 SSR (實驗性): 在邊緣伺服器端渲染您的應用程式。
- SWC 外掛程式 (實驗性): 使用您自己的外掛程式擴充編譯功能。
next/image
的改進: 包括新的next/future/image
組件。
立即執行 npm i next@latest
來更新。
中介層 (穩定版)
我們很高興宣布中介層在 12.2 版本中已成為穩定版,並根據使用者的回饋改進了 API。
中介層允許您在請求完成之前執行程式碼。根據傳入的請求,您可以透過重新編寫、重新導向、新增標頭或設定 Cookie 來修改回應。
import { NextRequest, NextResponse } from 'next/server';
// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
req.nextUrl.pathname = isInBeta ? '/beta' : '/';
return NextResponse.rewrite(req.nextUrl);
}
// Supports both a single value or an array of matches
export const config = {
matcher: '/',
};
若要更新至中介層最新的 API 變更,請參閱移轉指南。
在 Vercel 上免費試用中介層,或在使用 next start
自行託管時試用。
隨需應變增量靜態重新產生 (穩定版)
隨需應變增量靜態重新產生 (ISR) 讓您無需重新部署即可更新網站上的內容。這讓您在無頭 CMS 或商務平台中的資料變更時,可以輕鬆地立即更新網站。這是社群中最受歡迎的功能之一,我們很高興它現在已成為穩定版。
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' });
}
try {
await res.revalidate('/path-to-revalidate');
return res.json({ revalidated: true });
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating');
}
}
增量靜態重新產生適用於任何支援 Next.js Build API (next build
) 的供應商。當部署到 Vercel時,當將頁面推送至邊緣時,隨需應變重新驗證會在約 300 毫秒內在全球範圍內傳播。
如需更多資訊,請查看文件,或查看我們的示範,以查看隨需應變重新驗證的實際運作情況。
邊緣 API 路由 (實驗性)
Next.js 現在也支援將 邊緣執行階段用於 API 路由。邊緣執行階段是比 Node.js 更輕量的執行階段,可為低延遲提供快速啟動。此外,邊緣 API 路由支援來自伺服器的串流回應。
您可以在 config
中設定 API 路由的執行階段,指定 nodejs
(預設) 或 experimental-edge
import type { NextRequest } from 'next/server';
export default (req: NextRequest) => {
return new Response(`Hello, from ${req.url} I'm now an Edge API Route!`);
};
export const config = {
runtime: 'experimental-edge',
};
由於邊緣執行階段非常輕量,因此在容納快速啟動方面存在限制,例如,它不支援特定於 Node.js 的 API,如 fs
。因此,API 路由的預設執行階段仍為 nodejs
。
如需更多資訊,請查看文件。
邊緣伺服器端渲染 (實驗性)
Next.js 現在支援將 邊緣執行階段用於伺服器渲染。
如上所述,邊緣執行階段是比 Node.js 更輕量的執行階段,可為低延遲提供快速啟動。與 React 18 一起使用時,它可為頁面啟用串流伺服器端渲染。
Next.js 使用 Node.js 作為伺服器端渲染頁面的預設執行階段。從 12.2 版本開始,如果您使用 React 18,您可以選擇使用邊緣執行階段。
您可以在 next.config.js
中全域設定執行階段,指定 nodejs
或 experimental-edge
module.exports = {
experimental: {
runtime: 'experimental-edge',
},
};
變更預設頁面執行階段會影響所有頁面,包括 SSR 串流和 伺服器組件功能。您也可以透過匯出 runtime
設定來覆寫每個頁面的此預設值
export const config = {
runtime: 'nodejs',
};
export default function Home() {}
您可以透過在執行階段查看 process.env.NEXT_RUNTIME
環境變數,以及在 webpack 編譯期間檢查 options.nextRuntime
變數來偵測您正在使用的執行階段。
如需更多資訊,請查看文件。
next/image
的改進
next/future/image
組件 (實驗性)
我們聽取了您對目前 Image 組件的回饋,並很高興分享新的 next/image
的早期預覽版。這個經過改良的新圖片組件需要的用戶端 JavaScript 較少,並簡化了您設定圖片樣式的方式
- 渲染單個
<img>
,而沒有<div>
或<span>
包裝器 - 新增對標準
style
屬性的支援 - 移除
layout
、objectFit
和objectPosition
屬性,改用style
或className
- 移除
IntersectionObserver
實作,改用原生延遲載入 - 移除
loader
設定,改用loader
屬性 - 注意:目前沒有
fill
模式,因此需要width
和height
屬性
這改善了效能,因為原生 loading="lazy"
不需要等待 React hydration 和用戶端 JavaScript。
如需更多資訊,請查看文件。
遠端模式 (實驗性)
next/image
現在支援實驗性設定選項 remotePatterns
,讓您在使用內建 Image Optimization API 時,為遠端圖片指定萬用字元。這允許比現有的 images.domains
設定進行更強大的比對,該設定僅對網域名稱執行完全比對。
module.exports = {
experimental: {
images: {
remotePatterns: [
{
// The `src` property hostname must end with `.example.com`,
// otherwise this will respond with 400 Bad Request.
protocol: 'https',
hostname: '**.example.com',
},
],
},
},
};
如需更多資訊,請查看文件。
停用圖片最佳化
零設定 Image Optimization API 阻止使用 next export
,因為它需要伺服器在圖片被請求時隨需應變地最佳化圖片。直到今天,以 next export
為目標的使用者需要設定 loader
以使用第三方 Image Optimization 供應商,但如果沒有可用的供應商,則沒有明確的解決方案。從今天開始,next export
使用者可以使用新的組態屬性,為 next/image
的所有實例停用 Image Optimization
module.exports = {
experimental: {
images: {
unoptimized: true,
},
},
};
SWC 外掛程式 (實驗性)
Next.js 編譯器使用 SWC 來轉換和最小化您的 JavaScript 程式碼以用於生產環境。Next.js 12.0 中引入了 SWC,以改善本機開發和建置效能。
您現在可以新增外掛程式 (以 WebAssembly 撰寫) 以自訂編譯期間的 SWC 轉換行為
module.exports = {
experimental: {
swcPlugins: [
['css-variable/swc', { displayName: true, basePath: __dirname }],
],
},
};
如需更多資訊,請查看文件。
React 18 支援改進
- 改進了對 CSS-in-JS 程式庫 (如
styled-components
和emotion
) 的支援,提供更順暢的升級體驗,且沒有重大變更。 - AMP 和 HTML 後最佳化 (CSS、字型最佳化) 現在已獲得適當的支援。
next/head
現在支援 React 18。- Next.js 的路由宣告工具 (用於向螢幕閱讀器和其他輔助技術正確宣告頁面轉換) 現在支援 React 18。
其他改進
- 支援 Next.js 編譯器中的 Emotion 轉換。現在支援
@emotion/babel-plugin
的大多數功能,除非您使用importMap
,否則可以移除它。如需更多資訊,請查看文件。 - 透過允許自訂預設選項 (包括
cssProp
選項),更好地支援 Next.js 編譯器中的styled-components
轉換。如需更多資訊,請查看文件。 - 更好地支援 JavaScript ES Modules,因此可以正確地
import
next/image
和next/link
等組件。 next/link
不再需要手動新增<a>
作為子項。您現在可以選擇加入此行為,並以向後相容的方式進行。- 我們新增了實驗性支援,透過修改
browsersList
來僅發佈現代 JavaScript。您可以透過在next.config.js
的experimental
選項中設定browsersListForSwc: true
和legacyBrowsers: false
來選擇加入此行為。 - 新的
@swc/helpers
最佳化可防止跨套件重複,從而減少套件大小,在最小設定中減少約2KB
,在較大的應用程式中減少更多 - 我們已大幅縮減 Next.js 的安裝大小。我們透過將我們的 monorepo 遷移到
pnpm
來實現這一點,這讓我們可以在建立我們使用的預編譯版本時移除重複的套件。這使得安裝大小減少了 14MB。 - 在我們持續努力改進 Next.js 自行託管的過程中,我們正在將我們的實驗性
outputStandalone: true
設定穩定化為output: 'standalone'
。此設定僅包含必要檔案/資產,包括移除在建置的部署套件中安裝所有node_modules
的需求,從而大幅縮減部署大小。可以在我們的with-docker
範例中看到此設定的實際運作情況。
版面配置 RFC & 進階路由支援
如果您錯過了,上個月我們宣布了版面配置 RFC – 這是自 2016 年推出以來 Next.js 最大的更新,包括
- 巢狀版面配置: 使用巢狀路由建置複雜的應用程式。
- 專為伺服器組件設計: 針對子樹導航進行了最佳化。
- 改進的資料擷取: 在版面配置中擷取,同時避免瀑布流。
- 使用 React 18 功能: 串流、轉場和 Suspense。
- 用戶端和伺服器路由: 以伺服器為中心的路由,具有類似 SPA 的行為。
- 100% 可逐步採用:沒有重大變更,因此您可以逐步採用。
- 進階路由慣例:離螢幕存放、即時轉場等等。
感謝貢獻者
Next.js 是 超過 2,000 位個別開發人員、Google Chrome 和 Meta 等產業合作夥伴以及我們 Vercel 核心團隊共同努力的成果。
此版本是由以下人員貢獻:@huozhi、@ijjk、@kwonoj、@ViolanteCodes、@akrabdev、@timneutkens、@jpveilleux、@stigkj、@jgoping、@oof2win2、@Brooooooklyn、@CGamesPlay、@lfades、@molebox、@steven-tey、@SukkaW、@Kikobeats、@balazsorban44、@erikbrinkman、@therealmarzouq、@remcohaszing、@perkinsjr、@shuding、@hanneslund、@housseindjirdeh、@RobertKeyser、@styfle、@htunnicliff、@lukeshumard、@sagnik3、@pixelass、@JoshuaKGoldberg、@rishabhpoddar、@nguyenyou、@kdy1、@sidwebworks、@gnoff、@gaspar09、@feugy、@mfix-stripe、@javivelasco、@Chastrlove、@goncharov-vlad、@NaveenDA、@Firfi、@idkwhojamesis、@FLCN-16、@icyJoseph、@ElijahPepe、@elskwid、@irvile、@Munawwar、@ykolbin、@hulufei、@baruchadi、@imadatyatalah、@await-ovo、@menosprezzi、@gazs、@Exortions、@rubens-lopes、@woochul2、@stefee、@stmtk1、@jlarmstrongiv、@MaedahBatool、@jameshfisher、@fabienheureux、@TxHawks、@mattbrandlysonos、@iggyzap、@src200、@AkifumiSato、@hermanskurichin、@kamilogorek、@ben-xD、@dawsonbooth、@Josehower、@crutchcorn、@ericmatthys、@CharlesStover、@charlypoly、@apmatthews、@naingaungphyo、@alexandrutasica、@stefanprobst、@dc7290、@DilwoarH、@tommarshall、@stanhong、@leerob、@appsbytom、@sshyam-gupta、@saulloalmeida、@indicozy、@ArianHamdi、@Clariity、@sebastianbenz、@7iomka、@gr-qft、@Schniz、@dgagn、@sokra、@okbel、@tbvjaos510、@dmvjs、@PepijnSenders、@JohnPhamous、@kyliau、@eric-burel、@alabhyajindal、@jsjoeio、@vorcigernix、@clearlyTHUYDOAN、@splatterxl、@manovotny、@maxproske、@nvh95、@frankievalentine、@nuta、@bagpyp、@dfelsie、@qqpann、@atcastle、@jsimonrichard、@mass2527、@ekamkohli、@Yuddomack、@tonyspiro、@saurabhmehta1601、@banner4422、@falsepopsky、@jantimon、@henriqueholtz、@ilfa、@matteobruni、@ryscheng、@hoonoh、@ForsakenHarmony、@william-keller、@AleksaC、@Miikis、@zakiego、@radunemerenco、@AliYusuf95 和 @dominiksipowicz。