Как заставить ваше серверное приложение Heroku эффективно создавать и обслуживать одностраничное приложение вместе с ним.

Кто-то из Stackoverflow задал вопрос о том, как запустить npm run build и заставить серверную часть обслуживать клиентское приложение как часть конвейера развертывания Heroku. Другими словами, как развернуть монорепозиторий фронтенд-бэкэнд на Heroku. Поскольку я собирал решение по кусочкам, когда портировал собственное веб-приложение на Heroku, я написал краткий ответ. Этот пост представляет собой более подробное руководство по настройке всего.

Основные принципы построения внешнего интерфейса как части вашего развертывания и последующего обслуживания его через серверное приложение сводятся к следующему:

  1. использование правильных сборочных пакетов на Heroku;
  2. указание процессу сборки Heroku скомпилировать интерфейсное приложение перед компиляцией slug приложения и кешированием зависимостей для последующих сборок.
  3. обеспечение того, чтобы скомпилированные ресурсы внешнего интерфейса попали в каталог, в котором их ожидает серверное приложение.

1. Использование правильных сборочных пакетов

Heroku автоматически определит пакет сборки для использования с помощью определенных эвристических методов. Например, если ваше приложение представляет собой обычное приложение Python, Heroku автоматически определит правильный пакет сборки (Python) для вашего приложения.

Однако, поскольку мы также пытаемся скомпилировать ресурсы внешнего интерфейса, нам придется указать Heroku использовать пакет сборки JavaScript в дополнение к пакету сборки для вашего языка серверной части.

Добавить buildpack довольно просто, вы можете сделать это либо через Heroku CLI, как описано здесь, либо через Heroku Dashboard. Пакет сборки для языка вашего приложения (например, приложение Python) должен быть внизу списка. Пакет сборки NodeJS используется только для компиляции ресурсов внешнего интерфейса.

2. Скомпилируйте приложение JS как часть зависимостей сборки и кеширования.

Следующим шагом является компиляция внешнего интерфейса приложения как части процесса сборки на Heroku. Добавьте package.json в корень вашего проекта, если у вас его еще нет. Две ключевые вещи, необходимые в package.json, - это инструкции по созданию внешнего интерфейса и кэширование каталога node_modules.

Например, если исходный код вашего внешнего приложения находится в client/, вот как package.json в корне проекта должен выглядеть (другие ключи опущены).

{
  ..
  "scripts": {
    "heroku-postbuild": "cd client && yarn install && yarn run build"
  },
  "cacheDirectories": [
    "client/node_modules"
  ]
  ..
}

Heroku автоматически выполнит указанные команды в heroku-postbuild - в данном случае yarn install и yarn run build. Он также будет кэшировать node_modules в каталоге client/ в соответствии с директивойcacheDirectories. Подробнее о процессе сборки и кастомном кешировании.

3. Убедитесь, что скомпилированные файлы попадают в нужное место.

Это хорошая практика. gitignore скомпилированные файлы. На этапе сборки файлы, скомпилированные для производства (т. Е. main.{js,css}), должны быть выведены в каталог, в котором серверная часть будет знать, где их ожидать, как в разработке, так и в производстве.

Например, в моем приложении, находящемся в разработке, main.{js,css} непрерывно компилируются с помощью Rollup по мере обновления исходных файлов. В производственной среде Rollup будет компилировать, обновлять и удалять main.js, очищать и минимизировать main.css в тот же каталог, что и при разработке. Другими словами, производственное приложение найдет соответствующие файлы в том же каталоге, что и в разработке, за исключением производственной среды, которую они скомпилировали для производства в процессе сборки Heroku.

Вот как может выглядеть типичная структура каталогов в таком сценарии. Грубо говоря, на этапе сборки в package.json файлы компилируются из client/src в server/static, где сервер будет знать, как их искать.

⌞ package.json
  ⌞ client
    ⌞ src
    ⌞ node_modules
    ⌞ ...
  ⌞ server
    ⌞ static
    ⌞ src
    ⌞ ...

Эталонная реализация

Пример репозитория, реализующего указатели в этом руководстве, с простым JavaScript в комплекте с Rollup, обслуживаемым приложением Flask, доступен на Github.

Первоначально опубликовано на https://www.karlsutt.com 29 января 2021 г.