Next.js 是一個非常受歡迎的 Node.js 框架,它可以方便地進行服務器端的 React 渲染,並提供許多其他令人驚喜的功能。
- Introduction
- 主要功能
- 安裝
- 入門
- 創建頁面
- 服務器端渲染
- 添加第二個頁面
- 熱加載
- 客戶端渲染
- 動態頁面
- CSS-in-JS
- 導出靜態網站
- 部署到 Vercel
- 了解更多關於 Next.js
Introduction
在使用由 React 驅動的現代 JavaScript 應用程式時感到很棒,直到你意識到與在客戶端渲染所有內容相關的一些問題。
首先,頁面需要更長的時間才能對用戶顯示,因為在內容加載之前,必須加載所有 JavaScript,然後應用程式需要運行以確定要在頁面上顯示什麼。
其次,如果你正在構建一個公開可用的網站,你將會遇到搜索引擎優化(SEO)問題。搜索引擎越來越善於運行和索引 JavaScript 應用程式,但最好還是能夠將內容發送給它們,而不是讓它們自己解決。
解決這些問題的方法是進行服務器端渲染,也稱為靜態預渲染。
Next.js 是一個 React 框架,可以以非常簡單的方式完成所有這些工作,但它並不僅限於此。它被創建者稱為零配置、單命令工具鏈,可用於 React 應用程式。
它提供了一個通用結構,允許你輕鬆構建前端 React 應用程式,並為你提供透明的服務器端渲染能力。
主要功能
以下是一個非詳盡的 Next.js 主要功能清單:
- 熱加載: 當檢測到任何變更時,Next.js 會重新載入頁面。
- 自動路由: 任何URL都會映射到文件系統,即放在
pages
文件夾中的文件,你不需要任何配置(當然你也可以進行自定義配置)。 - 單文件組件: 使用完全集成的 styled-jsx,Next.js 讓添加與組件相關的樣式變得非常容易。
- 服務器端渲染: 你可以(可選地)在服務器端渲染 React 組件,在將 HTML 發送給客戶端之前進行渲染。
- 生態系統相容性: Next.js 與其他 JavaScript、Node 和 React 生態系統相容。
- 自動代碼拆分: 只渲染頁面所需的庫和 JavaScript,不多不少。
- 預取資源:
Link
組件,用於鏈接不同的頁面,支持prefetch
屬性,可在後台自動預取頁面資源(包括由於代碼拆分而丟失的代碼)。 - 動態組件: 你可以動態地引入 JavaScript 模塊和 React 組件 (https://github.com/vercel/next.js#dynamic-import)。
- 靜態導出: 使用
next export
命令,Next.js 允許你從應用程式導出一個完全靜態的網站。
安裝
Next.js 支持所有主要平台:Linux、macOS、Windows。
使用 npm 輕鬆開始 Next.js 項目:
npm install next react react-dom
入門
創建一個包含以下內容的 package.json
文件:
{
"scripts": {
"dev": "next"
}
}
現在運行以下命令:
npm run dev
該腳本將引發錯誤,因為找不到 pages
文件夾。這是 Next.js 運行所需的唯一文件夾。
創建一個空的 pages
文件夾,然後再次運行該命令,Next.js 將在 localhost:3000
上啟動一個服務器。
現在轉到該網址,你將看到一個友好的 404 頁面,並具有漂亮的乾淨設計。
Next.js 還處理其他錯誤類型,例如 500 錯誤。
創建頁面
在 pages
文件夾中創建一個 index.js
文件,其中包含一個簡單的 React 函數組件:
export default () => (
<div>
<p>Hello World!</p>
</div>
)
如果你訪問 localhost:3000
,將自動渲染此組件。
為什麼這是如此簡單?
Next.js 使用聲明式的頁面結構,其基於文件系統結構。
頁面位於 pages
文件夾中,頁面 URL 由頁面文件名確定。文件系統是頁面 API。
服務器端渲染
在頁面源代碼中打開 檢視 -> 開發人員 -> 查看源代碼
(使用 Chrome)。
如你所見,由組件生成的 HTML 直接包含在頁面源碼中。它不是在客戶端渲染,而是在服務器端渲染。
Next.js 團隊希望為開發人員提供一個類似於創建基本 PHP 項目時所獲得的服務器渲染頁面的開發體驗,例如,你只需放置 PHP 文件並調用它們,它們就會以頁面的形式顯示出來。當然,內部實現當然很不同,但易於使用的方式是顯而易見的。
添加第二個頁面
現在,讓我們創建另一個頁面,在 pages/contact.js
中添加以下內容:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>聯繫我們!</a>
</p>
</div>
)
如果你將瀏覽器指向 localhost:3000/contact
,將顯示該頁面。可見,該頁面也已進行了服務器端渲染。
熱加載
請注意,在加載第二個頁面時,你無需重新啟動 npm 進程。Next.js 會在內部自動處理此操作。
客戶端渲染
服務器端渲染非常方便,因為它可以加速頁面加載並改善用戶體驗,但在瀏覽網站時,客戶端渲染對於加快頁面加載並提高用戶體驗非常重要。
Next.js 提供了一個 Link
組件,你可以使用它來建立鏈接。試著將上面的兩個頁面連接起來。
將 index.js
更改為以下代碼:
import Link from 'next/link'
export default () => (
<div>
<p>Hello World!</p>
<Link href='/contact'>
<a>聯繫我!</a>
</Link>
</div>
)
現在返回瀏覽器,並點擊此鏈接。你會看到 Contact 頁面立即加載,而不需要刷新頁面。
這是客戶端導航正確工作的結果,完全支持 History API,這意味著你的用戶返回鍵不會失效。
如果你現在 cmd+點擊
驗證鏈接,將以新標簽頁面打開相同的 Contact 頁面,但這次是服務器端渲染。
動態頁面
Next.js 的一個很好的用例是博客,因為這是所有開發人員都熟悉的內容,同時它也很適合作為處理動態頁面的簡單示例。
動態頁面是一個沒有固定內容的頁面,而是基於某些參數顯示某些數據。
將 index.js
更改為:
import Link from 'next/link'
const Post = (props) => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<div>
<h2>我的博客</h2>
<ul>
<li>
<Post title='另一篇文章' />
<Post title='第二篇文章' />
<Post title='Hello, world!' />
</li>
</ul>
</div>
)
這將創建一系列帖子,並將標題查詢參數填入帖子標題中:
現在在 pages
文件夾中創建一個 post.js
文件,並添加以下內容:
export default (props) => <h1>{props.url.query.title}</h1>
現在點擊一個帖子,將在 h1
標籤中呈現該帖子的標題:
你可以使用不帶查詢參數的清晰 URL。Next.js 的 Link 組件通過接受 as
屬性來幫助我們傳遞一個簡略標識:
import Link from 'next/link'
const Post = (props) => (
<li>
<Link as={`/${props.slug}`} href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
)
export default () => (
<div>
<h2>我的博客</h2>
<ul>
<li>
<Post slug='yet-another-post' title='另一篇文章' />
<Post slug='second-post' title='第二篇文章' />
<Post slug='hello-world' title='Hello, world!' />
</li>
</ul>
</div>
)
CSS-in-JS
Next.js 默認提供對 styled-jsx 的支持,這是由相同開發團隊提供的一種 CSS-in-JS 解決方案,但你也可以使用任何你喜歡的庫,比如 Tailwind CSS。
示例:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>聯繫我們!</a>
<style jsx>{`
p {
font-family: 'Courier New';
}
a {
text-decoration: none;
color: black;
}
a:hover {
opacity: 0.8;
}
`}</style>
</div>
)
樣式僅作用於該組件,但你也可以在 style
元素中添加 global
以編輯全局樣式:
export default () => (
<div>
<p>
<a href='mailto:[[email protected]](/cdn-cgi/l/email-protection)'>聯繫我們!</a>
</p>
<style jsx global>{`
body {
font-family: 'Benton Sans', 'Helvetica Neue';
margin: 2em;
}
h2 {
font-style: italic;
color: #373fff;
}
`}</style>
</div>
)
導出靜態網站
Next.js 應用程式可以輕鬆導出為靜態網站,並可以在超快的靜態網站主機上部署,例如 Vercel(由致力於 Next.js 開發的同一團隊開發),但也包括 Netlify、Cloudflare Pages 或 Firebase Hosting,而無需設置 Node 環境。
部署到 Vercel
如果你的網站不僅僅是一個靜態網站,並且使用 API 路由,我強烈建議使用 Vercel。
Vercel 是 Next.js 背後的公司,並提供專為 Next.js 應用程式量身定制的出色托管服務。
Vercel 是任何網站的理想托管服務,特別是當涉及到 Next.js 時,你可以使用 API 路由作為無服務器函數进行部署。
其他平台(例如 Netlify)也有這種方式可以部署具有 API 路由的 Next.js 應用程式(請參閱 https://docs.netlify.com/integrations/frameworks/next-js/),但在 Vercel 上,Next.js 是一位頂尖公民。
你有自動部署為無服務器函數的 API 路由,並且可以更精細地控制、查看日誌,等等。
如果你使用 Next.js,你一定要試試看 Vercel。
了解更多關於 Next.js
請查看我免費的 Next.js 手冊!