@linyjs/client-module-interface
v0.0.24
Published
前端模块接口定义包,提供插件式架构所需的类型定义和工具函数。
Readme
@linyjs/client-module-interface
前端模块接口定义包,提供插件式架构所需的类型定义和工具函数。
安装
npm install @linyjs/client-module-interface核心功能
1. 依赖注入类型
IModule- 模块定义IServiceDef- 服务定义IModuleHandler- 模块生命周期处理器IModuleContainer- 模块容器
2. 前端领域类型
IComponent- React 组件类型IRoute- 路由定义IRouteGuard- 路由守卫IRouteLoader- 路由数据加载器
3. 服务接口
IRouteService- 路由服务IGlobalStateService- 全局状态服务(jotai atoms)IComponentListService- 组件列表服务IHooksService- Hooks 服务
4. 资源消费 Hooks ⭐
useClientComponent
从全局注册表中获取 React 组件。
import { useClientComponent } from '@linyjs/client-module-interface'
// 跨模块引用
const Avatar = useClientComponent('userModule.userComponents.Avatar')
// 在组件中使用
function UserProfile() {
return (
<div>
{Avatar && <Avatar userId="123" size="large" />}
</div>
)
}useClientHook
从全局注册表中获取自定义 Hook。
import { useClientHook } from '@linyjs/client-module-interface'
// 跨模块引用
type UseAuthHook = () => { isAuthenticated: boolean; user: any }
const useAuth = useClientHook<UseAuthHook>('authModule.authHooks.useAuth')
// 在组件中使用
function AuthStatus() {
const authState = useAuth ? useAuth() : null
return (
<div>
{authState?.isAuthenticated ? '已登录' : '未登录'}
</div>
)
}useClientService
从全局注册表中获取服务实例。
import { useClientService } from '@linyjs/client-module-interface'
interface IUserService {
getUser(id: string): Promise<User>
updateUser(id: string, data: Partial<User>): Promise<void>
}
// 跨模块引用
const userService = useClientService<IUserService>('userModule.userService')
// 在组件中使用
function UserManagement() {
const handleLoadUser = async () => {
if (userService) {
const user = await userService.getUser('123')
console.log(user)
}
}
return <button onClick={handleLoadUser}>加载用户</button>
}5. React Context
ClientComponentsContext- 组件注册表 ContextClientGlobalStateContext- 全局状态 Context(jotai atoms)ClientServicesContext- 服务注册表 ContextClientHooksContext- Hooks 注册表 Context
引用规则
模块内引用 vs 跨模块引用
| 资源类型 | 模块内引用 | 跨模块引用 |
|---------|-----------|-----------|
| 组件 | serviceTag.componentName | moduleName.serviceTag.componentName |
| Hook | serviceTag.hookName | moduleName.serviceTag.hookName |
| 服务 | serviceTag | moduleName.serviceTag |
| 全局状态 | serviceTag.atomName | moduleName.serviceTag.atomName |
注意:当前版本中,模块内引用需要显式传递完整路径(包含 moduleName),未来会通过 ModuleContext 自动获取当前模块名。
RegistryKey 格式
- 组件:
moduleName.serviceTag.componentName- 示例:
'userModule.userComponents.Avatar'
- 示例:
- Hook:
moduleName.serviceTag.hookName- 示例:
'authModule.authHooks.useAuth'
- 示例:
- 服务:
moduleName.serviceTag- 示例:
'userModule.userService'
- 示例:
- 全局状态:
moduleName.serviceTag.atomName- 示例:
'userModule.userState.user'
- 示例:
最佳实践
1. 类型安全
使用泛型参数为服务和 Hook 提供类型约束:
// ✅ 推荐
const userService = useClientService<IUserService>('userModule.userService')
const useAuth = useClientHook<UseAuthHook>('authModule.authHooks.useAuth')
// ❌ 不推荐(失去类型检查)
const userService = useClientService('userModule.userService')2. 空值检查
所有 Hook 都可能返回 undefined(资源未找到时),使用前应该进行空值检查:
const Avatar = useClientComponent('userModule.userComponents.Avatar')
// ✅ 推荐:空值检查
if (Avatar) {
return <Avatar userId="123" />
}
// ✅ 推荐:可选链
return Avatar ? <Avatar userId="123" /> : null3. 命名规范
- 组件:PascalCase,如
Avatar、UserProfile - Hook:camelCase 且以
use开头,如useAuth、useUser - 服务:camelCase,如
userService、apiService
4. 模块设计
每个模块应该明确声明提供的服务类型:
// 组件服务
class UserComponentService implements IComponentListService {
components = {
Avatar: UserAvatar,
Profile: UserProfile,
}
}
// Hook 服务
class AuthHooksService implements IHooksService {
hooks = {
useAuth,
usePermissions,
}
}
// 普通服务
class UserServiceImpl implements IUserService {
// ...
}示例项目
查看 src/hooks-example.tsx 文件了解完整的使用示例。
相关文档
License
MIT
