Создание приложения React с помощью команды create-react-app может показаться волшебством. Если вы раньше использовали React, вы могли смутно осознавать наличие таких вещей, как Webpack или Babel, под капотом, но вам не требуется ничего знать о них, чтобы успешно создать высокофункциональное приложение.

Но что именно делает все это под капотом? И все ли это необходимо для каждого приложения? Это некоторые из вопросов, которые у меня возникли после того, как я некоторое время использовал create-react-app, поэтому я решил найти ответы на них, создав приложение React с нуля.

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

  1. Реагировать - это довольно очевидно на первый взгляд, но что такое react и что необходимо для его использования?
  2. Bundler - именно здесь create-react-app делает за вас большую часть тяжелой работы. Кроме того, именно здесь вы сможете максимально избавиться от лишнего веса, когда дело доходит до настройки сборки для разработки. Я объясню, что абсолютно необходимо для приложения React и почему.
  3. Сервер - вам нужен сервер для размещения вашего приложения во время разработки, желательно с включенной горячей перезагрузкой. Здесь я буду использовать сервер разработки Webpack, но в ближайшем будущем я опубликую продолжение этой статьи, в котором объясняется, как создать собственный сервер JavaScript с Express и использовать его для разработки. (ОБНОВЛЕНИЕ: я довел до конца)
  4. Тесты - Конечно, мы не можем забыть тесты. Для краткости я не буду включать тестирование в эту статью. Кроме того, установка Jest очень хорошо описана в документации, и я бы в основном перефразировал их инструкции.

Так как же нам на самом деле создать этот простой проект без create-react-app? Просто создав каталог проекта и инициализировав npm, чтобы мы могли установить наши пакеты:

mkdir bare-bones-react
cd bare-bones-react
npm init

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

Реагировать

Теперь, когда у нас настроен каталог нашего проекта с npm, давайте займемся установкой React. Сам React (пакет с именем react) по сути представляет собой библиотеку ссылок на React API. Чтобы фактически визуализировать компоненты React, вам также понадобится средство визуализации, которое будет внедрять функции в эти ссылки и отображать их в DOM.

Следовательно, чтобы использовать React в нашем приложении, нам нужно установить два пакета: react и react-dom. Поначалу такое разделение может показаться странным, но это часть того, что делает React великим. Если вам не нравится react-dom, вы можете использовать другое средство визуализации и по-прежнему иметь доступ ко всему React API.

Я собираюсь использовать react-dom, потому что я еще не изучал другой модуль рендеринга. Итак, чтобы установить React, мы введем в командную строку следующее:

npm i react react-dom

И затем нам также нужно указать react-dom, что и где рендерить. Для этого нам понадобится index.js файл:

Здесь мы говорим react-dom отобразить наш App компонент внутри узла DOM с идентификатором root. Это означает, что нам также понадобится index.html файл с элементом с идентификатором root:

И нам также нужно будет определить компонент App, чтобы мы не получали сообщение об ошибке. Я оставлю это на ваше усмотрение.

Бандлер (Webpack, Babel, ESLint)

Следующая деталь, которая нам понадобится, - это сборщик. Что такое упаковщик? Он объединяет весь ваш JavaScript, включая модули, в один файл. Причина, по которой это важно, заключается в том, что в конечном итоге ваш JavaScript нужно будет загрузить в документ HTML, а загрузка <script> тегов очень дорога. Сборщик позволяет вам сжать весь ваш JavaScript в один файл (вместе с CSS, если хотите), чтобы его можно было загрузить с помощью одного тега <script>.

Мы будем использовать Webpack в качестве сборщика и настроим его для использования как Babel, так и ESLint в процессе сборки.

Babel необходимо включать в приложения React, потому что он преобразует ES6 и JSX в обратно совместимый код. В ESLint нет необходимости, но очень полезно иметь линтер во время разработки.

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

Чтобы использовать все это в нашем проекте, нам придется установить довольно много разных пакетов. Начнем с Webpack:

npm i --save-dev webpack webpack-cli html-webpack-plugin

Мы устанавливаем Webpack вместе с webpack-cli, что позволяет нам скомпилировать наш проект из командной строки. html-webpack-plugin сгенерирует новый index.html файл с необходимым тегом <script> на основе файла шаблона index.html, который мы создали в предыдущей части.

Я также хочу установить несколько загрузчиков для Webpack, которые будут использоваться при компиляции нашего проекта:

npm i --save-dev html-loader css-loader style-loader

Затем мы установим Babel и связанные с ним пакеты:

npm i --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

Наконец, мы добавим ESLint и дополнительные пакеты, необходимые для его использования с Webpack и Babel:

npm i --save-dev eslint eslint-loader eslint-plugin-react babel-eslint

Хорошо, мы только что установили много всего. На данный момент это может показаться немного подавляющим, но просто помните, что все эти разные пакеты работают вместе для достижения одной цели: генерации связанного, обратно совместимого кода.

Кроме того, мы лучше поймем, как Webpack все это использует, когда начнем его настраивать.

Настройка Webpack, Babel и ESLint

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

node_modules
src
   App.js
   index.html
   index.js
package.json
package-lock.json

Я переместил App.js, index.html и index.js в каталог src, потому что наш корневой каталог скоро заполнится файлами конфигурации. Вы можете организовать свой каталог, как хотите, но имейте в виду, что вам нужно будет предоставить Webpack пути к некоторым из этих файлов. Если вы организуете свой проект по-другому, вам потребуется соответствующим образом скорректировать пути к файлам.

Начнем с Webpack. Создайте файл в корневом каталоге вашего проекта с именем webpack.config.js. Из этого файла мы экспортируем наши настройки конфигурации следующим образом:

И давайте посмотрим, что все это делает:

  • "mode" не требует пояснений. Мы сообщаем, что Webpack находится в разработке.
  • "entry" - это наш основной файл JavaScript или «точка входа». В React это файл, в котором мы используем наш рендерер.
  • "output" сообщает Webpack, куда поместить наш связанный код и как назвать файл. Здесь мы говорим Webpack создать каталог с именем /dir в корневом каталоге (__dirname - это переменная узла, представляющая текущий путь к каталогу) и создать в нем файл с именем bundle.js.
  • "devtool" позволяет нам использовать инструменты разработки, предоставляемые Webpack. Я использую source-map, потому что после того, как Webpack скомпилирует наш проект, весь наш код будет расположен в одном файле, который мы не создавали. source-map создает отдельный файл, который сопоставляет источник кода в нашем связанном файле с файлами JavaScript, которые мы фактически создали.
  • "module" - это то место, где мы говорим Webpack использовать все те загрузчики, которые мы установили ранее. Мы используем регулярное выражение, чтобы указать каждому загрузчику, на какие расширения файлов нужно настроить таргетинг. Кроме того, мы говорим Webpack запустить ESLint до того, как Babel переведет наш код ("enforce": “pre",), чтобы он мог предупреждать нас о вещах в нашем исходном коде, а не о скомпилированном коде.
  • "plugins" - это то место, где мы сообщаем Webpack, какие плагины мы хотим использовать вместе с любой конфигурацией этих плагинов. Здесь мы используем html-webpack-plugin для создания HTML-файла со всем необходимым для загрузки нашего кода.

Это много настроек. К счастью, другие файлы конфигурации намного проще. Далее идет Вавилон.

Чтобы настроить Babel, создайте в корневом каталоге файл с именем .babelrc и включите следующее:

Файлы конфигурации Babel могут быть более сложными, но для наших целей все, что нам нужно сделать, это указать Babel использовать установленные нами пресеты. Короче говоря, @babel/preset-env преобразует новейший синтаксис JavaScript, а @babel/preset-react преобразует JSX.

Наконец, мы настроим ESLint. Создайте в корневом каталоге файл с именем .eslintrc.js и включите в него следующее:

По сути, мы здесь уведомляем ESLint о том, что мы используем Babel и React. Мы также хотим сообщить ESLint, что работаем в среде браузера. В противном случае он неправильно предупредит нас о том, что глобальные переменные, такие как document, не определены.

Теперь, когда все настроено, мы можем скомпилировать наш проект. Если вы установили webpack-cli, вы сможете скомпилировать свой проект, просто набрав webpack в терминале и нажав Enter. Если это не помогло, попробуйте npx webpack.

После успешной компиляции проекта вы можете использовать псевдоним команды webpack в вашем package.json файле в сценарии "build":

Сервер разработки

Последнее, что нам нужно, чтобы начать разработку нашего приложения, - это сервер. К счастью для нас, у Webpack есть собственный сервер разработки, который сразу же интегрируется с Webpack. Все, что нам нужно сделать, это установить его:

npm i --save-dev webpack-dev-server

Затем, чтобы запустить его, введите следующую команду:

webpack-dev-server --mode development --open --hot

Как и в случае с командой webpack, вам может потребоваться использовать вместо нее npx:

npx webpack-dev-server --mode development --open --hot

Флаг --open сообщает серверу открыть браузер, когда сервер будет готов. Флаг --hot указывает серверу использовать горячую перезагрузку, что означает, что сервер будет обновлять страницу каждый раз, когда вы сохраняете изменение в одном из файлов проекта (к чему вы привыкли, если использовали create-react-app).

Теперь вы можете загрузить свое приложение в свой браузер. Вы можете присвоить этой команде псевдоним npm start, добавив ее в раздел scripts вашего package.json:

Вот и все: полнофункциональное приложение React, созданное без использования create-react-app. Я надеюсь, что это поможет прояснить хотя бы часть того, что происходит под капотом приложений React, которые вы уже создали.