自訂伺服器

範例

預設情況下,Next.js 包含自己的伺服器,可透過 next start 啟動。如果您已有現有的後端服務,仍然可以將其與 Next.js 一起使用(這不屬於自訂伺服器)。自訂 Next.js 伺服器允許您以 100% 程式化的方式啟動伺服器,以便使用自訂的伺服器模式。大多數情況下,您不需要這樣做——但此功能仍提供給需要完全自訂的使用者。

須知事項:

  • 在決定使用自訂伺服器之前,請注意僅應在 Next.js 內建路由無法滿足您的應用需求時才使用此功能。自訂伺服器會移除重要的效能優化,例如 無伺服器函式 (serverless functions)自動靜態優化 (Automatic Static Optimization)
  • 自訂伺服器無法部署在 Vercel 上。

請參考以下自訂伺服器的範例:

server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// 使用中介軟體時,必須提供 `hostname` 和 `port`
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  createServer(async (req, res) => {
    try {
      // 請確保將 `true` 作為第二個參數傳遞給 `url.parse`。
      // 這會告訴它解析 URL 的查詢部分。
      const parsedUrl = parse(req.url, true)
      const { pathname, query } = parsedUrl

      if (pathname === '/a') {
        await app.render(req, res, '/a', query)
      } else if (pathname === '/b') {
        await app.render(req, res, '/b', query)
      } else {
        await handle(req, res, parsedUrl)
      }
    } catch (err) {
      console.error('處理請求時發生錯誤', req.url, err)
      res.statusCode = 500
      res.end('內部伺服器錯誤')
    }
  })
    .once('error', (err) => {
      console.error(err)
      process.exit(1)
    })
    .listen(port, () => {
      console.log(`> 準備就緒,請訪問 http://${hostname}:${port}`)
    })
})

server.js 不會經過 babel 或 webpack 處理。請確保此檔案所需的語法和來源與您當前運行的 node 版本相容。

要運行自訂伺服器,您需要更新 package.json 中的 scripts,如下所示:

package.json
{
  "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 導入是一個函式,接收包含以下選項的物件:

選項類型描述
confObjectnext.config.js 中使用的物件相同。預設為 {}
customServerBoolean(選填)當伺服器由 Next.js 創建時設為 false
devBoolean(選填)是否以開發模式啟動 Next.js。預設為 false
dirString(選填)Next.js 專案的位置。預設為 '.'
quietBoolean(選填)隱藏包含伺服器資訊的錯誤訊息。預設為 false
hostnameString(選填)伺服器運行的主機名稱
portNumber(選填)伺服器運行的埠號
httpServernode:http#Server(選填)Next.js 運行的 HTTP 伺服器

返回的 app 可用於根據需求讓 Next.js 處理請求。

停用檔案系統路由

預設情況下,Next 會將 pages 資料夾中的每個檔案以與檔案名稱相符的路徑提供服務。如果您的專案使用自訂伺服器,這種行為可能會導致相同的內容從多個路徑提供服務,這可能會對 SEO 和使用者體驗 (UX) 造成問題。

要停用此行為並防止基於 pages 中的檔案進行路由,請打開 next.config.js 並停用 useFileSystemPublicRoutes 設定:

next.config.js
module.exports = {
  useFileSystemPublicRoutes: false,
}

請注意,useFileSystemPublicRoutes 僅停用 SSR 的檔案名稱路由;客戶端路由仍可能訪問這些路徑。使用此選項時,您應以程式化的方式防止導航到不希望的路由。

您可能還希望配置客戶端路由以防止客戶端重新導向到檔案名稱路由;有關此內容,請參閱 router.beforePopState

On this page