摘要:中文站點(diǎn)中文站當(dāng)前翻譯版本為。注意將不能使用在子組件中。只能使用在頁(yè)面中。替換路由組件默認(rèn)將新推入路由棧中。以防服務(wù)端渲染發(fā)生錯(cuò)誤,建議事件寫(xiě)在生命周期里。禁止文件路由默認(rèn)情況,將會(huì)把下的所有文件匹配路由如渲染為如果你的項(xiàng)目使用
Next.js 是一個(gè)輕量級(jí)的 React 服務(wù)端渲染應(yīng)用框架。
Next.js中文站點(diǎn) http://nextjs.frontendx.cn
Next.js中文站Github https://github.com/raoenhui/next-site-cn
當(dāng)前翻譯版本為 7.0.0-canary.8。
怎么使用
安裝
代碼自動(dòng)分割
CSS
支持嵌入樣式
內(nèi)嵌樣式
使用 CSS / Sass / Less / Stylus files
靜態(tài)文件服務(wù)(如圖像)
獲取數(shù)據(jù)以及組件生命周期
路由
用法
URL 對(duì)象
替換路由
組件支持點(diǎn)擊事件onClick
暴露href給子元素
禁止?jié)L動(dòng)到頁(yè)面頂部
命令式
攔截器 popstate
URL 對(duì)象用法
路由事件
淺層路由
高階組件
預(yù)加載頁(yè)面
用法
命令式 prefetch 寫(xiě)法
自定義服務(wù)端路由
禁止文件路由
動(dòng)態(tài)前綴
動(dòng)態(tài)導(dǎo)入
1. 基礎(chǔ)支持 (同樣支持 SSR)
2. 自定義加載組件
3. 禁止使用 SSR
4. 同時(shí)加載多個(gè)模塊
自定義
自定義
自定義錯(cuò)誤處理
渲染內(nèi)置錯(cuò)誤頁(yè)面
自定義配置
設(shè)置自定義構(gòu)建目錄
禁止 etag 生成
配置 onDemandEntries
配置頁(yè)面后綴名解析擴(kuò)展
配置構(gòu)建 ID
自定義 webpack 配置
自定義 babel 配置
暴露配置到服務(wù)端和客戶端
啟動(dòng)服務(wù)選擇 hostname
CDN 支持前綴
項(xiàng)目部署
瀏覽器支持
導(dǎo)出靜態(tài)頁(yè)面
使用
限制
多 zone
怎么定義一個(gè) zone
怎么合并他們
技巧
FAQ
貢獻(xiàn)
作者
怎么使用 安裝安裝它:
npm install --save next react react-dom
將下面腳本添加到 package.json 中:
{ "scripts": { "dev": "next", "build": "next build", "start": "next start" } }
下面, 文件系統(tǒng)是主要的 API. 每個(gè).js 文件將變成一個(gè)路由,自動(dòng)處理和渲染。
新建 ./pages/index.js 到你的項(xiàng)目中:
export default () =>Welcome to next.js!
運(yùn)行 npm run dev 命令并打開(kāi) http://localhost:3000。 如果你想使用其他端口,可運(yùn)行 npm run dev -- -p <設(shè)置端口號(hào)>.
目前為止我們可以了解到:
自動(dòng)打包編譯 (使用 webpack 和 babel)
熱加載
以 ./pages作為服務(wù)端的渲染和索引
Static file serving. ./static/ is mapped to /static/ (given you create a ./static/ directory inside your project)
靜態(tài)文件服務(wù). ./static/ 映射到 /static/ (可以 創(chuàng)建一個(gè)靜態(tài)目錄 在你的項(xiàng)目中)
這里有個(gè)簡(jiǎn)單的案例,可以下載看看 sample app - nextgram
代碼自動(dòng)分割每個(gè)頁(yè)面只會(huì)導(dǎo)入import中綁定以及被用到的代碼. 也就是說(shuō)并不會(huì)加載不需要的代碼!
import cowsay from "cowsay-browser" export default () =>CSS 支持嵌入樣式{cowsay.say({ text: "hi there!" })}
Examples
我們綁定 styled-jsx 來(lái)生成獨(dú)立作用域的 CSS. 目標(biāo)是支持 "shadow CSS",但是 不支持獨(dú)立模塊作用域的 JS.
export default () =>Hello worldscoped!
想查看更多案例可以點(diǎn)擊 styled-jsx documentation查看.
內(nèi)嵌樣式
Examples
有些情況可以使用 CSS 內(nèi)嵌 JS 寫(xiě)法。如下所示:
export default () =>hi there
更復(fù)雜的內(nèi)嵌樣式解決方案,特別是服務(wù)端渲染的時(shí)樣式更改。我們可以通過(guò)包裹自定義 Document,來(lái)添加樣式,案例如下:custom
支持用.css, .scss, .less or .styl,需要配置默認(rèn)文件 next.config.js,具體可查看下面鏈接
@zeit/next-css
@zeit/next-sass
@zeit/next-less
@zeit/next-stylus
靜態(tài)文件服務(wù)(如圖像)在根目錄下新建文件夾叫static。代碼可以通過(guò)/static/來(lái)引入相關(guān)的靜態(tài)資源。
export default () =>
_注意:不要自定義靜態(tài)文件夾的名字,只能叫static ,因?yàn)橹挥羞@個(gè)名字 Next.js 才會(huì)把它當(dāng)作靜態(tài)資源。
生成
Examples
我們?cè)O(shè)置一個(gè)內(nèi)置組件來(lái)裝載到頁(yè)面中。
import Head from "next/head" export default () =>My page title Hello world!
我們定義key屬性來(lái)避免重復(fù)的標(biāo)簽,保證只渲染一次,如下所示:
import Head from "next/head" export default () => ()My page title Hello world!
只有第二個(gè)才被渲染。
注意:在卸載組件時(shí),的內(nèi)容將被清除。請(qǐng)確保每個(gè)頁(yè)面都在其定義了所需要的內(nèi)容,而不是假設(shè)其他頁(yè)面已經(jīng)加過(guò)了
獲取數(shù)據(jù)以及組件生命周期
Examples
如果你需要一個(gè)有狀態(tài)、生命周期或有初始數(shù)據(jù)的 React 組件(而不是上面的無(wú)狀態(tài)函數(shù)),如下所示:
import React from "react" export default class extends React.Component { static async getInitialProps({ req }) { const userAgent = req ? req.headers["user-agent"] : navigator.userAgent return { userAgent } } render() { return (Hello World {this.props.userAgent}) } }
相信你注意到,當(dāng)頁(yè)面渲染時(shí)加載數(shù)據(jù),我們使用了一個(gè)異步方法getInitialProps。它能異步獲取 JS 普通對(duì)象,并綁定在props上
當(dāng)服務(wù)渲染時(shí),getInitialProps將會(huì)把數(shù)據(jù)序列化,就像JSON.stringify。所以確保getInitialProps返回的是一個(gè)普通 JS 對(duì)象,而不是Date, Map 或 Set類型。
當(dāng)頁(yè)面初次加載時(shí),getInitialProps只會(huì)在服務(wù)端執(zhí)行一次。getInitialProps只有在路由切換的時(shí)候(如Link組件跳轉(zhuǎn)或路由自定義跳轉(zhuǎn))時(shí),客戶端的才會(huì)被執(zhí)行。
當(dāng)頁(yè)面初始化加載時(shí),getInitialProps只會(huì)加載在服務(wù)端。只有當(dāng)路由跳轉(zhuǎn)(Link組件跳轉(zhuǎn)或 API 方法跳轉(zhuǎn))時(shí),客戶端才會(huì)執(zhí)行getInitialProps。
注意:getInitialProps將不能使用在子組件中。只能使用在pages頁(yè)面中。
只有服務(wù)端用到的模塊放在getInitialProps里,請(qǐng)確保正確的導(dǎo)入了它們,可參考import them properly。
否則會(huì)拖慢你的應(yīng)用速度。
你也可以給無(wú)狀態(tài)組件定義getInitialProps:
const Page = ({ stars }) =>Next stars: {stars}Page.getInitialProps = async ({ req }) => { const res = await fetch("https://api.github.com/repos/zeit/next.js") const json = await res.json() return { stars: json.stargazers_count } } export default Page
getInitialProps入?yún)?duì)象的屬性如下:
pathname - URL 的 path 部分
query - URL 的 query 部分,并被解析成對(duì)象
asPath - 顯示在瀏覽器中的實(shí)際路徑(包含查詢部分),為String類型
req - HTTP 請(qǐng)求對(duì)象 (只有服務(wù)器端有)
res - HTTP 返回對(duì)象 (只有服務(wù)器端有)
jsonPageRes - 獲取數(shù)據(jù)響應(yīng)對(duì)象 (只有客戶端有)
err - 渲染過(guò)程中的任何錯(cuò)誤
路由 用法
Examples
可以用 組件實(shí)現(xiàn)客戶端的路由切換。
// pages/index.js import Link from "next/link" export default () =>Click{" "} here {" "} to read more
// pages/about.js export default () =>Welcome to About!
注意:可以使用使鏈接和預(yù)加載在后臺(tái)同時(shí)進(jìn)行,來(lái)達(dá)到頁(yè)面的最佳性能。
客戶端路由行為與瀏覽器很相似:
組件獲取
如果組件定義了getInitialProps,數(shù)據(jù)獲取了。如果有錯(cuò)誤情況將會(huì)渲染 _error.js。
1和2都完成了,pushState執(zhí)行,新組件被渲染。
如果需要注入pathname, query 或 asPath到你組件中,你可以使用withRouter。
Examples
組件接收 URL 對(duì)象,而且它會(huì)自動(dòng)格式化生成 URL 字符串
// pages/index.js import Link from "next/link" export default () =>Click{" "} here {" "} to read more
將生成 URL 字符串/about?name=Zeit,你可以使用任何在Node.js URL module documentation定義過(guò)的屬性。
組件默認(rèn)將新 url 推入路由棧中。你可以使用replace屬性來(lái)防止添加新輸入。
// pages/index.js import Link from "next/link" export default () =>Click{" "} here {" "} to read more
支持每個(gè)組件所支持的onClick事件。如果你不提供標(biāo)簽,只會(huì)處理onClick事件而href將不起作用。
// pages/index.js import Link from "next/link" export default () =>Click{" "}
如子元素是一個(gè)沒(méi)有 href 屬性的標(biāo)簽,我們將會(huì)指定它以免用戶重復(fù)操作。然而有些時(shí)候,我們需要里面有標(biāo)簽,但是Link組件不會(huì)被識(shí)別成超鏈接,結(jié)果不能將href傳遞給子元素。在這種場(chǎng)景下,你可以定義一個(gè)Link組件中的布爾屬性passHref,強(qiáng)制將href傳遞給子元素。
注意: 使用a之外的標(biāo)簽而且沒(méi)有通過(guò)passHref的鏈接可能會(huì)使導(dǎo)航看上去正確,但是當(dāng)搜索引擎爬行檢測(cè)時(shí),將不會(huì)識(shí)別成鏈接(由于缺乏 href 屬性),這會(huì)對(duì)你網(wǎng)站的 SEO 產(chǎn)生負(fù)面影響。
import Link from "next/link" import Unexpected_A from "third-library" export default ({ href, name }) =>{name}
的默認(rèn)行為就是滾到頁(yè)面頂部。當(dāng)有 hash 定義時(shí)(#),頁(yè)面將會(huì)滾動(dòng)到對(duì)應(yīng)的 id 上,就像標(biāo)簽一樣。為了預(yù)防滾動(dòng)到頂部,可以給加
scroll={false}屬性:
Disables scrolling Changes with scrolling to top命令式
Examples
你也可以用next/router實(shí)現(xiàn)客戶端路由切換
import Router from "next/router" export default () =>攔截器 popstateClick Router.push("/about")}>here to read more
有些情況(比如使用custom router),你可能想監(jiān)聽(tīng)popstate,在路由跳轉(zhuǎn)前做一些動(dòng)作。
比如,你可以操作 request 或強(qiáng)制 SSR 刷新
import Router from "next/router" Router.beforePopState(({ url, as, options }) => { // I only want to allow these two routes! if (as !== "/" || as !== "/other") { // Have SSR render bad routes as a 404. window.location.href = as return false } return true });
如果你在beforePopState中返回 false,Router將不會(huì)執(zhí)行popstate事件。
例如Disabling File-System Routing。
以上Router對(duì)象的 API 如下:
route - 當(dāng)前路由的String類型
pathname - 不包含查詢內(nèi)容的當(dāng)前路徑,為String類型
query - 查詢內(nèi)容,被解析成Object類型. 默認(rèn)為{}
asPath - 展現(xiàn)在瀏覽器上的實(shí)際路徑,包含查詢內(nèi)容,為String類型
push(url, as=url) - 頁(yè)面渲染第一個(gè)參數(shù) url 的頁(yè)面,瀏覽器欄顯示的是第二個(gè)參數(shù) url
replace(url, as=url) - performs a replaceState call with the given url
beforePopState(cb=function) - 在路由器處理事件之前攔截.
push 和 replace 函數(shù)的第二個(gè)參數(shù)as,是為了裝飾 URL 作用。如果你在服務(wù)器端設(shè)置了自定義路由將會(huì)起作用。
push 或 replace可接收的 URL 對(duì)象(組件的 URL 對(duì)象一樣)來(lái)生成 URL。
import Router from "next/router" const handler = () => Router.push({ pathname: "/about", query: { name: "Zeit" } }) export default () =>Click here to read more
也可以像組件一樣添加額外的參數(shù)。
你可以監(jiān)聽(tīng)路由相關(guān)事件。
下面是事件支持列表:
routeChangeStart(url) - 路由開(kāi)始切換時(shí)觸發(fā)
routeChangeComplete(url) - 完成路由切換時(shí)觸發(fā)
routeChangeError(err, url) - 路由切換報(bào)錯(cuò)時(shí)觸發(fā)
beforeHistoryChange(url) - 瀏覽器 history 模式開(kāi)始切換時(shí)觸發(fā)
hashChangeStart(url) - 開(kāi)始切換 hash 值但是沒(méi)有切換頁(yè)面路由時(shí)觸發(fā)
hashChangeComplete(url) - 完成切換 hash 值但是沒(méi)有切換頁(yè)面路由時(shí)觸發(fā)
這里的url是指顯示在瀏覽器中的 url。如果你用了Router.push(url, as)(或類似的方法),那瀏覽器中的 url 將會(huì)顯示 as 的值。
下面是如何正確使用路由事件routeChangeStart的例子:
const handleRouteChange = url => { console.log("App is changing to: ", url) } Router.events.on("routeChangeStart", handleRouteChange)
如果你不想長(zhǎng)期監(jiān)聽(tīng)該事件,你可以用off事件去取消監(jiān)聽(tīng):
Router.events.off("routeChangeStart", handleRouteChange)
如果路由加載被取消(比如快速連續(xù)雙擊鏈接)
Router.events.on("routeChangeError", (err, url) => { if (err.cancelled) { console.log(`Route to ${url} was cancelled!`) } })
Examples
淺層路由允許你改變 URL 但是不執(zhí)行getInitialProps生命周期。你可以加載相同頁(yè)面的 URL,得到更新后的路由屬性pathname和query,并不失去 state 狀態(tài)。
你可以給Router.push 或 Router.replace方法加shallow: true參數(shù)。如下面的例子所示:
// Current URL is "/" const href = "/?counter=10" const as = href Router.push(href, as, { shallow: true })
現(xiàn)在 URL 更新為/?counter=10。在組件里查看this.props.router.query你將會(huì)看到更新的 URL。
你可以在componentdidupdate鉤子函數(shù)中監(jiān)聽(tīng) URL 的變化。
componentDidUpdate(prevProps) { const { pathname, query } = this.props.router // verify props have changed to avoid an infinite loop if (query.id !== prevProps.router.query.id) { // fetch data based on the new query } }
高階組件注意:
淺層路由只作用于相同 URL 的參數(shù)改變,比如我們假定有個(gè)其他路由about,而你向下面代碼樣運(yùn)行:
Router.push("/?counter=10", "/about?counter=10", { shallow: true })那么這將會(huì)出現(xiàn)新頁(yè)面,即使我們加了淺層路由,但是它還是會(huì)卸載當(dāng)前頁(yè),會(huì)加載新的頁(yè)面并觸發(fā)新頁(yè)面的getInitialProps。
Examples
如果你想應(yīng)用里每個(gè)組件都處理路由對(duì)象,你可以使用withRouter高階組件。下面是如何使用它:
import { withRouter } from "next/router" const ActiveLink = ({ children, router, href }) => { const style = { marginRight: 10, color: router.pathname === href? "red" : "black" } const handleClick = (e) => { e.preventDefault() router.push(href) } return ( {children} ) } export default withRouter(ActiveLink)
上面路由對(duì)象的 API 可以參考next/router.
預(yù)加載頁(yè)面?? 只有生產(chǎn)環(huán)境才有此功能 ??
Examples
Next.js 有允許你預(yù)加載頁(yè)面的 API。
用 Next.js 服務(wù)端渲染你的頁(yè)面,可以達(dá)到所有你應(yīng)用里所有未來(lái)會(huì)跳轉(zhuǎn)的路徑即時(shí)響應(yīng),有效的應(yīng)用 Next.js,可以通過(guò)預(yù)加載應(yīng)用程序的功能,最大程度的初始化網(wǎng)站性能。查看更多.
Next.js 的預(yù)加載功能只預(yù)加載 JS 代碼。當(dāng)頁(yè)面渲染時(shí),你可能需要等待數(shù)據(jù)請(qǐng)求。用法
你可以給添加 prefetch 屬性,Next.js 將會(huì)在后臺(tái)預(yù)加載這些頁(yè)面。
import Link from "next/link" // example header component export default () =>命令式 prefetch 寫(xiě)法
大多數(shù)預(yù)加載是通過(guò)處理的,但是我們還提供了命令式 API 用于更復(fù)雜的場(chǎng)景。
import { withRouter } from "next/router" export default withRouter(({ router }) =>setTimeout(() => router.push("/dynamic"), 100)}> A route transition will happen after 100ms {// but we can prefetch it! router.prefetch("/dynamic")})
路由實(shí)例只允許在應(yīng)用程序的客戶端。以防服務(wù)端渲染發(fā)生錯(cuò)誤,建議 prefetch 事件寫(xiě)在componentDidMount()生命周期里。
import React from "react" import { withRouter } from "next/router" class MyLink extends React.Component { componentDidMount() { const { router } = this.props router.prefetch("/dynamic") } render() { const { router } = this.props return ( ) } } export default withRouter(MyLink)自定義服務(wù)端路由
Examples
一般你使用next start命令來(lái)啟動(dòng) next 服務(wù),你還可以編寫(xiě)代碼來(lái)自定義路由,如使用路由正則等。
當(dāng)使用自定義服務(wù)文件,如下面例子所示叫 server.js 時(shí),確保你更新了 package.json 中的腳本。
{ "scripts": { "dev": "node server.js", "build": "next build", "start": "NODE_ENV=production node server.js" } }
下面這個(gè)例子使 /a 路由解析為./pages/b,以及/b 路由解析為./pages/a;
// This file doesn"t go through babel or webpack transformation. // Make sure the syntax and sources this file requires are compatible with the current node version you are running // See https://github.com/zeit/next.js/issues/1245 for discussions on Universal Webpack or universal Babel const { createServer } = require("http") const { parse } = require("url") const next = require("next") const dev = process.env.NODE_ENV !== "production" const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { createServer((req, res) => { // Be sure to pass `true` as the second argument to `url.parse`. // This tells it to parse the query portion of the URL. const parsedUrl = parse(req.url, true) const { pathname, query } = parsedUrl if (pathname === "/a") { app.render(req, res, "/b", query) } else if (pathname === "/b") { app.render(req, res, "/a", query) } else { handle(req, res, parsedUrl) } }).listen(3000, err => { if (err) throw err console.log("> Ready on http://localhost:3000") }) })
next的 API 如下所示
next(opts: object)
opts 的屬性如下:
dev (boolean) 判斷 Next.js 應(yīng)用是否在開(kāi)發(fā)環(huán)境 - 默認(rèn)false
dir (string) Next 項(xiàng)目路徑 - 默認(rèn)"."
quiet (boolean) 是否隱藏包含服務(wù)端消息在內(nèi)的錯(cuò)誤信息 - 默認(rèn)false
conf (object) 與next.config.js的對(duì)象相同 - 默認(rèn){}
生產(chǎn)環(huán)境的話,可以更改 package.json 里的start腳本為NODE_ENV=production node server.js。
禁止文件路由默認(rèn)情況,Next將會(huì)把/pages下的所有文件匹配路由(如/pages/some-file.js 渲染為 site.com/some-file)
如果你的項(xiàng)目使用自定義路由,那么有可能不同的路由會(huì)得到相同的內(nèi)容,可以優(yōu)化 SEO 和用戶體驗(yàn)。
禁止路由鏈接到/pages下的文件,只需設(shè)置next.config.js文件如下所示:
// next.config.js module.exports = { useFileSystemPublicRoutes: false }
注意useFileSystemPublicRoutes只禁止服務(wù)端的文件路由;但是客戶端的還是禁止不了。
你如果想配置客戶端路由不能跳轉(zhuǎn)文件路由,可以參考Intercepting popstate。
動(dòng)態(tài)前綴有時(shí)你需要設(shè)置動(dòng)態(tài)前綴,可以在請(qǐng)求時(shí)設(shè)置assetPrefix改變前綴。
使用方法如下:
const next = require("next") const micro = require("micro") const dev = process.env.NODE_ENV !== "production" const app = next({ dev }) const handleNextRequests = app.getRequestHandler() app.prepare().then(() => { const server = micro((req, res) => { // Add assetPrefix support based on the hostname if (req.headers.host === "my-app.com") { app.setAssetPrefix("http://cdn.com/myapp") } else { app.setAssetPrefix("") } handleNextRequests(req, res) }) server.listen(port, (err) => { if (err) { throw err } console.log(`> Ready on http://localhost:${port}`) }) })動(dòng)態(tài)導(dǎo)入
Examples
ext.js 支持 JavaScript 的 TC39 提議dynamic import proposal。你可以動(dòng)態(tài)導(dǎo)入 JavaScript 模塊(如 React 組件)。
動(dòng)態(tài)導(dǎo)入相當(dāng)于把代碼分成各個(gè)塊管理。Next.js 服務(wù)端動(dòng)態(tài)導(dǎo)入功能,你可以做很多炫酷事情。
下面介紹一些動(dòng)態(tài)導(dǎo)入方式:
1. 基礎(chǔ)支持 (同樣支持 SSR)import dynamic from "next/dynamic" const DynamicComponent = dynamic(import("../components/hello")) export default () =>2. 自定義加載組件HOME PAGE is here!
import dynamic from "next/dynamic" const DynamicComponentWithCustomLoading = dynamic( import("../components/hello2"), { loading: () =>3. 禁止使用 SSR...
} ) export default () =>HOME PAGE is here!
import dynamic from "next/dynamic" const DynamicComponentWithNoSSR = dynamic(import("../components/hello3"), { ssr: false }) export default () =>4. 同時(shí)加載多個(gè)模塊HOME PAGE is here!
import dynamic from "next/dynamic" const HelloBundle = dynamic({ modules: () => { const components = { Hello1: import("../components/hello1"), Hello2: import("../components/hello2") } return components }, render: (props, { Hello1, Hello2 }) =>自定義}) export default () =>{props.title}
Examples
組件來(lái)初始化頁(yè)面。你可以重寫(xiě)它來(lái)控制頁(yè)面初始化,如下面的事:
當(dāng)頁(yè)面變化時(shí)保持頁(yè)面布局
當(dāng)路由變化時(shí)保持頁(yè)面狀態(tài)
使用componentDidCatch自定義處理錯(cuò)誤
注入額外數(shù)據(jù)到頁(yè)面里 (如 GraphQL 查詢)
重寫(xiě)的話,新建./pages/_app.js文件,重寫(xiě) App 模塊如下所示:
import App, {Container} from "next/app" import React from "react" export default class MyApp extends App { static async getInitialProps ({ Component, router, ctx }) { let pageProps = {} if (Component.getInitialProps) { pageProps = await Component.getInitialProps(ctx) } return {pageProps} } render () { const {Component, pageProps} = this.props return自定義} }
Examples
在服務(wù)端呈現(xiàn)
初始化服務(wù)端時(shí)添加文檔標(biāo)記元素
通常實(shí)現(xiàn)服務(wù)端渲染會(huì)使用一些 css-in-js 庫(kù),如styled-components, glamorous 或 emotion。styled-jsx是 Next.js 自帶默認(rèn)使用的 css-in-js 庫(kù)
Next.js會(huì)自動(dòng)定義文檔標(biāo)記,比如,你從來(lái)不需要添加, 等。如果想自定義文檔標(biāo)記,你可以新建./pages/_document.js,然后擴(kuò)展Document類:
// _document is only rendered on the server side and not on the client side // Event handlers like onClick can"t be added to this file // ./pages/_document.js import Document, { Head, Main, NextScript } from "next/document" export default class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx) return { ...initialProps } } render() { return () } }
鉤子getInitialProps接收到的參數(shù)ctx對(duì)象都是一樣的
回調(diào)函數(shù)renderPage是會(huì)執(zhí)行 React 渲染邏輯的函數(shù)(同步),這種做法有助于此函數(shù)支持一些類似于 Aphrodite 的 renderStatic 等一些服務(wù)器端渲染容器。
注意:外的 React 組件將不會(huì)渲染到瀏覽器中,所以那添加應(yīng)用邏輯代碼。如果你頁(yè)面需要公共組件(菜單或工具欄),可以參照上面說(shuō)的App組件代替。
自定義錯(cuò)誤處理404和500錯(cuò)誤客戶端和服務(wù)端都會(huì)通過(guò)error.js組件處理。如果你想改寫(xiě)它,則新建_error.js在文件夾中:
import React from "react" export default class Error extends React.Component { static getInitialProps({ res, err }) { const statusCode = res ? res.statusCode : err ? err.statusCode : null; return { statusCode } } render() { return (渲染內(nèi)置錯(cuò)誤頁(yè)面{this.props.statusCode ? `An error ${this.props.statusCode} occurred on server` : "An error occurred on client"}
) } }
如果你想渲染內(nèi)置錯(cuò)誤頁(yè)面,你可以使用next/error:
import React from "react" import Error from "next/error" import fetch from "isomorphic-unfetch" export default class Page extends React.Component { static async getInitialProps() { const res = await fetch("https://api.github.com/repos/zeit/next.js") const statusCode = res.statusCode > 200 ? res.statusCode : false const json = await res.json() return { statusCode, stars: json.stargazers_count } } render() { if (this.props.statusCode) { return} return ( Next stars: {this.props.stars}) } }
如果你自定義了個(gè)錯(cuò)誤頁(yè)面,你可以引入自己的錯(cuò)誤頁(yè)面來(lái)代替next/error自定義配置
如果你想自定義 Next.js 的高級(jí)配置,可以在根目錄下新建next.config.js文件(與pages/ 和 package.json一起)
注意:next.config.js是一個(gè) Node.js 模塊,不是一個(gè) JSON 文件,可以用于 Next 啟動(dòng)服務(wù)已經(jīng)構(gòu)建階段,但是不作用于瀏覽器端。
// next.config.js module.exports = { /* config options here */ }
或使用一個(gè)函數(shù):
module.exports = (phase, {defaultConfig}) => { // // https://github.com/zeit/ return { /* config options here */ } }
phase是配置文件被加載時(shí)的當(dāng)前內(nèi)容。你可看到所有的 phases 常量:constants
這些常量可以通過(guò)next/constants引入:
const {PHASE_DEVELOPMENT_SERVER} = require("next/constants") module.exports = (phase, {defaultConfig}) => { if(phase === PHASE_DEVELOPMENT_SERVER) { return { /* development only config options here */ } } return { /* config options for all phases except development here */ } }設(shè)置自定義構(gòu)建目錄
你可以自定義一個(gè)構(gòu)建目錄,如新建build文件夾來(lái)代替.next 文件夾成為構(gòu)建目錄。如果沒(méi)有配置構(gòu)建目錄,構(gòu)建時(shí)將會(huì)自動(dòng)新建.next文件夾
// next.config.js module.exports = { distDir: "build" }禁止 etag 生成
你可以禁止 etag 生成根據(jù)你的緩存策略。如果沒(méi)有配置,Next 將會(huì)生成 etags 到每個(gè)頁(yè)面中。
// next.config.js module.exports = { generateEtags: false }配置 onDemandEntries
Next 暴露一些選項(xiàng)來(lái)給你控制服務(wù)器部署以及緩存頁(yè)面:
module.exports = { onDemandEntries: { // period (in ms) where the server will keep pages in the buffer maxInactiveAge: 25 * 1000, // number of pages that should be kept simultaneously without being disposed pagesBufferLength: 2, } }
這個(gè)只是在開(kāi)發(fā)環(huán)境才有的功能。如果你在生成環(huán)境中想緩存 SSR 頁(yè)面,請(qǐng)查看SSR-caching
配置頁(yè)面后綴名解析擴(kuò)展如 typescript 模塊@zeit/next-typescript,需要支持解析后綴名為.ts的文件。pageExtensions 允許你擴(kuò)展后綴名來(lái)解析各種 pages 下的文件。
// next.config.js module.exports = { pageExtensions: ["jsx", "js"] }配置構(gòu)建 ID
Next.js 使用構(gòu)建時(shí)生成的常量來(lái)標(biāo)識(shí)你的應(yīng)用服務(wù)是哪個(gè)版本。在每臺(tái)服務(wù)器上運(yùn)行構(gòu)建命令時(shí),可能會(huì)導(dǎo)致多服務(wù)器部署出現(xiàn)問(wèn)題。為了保持同一個(gè)構(gòu)建 ID,可以配置generateBuildId函數(shù):
// next.config.js module.exports = { generateBuildId: async () => { // For example get the latest git commit hash here return "my-build-id" } }自定義 webpack 配置
Examples
可以使用些一些常見(jiàn)的模塊
@zeit/next-css
@zeit/next-sass
@zeit/next-less
@zeit/next-preact
@zeit/next-typescript
注意: webpack方法將被執(zhí)行兩次,一次在服務(wù)端一次在客戶端。你可以用isServer屬性區(qū)分客戶端和服務(wù)端來(lái)配置
多配置可以組合在一起,如:
const withTypescript = require("@zeit/next-typescript") const withSass = require("@zeit/next-sass") module.exports = withTypescript(withSass({ webpack(config, options) { // Further custom configuration here return config } }))
為了擴(kuò)展webpack使用,可以在next.config.js定義函數(shù)。
// next.config.js is not transformed by Babel. So you can only use javascript features supported by your version of Node.js. module.exports = { webpack: (config, { buildId, dev, isServer, defaultLoaders }) => { // Perform customizations to webpack config // Important: return the modified config return config }, webpackDevMiddleware: config => { // Perform customizations to webpack dev middleware config // Important: return the modified config return config } }
webpack的第二個(gè)參數(shù)是個(gè)對(duì)象,你可以自定義配置它,對(duì)象屬性如下所示:
buildId - 字符串類型,構(gòu)建的唯一標(biāo)示
dev - Boolean型,判斷你是否在開(kāi)發(fā)環(huán)境下
isServer - Boolean 型,為true使用在服務(wù)端, 為false使用在客戶端.
defaultLoaders - 對(duì)象型 ,內(nèi)部加載器, 你可以如下配置
babel - 對(duì)象型,配置babel-loader.
hotSelfAccept - 對(duì)象型, hot-self-accept-loader配置選項(xiàng).這個(gè)加載器只能用于高階案例。如 @zeit/next-typescript添加頂層 typescript 頁(yè)面。
defaultLoaders.babel使用案例如下:
// Example next.config.js for adding a loader that depends on babel-loader // This source was taken from the @zeit/next-mdx plugin source: // https://github.com/zeit/next-plugins/blob/master/packages/next-mdx module.exports = { webpack: (config, {}) => { config.module.rules.push({ test: /.mdx/, use: [ options.defaultLoaders.babel, { loader: "@mdx-js/loader", options: pluginOptions.options } ] }) return config } }自定義 babel 配置
Examples
為了擴(kuò)展方便我們使用babel,可以在應(yīng)用根目錄新建.babelrc文件,該文件可配置。
如果有該文件,我們將會(huì)考慮數(shù)據(jù)源,因此也需要定義 next 項(xiàng)目需要的東西,也就是 next/babel預(yù)設(shè)。
這種設(shè)計(jì)方案將會(huì)使你不詫異于我們可以定制 babel 配置。
下面是.babelrc文件案例:
{ "presets": ["next/babel"], "plugins": [] }
next/babel預(yù)設(shè)可處理各種 React 應(yīng)用所需要的情況。包括:
preset-env
preset-react
plugin-proposal-class-properties
plugin-proposal-object-rest-spread
plugin-transform-runtime
styled-jsx
presets / plugins 不允許添加到.babelrc中,然而你可以配置next/babel預(yù)設(shè):
{ "presets": [ ["next/babel", { "preset-env": {}, "transform-runtime": {}, "styled-jsx": {}, "class-properties": {} }] ], "plugins": [] }
"preset-env"模塊選項(xiàng)應(yīng)該保持為 false,否則 webpack 代碼分割將被禁用。
暴露配置到服務(wù)端和客戶端next/config模塊使你應(yīng)用運(yùn)行時(shí)可以讀取些存儲(chǔ)在next.config.js的配置項(xiàng)。serverRuntimeConfig屬性只在服務(wù)器端可用,publicRuntimeConfig屬性在服務(wù)端和客戶端可用。
// next.config.js module.exports = { serverRuntimeConfig: { // Will only be available on the server side mySecret: "secret" }, publicRuntimeConfig: { // Will be available on both server and client staticFolder: "/static", mySecret: process.env.MY_SECRET // Pass through env variables } }
// pages/index.js import getConfig from "next/config" // Only holds serverRuntimeConfig and publicRuntimeConfig from next.config.js nothing else. const {serverRuntimeConfig, publicRuntimeConfig} = getConfig() console.log(serverRuntimeConfig.mySecret) // Will only be available on the server side console.log(publicRuntimeConfig.staticFolder) // Will be available on both server and client export default () =>啟動(dòng)服務(wù)選擇 hostname
啟動(dòng)開(kāi)發(fā)環(huán)境服務(wù)可以設(shè)置不同的 hostname,你可以在啟動(dòng)命令后面加上--hostname 主機(jī)名 或 -H 主機(jī)名。它將會(huì)啟動(dòng)一個(gè) TCP 服務(wù)器來(lái)監(jiān)聽(tīng)連接所提供的主機(jī)。
CDN 支持前綴建立一個(gè) CDN,你能配置assetPrefix選項(xiàng),去配置你的 CDN 源。
const isProd = process.env.NODE_ENV === "production" module.exports = { // You may only need to add assetPrefix in the production. assetPrefix: isProd ? "https://cdn.mydomain.com" : "" }
注意:Next.js 運(yùn)行時(shí)將會(huì)自動(dòng)添加前綴,但是對(duì)于/static是沒(méi)有效果的,如果你想這些靜態(tài)資源也能使用 CDN,你需要自己添加前綴。有一個(gè)方法可以判斷你的環(huán)境來(lái)加前綴,如 in this example。
項(xiàng)目部署部署中,你可以先構(gòu)建打包生成環(huán)境代碼,再啟動(dòng)服務(wù)。因此,構(gòu)建和啟動(dòng)分為下面兩條命令:
next build next start
例如,使用now去部署package.json配置文件如下:
{ "name": "my-app", "dependencies": { "next": "latest" }, "scripts": { "dev": "next", "build": "next build", "start": "next start" } }
然后就可以直接運(yùn)行now了。
Next.js 也有其他托管解決方案。請(qǐng)查考 wiki 章節(jié)"Deployment" 。
注意:NODE_ENV可以通過(guò)next命令配置,如果沒(méi)有配置,會(huì)最大渲染,如果你使用編程式寫(xiě)法的話programmatically,你需要手動(dòng)設(shè)置NODE_ENV=production。
注意:推薦將.next或自定義打包文件夾custom dist folder放入.gitignore 或 .npmignore中。否則,使用files 或 now.files
添加部署白名單,并排除.next或自定義打包文件夾。
Next.js 支持 IE11 和所有的現(xiàn)代瀏覽器使用了@babel/preset-env。為了支持 IE11,Next.js 需要全局添加Promise的 polyfill。有時(shí)你的代碼或引入的其他 NPM 包的部分功能現(xiàn)代瀏覽器不支持,則需要用 polyfills 去實(shí)現(xiàn)。
ployflls 實(shí)現(xiàn)案例為polyfills。
導(dǎo)出靜態(tài)頁(yè)面
Examples
next export可以輸出一個(gè) Next.js 應(yīng)用作為靜態(tài)資源應(yīng)用而不依靠 Node.js 服務(wù)。
這個(gè)輸出的應(yīng)用幾乎支持 Next.js 的所有功能,包括動(dòng)態(tài)路由,預(yù)獲取,預(yù)加載以及動(dòng)態(tài)導(dǎo)入。
next export將把所有有可能渲染出的 HTML 都生成。這是基于映射對(duì)象的pathname關(guān)鍵字關(guān)聯(lián)到頁(yè)面對(duì)象。這個(gè)映射叫做exportPathMap。
頁(yè)面對(duì)象有2個(gè)屬性:
page - 字符串類型,頁(yè)面生成目錄
query - 對(duì)象類型,當(dāng)預(yù)渲染時(shí),query對(duì)象將會(huì)傳入頁(yè)面的生命周期getInitialProps中。默認(rèn)為{}。
使用通常開(kāi)發(fā) Next.js 應(yīng)用你將會(huì)運(yùn)行:
next build next export
next export命令默認(rèn)不需要任何配置,將會(huì)自動(dòng)生成默認(rèn)exportPathMap生成pages目錄下的路由你頁(yè)面。
如果你想動(dòng)態(tài)配置路由,可以在next.config.js中添加異步函數(shù)exportPathMap。
// next.config.js module.exports = { exportPathMap: async function (defaultPathMap) { return { "/": { page: "/" }, "/about": { page: "/about" }, "/readme.md": { page: "/readme" }, "/p/hello-nextjs": { page: "/post", query: { title: "hello-nextjs" } }, "/p/learn-nextjs": { page: "/post", query: { title: "learn-nextjs" } }, "/p/deploy-nextjs": { page: "/post", query: { title: "deploy-nextjs" } } } } }
注意:如果 path 的結(jié)尾是目錄名,則將導(dǎo)出/dir-name/index.html,但是如果結(jié)尾有擴(kuò)展名,將會(huì)導(dǎo)出對(duì)應(yīng)的文件,如上/readme.md。如果你使用.html以外的擴(kuò)展名解析文件時(shí),你需要設(shè)置 header 的Content-Type頭為"text/html".
輸入下面命令:
next build next export
你可以在package.json添加一個(gè) NPM 腳本,如下所示:
{ "scripts": { "build": "next build", "export": "npm run build && next export" } }
接著只用執(zhí)行一次下面命令:
npm run export
然后你將會(huì)有一個(gè)靜態(tài)頁(yè)面應(yīng)用在out 目錄下。
你也可以自定義輸出目錄??梢赃\(yùn)行next export -h命令查看幫助。
現(xiàn)在你可以部署out目錄到任意靜態(tài)資源服務(wù)器上。注意如果部署 GitHub Pages 需要加個(gè)額外的步驟,文檔如下
例如,訪問(wèn)out目錄并用下面命令部署應(yīng)用ZEIT Now.
now限制
使用next export,我們創(chuàng)建了個(gè)靜態(tài) HTML 應(yīng)用。構(gòu)建時(shí)將會(huì)運(yùn)行頁(yè)面里生命周期getInitialProps 函數(shù)。
req和res只在服務(wù)端可用,不能通過(guò)getInitialProps。
所以你不能預(yù)構(gòu)建 HTML 文件時(shí)動(dòng)態(tài)渲染 HTML 頁(yè)面。如果你想動(dòng)態(tài)渲染可以運(yùn)行next start或其他自定義服務(wù)端 API。多 zone
Examples
一個(gè) zone 時(shí)一個(gè)多帶帶的 Next.js 應(yīng)用。如果你有很多 zone,你可以合并成一個(gè)應(yīng)用。
例如,你如下有兩個(gè) zone:
https://docs.my-app.com 服務(wù)于路由 /docs/**
https://ui.my-app.com 服務(wù)于所有頁(yè)面
有多 zone 應(yīng)用技術(shù)支持,你可以將幾個(gè)應(yīng)用合并到一個(gè),而且可以自定義 URL 路徑,使你能同時(shí)多帶帶開(kāi)發(fā)各個(gè)應(yīng)用。
與 microservices 觀念類似, 只是應(yīng)用于前端應(yīng)用.怎么定義一個(gè) zone
zone 沒(méi)有多帶帶的 API 文檔。你需要做下面事即可:
確保你的應(yīng)用里只有需要的頁(yè)面 (例如, https://ui.my-app.com 不包含 /docs/**)
確保你的應(yīng)用有個(gè)前綴assetPrefix。(你也可以定義動(dòng)態(tài)前綴dynamically)
怎么合并他們你能使用 HTTP 代理合并 zone
你能使用代理micro proxy來(lái)作為你的本地代理服務(wù)。它允許你定義路由規(guī)則如下:
{ "rules": [ {"pathname": "/docs**", "method":["GET", "POST", "OPTIONS"], "dest": "https://docs.my-app.com"}, {"pathname": "/**", "dest": "https://ui.my-app.com"} ] }
生產(chǎn)環(huán)境部署,如果你使用了ZEIT now,可以它的使用path alias 功能。否則,你可以設(shè)置你已使用的代理服務(wù)編寫(xiě)上面規(guī)則來(lái)路由 HTML 頁(yè)面
技巧設(shè)置301重定向
只處理服務(wù)器端模塊
構(gòu)建項(xiàng)目 React-Material-UI-Next-Express-Mongoose-Mongodb
構(gòu)建一個(gè) SaaS 產(chǎn)品 React-Material-UI-Next-MobX-Express-Mongoose-MongoDB-TypeScript
問(wèn)答它的開(kāi)發(fā)體驗(yàn)和終端用戶體驗(yàn)都很好,所以我們決定開(kāi)源出來(lái)給大家共享。
這個(gè)產(chǎn)品可以用于生產(chǎn)環(huán)境嗎?
https://zeit.co 都是一直用 Next.js 寫(xiě)的。
一個(gè)最簡(jiǎn)單 Next 應(yīng)該用 gzip 壓縮后大約65kb
體積多大?
客戶端大小根據(jù)應(yīng)用需求不一樣大小也不一樣。
是,因?yàn)樗屇愕?SSR 開(kāi)發(fā)更簡(jiǎn)單。 不是,因?yàn)樗?guī)定了一定的目錄結(jié)構(gòu),使我們能做以下更高級(jí)的事: 服務(wù)端渲染 自動(dòng)代碼分割 此外,Next.js 還提供兩個(gè)內(nèi)置特性: 路由與懶加載組件: (通過(guò)引入 next/link) 修改的組件: (通過(guò)引入 next/head) 如果你想寫(xiě)共用組件,可以嵌入 Next.js 應(yīng)用和 React 應(yīng)用中,推薦使用create-react-app。你可以更改import保持代碼清晰。
這個(gè)像 create-react-app?
是或不是.
怎么解決 CSS 嵌入 JS 問(wèn)題?
Next.js 自帶styled-jsx庫(kù)支持 CSS 嵌入 JS。而且你可以選擇其他嵌入方法到你的項(xiàng)目中,可參考文檔as mentioned before。
可以參照這些 以及 這些
哪些語(yǔ)法會(huì)被轉(zhuǎn)換?怎么轉(zhuǎn)換它們?
我們遵循 V8 引擎的,如今 V8 引擎廣泛支持 ES6 語(yǔ)法以及async和await語(yǔ)法,所以我們支持轉(zhuǎn)換它們。但是 V8 引擎不支持修飾器語(yǔ)法,所以我們也不支持轉(zhuǎn)換這語(yǔ)法。
路由不需要被提前知道 路由總是被懶加載 頂層組件可以定義生命周期getInitialProps來(lái)阻止路由加載(當(dāng)服務(wù)端渲染或路由懶加載時(shí)) 因此,我們可以介紹一個(gè)非常簡(jiǎn)單的路由方法,它由下面兩部分組成: 每個(gè)頂層組件都將會(huì)收到一個(gè)url對(duì)象,來(lái)檢查 url 或修改歷史記錄
組件用于包裝如()標(biāo)簽的元素容器,來(lái)執(zhí)行客戶端轉(zhuǎn)換。 我們使用了些有趣的場(chǎng)景來(lái)測(cè)試路由的靈活性,例如,可查看nextgram。
為什么使用新路由?
Next.js 的特別之處如下所示:
在客戶端,我們組件有個(gè)屬性as,可以裝飾改變獲取到的 URL。我怎么定義自定義路由?
我們通過(guò)請(qǐng)求處理來(lái)添加任意 URL 與任意組件之前的映射關(guān)系。
怎么獲取數(shù)據(jù)?
這由你決定。getInitialProps是一個(gè)異步函數(shù)async(也就是函數(shù)將會(huì)返回個(gè)Promise)。你可以在任意位置獲取數(shù)據(jù)。
我可以使用 GraphQL 嗎?
是的! 這里有個(gè)例子Apollo.
我可以使用 Redux 嗎?
是的! 這里有個(gè)例子
我可以在 Next 應(yīng)用中使用我喜歡的 Javascript 庫(kù)或工具包嗎?
從我們第一次發(fā)版就已經(jīng)提供很多例子,你可以查看這些例子。
PHP 的易用性也是個(gè)很好的靈感來(lái)源,我們覺(jué)得 Next.js 可以替代很多需要用 PHP 輸出 HTML 的場(chǎng)景。 與 PHP 不同的是,我們得利于 ES6 模塊系統(tǒng),每個(gè)文件會(huì)輸出一個(gè)組件或方法,以便可以輕松的導(dǎo)入用于懶加載和測(cè)試 我們研究 React 的服務(wù)器渲染時(shí)并沒(méi)有花費(fèi)很大的步驟,因?yàn)槲覀儼l(fā)現(xiàn)一個(gè)類似于 Next.js 的產(chǎn)品,React 作者 Jordan Walke 寫(xiě)的react-page (現(xiàn)在已經(jīng)廢棄)什么啟發(fā)我們做這個(gè)?
我們實(shí)現(xiàn)的大部分目標(biāo)都是通過(guò) Guillermo Rauch 的Web 應(yīng)用的7原則來(lái)啟發(fā)出的。
可查看 contributing.md
作者Arunoda Susiripala (@arunoda) – ZEIT
Tim Neutkens (@timneutkens) – ZEIT
Naoyuki Kanezawa (@nkzawa) – ZEIT
Tony Kovanen (@tonykovanen) – ZEIT
Guillermo Rauch (@rauchg) – ZEIT
Dan Zajdband (@impronunciable) – Knight-Mozilla / Coral Project
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97685.html
摘要:踩坑幾乎一整年沒(méi)咋寫(xiě)文章,主要是懶,加上工作也挺忙。遇到一些坑,也有一些收獲這里記錄一下。個(gè)人習(xí)慣使用啟動(dòng)服務(wù)??偨Y(jié)說(shuō)了上面那么多,其實(shí)官方文檔里都有相關(guān)例子,就當(dāng)我的個(gè)人踩坑記錄吧。 Next.js踩坑 幾乎一整年沒(méi)咋寫(xiě)文章,主要是懶,加上工作也挺忙。但是想趁著年底發(fā)一篇,希望明年更勤奮一點(diǎn)。其實(shí)不是沒(méi)東西寫(xiě),就是想深入一個(gè)東西還是很困難的,要查各種資料,最終還是懶就是了。 next...
摘要:官方也有一個(gè)的工具,但是只能簡(jiǎn)單的安裝基礎(chǔ)的依賴,或者通過(guò)他們提供的某個(gè)例子來(lái)構(gòu)建自己的項(xiàng)目。由于目前還在開(kāi)發(fā)階段只支持上面這些的配置也是平常我用的比較多的配置。 因?yàn)楣镜臉I(yè)務(wù)需求現(xiàn)在開(kāi)發(fā)都用nextjs來(lái)實(shí)現(xiàn)React的服務(wù)端渲染,為了之后開(kāi)發(fā)方便自己寫(xiě)了個(gè)腳手架工具。 官方也有一個(gè)create-next-app的工具,但是只能簡(jiǎn)單的安裝基礎(chǔ)的依賴,或者通過(guò)他們提供的某個(gè)例子來(lái)構(gòu)建...
摘要:樣式在中寫(xiě)樣式,一般可以歸為類,一類是基于文件的傳統(tǒng)方式包括,等,另一類則是。我們回到我們的代碼中,更改,代碼如下在標(biāo)簽中,我們寫(xiě)我們的,必須包含在中,否則會(huì)報(bào)錯(cuò)。至此,的基礎(chǔ)概念已經(jīng)介紹完了,更高級(jí)的用法,可以參考官方的例子。 本篇教程基于上一篇的基礎(chǔ),主要講解服務(wù)端渲染,樣式以及部署相關(guān)的一些知識(shí),若你沒(méi)有看過(guò)上一篇的內(nèi)容,或者你看過(guò)又忘了,建議重新去看一遍。 順便說(shuō)一句,Next...
摘要:是一個(gè)基于實(shí)現(xiàn)的服務(wù)端渲染框架,地址為。本文先從簡(jiǎn)單地基礎(chǔ)概念開(kāi)始,一步一步帶大家認(rèn)識(shí)。本篇教程到此結(jié)束,后面會(huì)跟大家介紹的服務(wù)端渲染及以及部署相關(guān)的一下概念及示例代碼。 Next.js是一個(gè)基于React實(shí)現(xiàn)的服務(wù)端渲染框架,github地址為next.js。 使用Next.js實(shí)現(xiàn)服務(wù)端渲染是一件非常簡(jiǎn)單的事,在這里,你完全可以不用自己去寫(xiě)webpack等配置,Next.js全都幫...
摘要:前言實(shí)習(xí)了大半年,又臨近畢業(yè),一直想做一個(gè)屬于自己的博客。于是就用和開(kāi)發(fā)了一個(gè)服務(wù)端渲染的博客系統(tǒng)。其中后端管理使用開(kāi)發(fā)前端頁(yè)面使用服務(wù)端渲染框架接口服務(wù)使用使用當(dāng)接口發(fā)生時(shí)向我發(fā)送郵件通知項(xiàng)目地址是點(diǎn)我訪問(wèn)項(xiàng)目地址,不要臉地求。 前言 實(shí)習(xí)了大半年,又臨近畢業(yè),一直想做一個(gè)屬于自己的博客。于是就用Vue、React和Koa開(kāi)發(fā)了一個(gè)服務(wù)端渲染的博客系統(tǒng)。其中: 后端管理使用Vue開(kāi)...
閱讀 3528·2021-11-18 10:02
閱讀 963·2021-09-04 16:48
閱讀 2047·2019-08-30 15:55
閱讀 3553·2019-08-30 15:52
閱讀 1825·2019-08-30 14:08
閱讀 3568·2019-08-30 13:19
閱讀 1155·2019-08-27 10:53
閱讀 3134·2019-08-26 12:11