Пример веб-приложения на TeqFW

Дата публикации: 2024-06-14

В демонстрации показано применение контейнера объектов и внедрения зависимостей @teqfw/di в браузерном приложении. Это знакомый ToDo List без серверной части: набор статических файлов загружается и исполняется в браузере.

Чистый JavaScript с ES-модулями даёт важное преимущество при отладке: в браузере видны те же файлы, что и в IDE.

Подключение контейнера

Библиотека доступна как ES-модуль, например через unpkg:

<script type="module">
  import Container from 'https://unpkg.com/@teqfw/di';
</script>

Создание и настройка

Контейнер не хранит заранее подготовленные объекты. Его Resolver вычисляет путь к исходнику по идентификатору зависимости. После создания контейнера связываем пространство имён Demo с папкой ./js:

const container = new Container();
const root = new URL(location.href).href.replace('index.html', '');
const resolver = container.getResolver();
resolver.addNamespaceRoot('Demo', root + '/js');

Тогда имена превращаются в адреса модулей:

Запуск приложения

Символ $ в конце идентификатора означает singleton. Контейнер создаёт его один раз и затем возвращает тот же объект:

const app = await container.get('Demo_App$');
app.run();

Базовые формы идентификаторов:

Описание зависимостей

Статический импорт нужен только для самого контейнера; остальные модули связываются идентификаторами в конструкторе:

export default class Demo_App {
  constructor({
    Demo_Defs$: defs,
    Demo_ToDo_List$: list,
  }) {
    this.defs = defs;
    this.list = list;
  }
}

Контейнер загрузит модули, создаст нужные singleton-объекты и передаст их приложению. Если нужен сам класс, а не его объект, запрос выглядит проще:

export default class Demo_ToDo_List {
  constructor({ Demo_ToDo_Item: ToDoItem }) {
    this.item = new ToDoItem();
  }
}

Вывод

@teqfw/di переносит привычные enterprise-подходы — контейнер объектов и пространства имён — в SPA и PWA. Для запуска демо достаточно разместить папку web/ на статическом хостинге. Позднее связывание избыточно для маленькой статичной страницы, но становится полезным в больших приложениях и наборах пакетов; тот же подход также позволяет разделять код фронтенда и Node.js-бэкенда.