introduction
默认来说,Next.js 通过next start
启动自己的服务器,如果你有存在的后端服务,你仍然通过Next.js 使用它(但这并不是自定义服务器), 一个自定义的Next.js 服务器允许你百分百编程式启动为了使用自定义的服务器模式 .. 大多数这个时候,你完全不需要,除非你需要完全自定义 …
注意: 一个自定义服务器不能够在Vercel上进行部署 …
在决定使用自定义服务器之前,请保持它应该仅仅能够被用于(Next.js 集成的路由已经不能满足应用需求),一个自定义服务器将丢失掉重要的性能优化,例如无服务器函数以及 自动静态优化 ….
让我们来查看一下一个自定义服务器的示例:
// server.js
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, '/a', query)
} else if (pathname === '/b') {
app.render(req, res, '/b', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
server.js
并没有通过babel 或者 webpack,确保语法以及来源是兼容于当前运行的node版本 …
为了运行自定义服务器(你需要更新 package.json
的scripts
部分)
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
自定义服务器使用以下导入关联Next.js 应用的服务器 ..
const next = require('next')
const app = next({})
上面的next
导入是一个函数(能够接收以下选择的对象)
dev
:Boolean
是否在开发模式中启动Next.js,默认为false
dir
:String
Next.js 项目的位置(默认当前项目)quiet
:Boolean
是否隐藏错误信息包括服务器信息 默认为false
conf
:object
这个对象能够使用在next.config.js中,默认为false …- 返回的
app
能够被用来让Next.js 处理请求 …
禁用文件系统路由
默认来说,Next
将为pages
中每一个文件根据路径名 匹配文件名提供路由,如果你的项目使用了自定义服务器,这些行为可能导致从多个路径下提供相同内容,这可能导致SEO 以及UX 的问题 …
为了禁用这个行为并且阻止基于pages
的文件路由,修改next.config.js
并禁用useFileSystemPublicRoutes
配置 …
module.exports = {
useFileSystemPublicRoutes: false
}
注意到这个属性禁用了来自SSR 的文件名路由,客户端路由仍然能够访问这些路径,当使用这个选项的时候,应该保证编程式导航到不需要的路由 ..
你也许希望配置客户端路由去禁用客户端重定向到文件名路由(对此参考router.beforePopState
https://www.nextjs.cn/docs/api-reference/next/router#routerbeforepopstate)