npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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 - 组件注册表 Context
  • ClientGlobalStateContext - 全局状态 Context(jotai atoms)
  • ClientServicesContext - 服务注册表 Context
  • ClientHooksContext - 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" /> : null

3. 命名规范

  • 组件:PascalCase,如 AvatarUserProfile
  • Hook:camelCase 且以 use 开头,如 useAuthuseUser
  • 服务:camelCase,如 userServiceapiService

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