提及 服務端渲染(ssr) 和 SPA,相信你總能說個一二:css
這二者的優缺點都很明顯,因此隨着時代的進步和技術的演變,誕生了 SSR + SPA 的新模式。而且在 react/vue
等前端框架相結合 node (ssr)
下,能夠最大限度的重用代碼(同構),減小開發維護成本。html
web 應用能夠分爲 瀏覽器端 和 服務器端 兩部分,對於同構應用來講,分爲 初次發送請求( SSR ) 和 後續操做( SPA )。前端
基於 React 能夠在服務端渲染的能力,Next 提供了一套完整且方便的同構應用解決方案。vue
Next.js,這是一個 React 的同構應用開發框架。node
咱們用 CLI 工具 -- Create Next App 來快速建立 Next.js 應用,經過配置參數 -e, --example [name]|[github-url]
能夠直接以 Next.js Repo中的模版建立應用:react
npx create-next-app nextjs-auth0 --example "https://github.com/vercel/next.js/tree/master/examples/auth0"
複製代碼
咱們今天使用 Next.js 的入門模版(默認):git
npx create-next-app my-nextjs
複製代碼
運行成功後,進入 my-nextjs
目錄,運行啓動命令,應用默認運行在 3000 端口:github
cd my-nextjs
npm run dev
複製代碼
http://localhost:3000/, 查看頁面源代碼,能夠發現全部的內容都是服務器端返回的: web
Next.js 在開發時遵循了必定的約定:npm
pages
目錄下,頁面做爲一個組件。pages/index.js
關聯的路由是 /
pages/posts/first-post.js
關聯的路由是 /posts/first-post
page
具備靜態方法 getInitialProps
,能夠獲取接口數據做爲組件的 props
。page/index.js
已經存在,咱們新建一個 pages/posts/first-post.js
:
export default function FirstPost() {
return <h1>First Post</h1>;
}
複製代碼
這時候,你訪問 http://localhost:3000/posts/first-post
, 應該能夠看到:
<Link>
組件能夠在客戶端實現頁面間的導航,和 React Router 同樣實現的是前端路由,不會引發頁面的刷新:
import Link from "next/link";
複製代碼
使用時,將 Link 包裹在 a 標籤外,好比在 posts/first-post
添加一個回首頁的連接:
import Link from "next/link";
export default function FirstPost() {
return (
<> <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
複製代碼
Link
組件默認在後臺預取目標頁面。 經過設置 prefetch={false}
(默認爲 true
) 能夠禁止頁面預取。當 prefetch
被設置爲 false
時,鼠標懸停在 上時仍然會觸發預取。預取功能只在生產環境中開啓。
<Link href="/posts/first-post" prefetch={false}>
<FirstPost />
</Link>
複製代碼
Link
組件的默認行爲是將新 URL
推送到 history
堆棧中,可使用 replace
來替換 URL,而不是新增,這樣發生跳轉後,將沒法後退到上一個頁面。
<Link href="/about" replace>
<a>About us</a>
</Link>
複製代碼
Next.js 支持具備動態路由的 pages(頁面)。例如,若是你建立了一個命名爲 pages/posts/[id].js
的文件,那麼就能夠經過 posts/1
、posts/2
等相似的路徑進行訪問。
若是你添加了一張圖片到 public/me.png
路徑,經過 /me.png
能夠直接訪問到它:
import Image from "next/image";
function Avatar() {
return <Image src="/me.png" alt="me" width="64" height="64" />;
}
export default Avatar;
複製代碼
public
目錄映射靜態文件,包括 robots.txt
、favicon.ico
、Google 站點驗證文件以及任何其它靜態文件(包括 .html
文件)。
注意:
- 請勿爲 public 更名。此名稱是寫死的,不能修改,而且只有此目錄能過夠存放靜態資源並對外提供訪問。
- 請確保靜態文件中沒有與
pages/
目錄下的文件重名的,不然這將致使錯誤。
動態加載(Lazy loading)是一種僅在資源須要時加載它們的策略。Next.js 也提供了 import dynamic from "next/dynamic"
幫助咱們實現動態加載策略。
普通 import 一個組件:
import Link from "next/link";
import Hello from "../../component/Hello";
export default function FirstPost() {
return (
<> <h1>First Post</h1> <Hello /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
複製代碼
動態加載一個組件:
import Link from "next/link";
import dynamic from "next/dynamic";
// import Hello from "../../component/Hello";
const DynamicComponent = dynamic(() => import("../../component/Hello"));
export default function FirstPost() {
return (
<> <h1>First Post</h1> <DynamicComponent /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
複製代碼
從 network 能夠看出,動態加載的狀況下,Hello 組件被做爲了單獨資源: