0.1.6 • Published 1 year ago

@cxra/routine-assistance v0.1.6

Weekly downloads
-
License
-
Repository
-
Last release
1 year ago

@cxra/routine-assistance

Pipes

isD checks if the value is defined

isND checks if the value is undefined or null

asSanitizedHtml is meant to be sanitized to declarative html for use in a template

@cxra/module-federation-navigator

Данная библиотека, предназначена:

  • To make it a little easier to work with Module Federation in basic cases.
  • Автоматизировать не только управление модулями через файл конфигурации, но и управление навигацией к этим модулям и доступностью их для разных контекстов исполнения. Данная потребность возникала: В продуктовой разработке когда один продукт разворачивается для разных заказчиков с разной конфигурациеи. Когда нужно предоставить возможность devops быстро отключать, включать и конфигурировать состав.
  • Сохранить возможность ленивой загрузки и при этом дать возможность самим модулям предоставлять компонент который будет использован в качестве навигационного элемента

Конфигурирование

Основные настройки описываются в конфигурационном файле манифеста модулей {manifest_name}.json для изменения конфигурации после развертывания.

  • Рекомендуемым местом расположения файла конфигурации для проектов где основное приложение написано на angular является .\{app-name}\src\assets\{manifest_name}.json для публикации стандартными средствами
  • Так же регулярным вариантом использования является сборка и предоставления манифеста server-side в виде ответа на запрос, так как формат данных манифеста json

Recommended point to load the configuration is to implement the standard angular app init loop, by provide APP_INITIALIZER

	providers: [{
		provide: APP_INITIALIZER,
		useFactory: (manifest: CXraModuleNavigatorManifest<cxra.module.federation.navigation.NavigableRemoteModuleConfig>) => 
			(): Promise<void> => 
				manifest.load('/assets/modules.manifest.json'),
		deps: [CXraModuleNavigatorManifest],
		multi: true
	}],

Настройка источников модулей

Данная библиотека основана на angular-architects/module-federation-plugin, по этому основными видами потребляемых модулей являются:

  • Модули angular. В качестве type указывается значение module.

    	```
    		"module-a": {
    			"type": "module"
    			"remoteEntry": "http://localhost:3000/remoteEntry.js"
    			"remoteName": "example-module-a"
    			"exposedModule": "./Module"
    			"elementName": "AppModule"
    			...
    		}
    	```
    
    	`elementName` наименование основного класса публикуемого как angular module.
    
    	В частности пример приведенный выше, справедлив для внешнего модуль публикованного следующим образом 
    	```
    		name: "example-module-a"
    		exposes: {
    			"./Module": "./examples/example-module-a/src/app/app.module.ts"
    			"./Component": "./examples/example-module-a/src/app/components/nav/nav.component.ts"
    		}
    	```
  • Скрипты js. В качестве type указывается значение script.

    	```
    		"react-a": {
    			"type": "script"
    			"remoteEntry": "https://witty-wave-0a695f710.azurestaticapps.net/remoteEntry.js"
    			"remoteName": "react"
    			"exposedModule": "./web-components"
    			"elementName": "react-element"
    		}
    	```
    
    	`elementName` наименование component получаемого из публикации в качестве root.

Общие настройки вне зависимости от типа:

remoteEntry публичный адрес размещения сгенерированного файла декларации интегрируемых модулей.

remoteName наименование remote object используемое для публикации.

exposedModule наименование секции размещения модуля в экспозиции.

Настройка навигации модуля

На базовом уровне навигация определяется свойством navigation.

  • Для модуля может быть определено поведение без навигационного элемента.

    	Данное решение может быть применимо в случаях когда функциональность remote модуля должна быть доступна только из определенного блока интерфейса или как звено определенного бизнес сценария. Такой подход реализуется по средствам доступа по конкретному маршруту.
    
    	`navigation` задается непосредственно строкой описывающей route.
    
    	```
    		"navigation": "module-a/offers/:id/accepted"
    	```
  • Для модуля может быть определена глобальная навигация.

    	Данное решение предоставляет возможность самому модулю запубликовать навигационный элемент, `component` который будет использован для отображения в меню, инвертировав данную зависимость из основного приложения. Или напрямую в конфигурационном файле определить `template` который будет использоваться в качестве навигационного элемента, что позволяет интегрироваться с remote module не публикующему навигационный элемент, например если он legacy или поставляется сторонним разработчиком.
    
    	`navigation` задается объектом содержащим ряд конфигураций.
    
    	```
    		"navigation": {
    			"route": {
    				"path": "module-a"
    			},
    			"component": {
    				"type": "ModuleANavComponent",
    				"remoteEntry": "http://localhost:3000/remoteEntry.js",
    				"exposedModule": "./Component"
    			}
    		}
    	```
    
    	* `route` описание route для lazy load сборки модуля
    		* `path` обязательная характеристика задающая строкой route
    		* `params` карта path параметров (_optional_)
    		* `queries` карта условных параметров (_optional_)
    	* `component` описание элемента для представления в навигации
    		* Может быть представлен конфигурацией использующей remote `component` и в данном случае описывается радом свойств.
    			* `type` название класса компонента из remote модуля который будет использоваться в качестве навигационного элемента
    
    				⚠️ Рекомендуется оформлять как __standalone__ компонент
    				```
    					@Component({
    						selector: 'module-a-nav'
    						standalone: true
    						...
    					})
    					export class ModuleANavComponent {}
    				```
    
    			* `remoteEntry` публичный адрес размещения сгенерированного файла декларации модуля содержащего навигационный элемент.
    			* `exposedModule` наименование секции размещения навигационного элемента в экспозиции.
    
    				```
    					exposes: {
    						"./Module": "./examples/example-module-a/src/app/app.module.ts"
    						"./Component": "./examples/example-module-a/src/app/components/nav/nav.component.ts"
    					}
    				```
    		* Может быть представлен конфигурацией использующей `template`
    
    			В данном случае описывается текстовым представлением шаблона напрямую в конфигурационном файле. И предоставляет возможность задания индивидуального значения каждому экземпляру развертывания силами devops.
    
    			```
    				"component": "<span>to <b>reAct-B</b></span>"
    			```

Управление доступностью навигации к модулю, в зависимости от контекста или состояния

В конфигурационном файле манифеста модулей {manifest_name}.json активность модуля и его навигации, может быть установлена в три состояния 'on' | 'off' | 'promise'.

	"module-b": {
		"state": "on | off | promise"
		...
	}
	...
  • on - модуль активен сразу и будет доступен сразу после загрузки инициированной активацией маршрута
  • off - навигация к модулю не будет доступна и маршруты для активации модуля не будут опубликованы
  • promise - навигация к модулю будет разблокировано если будет найдено и выполнено положительно обещание активации, публикуемое по token в DI

    	```
    		providers: [{
    			provide: CXRA_MODULE_OPTIONS,
    			useFactory: (_http: HttpClient) => ({
    				['module-a']: {
    					state: new Promise<boolean>((resolve) => {
    						_http.get<...>(...).pipe(
    							map(user => user.permissions.has(...)),
    							...
    							takeUntil(...)
    						).subscribe(() => resolve(true));
    					})
    				}
    			}),
    			deps: [HttpClient],
    			multi: true
    		}, ...],
    	```

@see cxra.module.federation.navigation.RemoteModuleState

Публикация пользовательских событий модуля

Для публикации реализации возможности отображения факта наличия ии самих пользовательских уведомлений remote module в навигационной части приложения в едином стиле, предусмотрена возможность опубликовать источник событий через контракт CXRA_MODULE_OPTIONS как в непосредственном модуле, так и в локализованном приложении потребителе. Тем самым инвертированная устранив зависимость на предоставление модулю интерфейсов для непосредственного размещения элементов в обобщенной части интерфейса приложения.

Для каждого модуля имеющего оповещения в его секции публикуется:

  • events - представляющий реализацию Observable<Array>

    	```
    		providers: [{
    			provide: CXRA_MODULE_OPTIONS,
    			useFactory: (...) => ({
    				['module-a']: {
    					...
    					events: new BehaviorSubject<unknown>(...)
    				}
    			}),
    			deps: [...],
    			multi: true
    		}]
    	```

Общие настройки

Для задания общих настроек навигации и менеджмента remote modules определен контракт CXRA_MODULE_NAVIGATOR_OPTIONS обладающий рядом характеристик.

  • undefined.component предназначена для определения компонента который будет использован в случае перехода к неопределенному элементу маршрутизации, в случае необходимости задания такого поведения централизовано

    	```
    		providers: [{
    			provide: CXRA_MODULE_NAVIGATOR_OPTIONS,
    			useValue: {
    				undefined: {
    					component: UnfoundComponent
    				}
    			}
    		}],
    	```

Examples

This repository provides examples of an application using this approach.

DescriptionProject
Контекст. Пример проекта используемого для публикации и обработки данных используемых между разными модулями.examples\example-context
Module A. С примером отключения навигации модуля из самого себя.examples\example-module-a
Module B. С примером инкапсуляции внутренних стилей и данных внешнего контекста.examples\example-module-b
Directly the application publishes different modules and navigation.examples\example-app

First run

  • Install packages: yarn install

    	Please note, you **must** use **yarn** during the beta phase of CLI 11 b/c it allows to override dependencies to force the CLI into webpack 5.
  • Build lib`s

    	Navigator: ``yarn build:module-federation-navigator``

Usage

  • Start all micro-frontend's and app: yarn start:example:navigator:all

let's try example

More

More about Module Federation

0.1.4

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago