Согласно заголовку, я покажу, как создать приложение React в виде одного HTML-файла, все еще используя Create React App и без извлечения. Это определенно не распространено и, вероятно, не является лучшей практикой (особенно с такими понятиями, как разделение пакетов и отложенная загрузка). Тем не менее, если вы столкнулись с ситуацией, когда вам нужно развернуть приложение React в виде одного HTML-файла (возможно, из-за некоторых ограничений, налагаемых вашей средой развертывания), это может помочь.

Использование CRACO (создать переопределение конфигурации приложения React)

Хотя приложение Create React абстрагируется от многих сложностей при настройке среды разработки React, оно не позволяет настраивать некоторые из его базовых конфигураций (например, Webpack, Babel), что формирует мотивацию таких библиотек, как CRACO, целью которой является быть хакерским слоем поверх Create React App. Хотя есть и другие подобные библиотеки, я обнаружил, что CRACO относительно проста для этой цели.

Встроенный JS и CSS

Основная цель состоит в том, чтобы использовать CRACO для переопределения определенной конфигурации веб-пакета, чтобы транспилированные JavaScript и CSS были встроены в файл HTML (например, index.html).

html-webpack-inline-source-plugin

Быстрый поиск в Google/stackoverflow подскажет использование этого плагина. Однако быстрый взгляд на его репозиторий GitHub показывает, что плагин больше не поддерживается и вместо этого указывает на InlineChunkHtmlPlugin, включенный как часть приложения Create React.

Встроенный JS с InlineChunkHtmlPlugin

Изучая файл конфигурации Webpack, используемый с приложением Create React, мы видим, что InlineChunkHtmlPlugin используется для встраивания только файлов JS с префиксом runtime.

...
// Inlines the webpack runtime script. This script is too small to warrant      
// a network request.
// https://github.com/facebook/create-react-app/issues/5358      isEnvProduction && 
  shouldInlineRuntimeChunk && 
  new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
...

Мы можем изменить выражение регулярного выражения на /.+[.]js/, чтобы вместо этого включить все файлы JS.

Встроенный CSS через загрузчики

Что касается CSS, мы смотрим на правила модуля Webpack и наблюдаем, как разные типы загрузчиков используются для разработки и производства. Мы также отмечаем, как загрузчик стилей, используемый в разработке (в основном для поддержки перезагрузки в реальном времени), добавляет стили через тег стиля в html. Кажется, это то, что нам нужно, и поэтому мы можем изменить производственную конфигурацию, чтобы также использовать style-loader.

...
const getStyleLoaders = (cssOptions, preProcessor) => { 
  const loaders = [
    isEnvDevelopment && require.resolve('style-loader'),
    isEnvProduction && { 
      loader: MiniCssExtractPlugin.loader,
...

Внедрение с CRACO

С нашим подходом к встраиванию необходимых файлов JS и CSS мы можем легко достичь нашей цели, используя CRACO в соответствии с его документацией. После включения зависимости CRACO и обновления соответствующих сценариев npm мы включаем наш craco.config.js следующим образом:

Следуя документации CRACO, мы используем атрибут configure для переопределения настроек, сгенерированных приложением Create React. Мы выполняем 2 шага, как указано выше:

  1. Замените регулярное выражение, используемое InlineChunkHtmlPlugin, чтобы включить все файлы JS. Обратите внимание, как мы находим плагин, используя instanceof
  2. Мы ищем загрузчик CSS из правил модуля и изменяем любую запись, которая использует mini-css-extract-plugin, чтобы использовать style-loader

Вывод

Мы только что увидели, как мы можем использовать CRACO для внесения незначительных изменений в конфигурацию веб-пакета, чтобы проект Create React App теперь мог собираться в один HTML. Конечно, это определенно взлом вокруг Create React App, и он очень чувствителен к изменениям, внесенным в проект Create React App. Кроме того, как упоминалось в начале, это что-то необычное, и вы, возможно, захотите сначала поставить под сомнение необходимость этого решения.