Первоначально опубликовано на https://devtails.xyz 28 февраля 2022 г.

На дворе 2022 год, и все ваши друзья, занимающиеся веб-разработкой, советуют вам изучить React. Чтобы упростить задачу, они рассказывают вам об этой штуке, которая называется Создать приложение React. Вы видите, что с помощью трех команд вы можете запустить полностью настроенное приложение React и радоваться.

npx create-react-app my-app
cd my-app
npm start

После минуты установки пакетов и нескольких секунд запуска npm start вы готовы к работе.

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

Наконец пришло время развернуть это приложение в мире и поделиться своим творением. Вы упрощаете задачу, просто запуская npm run build и добавляя команду для scp файлов на свой сервер.

Вы впервые запускаете npm run build и обнаруживаете, что это занимает 20 секунд. «Это единственный раз, когда я буду развертывать», — говорите вы себе и не обращаете внимания на то, сколько времени занимает сборка.

Вы загружаете свой крутой новый сайт и понимаете, что у вас опечатка. Вы делаете быстрое изменение, а затем повторно развертываете. Прежде чем ваши изменения вступят в силу, пройдет еще 20 секунд.

«Хм, может быть, мне стоит обновить здесь отступы». — А если бы это был другой цвет? «Я должен добавить Google Analytics». Все виды новых идей роятся в вашем уме. Каждый из них требует для обновления только одну строку кода. Тем не менее, чтобы развернуть этот код, потребуется 20–30 секунд.

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

Это не выдуманная история. Это моя текущая ситуация с Кайдзен, музыкальным приложением, над которым я сейчас работаю.

В других проектах я видел, как время сборки в продакшене увеличилось до более чем минуты. Иногда требуется в два раза больше времени при работе на более медленной машине сборки.

В прошлом я писал о важности быстрой итерации в статье 3 строки кода не должны занимать весь день. Тот же принцип распространяется и на развертывание кода. Нельзя утверждать, что что-то сделано, пока оно не будет полностью проверено в производственной среде. Чем медленнее этот процесс, тем дольше человек должен ждать, чтобы увидеть, работает ли его код должным образом.

В этом посте показано, как заменить сборщик веб-пакетов, установленный приложением create-react-app, на гораздо более быстрый сборщик esbuild.

Ранее я писал о связывании вашего экспресс-приложения с помощью esbuild, в котором используются некоторые преимущества esbuild.

Установить сборку

npm i -D esbuild

Обновить скрипт сборки в package.json

// package.json
"scripts": {
    "start": "react-scripts start",
    "build": "esbuild src/index.js --bundle --outfile=public/js/app.js --loader:.js=jsx",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},

Повторно запустить сборку

npm run build

В приложении create-react-app по умолчанию вы должны увидеть следующие ошибки:

Включить синтаксис JSX для файлов js

Первые две ошибки предполагают добавление --loader:.js=jsx в команду сборки. Esbuild делает это по умолчанию для файлов с расширением jsx, но это необходимо для обработки файлов только с расширением .js.

// package.json
"build": "esbuild src/index.js --bundle --outfile=build/js/app.js --loader:.js=jsx"

Первые две ошибки предполагают добавление --loader:.js=jsx в команду сборки. Esbuild делает это по умолчанию для файлов с расширением jsx, но это необходимо для обработки файлов только с расширением .js.

Добавить загрузчик для SVG

Приложение по умолчанию использует синтаксис импорта для включения изображения SVG. esbuild по умолчанию не обрабатывает файлы этого типа. Чтобы поддерживать такие вещи, esbuild поставляется с поддержкой плагинов. Вы можете найти список плагинов сообщества esbuild здесь. В этом случае мы будем использовать esbuild-plugin-inline-image, чтобы встроить наше изображение svg. В качестве бонуса этот плагин также будет удовлетворять будущие потребности img.

npm i -D esbuild-plugin-inline-image

Чтобы загрузить новый плагин, нам нужно изменить нашу команду сборки, чтобы использовать esbuild JavaScript API.

// build.js
const esbuild = require("esbuild");
const inlineImage = require("esbuild-plugin-inline-image");

esbuild.build({
  entryPoints: ["./src/index.js"],
  outfile: "./public/js/app.js",
  minify: true,
  bundle: true,
  loader: {
    ".js": "jsx",
  },
  plugins: [inlineImage()],
}).catch(() => process.exit(1));
// package.json
"build": "node build.js"

И с этими изменениями вы должны увидеть успешную сборку при запуске npm run build.

На моем компьютере эта команда сборки теперь занимает ~ 60 миллисекунд. Буквально в 100 раз быстрее, чем 6-секундная сборка веб-пакета. Но мы еще не закончили, нам еще нужно увидеть и запустить эти изменения.

Обновите index.html в папке public

Create React App создает папку public с несколькими предварительно заполненными файлами. Включенный index.html есть больше шаблона, который затем обрабатывается и выводится в папку build при запуске react-scripts build.

С нашей новой сборкой esbuild нет необходимости в том, чтобы этот файл был шаблоном. Удалите ссылки на %PUBLIC_URL% и добавьте тег script, указывающий на наши недавно созданные пакеты app.js и app.css.

// public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <link rel="manifest" href="/manifest.json" />
    <title>React App</title>
    <script src="/assets/app.js" async defer></script>
    <link rel="stylesheet" href="/assets/app.css"/>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

Вы также, вероятно, захотите добавить public/js к .gitignore, так как вы, вероятно, не хотите проверять производственную сборку.

Добавьте скрипт serve.js для автоматического восстановления изменений

// serve.js
const esbuild = require("esbuild");
const inlineImage = require("esbuild-plugin-inline-image");

esbuild
  .serve(
    {
      servedir: "public",
      port: 8000,
    },
    {
      entryPoints: ["./src/index.js"],
      outfile: "./public/js/app.js",
      bundle: true,
      loader: {
        ".js": "jsx",
      },
      plugins: [inlineImage()],
    }
  )
  .catch(() => process.exit());

Замените npm start на serve.js

// package.json
"start": "node serve.js"

Запуск npm start запустит локальный сервер разработки на порту 8000, чтобы вы могли получить доступ через http://localhost:8000. При этом вы должны увидеть, что приложение работает так, как ожидалось, и как первоначальная сборка, так и последующие сборки выполняются молниеносно.

Заключение

Всего за несколько шагов мы преобразовали 6-секундную сборку в 60-миллисекундную. Есть несколько вещей, которые еще можно было бы исправить, но в конечном итоге это должно дать вам хорошее начало для того, как преобразовать сборку React на основе веб-пакета в esbuild. Как упоминалось ранее, я буду изучать это преобразование дальше с кодом внешнего интерфейса для Кайдзен и буду писать о любых проблемах, с которыми я сталкиваюсь в более крупном проекте.

Первоначально опубликовано на https://devtails.xyz 28 февраля 2022 г.