Сборка приложения React с нуля¶
Если у вашего приложения есть ограничения, которые плохо покрываются существующими фреймворками, вы предпочитаете создать собственный фреймворк или просто хотите изучить основы приложения React, вы можете собрать приложение React с нуля.
Подумайте об использовании фреймворка
Начало с нуля — простой способ начать использовать React, но важный компромисс в том, что этот путь часто равносилен созданию собственного самодельного фреймворка. По мере изменения требований вам, возможно, придётся решать всё больше задач уровня фреймворка, для которых у рекомендуемых нами фреймворков уже есть хорошо проработанные и поддерживаемые решения.
Например, если в будущем приложению понадобится серверный рендеринг (SSR), генерация статических сайтов (SSG) и/или серверные компоненты React (RSC), реализовывать это придётся самостоятельно. Точно так же будущие возможности React, которые требуют интеграции на уровне фреймворка, придётся реализовывать самостоятельно, если вы захотите их использовать.
Рекомендуемые нами фреймворки также помогают создавать более производительные приложения. Например, сокращение или устранение водопадов сетевых запросов улучшает опыт пользователя. Для учебного проекта это может быть не главным приоритетом, но если у приложения появятся пользователи, производительность, возможно, захочется улучшить.
Этот путь также усложняет получение поддержки: маршрутизация, получение данных и другие возможности будут устроены уникально для вашей ситуации. Выбирайте этот вариант, только если вам комфортно решать такие задачи самостоятельно или если вы уверены, что эти возможности вам никогда не понадобятся.
Список рекомендуемых фреймворков смотрите в статье Создание приложения React.
Шаг 1: Установите инструмент сборки¶
Первый шаг — установить инструмент сборки, например vite, parcel или rsbuild. Такие инструменты умеют упаковывать и запускать исходный код, дают сервер разработки для локальной работы и команду сборки, чтобы развернуть приложение на производственном сервере.
Vite¶
Vite — инструмент сборки, который стремится дать более быстрый и лёгкий опыт разработки современных веб-проектов.
npm create vite@latest my-app -- --template react-ts
Vite придерживается своего подхода и поставляется с разумными настройками по умолчанию. У Vite богатая экосистема плагинов для fast refresh, JSX, Babel/SWC и других типичных возможностей. Чтобы начать, смотрите плагин React или плагин React SWC для Vite и пример проекта React SSR.
Vite уже используется как инструмент сборки в одном из рекомендуемых нами фреймворков: React Router.
Parcel¶
Parcel сочетает отличный опыт разработки из коробки с масштабируемой архитектурой, которая проводит проект от самого начала до крупных производственных приложений.
npm install --save-dev parcel
Parcel из коробки поддерживает fast refresh, JSX, TypeScript, Flow и стили. Чтобы начать, смотрите рецепт React для Parcel.
Rsbuild¶
Rsbuild — инструмент сборки на базе Rspack, который даёт цельный опыт разработки приложений React. В нём уже настроены тщательно подобранные значения по умолчанию и оптимизации производительности.
npx create-rsbuild --template react
В Rsbuild встроена поддержка возможностей React: fast refresh, JSX, TypeScript и стилей. Чтобы начать, смотрите руководство React для Rsbuild.
Metro для React Native
Если вы начинаете с нуля с React Native, понадобится Metro — бандлер JavaScript для React Native. Metro умеет собирать бандлы для платформ вроде iOS и Android, но по сравнению с инструментами на этой странице ему не хватает многих возможностей. Мы рекомендуем начинать с Vite, Parcel или Rsbuild, если проекту не нужна поддержка React Native.
Шаг 2: Соберите типичные шаблоны приложения¶
Перечисленные выше инструменты сборки начинают с приложения только на клиенте — одностраничного приложения (SPA), — но не включают готовых решений для типичных задач вроде маршрутизации, получения данных или стилей.
В экосистеме React много инструментов для этих задач. Мы перечислили несколько широко используемых как отправную точку, но вы можете выбрать другие, если они подходят вам лучше.
Маршрутизация¶
Маршрутизация определяет, какой контент или какие страницы показывать, когда пользователь открывает конкретный URL. Нужно настроить маршрутизатор, который сопоставляет URL с разными частями приложения. Также нужно обрабатывать вложенные маршруты, параметры маршрута и параметры запроса. Маршрутизаторы можно настраивать в коде или описывать на основе структуры папок и файлов компонентов.
Маршрутизаторы — центральная часть современных приложений. Обычно они интегрированы с получением данных (включая предварительную загрузку данных для всей страницы, чтобы она открывалась быстрее), разделением кода (чтобы уменьшить размер клиентского бандла) и подходами к рендерингу страниц (чтобы решать, как генерируется каждая страница).
Мы предлагаем использовать:
Получение данных¶
Получение данных с сервера или из другого источника — ключевая часть большинства приложений. Чтобы делать это правильно, нужно обрабатывать состояния загрузки и ошибки и кэшировать полученные данные, а это бывает сложно.
Специализированные библиотеки получения данных берут на себя сложную работу по загрузке и кэшированию, чтобы вы сосредоточились на том, какие данные нужны приложению и как их показать. Обычно эти библиотеки используют прямо в компонентах, но их также можно встроить в загрузчики маршрутов для более быстрой предварительной загрузки и лучшей производительности, а также в серверный рендеринг.
Учтите, что получение данных прямо в компонентах может замедлить загрузку из-за водопадов сетевых запросов, поэтому мы рекомендуем по возможности заранее загружать данные в загрузчиках маршрутизатора или на сервере. Тогда данные страницы запрашиваются все сразу, пока страница отображается.
Если вы получаете данные из большинства бэкендов или API в стиле REST, мы предлагаем использовать:
Если вы получаете данные из GraphQL API, мы предлагаем использовать:
Разделение кода¶
Разделение кода — это разбиение приложения на меньшие бандлы, которые можно загружать по требованию. Размер кода растёт с каждой новой возможностью и дополнительной зависимостью. Приложения могут загружаться медленно, потому что весь код приложения нужно отправить до того, как им можно воспользоваться. Кэширование, сокращение возможностей и зависимостей и перенос части кода на сервер помогают смягчить медленную загрузку, но это неполные решения, и при чрезмерном использовании они могут жертвовать функциональностью.
Точно так же, если вы полагаетесь на то, что приложения, использующие ваш фреймворк, сами разделяют код, можно столкнуться с ситуациями, когда загрузка становится медленнее, чем если бы разделения кода не было вовсе. Например, ленивая загрузка графика откладывает отправку кода, нужного для его рендеринга, отделяя код графика от остального приложения. Parcel поддерживает разделение кода с помощью React.lazy. Однако если график загружает свои данные после первоначального рендеринга, ждать приходится дважды. Это водопад: вместо того чтобы одновременно запросить данные для графика и отправить код для его рендеринга, нужно ждать, пока каждый шаг завершится по очереди.
Разделение кода по маршрутам, если оно интегрировано со сборкой бандла и получением данных, может сократить время начальной загрузки приложения и время, за которое отрисовывается самый крупный видимый контент (Largest Contentful Paint).
Инструкции по разделению кода смотрите в документации инструмента сборки: - Оптимизации сборки Vite - Разделение кода в Parcel - Разделение кода в Rsbuild
Повышение производительности приложения¶
Поскольку выбранный инструмент сборки поддерживает только одностраничные приложения (SPA), вам нужно будет реализовать другие шаблоны рендеринга, такие как серверный рендеринг (SSR), генерация статических сайтов (SSG) и/или серверные компоненты React (RSC). Даже если сначала эти возможности не нужны, в будущем некоторым маршрутам могут пойти на пользу SSR, SSG или RSC.
-
Одностраничные приложения (SPA) загружают одну HTML-страницу и динамически обновляют её по мере взаимодействия пользователя с приложением. С SPA проще начать, но начальная загрузка может быть медленнее. SPA — архитектура по умолчанию для большинства инструментов сборки.
-
Потоковый серверный рендеринг (SSR) отрисовывает страницу на сервере и отправляет полностью отрисованную страницу клиенту. SSR может улучшить производительность, но настроить и сопровождать его сложнее, чем одностраничное приложение. С добавлением потоковой передачи SSR может оказаться очень сложным в настройке и сопровождении. Смотрите руководство по SSR в Vite.
-
Генерация статических сайтов (SSG) создаёт статические HTML-файлы приложения во время сборки. SSG может улучшить производительность, но настроить и сопровождать её сложнее, чем серверный рендеринг. Смотрите руководство по SSG в Vite.
-
Серверные компоненты React (RSC) позволяют смешивать компоненты времени сборки, только серверные и интерактивные компоненты в одном дереве React. RSC могут улучшить производительность, но сейчас для настройки и сопровождения нужна глубокая экспертиза. Смотрите примеры RSC в Parcel.
Стратегии рендеринга нужно интегрировать с маршрутизатором, чтобы приложения, собранные на вашем фреймворке, могли выбирать стратегию рендеринга на уровне отдельного маршрута. Тогда разные стратегии можно будет использовать, не переписывая всё приложение. Например, посадочной странице может быть полезна статическая генерация (SSG), а страница с лентой контента может лучше всего работать с серверным рендерингом.
Правильная стратегия рендеринга для нужных маршрутов может сократить время до загрузки первого байта контента (Time to First Byte), до отрисовки первого фрагмента контента (First Contentful Paint) и до отрисовки самого крупного видимого контента приложения (Largest Contentful Paint).
И ещё...¶
Это лишь несколько примеров возможностей, которые придётся продумать новому приложению при сборке с нуля. Со многими ограничениями, на которые вы наткнётесь, будет трудно справиться: задачи связаны друг с другом и могут требовать глубокой экспертизы в областях, которые вам незнакомы.
Если вы не хотите решать эти задачи самостоятельно, можно начать с фреймворка, в котором эти возможности есть из коробки.
Источник — https://react.dev/learn/build-a-react-app-from-scratch