Стартовый шаблон Next.js + MUI5 + TypeScript

456

12/11/2021

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

Вадим Пашаев

Вадим Пашаев

Инженер, веб-разработчик, путешественник

Стартовый шаблон Next.js + MUI5 + TypeScript
Регистрация товарных знаков
Craftum - создайте сайт за 15 минут
Домены, хостинг от reg.ru

И здесь встает вопрос, а будут ли они работать вместе должным образом.

Итак, какие задачи перед нами стоят:

  • Обеспечить стабильную сборку для быстрого создания новых проектов и прототипирования;
  • Обеспечить статическую типизацию и проверку типов для улучшения качества кода;
  • Перейти на новый Material UI 5, который претерпел очень много полезных изменений по сравнению с 4 версией (который для нашей студии уже стал стандартом, де-факто);

В этой статье мы соберем с вами сборку на Next.js + MUI5 + TypeScript.

Cвязка React+Typescript давно уже стала самой популярная для создания клиентских приложений. Их в своих проектах уже используют следующие бренды: Yandex, Тинькофф, ВК, Avito, Сбербанк, Контур, Netflix, Instagram, Pinterest, AirBNB и другие крупные компании.

Next.js

Next.js — это основанный на React фреймворк, предназначенный для разработки веб-приложений, обладающих функционалом, выходящим за рамки SPA, т.е. так называемых одностраничных приложений. Известно, что основным недостатком одностраничных приложений или SPA являются проблемы с индексацией страниц таких приложений поисковыми роботами, что негативно влияет на SEO.

TypeScript

TypeScript (далее TS) - это надстройка над JavaScript (далее JS), которая добавляет статическую типизацию и еще кучу полезных фишек в нативный JS, старается исправить большинство недочетов и предоставляет нам мощнейшие иструменты для улучшения качества кода. Про все достоинства и недостатки TS подробнее можно почитать в других статьях. Например, здесь.

Наиболее распространенными ошибками, совершаемыми JavaScript-разработчиками, являются ошибки вида, когда вместо ожидаемого значения используется неправильное. Это может быть связано с простыми опечатками, непониманием интерфейса используемой библиотеки, неверными предположениями о поведении кода во время выполнения и т.д. Цель TypeScript - осуществлять проверку типов значений, используемых в программе, написанной на JavaScript. TypeScript - это инструмент, который выполняет свою работу до запуска кода (поэтому его называют статическим) и обеспечивает использование приложением значений правильных типов.

О том, что дает нам TypeScript в React можно подробнее прочитать здесь.

MUI5 (MaterialUI 5)

MUI - это довольно надежная, настраиваемая и доступная библиотека базовых и расширенных компонентов, позволяющая создавать собственную систему дизайна и быстрее разрабатывать приложения на React.

Собираем шаблон

1. Установка Next.js и TypeScript

Для начала сборки нам потребуется создать шаблонный проект на Next.js + Typescript. Next.js поддерживает TypeScript из коробки, поэтому все, что нам нужно сделать на этом этапе, это набрать в консоли:

yarn create next-app --typescript

Где флаг --typescript как раз указывает на создание проекта с надстройкой TypeScript.

После запуска команды вам предложат задать имя для проекта, которое и будет совпадать с именем папки, в которой создастся проект.

2. Установка MUI

С установкой MaterialUI-5 все немного сложнее ;)

Для начала в проект устанавливаем следующие пакеты:

yarn add @emotion/cache @emotion/react @emotion/server @emotion/styled @mui/icons-material @mui/material

3. Редактируем файл _app.js

Next.js использует компонент App для инициализации страниц, поэтому вы можете переопределить поведение по умолчанию, который позволит использовать очень интересные вещи:

  1. Сохранение частей макета при переключении между страницами;
  2. Сохранение состояния при навигации по страницам;
  3. Пользовательская обработка ошибок;
  4. Встраивание дополнительных данных на страницу;
  5. Добавление глобальных CSS-стилей.

Что нужно сделать?

Идем в документацию Next.js и открываем раздел Advanced Features/Custom App. Копируем оттуда весь код и создаем файл _app.js в папке /pages

// import App from 'next/app'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
//   // calls page's `getInitialProps` and fills `appProps.pageProps`
//   const appProps = await App.getInitialProps(appContext);
//
//   return { ...appProps }
// }

export default MyApp

После этого необходимо добавить несколько изменений в файл _app.js

import Head from 'next/head'
import type { AppProps } from 'next/app'
import { ThemeProvider } from '@mui/material/styles'
import { CssBaseline } from '@mui/material'
import { CacheProvider, EmotionCache } from '@emotion/react'
import theme from '../styles/theme'
import createEmotionCache from '../utils/createEmotionCache'

const clientSideEmotionCache = createEmotionCache()

interface MyAppProps extends AppProps {
  emotionCache?: EmotionCache
}

export default function MyApp({ Component, emotionCache = clientSideEmotionCache, pageProps }: MyAppProps) {
  return (
    <CacheProvider value={emotionCache}>
      <Head>
        <title>Change title in _app.tsx</title>
        <meta name="viewport" content='initial-scale=1, width=device-width' />
      </Head>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <Component {...pageProps} />
      </ThemeProvider>
    </CacheProvider>
  )
}

4. Добавляем файл _document.js

Файл _document.js в Next.js обычно используется для дополнения тегов <html> и <body> вашего приложения. Это необходимо, потому, что страницы Next.js пропускают определение разметки окружающего документа.

Создаем в папке /pages файл _document.js. И вписываем сюда следующий код.

import React from 'react'
import Document, { Html, Head, NextScript, Main } from "next/document"
import createEmotionServer from "@emotion/server/create-instance"
import theme from '../styles/theme'
import createEmotionCache from "../utils/createEmotionCache"

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="ru">
        <Head>
          <meta name="theme-color" content={theme.palette.primary.main} />
          <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
          <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

MyDocument.getInitialProps = async (ctx) => {
  const originalRenderPage = ctx.renderPage

  const cache = createEmotionCache()

  const { extractCriticalToChunks } = createEmotionServer(cache)

  ctx.renderPage = () => originalRenderPage({
    enhanceApp: (App: any) => function EnhanceApp(props) {
      return <App emotionCache={cache} {...props} />
    }
  })

  const initialProps = await Document.getInitialProps(ctx)

  const emotionStyles = extractCriticalToChunks(initialProps.html)
  const emotionStyleTags = emotionStyles.styles.map(style => (
    <style
      data-emotion={`${style.key} ${style.ids.join(' ')}`}
      key={style.key}
      dangerouslySetInnerHTML={{ __html: style.css }}
    />
  ))

  return {
    ...initialProps,
    styles: [...React.Children.toArray(initialProps.styles), ...emotionStyleTags]
  }
}

5. Пишем первую страницу на MaterialUI 5

import { Link, Typography } from '@mui/material'
import { NextPage } from 'next'
import NextLink from 'next/link'
import Layout from '../components/Layout'

const HomePage: NextPage = () => {
  return (
    <Layout title="Главная | Next.js + TypeScript Example">
      <Typography component="h1" variant='h1'>Привет, Next.js 👋</Typography>
      <Typography>
        <NextLink href="/about" passHref>
          <Link>О нас</Link>
        </NextLink>
      </Typography>
    </Layout>
  )
}

export default HomePage

Все на этом туториал завершен. Код можно найти на Github

Подписаться на рассылку

Получите лучшие новости по веб-разработке и AI

Подписаться на рассылку

Получите лучшие новости по веб-разработке и AI

Оценка проекта

Хотите быструю оценку Вашего проекта?

Василий Иванов
Максим Насенников
Виктория Мальцева
Vadim Pashaev

Заполните форму справа и наша команда экспертов поможет найти для Вас оптимальное решение вашей идеи или задачи

Есть интересная идея?

И вы очень хотите ее реализовать, пишите нам и получите подробное коммерческое предложение и быструю реализацию