Цель этой статьи — показать простой способ работы с HMR в проекте NodeJS с использованием Typescript. Мы также продемонстрируем, как проверять наш проект в режиме реального времени с помощью отладчика vscode.

Не волнуйтесь, эта статья проста, я надеюсь, она будет вам полезна, даже если вы учитесь программировать на Javascript/Typescript.

Требования

  • NodeJS 14+
  • Зависимость Npx установлена ​​(Npx — это зависимость cli, которая помогает упростить процесс установки и выполнения пакетов). Если он у вас не установлен, вы можете запустить следующую команду, чтобы установить его:
npm i --location=global npx

Введение

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

В google вы можете найти много информации, которая объясняет, что эта функциональность поставляется с Webpack, хотя есть несколько независимых инструментов для Node или интегрированных реализаций в цепочках инструментов с включенным такого рода решением, например, Vite или Parcel.

В этой возможности мы будем работать с BeyondJS, метаплатформой, которая по умолчанию включает HMR и основана на создании стандартных пакетов NPM и NODEJS. BeyondJS не нуждается в упаковщиках, как Webpack.

Начало работы

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

Оказавшись там, мы создадим папку «beyond-tutorials» с помощью следующей команды: mkdir beyond-tutorials.

Далее нам нужно получить доступ к папке cd beyond-tutorials.

Оказавшись там, мы выполняем следующую команду и ждем ее завершения:

npx @beyond-js/create-project --type node --name @beyond-tutorials/hmr

Приведенная выше команда делает следующее:

  • Устанавливает BeyondJS глобально.
  • Он создает базовую структуру проекта BeyondJS с помощью Node.

Когда команда завершена, мы открываем Vscode, выполнив:

code .

Если все было выполнено правильно, мы сможем увидеть структуру, подобную приведенной ниже:

Файлы beyond.json и projects.json — это файлы, управляемые BeyondJS, и они позволяют выполнять расширенные настройки, которые не нужны в этой статье. Если вам интересно, вы можете подробнее прочитать о них в официальной документации.

Папка hmr — это наш проект, и там мы найдем следующую структуру:

  • package.json: содержит важные метаданные о проекте, который будет опубликован. Он также определяет функциональные атрибуты проекта. Используется менеджерами пакетов для управления зависимостями и BeyondJS, чтобы знать все важные детали проекта.
  • project.json: содержит дополнительную информацию о проекте.
  • modules: папка, в которой находятся модули проекта. Настраиваемое значение в файле `project.json`.
  • start.mjs: базовый файл для выполнения проекта в узле. Мы собираемся увидеть это в деталях позже.

Запускаем BeyondJS

Для работы с BeyondJS нам нужно инициализировать сервер разработки, чтобы выполнить его в консоли (Вы должны находиться в папке Beyond-tutorials):

beyond run

Если он работает без проблем, мы можем увидеть следующее сообщение:

Welcome to BeyondJS! DevServer is running.
Follow the link to manage your packages with the workspace:
https://workspace.beyondjs.com?port=4000

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

BeyondJS предоставляет пакет «bee» (Beyond Execution Environment), который обрабатывает проекты JavaScript, которые не запускаются в браузере. BeyondJS выполнит наш проект в независимом процессе и будет отвечать за выпуск горячих обновлений без необходимости перезапуска службы.

Настройка vscode для проверки

Теперь мы открываем файл start.mjs, который является особым файлом, если вы хотите работать с отладчиком. Строки прямые:

import bee from "@beyond-js/bee";
(async () => {
    try {
        bee("http://localhost:6500", { inspect: 4000 });
    } catch (e) {
        console.error(e);
    }
})();

Функция bee получает два параметра: URL-адрес DevServer, составленный из localhost, а также порт devServer и порт проверки, настроенные в файле project.jsonfile.

Примечание. BeyondJS предоставляет рабочее пространство, которое позволяет нам управлять проектами, модулями и процессами наших проектов в соответствии с их средой.

Затем (нам нужно, чтобы start.mjs opened) мы идем на панель активности нашего vscode и нажимаем на опцию «Выполнить и отлаживать» (вы можете получить к ней доступ с помощью [ctrl | команда] + Shift + D), вы увидите следующий экран:

Мы перейдем к выполнению Run and Debug, vscode покажет модальное окно с вопросом, какой тип процесса мы хотим запустить, а затеммы выберем узел.

vscode запустит процесс прикрепления к нему файла start.mjs, чтобы мы могли проверить его на вкладке «консоль отладки».

Примечание. vscode по умолчанию пытается выполнить открытый файл и придерживаться этого процесса при запуске, но он может получать более сложные и специфические конфигурации. Для этого необходимо создать файл launch.json.

Тестирование HMR.

Пришло время поработать с нашим основным модулем. Вы можете увидеть это, если откроете файл `modules/main/index.ts`.

Вы увидите, что он имеет следующий код:

export const /*bundle */ message = "Welcome to the first node project made with BeyondJS";

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

const module = await bimport('@beyond-tutorials/hmr/main');

Функция bimport похожа на поддержку асинхронного EcmaScript, но добавляет пару вещей, которые позволяют нам импортировать модули, не беспокоясь об используемой среде.

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

Имя пакета JavaScript определяется в момент его создания и состоит из области видимости «@beyond-tutorial», которая не является обязательной. Имя пакета «hmr».

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

  • message: строка, представленная в нашем модуле.
  • hmr: это объект, предоставляемый BeyondJS, позволяющий нам определять действия на основе горячих обновлений.
  • __beyond_pkg: внутренний объект BeyondJS.

Теперь давайте подпишемся на изменения hmr нашего модуля, выполнив в консоли следующий код:

module.hmr.on('change', ()=> console.log(module.message, performance.now()));

Далее открываем файл index.ts нашего модуля и меняем значение переменной message. Мы сможем увидеть, как console.log печатается в консоли отладчика, показывая нам значение обновленной переменной.

Вот и все! У нас есть модуль в машинописном тексте, где hmr обновляется в режиме реального времени.

Еще одна интересная проблема заключается в том, что служба узла не перезапускается, что делает поведение HMR намного более эффективным, чем такие инструменты, как nodemon, которые перезапускают всю службу.

BeyondJS позаботится о немедленной транспиляции машинописного кода и обновлении в HMR.

Кроме того, мы можем видеть, как обновляется код, напрямую обращаясь к файлу с devServer. Просто перейдите по адресу http://localhost:6500/main.js, и вы получите сгенерированный код.

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

Вам не нужно настраивать start.mjs для каждого проекта, вы можете использовать рабочее пространство BeyondJS, и оно сделает это за вас.

HMR между модулями

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

Для простоты мы скопируем и вставим всю папку основного модуля и переименуем копию в «второй», затем откроем файл module.json и переименуем наш модуль в «второй».

module.json во второй папке должен выглядеть так:

{
    "name": "second",
    "bundle": "ts",
    "files": "*"
}

Точка входа «bundle»: «ts» указывает BeyondJS, что мы будем использовать только TypeScript в этом модуле, существуют и другие типы пакетов для обработки других процессоров, таких как SASS, многоязычные файлы и т. д.

Давайте откроем наш файл second/index.ts и изменим его содержимое на:

export /*bundle*/ const data = {
    language: 'Javascript',
    Framework: 'BeyondJs'
}

Затем мы переходим к файлу index.ts модуля main и корректируем его, чтобы импортировать новый модуль и использовать импортированный объект данных.

import { data, hmr } from "@beyond-tutorials/hmr/second";
export const /*bundle */ message = "Welcome to the first node project 12 12";
hmr.on("change", () => {
    console.log(`second module changed`, data.languages);
});

Итак, в основном, что мы сделали, это импортировали модуль, извлекая данные и объект hmr, подписались на изменения hmr и распечатали данные. При сохранении вы заметите, что консоль отладчика была обновлена ​​путем печати объекта данных, и что создание модуля было распознано без необходимости перезапуска службы.

Теперь давайте перейдем к индексному файлу второго модуля и добавим свойство языка в объект данных:

export /*bundle*/ const data = {
    language: "Javascript",
    Framework: "BeyondJs",
    languages: ["js", "ts"],
};

Вы заметите, что console.log события немедленно печатается в консоли отладчика.

Если вы зашли так далеко, вы смогли проверить простое и эффективное поведение hmr с помощью BeyondJS с непосредственной скоростью, которая значительно улучшит ваш опыт разработки.

Но в реальной жизни, какую пользу мы все это получаем?

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

В следующей статье мы подключимся к базе данных MySQL, используя Sequelize, чтобы протестировать ее.

Без статуса JS

Экспорт модулей ES является статическим. Команда BeyondJS работает над поддержкой возможности динамического добавления новых экспортируемых элементов в модуль, что позволит получить к ним доступ без перезапуска службы. А пока при добавлении новых элементов в экспорт необходимо перезапускать.

Согласно официальной документации, BeyondJS в настоящее время находится в бета-версии, ожидая выхода стабильной версии. Его выпуск ожидается в январе 2023 года. Однако уже сейчас он доступен для создания и компиляции проектов для продуктивных сред.