next 服務(wù)端渲染
實(shí)際上,next 一直都是執(zhí)行的服務(wù)端渲染.npm start
執(zhí)行的是 next 自帶的服務(wù)器來(lái)運(yùn)行你的應(yīng)用.next 是支持自定義服務(wù)器的,同時(shí)能夠支持現(xiàn)有的路由和模式,你可以在此基礎(chǔ)上添加一些自己的需求.
新建/server.js
const express = require("express");
const next = require("next");
const dev = process.env.NODE_ENV !== "production"; //判斷是否開(kāi)發(fā)環(huán)境
const app = next({ dev }); //創(chuàng)建一個(gè)next的app
const handle = app.getRequestHandler(); //請(qǐng)求處理
app
.prepare()
.then(() => {
const server = express();
//用來(lái)進(jìn)行簡(jiǎn)化路徑匹配
server.get("/b/:currentBookId", (req, res) => {
const actualPage = "/book/[currentBookId]";
const queryParams = { currentBookId: req.params.currentBookId };
app.render(req, res, actualPage, queryParams);
});
server.get("*", (req, res) => {
return handle(req, res);
});
server.listen(6776, err => {
if (err) throw err;
console.log("> Ready on http://localhost:6776");
});
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
其中 app 有 next(opts: object)創(chuàng)建而來(lái)
- dev(bool)是否在開(kāi)發(fā)模式下啟動(dòng) Next.js-默認(rèn) false
- dir(string)項(xiàng)目所在的位置-默認(rèn)'.'
- quiet(bool)隱藏包含服務(wù)器信息的錯(cuò)誤消息-默認(rèn) false
- conf(object)與您要使用的對(duì)象相同 next.config.js-默認(rèn){}
同時(shí)修改 package.json 中的配置
"server:dev": "node server.js",
"server:start": "NODE_ENV=production node server.js",
解決使用路由隱藏 as 會(huì) 404 的問(wèn)題
例如
<Link href={`/book/${item.id}`} as={`/b/${item.id}`}>
然后在npm run dev
的情況下,我們使用 next 默認(rèn)的服務(wù)器.頁(yè)面在使用 as 的時(shí)候起了一個(gè)縮寫(xiě)路徑名稱,這種情況在第一次進(jìn)入是正常匹配的,但是刷新就會(huì) 404,原因在于服務(wù)器目前并不清楚 b 代表的是什么路徑.
而在 server.js 中就添加了關(guān)于 b 的縮寫(xiě)匹配
//用來(lái)進(jìn)行簡(jiǎn)化路徑匹配
server.get("/b/:currentBookId", (req, res) => {
const actualPage = "/book/[currentBookId]";
const queryParams = { currentBookId: req.params.currentBookId };
app.render(req, res, actualPage, queryParams);
});
此時(shí)我們npm run server:dev
開(kāi)啟自定義服務(wù)器,打開(kāi)頁(yè)面進(jìn)入縮寫(xiě)路徑,我們刷新發(fā)現(xiàn)頁(yè)面會(huì)保留.
之后
npm run dev
命令可以拋棄了
多路徑頁(yè)面
next 默認(rèn)會(huì)將 pages 下的 js 文件創(chuàng)建出對(duì)應(yīng)的路徑.我們起了路由別名,并且通過(guò)自定義路由讓路由的別名生效.但是我們?cè)俅屋斎?book/[currentBookId],發(fā)現(xiàn)依舊可以匹配到同樣的頁(yè)面,造成一個(gè)頁(yè)面擁有的 2 個(gè)及以上的路徑.這可能會(huì)導(dǎo)致 SEO 和 UX 問(wèn)題
我們通過(guò)設(shè)置 useFileSystemPublicRoutes 來(lái)禁用默認(rèn)路由
// next.config.js
module.exports = {
useFileSystemPublicRoutes: false,
}
重啟打開(kāi)網(wǎng)站,book/[currentBookId]就會(huì)直接 404 了.
useFileSystemPublicRoutes 禁用來(lái)自 SSR 的文件名路由.客戶端路由仍然可以訪問(wèn)這些路徑,需要攔截 popstate來(lái)配置客戶端也禁用.
動(dòng)態(tài) assetPrefix
有時(shí)候我們需要?jiǎng)討B(tài)路由,比如根據(jù)基于請(qǐng)求更改 assetPrefix,這時(shí)候我們需要使用 app.setAssetPrefix
server.get("*", (req, res) => {
if (req.headers.host === "my-app.com") {
app.setAssetPrefix("http://cdn.com/myapp");
} else {
app.setAssetPrefix("");
}
return handle(req, res);
});
禁用 X-Powered-By
Next.js 將添加 x-powered-by 到請(qǐng)求標(biāo)頭中。這個(gè)是由語(yǔ)言解析器或者應(yīng)用程序框架輸出的寺酪。這個(gè)值的意義用于告知網(wǎng)站是用何種語(yǔ)言或框架編寫(xiě)的酱酬。
直接禁用它
// next.config.js
module.exports = {
poweredByHeader: false,
}