~ 4 мин
Стартовый шаблон Next.js + MUI5 + TypeScript
456
12/11/2021
Очень часто при старте проекта необходимо выбрать набор инструментов, которые значительно упрощают разработку и, которые можно в дальнейшем использовать и в других проектах.
И здесь встает вопрос, а будут ли они работать вместе должным образом.
Итак, какие задачи перед нами стоят:
- Обеспечить стабильную сборку для быстрого создания новых проектов и прототипирования;
- Обеспечить статическую типизацию и проверку типов для улучшения качества кода;
- Перейти на новый 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 для инициализации страниц, поэтому вы можете переопределить поведение по умолчанию, который позволит использовать очень интересные вещи:
- Сохранение частей макета при переключении между страницами;
- Сохранение состояния при навигации по страницам;
- Пользовательская обработка ошибок;
- Встраивание дополнительных данных на страницу;
- Добавление глобальных 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
Взгляните на наш стартап:
Выбирай экскурсии и активности по всему миру
Уже зарегистрировано 0 стран, 0 направлений, 0 экскурсий
Есть интересная идея?
И вы очень хотите ее реализовать, пишите нам и получите подробное коммерческое предложение и быструю реализацию