企业服务目录
@ng-mfe/services 将企业应用的通用能力沉淀为 11 项界面无关服务:不依赖任何 UI 框架、以纯 TypeScript 实现、通过构造参数与鸭子类型注入协作。Portal 在启动时创建单例并注入 MfeEngine,子应用经 MfeBootstrapContext 按字段消费——同一份服务实例跨 Angular / Vue / React / Web Component / 纯 JS 子应用共享。
// examples/portal/src/app/services/mfe.init.ts(节选,真实源码)
import { AuthService } from '@ng-mfe/services/auth';
import { CacheService, CacheMonitor } from '@ng-mfe/services/cache';
import { ACLService } from '@ng-mfe/services/acl';
import { I18nService, SettingsService, MenuService } from '@ng-mfe/services/theme';
import { HttpMiddlewarePipeline, DeduplicateMiddleware, TimeoutMiddleware } from '@ng-mfe/services/http-pipeline';
const auth = new AuthService({ loginUrl: '/login' });
const cache = new CacheService({ maxEntries: 500, ttl: 300_000, defaultLevel: 'm' });
const cacheMonitor = new CacheMonitor(cache, { interval: 30_000, threshold: 0.6, minSamples: 20 });
const acl = new ACLService();
const i18n = new I18nService({ defaultLang: 'zh-CN', fallbackLangs: ['en'] });
const settings = new SettingsService();
const menu = new MenuService({ acl });
const httpPipeline = new HttpMiddlewarePipeline();
httpPipeline.use(new DeduplicateMiddleware());
httpPipeline.use(new TimeoutMiddleware(15000));
const engine = new MfeEngine(options, {
eventBus, sharedState, acl, auth, cache, settings, menu, i18n, httpPipeline,
});服务对象经引擎注入后,子应用在 bootstrap(ctx) 中以 ctx.auth / ctx.cache / ctx.i18n 等字段消费(完整字段见 核心概念)。
服务清单
| 服务 | 子路径 | 一句话职责 | 核心入口 | 深入阅读 |
|---|---|---|---|---|
| ACL 权限 | @ng-mfe/services/acl | 角色 + 能力双模型权限判定,oneOf / allOf / except | ACLService.can() setRole() setAbility() | API · 教程 14 |
| 认证 | @ng-mfe/services/auth | 双 Token 模型、JWT 解析、单飞刷新、4 种 TokenStore | AuthService.set() refreshToken() | API · 架构 |
| 多级缓存 | @ng-mfe/services/cache | L1/L2/L3 三级缓存 + 单飞 + 监控建议 | CacheService.getOrSet() CacheMonitor | API · 架构 |
| 功能开关 | @ng-mfe/services/feature-flag | 布尔/条件式开关,支持远程加载 | FeatureFlagService.isEnabled() | API · Recipe |
| HTTP 管道 | @ng-mfe/services/http-pipeline | 中间件管道 + 重试/去重/超时统一执行回路 | HttpMiddlewarePipeline.run() | API · 架构 |
| 日志 | @ng-mfe/services/logger | 分级日志 + 可插拔 Sink + 子 Logger | LoggerService createChild() | API |
| Mock | @ng-mfe/services/mock | 规则式本地模拟 + CRUD 工厂 + 跨应用规则合并 | MockService createCrudMock() | API · Recipe |
| 通知 | @ng-mfe/services/notification | 通知中心 + 宿主注入确认框 | NotificationService.success() confirm() | API · Recipe |
| 存储 | @ng-mfe/services/storage | 带前缀/TTL 的 local+session 双层存储 | StorageService.set() get() | API |
| 主题/菜单/I18n | @ng-mfe/services/theme | 布局设置持久化、菜单 ACL 过滤、扁平词条翻译 | SettingsService MenuService I18nService.fanyi() | API · 教程 15 |
| WebSocket | @ng-mfe/services/websocket | 多连接管理、自动重连、JSON 收发 | WebSocketService.connect() send() | API · Recipe |
通用设计约定
界面无关 —— 所有服务不 import 任何框架(唯一运行时依赖是 @ng-mfe/core 的 EventBus,用于 AuthCoordinator 事件广播);UI 行为(确认框、Toast)由宿主通过回调注入,例如 NotificationService.setConfirmHandler()。
鸭子类型协作 —— 服务间协作面向最小接口而非具体类:MenuService 只要求注入 { can(value): boolean } 与 { fanyi(key): string },MapLayerRegistry 的权限过滤同理(见 地图架构)。这让 Mock 与替身(见 @ng-mfe/testing 的 createMockAcl 等 8 个工厂)天然可替换。
配置即构造参数 —— 每个服务以可选的 Plain Object 配置初始化,默认值面向中后台场景(如 CacheService 默认 maxEntries: 1000、AuthService 默认提前 60s 刷新),全部默认值在 API 参考对应页逐项列出。
生命周期 —— 服务单例由 Portal 持有;AuthCoordinator.start() 登出时自动级联 acl.clear() / menu.clear() / cache.clear() 并广播 MFE_EVENTS.AUTH_LOGOUT;各服务提供 destroy() 供测试与引擎销毁时释放定时器与监听器。
错误处理速查
| 服务 | 常见异常 | 处理方式 |
|---|---|---|
| auth | 刷新失败 | refreshToken({ logoutOnFailure: true })(默认)自动登出并广播 |
| shared-state | 写入受保护键 | 抛 Error('[ng-mfe/state] Key "…" is protected. Only Portal can modify it.'),以 owner: 'portal' 写入 |
| websocket | 未连接时 send | 抛 Error('连接 xx 未就绪'),先监听 onStatus 为 connected |
| event-bus | RPC 超时 | request() 默认 5000ms 后 reject,调用方 catch 降级 |
| cache | 存储配额/序列化失败 | 持久层读写失败静默降级为内存语义,不阻断业务 |
最佳实践
- 子应用永远不要 new 服务 —— 服务实例的唯一持有者是 Portal;子应用从
ctx取用,保证跨应用状态一致。 - 写权限收敛到 Portal ——
currentUser等键注册进protectedKeys,登录流程由 Portal 完成,子应用只读订阅。 - 网络请求走管道 —— 三框架分别用
createHttpPipelineInterceptor/createMfeAxiosInterceptors/createMfeFetch接入统一管道,自动获得去重、超时、重试与缓存。 - Mock 规则按子应用注册 —— 子应用
registerAppMockRules('my-app', rules),Portal 端enableAutoMerge()自动合并;独立运行时再自装installMockFetch。 - 读懂数据,再调缓存 ——
CacheMonitor.onOptimize的建议(扩容/延长 TTL/晋升热键)基于真实命中率采样,设置页的"缓存优化建议"即由此驱动。