introduction
默认来说,Next.js 通过next start启动自己的服务器,如果你有存在的后端服务,你仍然通过Next.js 使用它(但这并不是自定义服务器), 一个自定义的Next.js 服务器允许你百分百编程式启动为了使用自定义的服务器模式 .. 大多数这个时候,你完全不需要,除非你需要完全自定义 …
注意: 一个自定义服务器不能够在Vercel上进行部署 …
在决定使用自定义服务器之前,请保持它应该仅仅能够被用于(Next.js 集成的路由已经不能满足应用需求),一个自定义服务器将丢失掉重要的性能优化,例如无服务器函数以及 自动静态优化 ….
让我们来查看一下一个自定义服务器的示例:
// server.jsconst { 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 } = parsedUrlif (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 errconsole.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,默认为falsedir:StringNext.js 项目的位置(默认当前项目)quiet:Boolean是否隐藏错误信息包括服务器信息 默认为falseconf: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)
