@application-kit/module-manifest
v0.1.0
Published
Манифест модуля продукта: контракты web-, CLI-, консьюмер- и грант-манифестов, сборщики модулей процесса с проверкой дублей, SSR-реестр клиентских модулей для NestJS и Vite-плагин клиентских entry по раскладке
Maintainers
Readme
@application-kit/module-manifest
Манифест модуля продукта: модуль сообщает сборке о себе файлами в своём корне, а приложение подключает его одной строкой в реестре процесса. Пакет даёт контракты этих файлов, сборщики модулей процесса с проверкой дублей имён, SSR-реестр клиентских модулей для NestJS и Vite-плагин, который находит клиентские entry по раскладке. Имён модулей, типа навигации и карты грантов продукта в пакете нет: реестры ведёт приложение, типы приходят параметрами.
Установка
yarn add @application-kit/module-manifestPeer-зависимости: @nestjs/common; для входа /nest — @libs-for-dev/vue-modular-application и vue-router; для входа
/vite-plugin — vite (только типы).
Входы
| Вход | Для чего | Тянет |
|------|----------|-------|
| @application-kit/module-manifest | контракты манифестов, сборщики collect*Modules, DuplicateModuleNameError | ничего (типы @nestjs/common) |
| @application-kit/module-manifest/nest | createModuleRegistryProvider — SSR-реестр клиентских модулей | @libs-for-dev/vue-modular-application |
| @application-kit/module-manifest/vite-plugin | vitePluginModuleEntries — script-теги клиентских entry в index.html | node:fs, node:path (типы vite) |
Импорт любого входа не имеет побочных эффектов и не требует окружения. Входы разделены по рантайм-графу: сборщики грузят
CLI- и консьюмер-процессы, и корень с ModuleRegistry втянул бы в них Vue, а vite.config — Nest.
Файлы модуля
| Файл в корне модуля | Контракт | Процесс |
|---------------------|----------|---------|
| module.manifest.ts | ModuleManifestInterface — name, web, clientModuleToken? | web |
| module.cli.ts | ProcessModuleManifestInterface — name, module | CLI |
| module.consumers.ts | ConsumerModuleManifestInterface — плюс queues | консьюмер |
| module.grants.ts | AbilityGrantsManifestInterface<TGrants> — name, grants | web и браузер |
Файл на процесс, а не поля одного манифеста: конфиги модулей валидируют окружение на импорте, и общий манифест тянул бы
в процесс чужой граф с чужим окружением. name равен имени папки модуля — по нему модуль включают из окружения.
Сборка процесса
import { collectProcessModules, collectWebModules } from '@application-kit/module-manifest'
@Module({ imports: [CommonWebModule, ...collectWebModules(MODULE_MANIFESTS)] })
export class AppModule {}
@Module({ imports: [ConsoleModule, ...collectProcessModules(CLI_MANIFESTS)] })
export class CliModule {}Сборщики сохраняют порядок регистрации и бросают DuplicateModuleNameError, если имя встречается дважды: включение
по имени иначе стало бы неоднозначным. collectClientWebModules отдаёт web-модули только тех модулей, у которых есть
clientModuleToken, — их импортирует оболочка, чтобы резолвить клиентские модули.
SSR-реестр клиентских модулей
import { collectClientWebModules } from '@application-kit/module-manifest'
import { createModuleRegistryProvider } from '@application-kit/module-manifest/nest'
@Module({
imports: collectClientWebModules(MODULE_MANIFESTS),
providers: [createModuleRegistryProvider(MODULE_MANIFESTS, () => new ClientVueModule())],
})
export class ClientModule {}Провайдер ModuleRegistry собирает оболочку первой, затем клиентские модули по токенам манифестов в порядке
регистрации — тот же порядок, что у script-тегов в браузере. Тип навигации реестра (TNavigation) выводится из
клиентского модуля оболочки (ClientModuleInterface<RouteRecordRaw[], TNavigation> из vue-modular-application).
Клиентские entry
import { vitePluginModuleEntries } from '@application-kit/module-manifest/vite-plugin'
export default defineConfig({
plugins: [vitePluginModuleEntries({ modulesDirectory: path.resolve(root, 'src/modules'), root })],
})Плагин заменяет в index.html плейсхолдер <!-- module-entries --> (MODULE_ENTRIES_PLACEHOLDER) script-тегами
файлов <modulesDirectory>/<name>/user-interface/client/app/entry.<name>.ts в порядке имён модулей. Entry с чужим
именем не принимается — опечатка не оставит модуль без клиента молча. Нет плейсхолдера — сборка падает с
MissingModuleEntriesPlaceholderError. Список берётся из раскладки, а не из манифестов: манифест тянет Nest-модуль и в
процесс Vite не импортируется.
Без Vite — те же шаги функциями: findModuleEntries(modulesDirectory) отдаёт пути entry в порядке имён модулей,
injectModuleEntries(html, { modulesDirectory, root }) — разметку с тегами на месте плейсхолдера.
