Кодмоды (Codemods)

Codemods — это программные преобразования, которые применяются к вашей кодовой базе. Они позволяют автоматически вносить большое количество изменений без необходимости ручного редактирования каждого файла.

Next.js предоставляет преобразования Codemods, которые помогают обновлять кодовую базу Next.js при изменении или устаревании API.

Использование

В терминале перейдите (cd) в папку вашего проекта и выполните:

Терминал
npx @next/codemod <transform> <path>

Замените <transform> и <path> соответствующими значениями.

  • transform — название преобразования
  • path — файлы или директория для преобразования
  • --dry Пробный запуск без внесения изменений в код
  • --print Выводит изменённый код для сравнения

Codemods для Next.js

13.2

Использование встроенного шрифта

built-in-next-font
Терминал
npx @next/codemod@latest built-in-next-font .

Этот codemod удаляет пакет @next/font и преобразует импорты @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.

Например:

pages/index.js
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>
  )
}

Преобразуется в:

pages/index.js
// '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 путём добавления встроенных стилей и удаления неиспользуемых пропсов.

  • Удаляет проп layout и добавляет style.
  • Удаляет проп objectFit и добавляет style.
  • Удаляет проп objectPosition и добавляет style.
  • Удаляет проп lazyBoundary.
  • Удаляет проп lazyRoot.
Терминал
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.

Например:

my-component.js
export default class Home extends React.Component {
  render() {
    return <div>Hello World</div>
  }
}

Преобразуется в:

my-component.js
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.

Например:

my-component.js
export default function () {
  return <div>Hello World</div>
}

Преобразуется в:

my-component.js
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__.