Способ автоматического перезапуска веб-пакета при изменении файла

Обновлено: 21.11.2024

Эта глава является ключом к совершенству настройки нашего приложения Express, по крайней мере, если мы делаем это правильно.

Самый распространенный способ обработки перезагрузки сервера — использование nodemon. Этот инструмент помещает ваш скрипт в отдельный процесс, следит за изменениями в ваших файлах и перезапускает весь процесс при запуске.

Хотя это работает очень просто и делает то, что нам нужно, это далеко не идеально. Поскольку наш сервер webpack-dev-server также работает в том же скрипте, он также будет перезапущен. Это имеет некоторые нежелательные последствия:

  • webpack настолько умен, что может пересобирать только те модули, которые были изменены. Это делает webpack очень быстрым. Однако, если сервер перезапустить, ему придется восстанавливать все с нуля.
  • Браузер разорвет соединение с сервером через сокет. У клиента есть механизм повторного подключения, но он выдает некоторые ошибки и в лучшем случае будет ненадежным.
  • Мы не сможем перезагрузить браузер, так как сервер также выйдет из строя, мы не можем позволить nodemon обратиться к wds, чтобы вызвать перезагрузку.

Итак, когда о Nodemon не могло быть и речи, я начал искать альтернативы и нашел несколько интересных сообщений в блоге на эту тему:

По сути, нам нужно сделать 3 вещи, чтобы заменить Nodemon более контролируемым решением:

  1. Используйте chokidar для отслеживания изменений файлов.
  2. Перезапустите сервер, как я узнал из блога Акшендры.
  3. Очистить требуемый кеш узла, как показано в записи блога Кевина.

Таким образом, мы сохраняем контроль над перезапуском, сохраняя работоспособность сервера webpack-dev-server.

Хорошо, хватит рассуждений, приступайте к коду!

Установка пакетов

Chokidar — это библиотека, являющаяся оболочкой собственного API NodeJS fs.watch. Nodemon также использует эту библиотеку.

Оберните приложение Express в функцию

Если мы создадим новый экземпляр сервера после перезапуска, нам также понадобится новый экземпляр приложения Express. Чтобы избежать «синглтона», мы должны обернуть определение приложения Express в функцию, чтобы мы получали новый экземпляр каждый раз при вызове функции.

В вашем /src/server/app.js — раньше

Мы должны адаптировать наш сценарий запуска для работы с этим изменением, поэтому в вашем /bin/www :

(Обратите внимание на замыкающие скобки)

Реализовать просмотр файлов и перезапуск сервера

Далее мы внесем существенные изменения в /bin/www . Вот как это выглядит:

Массив сокетов будет иметь ссылку на каждое подключение к серверу. Нам понадобится это, чтобы закрыть их перед закрытием сервера.

server будет содержать активный экземпляр сервера.

Код для запуска http-сервера теперь заключен в промис внутри этого метода. Я также добавил прослушиватель событий «соединение», который помещает сокет в массив сокетов. Это будет использовано для уничтожения любых открытых соединений, когда мы захотим выключить сервер.

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

Остановите сервер после уничтожения любых подключений к открытым сокетам, если таковые имеются.

Перезапустить = остановить + очистить кеш + запустить!

Это фактически запускает сервер при вызове скрипта.

Запустите webpack-dev-server.

Начать просмотр файлов сервера и вызвать перезагрузку() при изменении файла.

Заключение

Вот оно! Теперь вы сможете запустить свой сервер разработки, запустив yarn start или npm run start . Всякий раз, когда вы вносите изменения на сервер (маршруты, представления и т. д.), он должен автоматически перезагружать сервер. Однако вам все равно придется обновить браузер вручную. Мы положим глазурь на торт в следующей главе!

После завершения этой главы ваше приложение должно выглядеть как пример приложения в теге Chapter-5.

Горячая замена модулей (HMR) заменяет, добавляет или удаляет модули во время работы приложения без полной перезагрузки. Это может значительно ускорить разработку несколькими способами:

  • Сохранение состояния приложения, утраченного при полной перезагрузке.
  • Экономьте драгоценное время разработки, обновляя только то, что изменилось.
  • Мгновенное обновление браузера при внесении изменений в CSS/JS в исходном коде, что почти сравнимо с изменением стилей непосредственно в инструментах разработчика браузера.

Как это работает

Давайте рассмотрим различные точки зрения, чтобы точно понять, как работает HMR.

В приложении

Следующие шаги позволяют заменять модули в приложении и из него:

  1. Приложение запрашивает у среды выполнения HMR наличие обновлений.
  2. Среда выполнения асинхронно загружает обновления и уведомляет приложение.
  3. Затем приложение просит среду выполнения применить обновления.
  4. Среда выполнения синхронно применяет обновления.

Вы можете настроить HMR так, чтобы этот процесс происходил автоматически, или вы можете выбрать, чтобы для обновлений требовалось взаимодействие с пользователем.

В компиляторе

В дополнение к обычным активам компилятор должен выдавать «обновление», чтобы разрешить обновление с предыдущей версии на новую версию. "Обновление" состоит из двух частей:

  1. Обновленный манифест (JSON)
  2. Один или несколько обновленных фрагментов (JavaScript)

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

Компилятор гарантирует, что идентификаторы модулей и идентификаторы фрагментов непротиворечивы между этими сборками. Обычно эти идентификаторы хранятся в памяти (например, с помощью webpack-dev-server), но их также можно сохранить в файле JSON.

В модуле

HMR — это дополнительная функция, которая влияет только на модули, содержащие код HMR. Одним из примеров может быть исправление стилей с помощью загрузчика стилей. Чтобы исправление работало, загрузчик стилей реализует интерфейс HMR; когда он получает обновление через HMR, он заменяет старые стили новыми.

Аналогичным образом при реализации интерфейса HMR в модуле можно описать, что должно произойти при обновлении модуля. Однако в большинстве случаев не обязательно писать код HMR в каждом модуле. Если в модуле нет обработчиков HMR, всплывает всплывающее окно обновления. Это означает, что один обработчик может обновить все дерево модулей. Если обновляется один модуль из дерева, перезагружается весь набор зависимостей.

Подробнее об интерфейсе module.hot см. на странице API HMR.

Во время выполнения

Здесь все становится немного более техническим. если вас не интересует внутреннее устройство, перейдите на страницу API HMR или в руководство по HMR.

Для среды выполнения модульной системы генерируется дополнительный код для отслеживания родительских и дочерних модулей . Со стороны управления среда выполнения поддерживает два метода: проверить и применить .

Метод apply помечает все обновленные модули как недействительные. Для каждого недопустимого модуля должен быть обработчик обновления в модуле или в его родителях. В противном случае недопустимый флаг всплывает и также делает недействительными родителей. Каждый пузырь продолжается до тех пор, пока не будет достигнута точка входа приложения или модуль с обработчиком обновления (в зависимости от того, что наступит раньше). Если он всплывает из точки входа, процесс завершается сбоем.

После этого все недопустимые модули удаляются (через обработчик удаления) и выгружаются. Затем текущий хеш обновляется и вызываются все обработчики принятия. Среда выполнения возвращается в состояние ожидания, и все продолжается как обычно.

Начать

HMR можно использовать при разработке в качестве замены LiveReload. webpack-dev-server поддерживает горячий режим, в котором он пытается обновиться с помощью HMR, прежде чем пытаться перезагрузить всю страницу. Дополнительные сведения см. в руководстве по замене горячего модуля.

Как и многие другие функции, сила webpack заключается в его настраиваемости. Существует множество способов настройки HMR в зависимости от потребностей конкретного проекта. Однако для большинства целей подойдет webpack-dev-server, который позволит вам быстро приступить к работе с HMR.

Читайте также: