Фундамент стека: Глубокий разбор TypeScript, React и архитектуры Next.js
Фундамент стека: Глубокий разбор TypeScript, React и архитектуры Next.js
Добро пожаловать в первый модуль курса «Создание эффектного портфолио». Прежде чем мы начнем создавать сложные анимации с Framer Motion или настраивать плавную прокрутку с Lenis, нам необходимо построить прочный фундамент. Эффектное портфолио — это не только красивая картинка, но и производительность, масштабируемость и чистота кода.
В этой статье мы разберем «большую тройку» нашего стека: TypeScript, React и Next.js (с использованием App Router). Мы не будем читать документацию вслух, а сфокусируемся на архитектурных принципах, которые критически важны для современного веб-разработчика.
TypeScript: Ваша страховка от ошибок
Многие новички воспринимают TypeScript как «JavaScript, который заставляет писать больше кода». Однако в контексте профессиональной разработки, TypeScript — это инструмент документации и предотвращения ошибок на этапе написания кода, а не его выполнения.
Статическая типизация против Динамической
JavaScript — язык с динамической типизацией. Это значит, что переменная может хранить число, затем строку, а затем объект. Это удобно для быстрых скриптов, но губительно для крупных приложений.
TypeScript вводит строгую типизацию. Если вы определили, что функция принимает объект с данными о проекте, вы физически не сможете передать туда что-то другое.
Рассмотрим пример компонента карточки проекта для портфолио:
// Определение структуры данных проекта
interface Project {
id: number;
title: string;
description: string;
tags: string[];
link?: string; // Опциональное поле
}
// Типизация пропсов компонента
interface ProjectCardProps {
data: Project;
isFeatured: boolean;
}
const ProjectCard = ({ data, isFeatured }: ProjectCardProps) => {
return (
<div className={isFeatured ? "featured" : "regular"}>
<h3>{data.title}</h3>
<p>{data.description}</p>
{/* TypeScript подскажет, что data.tags — это массив */}
{data.tags.map(tag => <span key={tag}>{tag}</span>)}
</div>
);
};
Интерфейсы и Типы
В нашем курсе мы будем часто использовать ключевое слово interface для описания форм объектов (например, пропсов компонентов) и type для создания союзов (Unions) или примитивов.
TypeScript не запускается в браузере. Он компилируется (транспилируется) в обычный JavaScript. Браузер никогда не узнает о ваших интерфейсах, они нужны только вам и вашему редактору кода.
React: Мышление компонентами
React изменил способ создания интерфейсов, перейдя от манипуляции DOM-деревом к декларативному описанию состояния. Для нашего портфолио важно понимать три кита React: Компоненты, Пропсы и Состояние.
Декларативный подход
Вместо того чтобы говорить браузеру «найди элемент с ID 'button' и добавь ему класс 'active'», мы говорим: «Кнопка должна быть активной, если переменная isActive равна true». React сам решит, как обновить DOM.
Хуки: Управление жизненным циклом
В функциональных компонентах мы используем хуки. Для портфолио нам понадобятся в основном:
- useState: Для хранения локального состояния (например, открыто ли модальное окно).
- useEffect: Для выполнения побочных эффектов (например, запуск анимации при появлении элемента или подписка на событие скролла).
- useRef: Для прямого доступа к DOM-элементу (критично для анимаций с GSAP или Lenis).
Пример использования useRef для анимации:
import { useRef, useEffect } from 'react';
const HeroSection = () => {
// Создаем ссылку на DOM-элемент.
// HTMLDivElement указывает TypeScript, какой именно это элемент.
const titleRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (titleRef.current) {
console.log("Элемент смонтирован:", titleRef.current);
// Здесь будет код анимации
}
}, []);
return <h1 ref={titleRef}>Привет, я разработчик</h1>;
};
Архитектура Next.js: App Router
Next.js — это мета-фреймворк поверх React. Если React — это библиотека для создания UI, то Next.js — это полноценный каркас для создания веб-приложений. В версии 13+ был представлен App Router, который мы и будем использовать.
Файловая маршрутизация
В Next.js структура папок определяет URL вашего сайта. Это интуитивно понятно и удобно.
app/page.tsxГлавная страница (/)app/about/page.tsxСтраница «Обо мне» (/about)app/projects/[id]/page.tsxДинамический маршрут (/projects/1,/projects/cool-app)
Server Components (RSC) vs Client Components
Это самая важная концепция в современном Next.js. По умолчанию все компоненты в папке app являются Серверными Компонентами (React Server Components).
| Характеристика | Server Components (RSC) | Client Components |
|---|---|---|
| Где рендерятся | На сервере (один раз при запросе) | На клиенте (в браузере) и сервере (гидратация) |
| Доступ к БД/Файлам | Прямой доступ | Нет доступа |
| Размер JS-бандла | Не влияет (код не летит в браузер) | Увеличивает размер бандла |
| Интерактивность | Нет (нельзя использовать onClick, useState) |
Да (полная интерактивность) |
Для портфолио это разделение критично. Тяжелые вычисления, получение данных о проектах из CMS или Markdown-файлов мы делаем в серверных компонентах. Анимации, слайдеры и формы обратной связи — в клиентских.
Чтобы превратить компонент в клиентский, нужно добавить директиву 'use client' в первой строке файла.
'use client'; // Магия происходит здесь
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
return <button onClick={() => setLikes(likes + 1)}>❤️ {likes}</button>;
}
Специальные файлы
В App Router есть зарезервированные имена файлов:
- layout.tsx: Обертка для страниц. Здесь живут
<html>,<body>, навигация и футер. Layout не перерисовывается при переходе между страницами внутри него, что идеально для сохранения состояния анимаций переходов. - page.tsx: Уникальный UI для конкретного маршрута.
- loading.tsx: Показывается, пока грузится содержимое
page.tsx. - not-found.tsx: Кастомная страница 404.
Tailwind CSS: Утилитарный подход
Вместо написания CSS-файлов и придумывания имен классов (.wrapper-main-content-left), мы используем утилитарные классы прямо в JSX.
Пример:
// Обычный CSS подход
<div className="card">
// Tailwind CSS подход
<div className="bg-white rounded-xl shadow-md p-6 hover:scale-105 transition-transform">
Это ускоряет разработку и гарантирует, что стили не будут конфликтовать. В сочетании с компонентами React, мы получаем изолированные, стилизованные блоки, которые легко переиспользовать.
Подготовка окружения
Для начала работы нам потребуется Node.js. Мы создадим проект следующей командой:
npx create-next-app@latest my-portfolio
При установке выберите следующие опции:
- TypeScript: Yes
- ESLint: Yes
- Tailwind CSS: Yes
src/directory: No (или Yes, по вкусу, но в курсе мы будем работать в корне)- App Router: Yes
- Customize default import alias: No (оставим
@/*)
Заключение
Мы разобрали фундамент. TypeScript обеспечит надежность данных, React даст нам компонентную модель, а Next.js App Router возьмет на себя маршрутизацию и оптимизацию производительности. Понимание разницы между Server и Client Components — ключ к созданию быстрого портфолио, которое нравится поисковикам и пользователям.
В следующей статье мы начнем настраивать базовый макет и интегрировать Lenis для создания той самой «дорогой» плавной прокрутки.