Upgrading to Version 9
버전 9로 업그레이드하려면 아래의 명령어를 실행하세요:
npm i next@9
yarn add next@9
pnpm up next@9
bun add next@9
알아두면 좋은 사항: TypeScript를 사용하는 경우,
@types/react
및@types/react-dom
도 해당 버전으로 업그레이드해야 합니다.
Production Deployment on Vercel
과거에 vercel.json
파일에서 동적 경로를 위해 routes
를 구성했다면, Next.js 9의 새로운 기능인 Dynamic Routing feature을 활용해 이러한 규칙을 제거할 수 있습니다.
Next.js 9의 동적 경로는 Vercel (opens in a new tab)에서 자동으로 구성되며, vercel.json
추가 설정이 필요하지 않습니다.
자세한 내용은 Dynamic Routing here에서 확인할 수 있습니다.
Check your Custom App File (pages/_app.js
)
과거에 Custom <App>
예제를 복사한 경험이 있는 경우, getInitialProps
를 제거할 수 있습니다.
새로운 Next.js 기능을 활용하기 위해 pages/_app.js
에서 getInitialProps
을 제거해 주세요!
getInitialProps
는 아무 작업도 하지 않으므로 제거해도 됩니다:
class MyApp extends App {
// 삭제해 주세요, 아무것도 수행하지 않습니다!
static async getInitialProps({ Component, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
render() {
// ... etc
}
}
Breaking Changes
@zeit/next-typescript
is no longer necessary
Next.js는 이제 @zeit/next-typescript
사용을 무시하고 이를 제거하라는 경고를 표시할 겁니다. 이 플러그인을 next.config.js
에서 제거하세요.
커스텀 .babelrc
에 @zeit/next-typescript/babel
참조가 있는 경우 이를 제거하세요.
fork-ts-checker-webpack-plugin
(opens in a new tab) 사용도 next.config.js
에서 제거해야 합니다.
TypeScript 정의 파일은 next 패키지에 포함되어 있으므로, 충돌을 방지하기 위해 @types/next를 제거해야 합니다.
다음 유형은 다릅니다:
이 목록은 업그레이드를 돕기 위해 커뮤니티가 작성한 것입니다. 차이점을 발견한다면, 이 목록에 pull-request를 보내어 다른 사용자들을 도와주세요.
From:
import { NextContext } from 'next'
import { NextAppContext, DefaultAppIProps } from 'next/app'
import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'
to
import { NextPageContext } from 'next'
import { AppContext, AppInitialProps } from 'next/app'
import { DocumentContext, DocumentInitialProps } from 'next/document'
The config
key is now an export on a page
페이지에서 config
라는 이름의 사용자 지정 변수를 더 이상 내보낼 수 없습니다. (예. export { config }
/ export const config ...
)
내보낸 변수는 이제 Opt-in AMP 및 API Route 기능과 같은 페이지 수준의 Next.js 구성을 지정하는 데 사용됩니다.
Next.js와 관련 없는 config 내보내기 변수는 다른 이름으로 변경해야 합니다.
next/dynamic
no longer renders "loading..." by default while loading
동적 컴포넌트는 로딩 중에 기본적으로 아무것도 렌더링하지 않습니다. loading
속성을 설정하여 이 동작을 계속 사용자 지정할 수 있습니다:
import dynamic from 'next/dynamic'
const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello2'),
{
loading: () => <p>Loading</p>,
},
)
withAmp
has been removed in favor of an exported configuration object
Next.js에서 page-level configuration 개념을 도입했기 때문에 일관성을 위해 withAmp
고차 컴포넌트를 제거했습니다.
해당 변경 사항은 아래 명령어를 Next.js 프로젝트의 루트에서 실행하여 자동으로 마이그레이션할 수 있습니다:
curl -L https://github.com/vercel/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js npx jscodeshift -t ./withamp-to-config.js pages/**/*.js
마이그레이션을 수동으로 수행하거나, codemod의 생성 결과를 보려면 아래를 참조하세요:
Before
import { withAmp } from 'next/amp'
function Home() {
return <h1>My AMP Page</h1>
}
export default withAmp(Home)
// or
export default withAmp(Home, { hybrid: true })
After
export default function Home() {
return <h1>My AMP Page</h1>
}
export const config = {
amp: true,
// or
amp: 'hybrid',
}
next export
no longer exports pages as index.html
과거, pages/about.js를 내보내면 out/about/index.html이 생성되었습니다. 이 행위는 out/about.html
이 생성되는 결과로 바뀌었습니다.
동작을 되돌리려면 다음 내용을 포함하는 next.config.js
파일을 생성하세요:
module.exports = {
trailingSlash: true,
}
pages/api/
is treated differently
pages/api/
의 페이지는 이제 API Routes (opens in a new tab)로 간주됩니다.
해당 경로에 있는 페이지는 더 이상 클라이언트 측 번들을 포함하지 않습니다.
Deprecated Features
next/dynamic
has deprecated loading multiple modules at once
next/dynamic
에서 여러 모듈을 한 번에 로드하는 기능을 사용하지 않게 되어 React(React.lazy
and Suspense
) 구현에 더 가까워졌습니다.
동작에 의존하는 코드를 업데이트하는 것은 비교적 간단합니다! 애플리케이션을 마이그레이션하는 데 도움이 되는 예제를 참고해 주세요:
Before
import dynamic from 'next/dynamic'
const HelloBundle = dynamic({
modules: () => {
const components = {
Hello1: () => import('../components/hello1').then((m) => m.default),
Hello2: () => import('../components/hello2').then((m) => m.default),
}
return components
},
render: (props, { Hello1, Hello2 }) => (
<div>
<h1>{props.title}</h1>
<Hello1 />
<Hello2 />
</div>
),
})
function DynamicBundle() {
return <HelloBundle title="Dynamic Bundle" />
}
export default DynamicBundle
After
import dynamic from 'next/dynamic'
const Hello1 = dynamic(() => import('../components/hello1'))
const Hello2 = dynamic(() => import('../components/hello2'))
function HelloBundle({ title }) {
return (
<div>
<h1>{title}</h1>
<Hello1 />
<Hello2 />
</div>
)
}
function DynamicBundle() {
return <HelloBundle title="Dynamic Bundle" />
}
export default DynamicBundle