Codemods
Codemods — это программные преобразования, которые применяются к кодовой базе. Они позволяют автоматически вносить массовые изменения без необходимости ручного редактирования каждого файла.
Next.js предоставляет преобразования Codemod для помощи в обновлении кодовой базы Next.js при изменении или устаревании API.
Использование
В терминале перейдите (cd
) в папку проекта и выполните:
npx @next/codemod <transform> <path>
Замените <transform>
и <path>
соответствующими значениями.
transform
— название преобразованияpath
— файлы или директория для преобразования--dry
Пробный запуск без внесения изменений в код--print
Вывод изменений для сравнения
Codemods для Next.js
14.0
Перенос импортов ImageResponse
next-og-import
npx @next/codemod@latest next-og-import .
Этот codemod переносит импорты из next/server
в next/og
для использования динамической генерации OG-изображений.
Пример:
import { ImageResponse } from 'next/server'
Преобразуется в:
import { ImageResponse } from 'next/og'
Использование экспорта viewport
metadata-to-viewport-export
npx @next/codemod@latest metadata-to-viewport-export .
Этот codemod переносит определённые метаданные viewport в экспорт viewport
.
Пример:
export const metadata = {
title: 'My App',
themeColor: 'dark',
viewport: {
width: 1,
},
}
Преобразуется в:
export const metadata = {
title: 'My App',
}
export const viewport = {
width: 1,
themeColor: 'dark',
}
13.2
Использование встроенного шрифта
built-in-next-font
npx @next/codemod@latest built-in-next-font .
Этот codemod удаляет пакет @next/font
и преобразует его импорты во встроенный next/font
.
Пример:
import { Inter } from '@next/font/google'
Преобразуется в:
import { Inter } from 'next/font/google'
13.0
Переименование импортов Next Image
next-image-to-legacy-image
npx @next/codemod@latest next-image-to-legacy-image .
Безопасно переименовывает импорты next/image
в приложениях Next.js 10, 11 или 12 в next/legacy/image
для Next.js 13. Также переименовывает next/future/image
в next/image
.
Пример:
import Image1 from 'next/image'
import Image2 from 'next/future/image'
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
)
}
Преобразуется в:
// 'next/image' становится 'next/legacy/image'
import Image1 from 'next/legacy/image'
// 'next/future/image' становится 'next/image'
import Image2 from 'next/image'
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
)
}
Миграция на новый компонент Image
next-image-experimental
npx @next/codemod@latest next-image-experimental .
Опасная миграция с next/legacy/image
на новый next/image
путём добавления inline-стилей и удаления неиспользуемых пропсов.
- Удаляет проп
layout
и добавляетstyle
. - Удаляет проп
objectFit
и добавляетstyle
. - Удаляет проп
objectPosition
и добавляетstyle
. - Удаляет проп
lazyBoundary
. - Удаляет проп
lazyRoot
.
Удаление тегов <a>
из компонентов Link
new-link
npx @next/codemod@latest new-link .
Удаляет теги <a>
внутри компонентов Link или добавляет проп legacyBehavior
для ссылок, которые не могут быть автоматически исправлены.
Пример:
<Link href="/about">
<a>About</a>
</Link>
// преобразуется в
<Link href="/about">
About
</Link>
<Link href="/about">
<a onClick={() => console.log('clicked')}>About</a>
</Link>
// преобразуется в
<Link href="/about" onClick={() => console.log('clicked')}>
About
</Link>
В случаях, когда автоматическое исправление невозможно, добавляется проп legacyBehavior
. Это позволяет приложению продолжать работать со старым поведением для конкретной ссылки.
const Component = () => <a>About</a>
<Link href="/about">
<Component />
</Link>
// становится
<Link href="/about" legacyBehavior>
<Component />
</Link>
11
Миграция с Create React App
cra-to-next
npx @next/codemod cra-to-next
Переносит проект Create React App в Next.js, создавая Pages Router и необходимую конфигурацию для соответствия поведению. Изначально используется рендеринг только на стороне клиента для предотвращения проблем совместимости из-за использования window
при SSR, что позволяет постепенно внедрять специфичные для Next.js функции.
Поделитесь отзывами об этом преобразовании в этом обсуждении.
10
Добавление импортов React
add-missing-react-import
npx @next/codemod add-missing-react-import
Преобразует файлы, не импортирующие React
, добавляя импорт для работы нового преобразования JSX в React.
Пример:
export default class Home extends React.Component {
render() {
return <div>Hello World</div>
}
}
Преобразуется в:
import React from 'react'
export default class Home extends React.Component {
render() {
return <div>Hello World</div>
}
}
9
Преобразование анонимных компонентов в именованные
name-default-component
npx @next/codemod name-default-component
Версии 9 и выше.
Преобразует анонимные компоненты в именованные для корректной работы с Fast Refresh.
Пример:
export default function () {
return <div>Hello World</div>
}
Преобразуется в:
export default function MyComponent() {
return <div>Hello World</div>
}
Компонент получает имя в camelCase на основе имени файла, также работает со стрелочными функциями.
8
Преобразование HOC AMP в конфигурацию страницы
withamp-to-config
npx @next/codemod withamp-to-config
Преобразует HOC withAmp
в конфигурацию страницы Next.js 9.
Пример:
// До
import { withAmp } from 'next/amp'
function Home() {
return <h1>My AMP Page</h1>
}
export default withAmp(Home)
// После
export default function Home() {
return <h1>My AMP Page</h1>
}
export const config = {
amp: true,
}
6
Использование withRouter
url-to-withrouter
npx @next/codemod url-to-withrouter
Преобразует устаревшее автоматически внедряемое свойство url
на страницах верхнего уровня в использование withRouter
и внедряемого им свойства router
. Подробнее: https://nextjs.org/docs/messages/url-deprecated
Пример:
import React from 'react'
export default class extends React.Component {
render() {
const { pathname } = this.props.url
return <div>Current pathname: {pathname}</div>
}
}
import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
class extends React.Component {
render() {
const { pathname } = this.props.router
return <div>Current pathname: {pathname}</div>
}
}
)
Это один из случаев. Все преобразуемые (и протестированные) случаи можно найти в директории __testfixtures__
.