Custom Server
기본적으로 Next.js는 next start
와 함께 자체 서버를 포함합니다. 기존 백엔드가 있는 경우에도 Next.js와 함께 사용할 수 있습니다(이는 커스텀 서버가 아닙니다). 커스텀 Next.js 서버는 커스텀 서버 패턴을 사용하기 위해 100% 프로그래매틱하게 서버를 시작할 수 있게 합니다. 대부분의 경우, 이것이 필요하지 않겠지만 완전한 커스터마이징을 위해 사용할 수 있습니다.
알아두면 좋은 점:
- 커스텀 서버를 사용하기로 결정하기 전에, Next.js의 통합 라우터가 애플리케이션 요구사항을 충족하지 못할 때만 사용해야 한다는 점을 유의하세요. 커스텀 서버는 서버리스 함수와 자동 정적 최적화 같은 중요한 성능 최적화를 제거합니다.
- 커스텀 서버는 Vercel (opens in a new tab)에 배포할 수 없습니다.
- Standalone output 모드는 커스텀 서버 파일을 추적하지 않으며, 이 모드는 별도의 최소한의
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 {
// `url.parse`에 두 번째 인수로 `true`를 전달해야 합니다.
// 이는 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('internal server error')
}
})
.once('error', (err) => {
console.error(err)
process.exit(1)
})
.listen(port, () => {
console.log(`> Ready on http://${hostname}:${port}`)
})
})
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 애플리케이션과 서버를 연결하기 위해 다음 import를 사용합니다:
const next = require('next')
const app = next({})
위의 next
import는 다음 옵션을 포함하는 객체를 받는 함수입니다:
Option | Type | Description |
---|---|---|
conf | Object | next.config.js에서 사용하는 것과 동일한 객체입니다. 기본값은 {} 입니다. |
customServer | Boolean | (Optional) 서버가 Next.js에 의해 생성되었을 때 false로 설정합니다. |
dev | Boolean | (Optional) Next.js를 개발 모드에서 실행할지 여부를 설정합니다. 기본값은 false 입니다. |
dir | String | (Optional) Next.js 프로젝트의 위치입니다. 기본값은 '.' 입니다. |
quiet | Boolean | (Optional) 서버 정보가 포함된 오류 메시지를 숨깁니다. 기본값은 false 입니다. |
hostname | String | (Optional) 서버가 실행되는 호스트 이름입니다. |
port | Number | (Optional) 서버가 실행되는 포트입니다. |
httpServer | node:http#Server | (Optional) Next.js가 실행되는 HTTP 서버입니다. |
반환된 app
은 Next.js가 요청을 처리할 수 있게 사용하는 데 사용할 수 있습니다.
Disabling file-system routing
기본적으로 Next
는 pages
폴더에 있는 각 파일을 파일명에 해당하는 경로명 아래에서 제공합니다. 프로젝트가 커스텀 서버를 사용하는 경우, 이 동작은 동일한 콘텐츠가 여러 경로에서 제공되는 결과를 초래할 수 있으며, 이는 SEO와 UX에 문제를 일으킬 수 있습니다.
이 동작을 비활성화하고 pages
의 파일 기반 라우팅을 방지하려면 next.config.js
를 열고 useFileSystemPublicRoutes
설정을 비활성화하세요:
module.exports = {
useFileSystemPublicRoutes: false,
}
주의하세요:
useFileSystemPublicRoutes
는 SSR에서 파일명 경로를 비활성화하지만, 클라이언트 측 라우팅은 여전히 해당 경로에 접근할 수 있습니다. 이 옵션을 사용할 때는 프로그래매틱하게 접근하지 않도록 경로 탐색을 방지해야 합니다.
클라이언트 측 라우터를 구성하여 파일명 경로로의 클라이언트 측 리디렉션을 허용하지 않도록 하려면
router.beforePopState
를 참조하세요.